jiwopene
jiwopene

Reputation: 3657

GNU ld produces ELF with no symbols when static library is used

I am trying to pack multiple object files into ar archive and then pass the archive to the linker.

My C source file foo.c contains this line:

void foo();

When it is compiled using gcc -c foo.c, it the resulting object file contains this symbol:

$ nm foo.o
0000000000000000 T foo

Then I archive it:

$ ar rcs foo.a foo.o

The archive now contains the file foo.o with the same symbol:

$ nm foo.a
foo.o:
0000000000000000 T foo

But linked ELF contains no symbol named foo:

$ ld foo.a
$ nm a.out
0000000000401000 A __bss_start
0000000000401000 A _edata
0000000000401000 A _end
                 U _start

Why is it not there?

I want to use this approach because I am producing multiple executable file variants with one common part (one archive, not shown for simplicity) and second part containing main symbol (the object files in foo.a).

Upvotes: 1

Views: 497

Answers (2)

n. m. could be an AI
n. m. could be an AI

Reputation: 120079

Static libraries are normally linked as follows. When the linker sees a static library, it takes the set of symbols unresolved so far, and looks each such symbol up in the library. Only objects that resolve these symbols are included in the final binary.

To override this behaviour, gnu ld has a switch --whole-archive. From the man page:

For each archive mentioned on the command line after the --whole-archive option, include every object file in the archive in the link, rather than searching the archive for the required object files. This is normally used to turn an archive file into a shared library, forcing every object to be included in the resulting shared library.

Upvotes: 1

jiwopene
jiwopene

Reputation: 3657

Use ld flag --whole-archive:

$ ld --whole-archive foo.a

Upvotes: 0

Related Questions