Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make gcc or ld report undefined symbols but not fail?

Tags:

c++

c

gcc

linker

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.

like image 525
Joseph Garvin Avatar asked Dec 10 '22 19:12

Joseph Garvin


1 Answers

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.

like image 66
wdebeaum Avatar answered Jan 25 '23 22:01

wdebeaum