43

I'm wondering what the -static option on gcc does. I need this option when compiling a certain application, however when I do I get the following error:

gcc -static -O3 -o prog prog.c
/usr/bin/ld: cannot find -lc
collect2: ld returned 1 exit status

What needs installation?

GCC version:

[user@localhost dir]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.6.1/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.6.1 20110908 (Red Hat 4.6.1-9) (GCC) 
bad_coder
  • 11,289
  • 20
  • 44
  • 72
sj755
  • 3,944
  • 14
  • 59
  • 79

3 Answers3

91

The -static option links a program statically, in other words it does not require a dependency on dynamic libraries at runtime in order to run.

To achieve static linking requires that the archive (.a) versions of your libraries exist on the system. so /usr/lib/libc.a, /usr/lib/crt1.o, etc.

On modern linux systems (as you are using red hat): when a binary links together it 1) either puts the code into the executable via .o and .a files, or 2) puts in references to dynamic libraries (.so) files that is resolved by /lib/ld-linux.so (or /lib64/ld-linux=x86-64.so) which is always at a well known place.

For your particular system, if a program is specifically looking to create a static version of itself then you need to install the static versions of your devel tools. You need, at the minimum, glibc-static package. You may also need libstdc++-static package as well.

galoget
  • 722
  • 9
  • 15
Ahmed Masud
  • 21,655
  • 3
  • 33
  • 58
23

The -static flag forces the linker to accept only static libraries and not any shared libraries.

If you want to use -static, you have to ensure that you have a static version of the C library installed, which might be tricky to find (most systems do not have a static C library any more). Or you have to cancel the effect of -static. However, in the example, that would defeat the purpose of -static since the only library linked is (implicitly) the C library.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 2
    Is there any particular reason why it should not be possible to simply have the linker statically attach code from whatever libraries are available to the linker? Even if references within the code are formatted in such a way that they must be resolved at runtime, I would think it should be possible to attach the appropriate routines to the executable file, and patch up references so they point to code within the executable file. – supercat Aug 29 '14 at 02:23
  • @supercat: In an ordinary archive library, the individual object files are separately identifiable and can easily be extracted from the library and linked into the executable. My impression (semi-informed) is that shared libraries do not contain the separate object files in the same way, so you get the whole lot or you get nothing. I dare say that it might be possible to simply link the entire shared library into the executable, but it might lead to a lot of unused code being built in too. I know some big companies prefer to use static linking for everything — less risk of unexpected change. – Jonathan Leffler Aug 29 '14 at 05:03
  • 2
    Even if code ends up having to be loaded dynamically, I would suggest that installed applications should by default each receive their own copies of most libraries. If libraries need to be upgraded, that could be handled by having the OS keep for each program a set up "upgrade settings" [e.g. if a program which uses FooLib 1.7 notices that "FooLib 1.8" is installed, it could allow the user to run it with either 1.7 or 1.8 and save the selection as a default]. That way if a program has FooLib-related problems, the user could upgrade it, but things wouldn't change spontaneously. – supercat Aug 29 '14 at 14:53
  • 2
    I wonder why systems haven't managed such functionality in their program-execution infrastructures? As someone noted in another comment, linkers were annoying in the 1980s and are still annoying 30+ years later. Is there any reason they should be? – supercat Aug 29 '14 at 14:55
  • 3
    If you implement it, maybe it will be used. The advantage of shared libraries is that you change the shared library and all applications that use automatically get the benefit of the bug fixes in the new version. The advantages of static linking are that you don't have to worry about shared library management and the application doesn't change unless you rebuild it. If you go the static linking route, then you end up with heavier memory usage (each different executable has its own copy of shared code), but you know that programs won't change accidentally. – Jonathan Leffler Aug 29 '14 at 15:01
0

On systems that support dynamic linking, this overrides -pie and prevents linking with the shared libraries. On other systems, this option has no effect.

Ref: https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

selfboot
  • 1,490
  • 18
  • 23