gnu.gcc.help
[Top] [All Lists]

Re: standard system libraries and -static option

Subject: Re: standard system libraries and -static option
From: Paul Pluzhnikov <ppluzhnikov-nsp@xxxxxxxxx>
Date: Sun, 13 Jul 2008 21:38:19 -0700
Newsgroups: gnu.gcc.help

Onno Garms <garms@xxxxxx> writes:

> I'm trying to build a binary that runs on as many linux distrubutions
> as possible.

In that case, link dynamically against all system libraries.
Contrary to popular belief, static linking does not produce portable
binaries on UNIX.

> At first glance this seems easy because in my case the
> binary does not depend on any libraries.

While it's possible to have a binary that does not depend on libc,
it is very unlikely that you have such a binary.

> But there are still the
> "standard system libraries" which the linker includes automatically

The linker does no such thing. The compiler front ends do add libc,
and possibly other "support" libraries.

> unless -nodefaultlibs or -nostdlib is set. I'm trying to understand
> these libraries now. On these I have several questions which I could
> not answer with Google.
>
> 1.) Where can I find a ful list of these standard system libraries?
> (Or, more basically, does a request for such a list make sense?)

Perform 'gcc -v' or 'g++ -v' -- this will show what the actual link
command is.

> 2.) How does the compiler decide wich standard system libraries
> actually to include? I found (using ldd or objdump) that a hello-world
> program does not include any.

This statement is very likely false:

$ echo "int main() { return 0; }" | gcc -xc -
$ ldd a.out
        libc.so.6 => /lib/tls/libc.so.6 (0x00b60000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00b47000)

> My program depends on stdc++, c, gcc_s,
> and m, of which gcc_s is only needed indirectly (by stdc++) and m not
> at all.

You must have linked with g++ then.

$ echo "int main() { return 0; }" | g++ -xc -
$ ldd a.out
        libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x06a16000)
        libm.so.6 => /lib/tls/libm.so.6 (0x00c84000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00967000)
        libc.so.6 => /lib/tls/libc.so.6 (0x00b60000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00b47000)

I am wondering how you came to the (possibly incorrect) conclusion
that libm is not needed at all, and that libgcc_s is only needed
indirectly?

> 3.) What does -static link into my executable? Am I correct to assume
> that above four libraries are linked statically into my executable?

Yes.

> Does that mean that libc is linked statically and the result depends
> on the (L)GPL?

I believe so. It is also likely that the result will be much less
portable: on newer Linux distributions, you are likely to get a
warning similar to this:

  Using 'getaddrinfo' in statically linked applications requires
  at runtime the shared libraries from the glibc version used
  for linking

IOW, if you link statically, then you must run on a system which
has the *exact* same version of glibc, as the system on which the
binary was built.

> 4.) What is the "official" way to link only some libraries statically?

  gcc ... -Wl,-Bstatic -lfoo -lbar -Wl,-Bdynamic -lbaz

Above links libfoo.a and libbar.a, but leaves libbaz as "default search".

Note that this doesn't work for libstdc++ and libgcc_s.

A recipe for getting rid of libgcc_s.so and libstdc++.so dynamic
dependency can be found here:
http://groups.google.com/group/comp.unix.programmer/msg/16aaa50e2d88cf8

> Searching for lib*.a and add it to the link line looks like a hack to
> me. I found libstdc++.a, but I did not find libgcc_s.a.
>
> 4.) My conclusion so far is that I should put
> libstdc++.a -lnodefaultlibs -lc -lgcc_s
> on the linker line.

This puts the libraries on the link line in the wrong order (and
order matters).

> The exe should run independent of the user's stdc++, because it has
> its own statically linked. It has no code compiled in that makes it
> depend on the GPL. It does depend on GLIBC (which I'm not allowed to
> link statically)

You *want* to link GLIBC dynamically, unless you can guarantee the
exact glibc match on the end-user system.

In addition, note that UNIX systems maintain backwards compatibility:
older dynamically linked binaries continue to run on newer systems.

But they don't provide the inverse. So you must either link on the
oldest OS you plan to support, or use "tricks", such
as Linux-to-(older)Linux crosscompiler, or apgcc (http://autopackage.org).

Cheers,
-- 
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.

<Prev in Thread] Current Thread [Next in Thread>