c++ undefined references with static library

C++Static Libraries

C++ Problem Overview


I'm trying to make a static library from a class but when trying to use it, I always get errors with undefined references on anything. The way I proceeded was creating the object file like

g++ -c myClass.cpp -o myClass.o

and then packing it with

ar rcs myClass.lib myClass.o

There is something I'm obviously missing generally with this. I bet it's something with symbols. Thanks for any advice, I know it's most probably something I could find out if reading some tutorial so sorry if bothering with stupid stuff again :)

edit:

myClass.h:

class myClass{
	public:
		myClass();
		void function();
};

myClass.cpp:

#include "myClass.h"

myClass::myClass(){}
void myClass::function(){}

program using the class:

#include "myClass.h"

int main(){
myClass mc;
mc.function();

return 0;
}

finally I compile it like this:

g++ -o main.exe -L. -l myClass main.cpp

the error is just classic:

C:\Users\RULERO~1\AppData\Local\Temp/ccwM3vLy.o:main.cpp:(.text+0x31): undefined
 reference to `myClass::myClass()'
C:\Users\RULERO~1\AppData\Local\Temp/ccwM3vLy.o:main.cpp:(.text+0x3c): undefined
 reference to `myClass::function()'
collect2: ld returned 1 exit status

C++ Solutions


Solution 1 - C++

This is probably a link order problem. When the GNU linker sees a library, it discards all symbols that it doesn't need. In this case, your library appears before your .cpp file, so the library is being discarded before the .cpp file is compiled. Do this:

g++ -o main.exe main.cpp -L. -lmylib

or

g++ -o main.exe main.cpp myClass.lib

The Microsoft linker doesn't consider the ordering of the libraries on the command line.

Solution 2 - C++

Another possible cause: forgetting extern "C".

I ran into this because I was trying to link a C++ program with a C static library. The library's header didn't have extern "C" so the linker was looking for a mangled function name, and the library actually had the unmangled function name.

It took a while to figure out what was going on, so I hope this helps someone else.

Solution 3 - C++

This is an issue how the linker optimizes the output code. Lets assume we have an executable that uses two libraries: Lib_A and Lib_B. Lib_A depends on Lib_B The Lib_A defines symbols: Lib_A1 and Lib_A2, and the Lib_B defines symbol Lib_B1 and Lib_B2. Now lets assume that the executable uses only symbol Lib_A1, and Lib_A1 uses symbol Lib_B1 which is defined in Lib_B. Symbol Lib_B1 is never used in the executable.

  1. In case of windows, the linker works like this: I have executable with two which uses some libs and all symbols used in executable and all libs are lib_A1 and lib_B1. Thus I will need these two symbols, and the rest is unnecessary. I will undefine lib_A2 and lib_B2
  2. In case of linux if you link Lib_B before Lib_A like this: g++ .... -lLib_B -lLib_A The linker works like this: I have executable that first links Lib_B. I do not see that the executable uses symbol Lib_B1 nor Lib_B2. They are unnecesary, thus I will undefine them. Later the linker see. Oh I have another library Lib_A. I can see that executable uses symbol Lib_B1. I will keep it and undefine unused symbol Lib_B2. It does not see that Lib_B1 uses Lib_A1, Which is already undefined.
  3. In case of linux if you link Lib_A before Lib_B like this: g++ ... -lLib_A -lLib_B The linker works like this: I have executable that first links Lib_A. Oh, I can see that executable uses Lib_A1. I will keep them and undefine Lib_A2. Later it can see. Oh I have another library Lib_B. I can see that now executable with already linked symbols, uses Lib_B1, I will keep them. As a result it keeps Lib_B1 and Lib_A1, and undefined Lib_B2 and Lib_A2.

Solution 4 - C++

Use:

g++ -o main.exe main.cpp myClass.lib 

Using the library path and the -l flag is fraught with problems, but if you must do it, rename your library to libmylib.a and then compile as:

g++ -o main.exe main.cpp -L. -lmylib 

Note also that for portability reasons, it's generally a bad idea to use mixed case in the names of source or output files.

Solution 5 - C++

This should avoid linking errors and create the .so shared library:

LOCAL_ALLOW_UNDEFINED_SYMBOLS := true

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPyjongView Question on Stackoverflow
Solution 1 - C++mchView Answer on Stackoverflow
Solution 2 - C++tprk77View Answer on Stackoverflow
Solution 3 - C++Grzegorz DymekView Answer on Stackoverflow
Solution 4 - C++anonView Answer on Stackoverflow
Solution 5 - C++OshiView Answer on Stackoverflow