Creating shared object from static library whose o

2019-08-01 22:33发布

问题:

For a project we are trying to create a shared object file that exports a set of functions specified in libname.exports. Of course we know that the object files from which the .so file gets linked have to be created using -fPIC, so that has been taken care of. We then combined the object files into an archive named libname.a. This should now be the basis for the .so file to be created - or so was the idea.

We're passing libname.exports to --retain-symbols-file, so the expected behavior was that the linker would pull in any of the .a members relevant to those symbols.

However, the output of nm libname.so is empty. On the other hand grepping in nm libname.a shows that the relevant symbols named in libname.exports exist in the .a members.

Now I stumbled over --whole-archive and thus adjusted the command line from:

gcc -o libname.so -shared -Wl,-z,defs,--retain-symbols-file,libname.exports,-L. libname.a -lc

to:

gcc -o libname.so -shared -Wl,-z,defs,--retain-symbols-file,libname.exports,-L.,--whole-archive,libname.a,--no-whole-archive -lc

which appears to have the intended effect of including all the object files from the .a (although the size difference is strange). However, nm libname.so still gives me no output.

How can I use the archive file to create a shared object with only the symbols named in libname.exports visible?

Unfortunately How to create a shared object file from static library doesn't quite answer my question.

Note: before you ask. The idea behind using the .a file as input is because it makes it easy to use a pattern rule in GNUmakefile and because the .a file with -fPIC is needed regardless. There shouldn't be any difference between linking the individual object files versus the archive file.

回答1:

You could use the -u SYMBOL option to force objects to be read in from an archive.

% cc -c -fPIC a.c
% nm a.o
00000000 T a
% ar rv liba.a a.o
ar: creating liba.a
a - a.o
% gcc -o liba.so -shared -u a liba.a
% nm liba.so | awk '$3 == "a" { print }'
0000042c T a

One thing to check would be the spellings of the symbols being specified with --retain-symbols-file. For example, symbol names in objects compiled from C++ code are likely to be mangled:

% g++ -c -fPIC a.c
% nm a.o | awk '$2 == "T" { print }'
00000000 T _Z1av