53
votes

I need to distribute a binary that will run on as many x86 Linux distributions as possible. That means that I have to statically link some libraries, like glibc, because the user might not have the version I use. Other libraries have to be dynamically linked, like fontconfig, because it relies on a cache file format and hard coded locations that may differ on each system.

What are the command line options to do this? If I specify -static, then gcc will refuse to dynamically link any libraries at all.

3

3 Answers

95
votes

Statically linking against any system library, and especially against libc, on modern UNIX or Linux systems makes the binary significantly less portable. Just don't do it.

Instead, use backward compatibility (binaries linked on an older system continue to run on all newer ones) to your advantage, either by linking your binary on an old system (I use RedHat 6.2, and I have not seen a Linux system where my binary will not run in the last 8 years), or by using something like autopackage (which has been deleted after this answer was written).

To answer your original question:

gcc main.o -Wl,-Bstatic -lfoo -Wl,-Bdynamic

will cause linker to use archive version of libfoo. [It is important to have the trailing -Wl,-Bdynamic precisely so you don't force static libc.]

7
votes

It should be noted that, under Linux, you can only (safely) statically link a library if none of the dynamic libraries depend on it. This means that if you're using any dynamic libraries at all, you can forget about statically linking libc. Just use a fairly old version to build against for libc's case; libc has maintained strong ABI backwards-compatiblity over the years.

4
votes

Try passing in the paths to the library files you're linking against on the linker command line (be they .a or .so libraries) and drop -static. That should do the trick.