User Manual

3.5 Linking

To use external libraries in your code, you must link them against your program after compiling your code. Most compiler frontends, such as gcc, can perform both compiling and linking, depending on the flags you use. A simple example of compiling and linking against the pthreads library in a single command is:

$ gcc -o myprogram myprogram.c -lpthread

The -o flag provides the name of the linked executable. The -l flag instructs the compiler to search for a library called 'pthread' in the typical library paths, such as /lib or /usr/lib.

3.5.1 Dynamic vs. static linking

Typically the linker will default to dynamic linking, which means the library will remain as a separate file with a .so extension (for 'shared object') that must be available when your program executes. You can see what libraries are dynamically linked against your program using

$ ldd myprogram

In the example with pthreads above, this may result in output like

libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003ebb200000)
libc.so.6 => /lib64/libc.so.6 (0x0000003eba600000)
/lib64/ld-linux-x86-64.so.2 (0x0000003eba200000)

which shows that the 'pthread' library was found by the linker at the path /lib64/libpthread.so.0 in the previous compile/link command.

In contrast, static linking means the object code from the library will be copied and duplicated inside your program. The advantage of this approach is that calls to functions within the library may have less overhead (because they do not pass through the dynamic loader) and the executable is self-contained and does not require any external .so files at runtime, which can make it more portable.

To link the pthread example statically, you would use

$ gcc -o myprogram myprogram.c -lpthread -static

This compiles and links 'myprogram' as a static executable, so that using ldd will generate the error

not a dynamic executable

Instead, you can use the nm tool to inspect what symbol names (functions, global variables, etc.) are contained in a static executable. This tool also works on static libraries, which have the extension .a. For instance, using nm on a statically compiled executable for R (the statistics package/language) outputs

...
00000000005ac970 T BZ2_bzclose
00000000005ac8c0 T BZ2_bzdopen
00000000005aca10 T BZ2_bzerror
00000000005ac960 T BZ2_bzflush
00000000005ac830 T BZ2_bzlibVersion
00000000005ac8b0 T BZ2_bzopen
00000000005ac8d0 T BZ2_bzread
00000000005ac920 T BZ2_bzwrite
0000000000614390 T BZ2_compressBlock
...

which shows that it was linked statically against the 'bzip2' compression library. You can also link a dynamic executable against a static library (e.g., if there is no dynamic version of the library available), but this usually requires that the static library was compiled with 'position independent code' (or PIC) using the flag -fPIC. Most of the static libraries available on CCV systems have been compiled with this flag.

3.5.2 Finding libraries

Many frequently used libraries are available already compiled and installed on CCV systems through software modules. These modules frequently have an environment variable that provides a shortcut for the include and library flags. You can use:

$ module help <package>

to find out more. For example, the help for the gotoblas2 module explains how to use the $GOTO shortcut:

You can compile and link statically against GotoBLAS2 and
the included LAPACK library using the $GOTO shortcut:
  CC -o blas-app blas-app.c $GOTO
Environment Variables:
    GOTO = -I/gpfs/runtime/opt/gotoblas2/1.13/include
           -L/gpfs/runtime/opt/gotoblas2/1.13/lib
           -lgoto2 -lpthread -lgfortran
GOTO_DIR = /gpfs/runtime/opt/gotoblas2/1.13