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 (
.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,
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_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 ------------------------------------------------------------------- /home/software/rhel6/Modules/modulefiles/fftw/3.3.2/intel/12.1: 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: http://www.fftw.org/ module-whatis Manual: http://www.fftw.org/#documentation -------------------------------------------------------------------
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.
-Ioption to the compiler indicates a location for header files and, in this case, points to a directory that holds the
-Lcompiler option indicates a library location and, in this case, points to a directory that holds the
libfftw3.sofiles, which are the library files.
mysource.cThis is the source code that refers to the FFTW3 library functions; that is, your program.
-lcompiler 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
-Land link the first
libfftw3.*file that it finds (that will be
libfftw3.soif you are specifying dynamic linking and
libfftw3.aif you are statically linking).
-ooption is followed by the name of the final, executable file, in this case
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
-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 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