Fully statically build application with all dependencies (libgcc, etc.)?
Asked Answered
W

1

7

I am currently trying to compile all my applications' dependencies as a static library. My motivation:

  1. Not to rely on any OS provided libraries in order to have a perfectly reproducible code base
  2. Avoid issues when deploying on other systems caused by dynamic linking
  3. Avoid run-time clashes when linking against different versions of a library
  4. Being able to cross-compile for other OS

However, as I initially dreaded I had to go down the rabbit hole quite fast. I am currently stuck with OpenCV and I'm sure there is more to come. However, my main questions are:

  1. Is it possible to build an entirely statically build app (e.g. libc, ligcc, etc. ?)
  2. Is it possible to link all libraries statically but link major components (libgcc, etc.) dynamically?
  3. If not, is it possible to link against statically built libraries (e.g. OpenCV) but to satisfy their dependencies by linking dynamically (zlib, libc, etc.)?
  4. I did research on the internet but couldn't find a comprehensive guide that dwells on the internals of linking (static vs. dynamic). Do you know about a good book / tutorial? Does a book about gcc get me further?
  5. Is this a very stupid idea?
Walter answered 31/10, 2017 at 19:35 Comment(3)
1. yes; 3. you need to build all dependencies as static libraries, statically link c++ runtime and make sure that system APIs your application is calling are reasonably portable; 4. yes (unless dealing with 0.5Gb executables is fine with you), but you can always tell "that is just what google did with go lang";Choirboy
you must take care of licensing: linking dynamically may be authorized by the lib but static linking may "contaminate" your code.Warren
@VTT thanks, I added another question Is it possible to link all libraries statically but link major components (libgcc, etc.) dynamically? Is that possible to keep the application size reasonable ?Walter
N
5

My motivation:

  1. Not to rely on any OS provided libraries in order to have a perfectly reproducible code base

  2. Avoid issues when deploying on other systems caused by dynamic linking

  3. Avoid run-time clashes when linking against different versions of a library

  4. Being able to cross-compile for other OS

Your motivations are all wrong.

For #1, you do not need a fully-static binary. You just need to link against a set of version-controlled libraries using --sysroot facility provided by GNU linkers

For #2, you motivation is misguided.

On Linux, a fully-static binary may crash in mysterious ways if the libc installed on a target system is different from (static) libc the program was built on. That is, a fully-static binary on Linux is (contrary to popular belief) significantly less portable than a dynamically linked one. One should simply never statically link libc.a on Linux.

This alone should make you abandon this approach (at least for any GLIBC based systems).

For #3, don't link against different versions of a library (at program build time), and no clashes will result.

For #4, the same solution as for #1 just works.

Nelle answered 1/11, 2017 at 3:50 Comment(2)
awesome thanks. I guess approach #1 is what I should look into carefullyWalter
Can you provide more detail as to why different versions of libc (static vs system) will crash? What's the interaction? thanks.Basile

© 2022 - 2024 — McMap. All rights reserved.