Search code examples
c++cstatic-linkingundefined-reference

Undefined references when statically linking C++ and C libraries


I have 3 libraries I am trying to link (more than that, but all that is needed for this explanation). The "root" library is c++, which has the second library as a dependency for it and is also c++. The third library is c and is a dependent of the second library.

When linking this project I am getting undefined references to all methods in the third library(which is in c) being called from the second library(which is c++). The third library has it's headers properly enclosed in "extern "C"" as it should for this type of use.

While trying to troubleshoot this I found that the macro for notifying the library that it is being built as static wasn't properly set, so I fixed that and found that it changed another macro that was being placed in front of all c-style functions from an export to instead say "extern "C"". To recap, c-style methods in a c++ library were being declared with "extern "C"" in front of them after I fixed another macro. When I did this all of the c-style methods I was calling in the second library from the "root" library started getting undefined references.

I thought this was odd as I've seen no other library do this, so I commended out the portion of the line where the macro was defined to "extern "C"", instead leaving it blank. When I did this the undefined references to the c-style methods in the second library went away and the undefined references to the methods in the third library returned.

I have tried to research this myself and pretty much every result is "Put an "extern "C" in brackets around it!", however that is already the case here. I also considered it could be a linker order issue, and verified the linker order set in the command going to the linker is appropriate. So I am at a loss as to what is causing this. It seems to be a name mangling thing, but I can't for the life of me find how this is happening or how to fix it.

My question: What the hell is going on? What other avenues can I explore to try and resolve this?

I am on Windows XP 32-bit, compiling with MinGW. If you want to look at code...well that is a bit complicated since this is for a big project, but the root library is a game engine I am working on, the second library is cAudio, and the third library is OpenAL soft. Here is the root directory of the repo, here is the base directory for cAudio, and here is the base directory for OpenAL soft we are using.

I apologize for this being so long, thanks in advance to anyone that made it this far!


Solution

  • I managed to find the cause of the issue. The short version is that CMake was misconfigured.

    The long version is that we had definitions being added manually via CMake when we try to build the library as static (which is the case here). There is one for cAudio, as well as OpenAL. When OpenAL compiled it was using definitions as provided in it's portion of the CMake script appropriately. These definitions were not shared with other projects in the hierarchy. So when it came time for cAudio to compile the export macro didn't resolve to being blank, instead resolving to have it set for "dllimport". When cAudio went to link it was expecting symbols prefixed with "_imp", which was not the case in the compiled library. Thus causing the undefined references I was getting.

    I resolved this by adding the appropriate definition in the cAudio CMake so that the import macro's resolved correctly when cAudio was being compiled with OpenAL includes.