A linker, any linker, knits together object files (some of which may be in libraries) such that every function needed by the program has a definition. If the linker fails to locate a definition for even one function, it will fail and the program will not run.
Returning to bsqldb.o
, we can use nm to see which functions are unresolved, and determine whether or not a particular library contains them. We'll ignore the symbols that start with an underscore, marking them per the C standard as being provided by the implementation[36], and focus on the last five in this abbreviated list.
Some unresolved functions in bsqldb.o
asprintf
, basename
Normally provided by the standard C library, but if not by FreeTDS™'s replacements library:
$
nm /usr/lib/libc.a | grep -w T | grep -E 'asprintf|basename'
0000000000000000 T _basename 0000000000000000 T _asprintf
calloc
Provided by the standard C library:
$
nm /usr/lib/libc.a | grep -w T | grep calloc
0000000000004240 T calloc
dbaltbind
, dbaltcolid
Provided by DB-Library
:
$
nm libsybdb.a | grep -Ew 'dbaltbind|dbaltcolid'
0000000000007140 T dbaltbind 0000000000003590 T dbaltcolid
Although these examples refer to static libraries, nm works just as well with dynamic libraries, too.
There are other tools besides nm. Windows®, for instance, has dumpbin, and the GNU bintools include objdump.
[36] Why and how leading underscores enter into this discussion is just one more example of arcane historical practices one needs to know to master the subject. For our purposes, though, it's enough to know that “implementation-provided” functions like these — functions provided by the C standard library — often have an underscored prepended.