C++ Undefined References with Static Library

c++ undefined references with static library

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.

Linking C++ to static library; undefined reference errors

The library libEAPI.a contains object files compiled in C, not C++.
The symbols therefore have not been name-mangled and cannot serve to
resolve the name-mangled function references generated by your C++
code.

Run:

nm libEAPI.a | grep EApiFanDisable

and you will see no change.

Run:

nm main.o | grep EApiFanDisable

and you will see the mangled symbol, which is neither EApiFanDisable nor EApiFanDisable()
but something more like _Z14EApiFanDisablev, that the linker is actually trying
to resolve.

To avoid these linkage errors you must inform your C++ compiler, when it
compiles the header file(s) of libEAPI, that the declarations therein have
external C linkage, so it will emit unmangled references to the symbols declared: like so:

main.cpp

...
extern "C" {
#include "EAPI.h" // or whatever
}

...

BTW, this commandline:

g++  -o secoTest -lpthread  main.o  libEAPI.a

will fail to link libpthread on a Debian-based distro (Ubuntu et al)
more recent than Debian 6, as all libraries must be linked in dependency order since then:

g++  -o secoTest main.o  libEAPI.a -lpthread

Even better, do not use the non-portable -lpthread and pass the portable
option -pthread for both compilation and linkage. It means: Do whatever
is right to compile/link with Posix Threads support

Why can a static library be linked despite undefined references (missing `extern C`)?

I would have expected it to fail already at linking the static library.

The static "library" is not linked. Its constituent object files are archived - bundled together in an object archive for convenience's sake. That's what the static "library" is. You can think of it as a bunch of object files packed in a "zip" file that the linker can then decode.

So, the only linking the object archive undergoes is when the target binary itself is linked (be it into a .dll/.so or executable).

The use of the object archive is equivalent to the use of the constituent object files: instead of passing the archive to the linker, you can pass all the object files it contained, with same results.

On Unix, the typical name for the tool that manages object archives is ar (archiver) - a very descriptive name indeed. In Unix tradition, the static "libraries" are called object archives. The term static "library" is a confusing misnomer and should be banned.

Usually ar is a much smaller program than the linker - often an order of magnitude smaller. The most rudimentary archiving is just a concatenation with a header added.

Undefined reference in static library to global symbol included in an earlier included static library?

Libraries have to at the end of the command line. ld is searching only one time for the symbols in the library.

LDFLAGS=-L/home/john/deps/install/opt/riscv/lib/gcc/riscv64-unknown-elf/8.1.0 -L/home/john/musl-1.1.23/install/lib -lcrt1 -lgcc -lc 

--library=archive
Add archive file archive to the list of files to link. This option may be used any number of times. ld will search its path-list for
occurrences of libarchive.a for every archive specified. On systems
which support shared libraries, ld may also search for libraries with
extensions other than .a. Specifically, on ELF and SunOS systems, ld
will search a directory for a library with an extension of .so before
searching for one with an extension of .a. By convention, a .so
extension indicates a shared library. The linker will search an
archive only once, at the location where it is specified on the
command line. If the archive defines a symbol which was undefined in
some object which appeared before the archive on the command line, the
linker will include the appropriate file(s) from the archive. However,
an undefined symbol in an object appearing later on the command line
will not cause the linker to search the archive again
. See the -(
option for a way to force the linker to search archives multiple
times. You may list the same archive multiple times on the command
line. This type of archive searching is standard for Unix linkers.
However, if you are using ld on AIX, note that it is different from
the behaviour of the AIX linker.

Undefined reference to functions while linking to static library

do I need to include X.a only or do I need to include both libaries to my code?

You don't "include" libraries in your code, you link them in.

When you link against X.a, the linker copies used parts of the library into your executable.

When you link against a.so, the linker makes a note that a.so is required at runtime, and (if you are using versioned symbols) which versions of symbols from a.so must be present at runtime, but doesn't copy any code from a.so into your executable. However, a.so is still required on the link time.

There are ways to link an executable without a.so, but they are best left to experts (there are too many possible gotcha's with that approach).

Undefined reference when linking with static library, but successful link when compiling with src

I haven't seen all your code, but the problem is most likely caused by how static linking works (http://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking/).

Try changing the order of the libraries, and specifically, try changing this:

$(MODULE_EXE): $(OBJS)
$(CC) $(LIB_DIRS) $(LIBS) $(LINKER_OPTS) -o $@ $^

into this:

$(MODULE_EXE): $(OBJS)
$(CC) $(LIB_DIRS) $(LINKER_OPTS) -o $@ $^ $(LIBS)


Related Topics



Leave a reply



Submit