Search code examples
linuxgccld

Does gcc -static affect all provided libraries?


Does the gcc's option -static affect only one library that follows immediately or does it affect all libraries provided on command line?

g++ -static -lutils1 -lutils2

Solution

  • GGC's -static linkage option prevents linkage with shared libraries. So all libraries that the linkage requires must be static. The linker must be able to find a static library to resolve all -lname options that are passed, as well as static versions of all default libraries that GCC silently appends to the linkage.

    That is the intended use of the -static option, although it is possible to make it more flexible.

    GCC's -static option works simply by causing GCC to pass the option -static|-Bstatic to the linker (ld), at a position in the generated ld commandline that precedes all the libraries in the linkage.

    The linker's -static option has a different meaning from GCC's. From the ld manual:

    -Bstatic

    -dn

    -non_shared

    -static

    Do not link against shared libraries. This is only meaningful on platforms for which shared libraries are supported. he different variants of this option are for compatibility with various systems. You may use this option multiple times on the command line: it affects library searching for -l options which follow it.

    (My emphasis)

    So the linker's -static|-Bstatic option means: Do not link any shared libraries until further notice. At a later point in the ld commandline you may cancel the effect of -static|-BStatic with the option -Bdynamic, which will allow dynamic libraries to be linked again, from that point on, until further notice.

    Unlike the linker, GCC has no option that cancels the effect of its -static option. However, GCC allows you to pass abitrary options through to ld, via -Wl,<ld-options>. So you can in fact cancel GCC's -static option at a later point in the commandline like this:

    gcc -static -o prog main.o -lfoo -lbar -Wl,-Bdynamic -lgum ...
    

    This will generate a linkage commandline in which -lfoo and -lbar must be resolved to static libraries but -lgum and any subsequent library can be resolved to a shared library or a static library, as usual. Though if you wanted to "turn on/turn off" dynamic linkage like this at different points in the commandline, it would be more natural not to use GCC's -static option and instead write the equivalent:

    gcc -o prog main.o -Wl,-Bstatic -lfoo -lbar -Wl,-Bdynamic -lgum ...