views:

267

answers:

5

I'm programming in FORTRAN and C on an SGI running Irix 6.5, but this should be applicable to all Unix-like systems. How do I find which library I need to link to my program when I get an "unresolved text symbol" link error? Here's an example of what I'm seeing from the linker:

ld32: ERROR  33 Unresolved text symbol "ortho2_" -- first referenced by ./libfoo.a

Do I just have to know which libraries are required, or is there some tool or command that can help me figure this out?

+9  A: 

You can use the nm command to list the dynamic symbols from a shared library:

nm -D /lib/libc.so.6

and then grep for the symbol you are looking for. Omit the -D for static libraries. You can use this in a loop or with xargs to scan multiple libraries.

I usually just use google (assuming the symbol is from a publicly available library).

Robert Gamble
Google is the answer. nm is nice, but in the cases where I've had to track down an unresolved link it is because someone was on a platform with obsolete libraries. More rarely, a newer library would remove a deprecated routine. In either case, nm won't find what's not there.
jaredor
+3  A: 

Using nm (as in Robert Gamble's answer) is the correct answer to your question. The trick is in knowing where to look for the libraries. What does your program do? If there is a large amount of numerics going on, chances are you should be linking against math libraries (like LAPACK or BLAS) and might want to start looking there. Web searching can also be helpful - I typed "ortho2" into my favorite search engine and got this documentation that suggests it's in libfgl.a

Note that when you search you should probably omit the trailing underscore - it's usually added to the routine name by the compiler.

Tim Whitcomb
Leading underscores can also be added by the compiler. In this case, I wonder if the Fortran compiler doesn't add the underscore to the end of the Fortran function names.
Jonathan Leffler
I've also run into cases where the names are followed by a double underscore. Using nm on my own code to see how it's altering names and then adjusting the compiler options accordingly is how I usually sort this out.
Tim Whitcomb
+3  A: 

I resisted the temptation to add this to Robert Gamble's answer - consider this a supplement to it.

Be wary of simply assuming that 'any match' is OK for use. There was a case in another SO question where a piece of code was moved from Windows to Unix and the Windows code used getch() to read a single character from the input. The user went through a process analogous to this and found getch() on Unix in the curses library. So, the user linked with the curses library and wondered why the code core dumped. The trouble is, the getch() actually used assumes that the proper initialization has been done, and the proper initialization was not done. In fact, it probably wasn't the routine that was needed.

On Solaris, there are options to nm that tell you the library name and even object file within the library that contains the symbol (these are -r for library name, and -R for object within library).

Beware C++ mangled names, too. The ortho2 example is clearly not C++ mangled.

Jonathan Leffler
+2  A: 

If it's a standard function, which ortho2 could be, the man page will tell you which library it is in.

David Norman
+2  A: 

I have a little lookfor script. Enter lookfor func_name

#!/bin/csh
foreach i (*.o *.a *.so)
 echo $i
 nm $i | grep -i $1
end
SumoRunner