Libraries are collections of functions that are already compiled and that can be included in your program without your having to write the functions yourself or compile them separately.

Why use libraries

Saving yourself time by not having to write the functions is one obvious reason to use a library. Additionally, many of the libraries focus on high performance and accuracy. Many of the libraries are very well-tested and proven. Others can add parallelism to computationally intensive functions without you having to write your own parallel code. In general, libraries can provide significant performance or accuracy dividends with relatively low investment of time.

Linking with libraries

To use libraries you must link them with your own code. When linking libraries that are not included with your compiler, you must tell the compiler/linker where to find the library’s (.so and .a) files. For libraries that require prototypes (C/C++, etc.) you must also tell the preprocessor/compiler where to find the header (.h) files. Fortran modules are also needed, if you are compiling Fortran code.

Environment variables from the module

The library modules provide environment variables to make it easier for you to provide the right information to the compiler and the linker. The naming scheme is, typically, a prefix indicating the library, for example, FFTW or NAG, followed by a suffix to indicate the variable’s function, for example, _INC for the directory containing the header files. So, for example, the module for FFTW3 includes the variables FFTW_INC and FFTW_LINK for the include and library directories, respectively.

One other variable that is often set by the library module is the LD_LIBRARY_PATH variable, which is used when you run the program to tell it where to find the libraries needed at run time. If you compile and link against an external library, you will almost always need to load the library module when you want to run the program so that this variable gets set.

To see the variable names that a module provides you can use the show option to the module command to show what is being set by the module. Here is an edited example of what that would print if you were to run it for FFTW.

$ module show fftw

setenv		 FFTW_ROOT /home/software/rhel6/fftw-3.3.2/intel-12.1 
setenv		 FFTW_LINK /home/software/rhel6/fftw-3.3.2/intel-12.1/lib 
setenv		 FFTW_INC /home/software/rhel6/fftw-3.3.2/intel-12.1/include 
prepend-path	 PATH /home/software/rhel6/fftw-3.3.2/intel-12.1/bin 
conflict	 fftw
[ . . . . ]
module-whatis	 Vendor Website: 
module-whatis	 Manual: 

In addition to the environment variables being set, the show option also displays the names of other modules with which FFTW3 conflicts (in this case, just itself), and there are links to documenation and the vendor web site.

Compile and link C in one step

Here is an example of compiling and linking a C program with the FFTW3 libraries.

icc -I$FFTW_INC -L$FFTW_LINK mysource.c -lfftw3 -o myprogram

Here is a breakdown of the components of that command.

  • -I$FFTW_INC The -I option to the compiler indicates a location for header files and, in this case, points to a directory that holds the fftw3.h header file.
  • -L$FFTW_LINK The -L compiler option indicates a library location and, in this case, points to a directory that holds the libfftw3.a and files, which are the library files.
  • mysource.c This is the source code that refers to the FFTW3 library functions; that is, your program.
  • -lfftw3 The -l compiler option indicates the name of a library that contains a function referenced in the source code. The compiler will look through the standard library (linker) paths the compiler came with and the ones added with -L and link the first libfftw3.* file that it finds (that will be if you are specifying dynamic linking and libfftw3.a if you are statically linking).
  • -o myprogram The -o option is followed by the name of the final, executable file, in this case myprogram.

Compile and link C in multiple steps

Sometimes you will need or want to compile some files without creating the final executable program, for example, if you have many smaller source files that all combine to make a complete executable. Here is an example

icc -c -I$FFTW_INC source1.c 
icc -c -I$FFTW_INC source2.c 
icc -L$FFTW_LINK source1.o source2.o -o myprogram -lfftw3

The -c compiler option tells the compiler to compile an object file only. Note that only the -I option is needed if you are not linking. The header files are needed to create the object code, which contain references to the functions in the library.

The last line does not actually compile anything, rather, it links the components. The -L option is the same as on the one-step compilation and linkage command and specifies where the binary library files are located. The -o option specifies the name of the final executable, in this case source, and the -l option names the library to be linked.

The location of the header files are only needed before linking. Thus the -I flags can be left off for the final step. The same for the -L and -l flags, which are only needed for the final link step. Note that all the object files to be linked need to be named.

Compile and link Fortran

Compiling a Fortran program is very similar to doing so for a C program. You should use the module show command for your library to check which environment variables will get defined. The main difference is that some libraries will have a module directory variable defined for the Fortran version. A good example is the NAG library, which defines NAG_MOD to be the directory that contains the NAG Fortran modules.

Here is an example of one-step compilation and linking using the Intel Fortran compiler and the NAG library.

$ ifort -I$NAG_MOD -L$NAG_LINK mysource.f90 -lnag_nag -o myprogram