11

Ok, this question is about portable as in no dependencies (i.e. "I can put the binaries in a USB key and bring it with me everywhere, e-mail them to friends etc").

I have heard of static linking but I'm confused to what are exactly the consequences of it; what can and what can't be static linked (i.e. what about Qt, OpenGL, libstdc++?) and to which degree the binary will be "portable" afterwards.

I've also heard of LSB (Linux Standard Base) but I don't know exactly what it is or if it can help in this sense.

Giovanni Funchal
  • 8,934
  • 13
  • 61
  • 110

4 Answers4

7

Static linking works for most libraries, but not those that use dynamically loaded modules. Just try and see if it works. You may still have issues with kernel compatibility; your program may be using system calls not available in older kernels.

The Linux Standard Base is supported by some Linux distros, but on Debian (and I think also Ubuntu) it has to be installed from a package. It also handles mostly administrative things like startup scripts, though it has some binary compatibility stuff. See this page for some info.

For the "put on USB key and run anywhere" requirement, check out CDE.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
5

You don't have to link all of the libraries the same way. I'd definitely stick with dynamic linking for libc and the other system libraries. And use static linking for anything C++; the binary API does change from time to time, and you need to be sure that the version of the library is the same as the version you compiled against---the surest way of doing that is to statically link the library into your executable. If any of the other libraries you use are written in C++, you'll probably want to compile them locally as well, rather than using a precompiled distribution, to ensure that they are compiled against the same binary API, and link them statically. The binary API for C is fixed, so you have more freedom: if the library is going to be present on every installation, and must have a version compatible with the version of the OS, link dynamically; otherwise, statically.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • Nice answer. Can you give examples of "system libraries" that may remain dynamic, other than the libc? – Giovanni Funchal Apr 06 '11 at 10:03
  • 1
    libm. Any of the X Windowing libraries. Any of the libraries implementing Posix functions. The critical point is that they will be present on the machine where you want to run your code, and that they don't depend on the version of gcc/g++ which compiled them. (Generally true for C, generally false for C++). – James Kanze Apr 06 '11 at 10:31
  • 2
    -1. GNU libc is explicitly not designed to be forward compatible; if you link with a recent libc, your program will check for that version or a newer version on startup, so it won't run on any older Linux distro. – Fred Foo Apr 06 '11 at 11:50
  • Ok, so I should compile against the oldest libc/libm I'll be supporting? – Giovanni Funchal Apr 06 '11 at 12:35
  • @Helltone: yes. Or you should link statically, or use some tool such as `cde`. – Fred Foo Apr 06 '11 at 13:20
  • @larsmans: Are you sure? That's the whole purpose of using dynamic linking. If you statically link libc, then your program will only run under exactly the version of the OS you linked against. If you dynamically link, it should run against any future versions, but also against any older versions, as long as you don't use functionality added since that version. – James Kanze Apr 06 '11 at 14:28
  • 1
    @James, sad but true: http://www.pixelbeat.org/programming/linux_binary_compatibility.html. I was recently on both sides of this issue. (This is not the only purpose of dynamic linking, btw., the other is reducing binary size and memory footprint. The "added functionality" is probably the reason why they chose this setup, since glibc is constantly being expanded.) – Fred Foo Apr 06 '11 at 14:37
  • @JamesKanze: [glibc has not been statically linkable for 15 years](http://stackoverflow.com/a/26306630/309483) – Janus Troelsen Mar 22 '15 at 18:12
1

To disappoint you: there is no solution to it. That statically link is there, and you can (if you want) link everything static => all dependencies from other libraries are removed. But there are other dependencies, which cant be avoided: First there is the architecture. We have here linux on PowerPC, linux on ARM, linux on Microblaze, linux on 32-bit x86, and linux on 64-bit x86. Secondly there is the the ABI and there syscalls. Those can (and indeed have in the past) change (e.g. exotic/new syscalls does not exist on old systems - and if you got those calls in your binary your program wont work).

The LSB is just a a standard (or better it tries to be - not everyone follows it) for the different distros to make adminstration, usage, and maintaining (and sometimes developing) easier by e.g. defining where which files are stored. It does not aim to make executables more portable.

flolo
  • 15,148
  • 4
  • 32
  • 57
  • As long as the options are small, I can distribute multiple binaries (two for 32/64-bit doesn't hurt), as I'm already doing that for Windows/MacOS. – Giovanni Funchal Apr 06 '11 at 12:34
  • @Helltone: When you have to possiblity to use multiple binaries you can avoid the architecture problem (e.g. 32/64 bit), BUT this does not solve the problem, with the newer syscalls. If you can pinpoint a version which you at least got, and rely only on syscalls that exist there or before, it can work. – flolo Apr 06 '11 at 12:44
0

Be careful with static linking using gcc, it does not really work any more. See

PAntoine
  • 679
  • 4
  • 9
  • 1
    I don't see anything in that article which says it doesn't work. Rather the contrary: for what he's asking, I'd statically link everything but the standard system libraries (libc, etc.). I'd especially statically link any C++, because the dynamic libraries installed on other machines might not have the same version as I compiled against. – James Kanze Apr 06 '11 at 09:52
  • It says that you can no longer statically link libstdc++ reliably. But, that means he will have some dependencies (OK, system ones) but it does mean he will need to make sure that an upto date version of libstdc++ is on the target machine. As one of the comments say, that had a 32/64bit issue. This is not the same as having NO external dependencies. See [this](http://stackoverflow.com/feeds/question/2085427) for problems. – PAntoine Apr 06 '11 at 10:10
  • 1
    No it doesn't. It says that you can't link something statically if a dynamically loaded component uses it. If you link everything using libstdc++ statically, there's no problem. (And in fact, IIRC, what he claims isn't strictly true, but you do need a special option to make the symbols in the executable visible from dynamically linked libraries.) – James Kanze Apr 06 '11 at 11:13
  • 1
    My point is GCC does not do what you expect. `-static` does not generate a static binary, you have to add `-static-libgcc` and `-static-libstdc++` and even if you do that, you might not get a static binary or one that works (or an error, if you do something silly). PS: what is the special option, you mention? – PAntoine Apr 06 '11 at 12:22
  • More generally, you have to specify whether you want static or dynamic linking for each library. (At least, that's the way I've always seen it done.) – James Kanze Apr 06 '11 at 14:29