How to make gcc or ld report undefined symbols but

2019-07-07 02:52发布

问题:

If you compile a shared library with GCC and pass the "-z defs" flag (which I think just gets passed blindly on to ld) then you get a nice report of what symbols are not defined, and ld fails (no .so file is created). On the other hand, if you don't specify "-z defs" or explicitly specify "-z nodefs" (the default), then a .so will be produced even if symbols are missing, but you get no report of what symbols were missing if any.

I'd like both! I want the .so to be created, but I'd also like any missing symbols to be reported. The only way I know of to do this so far is to run it twice, once with "-z defs" and once without. This means the potentially long linking stage is done twice though, which will make the compile/test cycle even worse.

In case you're wondering my ultimate goal -- when compiling a library, undefined symbols in a local object file indicates a dependency wasn't specified that should have been in my build environment, whereas if a symbol is missing in a library that you're linking against that's not an error (-l flags are only given for immediate dependencies, not dependencies of dependencies, under this system). I need the report for the part where it lists "referenced in file" so I can see whether the symbol was referenced by a local object or a library being linked. The --allow-shlib-undefined option almost fixes this but it doesn't work when linking against static libraries.

Preference to solutions that will work with both the GNU and Solaris linkers.

回答1:

Instead of making ld report the undefined symbols during linking, you could use nm on the resulting .so file. For example:

nm --dynamic --undefined-only foo.so

EDIT: Though I guess that doesn't give you which source files the symbols are used in. Sorry I missed that part of your question.

You could still use nm for an approximate solution, along with grep:

for sym in `nm --dynamic --undefined-only foo.so |cut -d' ' -f11 |c++filt -p` ; do
    grep -o -e "\\<$sym\\>" *.cpp *.c *.h
done

This might have problems with local symbols of the same name, etc.



回答2:

From the GNU ld 2.15 NEWS file:

  • Improved linker's handling of unresolved symbols. The switch --unresolved-symbols= has been added to tell the linker when it should report them and the switch --warn-unresolved-symbols has been added to make reports be issued as warning messages rather than errors.


标签: c++ c gcc linker