Static Linking
This document is for those who want to build a GAMMA and/or GAMMA programs (using the gamma
script) without runtime dependencies. One scenario where this might be useful is when building a binary that's meant to run on a cluster. A statically linked binary means that you don't need to copy as many support libraries to the cluster slaves.
Static linking is a non-standard path so we don't recommend it if you're not willing to battle linker options and error messages. This is not for the faint of heart.
Also note that this document is pretty Linux-specific, although some if it could perhaps be applied to OS X. (I haven't tried it.)
This document summarizes some of a Vespa mailing list conversation. You might want to read the whole thread for background information.
Statically Linking GAMMA to BLAS
Note: GAMMA doesn't use BLAS by default. Your choice of library will affect the name you use to link to it, so the instructions below are generic and must be customized to your installation. The examples below assume you use OpenBLAS.
One can convince the linker to link the BLAS library statically while linking all other libraries dynamically by changing the BLAS_LIBS
definition in the Makefile to this:
BLAS_LIBS = -L/usr/local/lib -Wl,-static -lopenblas -Wl,-Bdynamic -lgfortran
The magic here is the -Wl,-static
flag. The gcc option -Wl
passes the following option directly to the linker. Using -Wl,-static
tells the linker to link all subsequently referenced libraries statically. (In this case, that's libopenblas
.) The flag -Wl,-Bdynamic
restores normal dynamic linking for the remainder of the link steps.
As one would expect, the resulting GAMMA binary does not depend on libopenblas
:
$ ldd ../../linux-gnu/libgamma.so
linux-vdso.so.1 => (0x00007fffe6721000)
libgfortran.so.3 => /usr/lib/x86_64-linux-gnu/libgfortran.so.3 (0x00007f420fe5e000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f420fb5e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f420f861000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f420f64b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f420f28c000)
libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007f420f055000)
/lib64/ld-linux-x86-64.so.2 (0x00007f421094a000)
Theoretically, one could also statically link to libgfortran
with these options:
BLAS_LIBS = -L/usr/local/lib -Wl,-static -lopenblas -lgfortran -Wl,-Bdynamic
However, on my test system (Linux Mint 13 x64) this gives an error that I don't know how to resolve:
Making Shared Library libgamma.so From Object Files
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.6/libgfortran.a(string_intrinsics.o): relocation R_X86_64_32S against `.bss.zero_length_string' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-linux-gnu/4.6/libgfortran.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [../../linux-gnu/libgamma.so.4.3.2] Error 1
As I said, this exercise is not for the faint of heart!
Statically Linking Your Programs to GAMMA
If you want the gamma
script to statically link your programs to the GAMMA static library, you'll have to edit that script. It normally resides in /usr/local/bin/gamma
.
The compile and link commands (one verbose and one silent; both are otherwise exactly the same) are near the bottom of the gamma
script. Replace this portion of the lines:
-lgamma
with this,
-Wl,-static -lgamma -Wl,-Bdynamic
GAMMA programs built with this script will no longer depend on the GAMMA library.