views:

120

answers:

1

When compiling our project, we create several archives (static libraries), say liby.a and libz.a that each contains an object file defining a function y_function() and z_function(). Then, these archives are joined in a shared object, say libyz.so, that is one of our main distributable target.

g++  -fPIC  -c -o y.o y.cpp
ar cr liby.a y.o
g++  -fPIC  -c -o z.o z.cpp
ar cr libz.a z.o
g++ -shared -L. -ly -lz -o libyz.so

When using this shared object into the example program, say x.c, the link fails because of an undefined references to functions y_function() and z_function().

g++ x.o -L. -lyz -o xyz

It works however when I link the final executable directly with the archives (static libraries).

g++ x.o -L. -ly -lz -o xyz

My guess is that the object files contained in the archives are not linked into the shared library because they are not used in it. How to force inclusion?

Edit:

Inclusion can be forced using --whole-archive ld option. But if results in compilation errors:

g++ -shared '-Wl,--whole-archive' -L. -ly -lz -o libyz.so
/usr/lib/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x1d): undefined reference to `__init_array_end'
/usr/bin/ld: /usr/lib/libc_nonshared.a(elf-init.oS): relocation R_X86_64_PC32 against undefined hidden symbol `__init_array_end' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value

Any idea where this comes from?

+3  A: 

You could try (ld(2)):

   --whole-archive
       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.  This
       option may be used more than once.

(gcc -Wl,--whole-archive)

Plus, you should put -Wl,--no-whole-archive at the end of the library list. (as said by Dmitry Yudakov in the comment below)

elmarco
Thanks, this looks like what I'm looking for, but it generates a link error I cannot figure where it comes from. I added details in the question.
Didier Trosset
there's importnat note in `man ld` for this option: don't forget to use -Wl,-no-whole-archive after your list of archives, because gcc will add its own list of archives to your link and you may not want this flag to affect those as well
Dmitry Yudakov