Uppsala Multidisciplinary Center for Advanced Computational Science

Undefined reference when compiling program, what to do?

If you get an error about "undefined reference" when compiling a program of your own from source code, then you are probably missing to include some required symbols which should be distributed in a separate library archive. To find which archive to include we can use the tools "readelf" and "nm".

Let us take an example. Here we have a situation where gcc has aborted the compilation due to not finding a couple of symbols starting with the name NSSLOWHASH:

/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libcrypt.a(sha512-crypt.o): In function
`__sha512_crypt_r': (.text+0x14ff): undefined reference to `NSSLOWHASH_Update'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libcrypt.a(sha512-crypt.o): In function
`__sha512_crypt_r': (.text+0x1537): undefined reference to `NSSLOWHASH_End'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libcrypt.a(sha512-crypt.o): In function
`__sha512_crypt_r': (.text+0x153f): undefined reference to `NSSLOWHASH_Destroy'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libcrypt.a(sha512-crypt.o): In function
`__sha512_crypt_r': (.text+0x1568): undefined reference to `NSSLOWHASH_Destroy'
collect2: ld returned 1 exit status
make: *** [plink_maf_mod] Error 1

If we inspect the shared object file we can see what other shared object that might be needed:

[johanhe@kalkyl3 ~]$ readelf --dynamic /usr/lib64/libcrypt.so

Dynamic section at offset 0x7de8 contains 25 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [libfreebl3.so]
0x000000000000000e (SONAME) Library soname: [libcrypt.so.1]

Here we see among other things that libfreebl is referenced and needed. We can list its symbols by the following command:

[johanhe@kalkyl3 ~]$ nm --print-file-name --dynamic /usr/lib64/libfreebl3.so | grep NSSLOW
/usr/lib64/libfreebl3.so:000000000003fd90 T NSSLOWHASH_Begin
/usr/lib64/libfreebl3.so:000000000003fdd0 T NSSLOWHASH_Destroy
/usr/lib64/libfreebl3.so:000000000003fdb0 T NSSLOWHASH_End
/usr/lib64/libfreebl3.so:000000000003fdc0 T NSSLOWHASH_Length
/usr/lib64/libfreebl3.so:000000000003fdf0 T NSSLOWHASH_NewContext
/usr/lib64/libfreebl3.so:000000000003fda0 T NSSLOWHASH_Update
/usr/lib64/libfreebl3.so:0000000000040050 T NSSLOW_Init
/usr/lib64/libfreebl3.so:000000000003fd60 T NSSLOW_Shutdown

It appears as the missing symbols are included in this file. So by making sure that make/configure/gcc include this library/directory in the compilation, your errors should go away. (This could be as easy as including the correct compiler module on the cluster, but if you're building something where you need more unusual dependencies you might have to add these inclusions manually.)