24

I found a good replacement IDE for Delphi called Lazarus. But I don't have a question for programmers.

Will the statically linked Linux binary work on all Linux distributions? I.e. it does not matter on what Linux distro I built it and it will work on Debian / ArchLinux / Ubuntu / OpenSUSE / ... whatever?

As a result of my findings, does really only matter 32bit vs 64bit? I want to be sure before I publish.

  • Vaguely related: Linux System calls in C on OS X. – G-Man Sep 7 '15 at 2:31
  • Can you more specific about what kind of libraries you plan to link your program with? Some libraries have hidden dependencies (data files, dynamic subsystems) or otherwise implicit assumptions about the system they are running on. – Thomas Erker Sep 8 '15 at 21:13
28

This answer was first written for the more general question "will my binary run on all distros", but it addresses statically linked binaries in the second half.


For anything that is more complex than a statically linked hello world, the answer is probably no.
Without testing it on distribution X, assume the answer is no for X.

If you want to ship your software in binary form, restrict yourself to

  • a few popular distributions for the field of use of your software (desktop, server, embedded, ...)

  • the latest one or two versions of each

Otherwise you end up with houndreds of distribution of all sizes, versions and ages (ten year old distribution are still in use and supported).

Test for those. Just a few pointer on what can (and will) go wrong otherwise:

  • The package of a tool/library you need is named differently across distributions and even versions of the same distribution

  • The libraries you need are too new or too old (wrong version). Don't assume just because your program can link, it links with the right library.

  • The same library (file on disk) is differently named on different distributions, making linking impossible

  • 32bit on 64bit: the 32bit environment might not be installed or some non-essential 32bit library is moved into an extra package apart from the 32on64 environment, so you have an extra dependency just for this case.

  • Shell: don't assume your version of Bash. Don't assume even Bash.

  • Tools: don't assume some non POSIX command line tool exists anywhere.

  • Tools: don't assume the tool recognizes an option just because the GNU version of your distro does.

  • Kernel interfaces: Don't assume the existence or structure of files in /proc just because they exist/have the structure on your machine

  • Java: are you really sure your program runs on IBM's JRE as shipped with SLES without testing it?

Bonus:

  • Instruction sets: binary compiled on your machine does not run on older hardware.

Is linking statically (or: bundling all the libraries you need with your software) a solution? Even if it works technically, the associated costs might be to high. So unfortunately, the answer is probably no either.

  • Security: you shift the responsibility to update the libraries from the user of your software to yourself.

  • Size and complexity: just for fun try to build a statically linked GUI program.

  • Interoperability: if your software is a "plugin" of any kind, you depend on the software which calls you.

  • Library design: if you link your program statically to GNU libc and use name services (getpwnam() etc.), you end up linked dynamically against libc's NSS (name service switch).

  • Library design: the library you link your program statically with uses data files or other resources (like timezones or locales).


For all the reasons mentioned above, testing is essential.

  • Get familiar with KVM or other virtualization techniques and have a VM of every Distribution you plan to support. Test your software on every VM.

  • Use minimal installations of those distributions.

  • Create a VM with a restricted instruction set (e.g. no SSE 4).

  • Statically linked or bundled only: check your binaries with ldd to see whether they are really statically linked / use only your bundled libraries.

  • Statically linked or bundled only: create an empty directory and copy your software into it. chroot into that directory and run your software.

  • That's a pretty comprehensive answer +1 – sirlark Sep 6 '15 at 22:44
  • 2
    Shell: In particular, Debian does not use bash, and since that greatly mitigated the Shellshock vulnerability on Debian systems, I cannot imagine it changing in the immediate future. – Kevin Sep 7 '15 at 4:32
  • 1
    Also, if you want to ship binaries, link them statically. – immibis Sep 7 '15 at 6:58
  • Why is "instruction set" called a "bonus"? If you distribute in binary form, you really do need to consider which ISAs you'll be compiling for. You might not care for m68k users, but it's hard to ignore ARM, IA32 and X86_64 at least. – Toby Speight Sep 7 '15 at 12:33
  • @TobySpeight Think of SSE4 and such. Might only bite you if you use assembler. – Thomas Erker Sep 7 '15 at 12:42
9

The answer is it depends., but in most cases, yes, as long as the necessary libraries are installed on the OS.

Generally, most major distros like the ones you mentioned have their package management tools that install the community maintained version of the application. This takes care of any prerequisite packages that the application will need. If you're installing it without a package manager, it's up to you to make sure all necessary packages and libraries are installed onto the OS. It's a good idea to include a list of these prerequisite applications in the documentation.

2

Crappy answer first: It depends

If you are releasing binaries, assume the answer to be "no" unless you are distributing all the libs that it ever involves with it (from the ground up, which is annoying unless you are providing a really huge system that stands on its own anyway) or are statically linking the equivalent.

...but wizards and money, and money wizards...

IBM has some "general Unixish" installers that have shocked me by working everywhere I have tried them: several Linuces from several kernel generations, OpenSolaris (or whatever it is called now), Solaris, and BSD. But they are huge. And the things they provide are equally huge. No svelt little racecar programs get published this way, just the big enterprisey type stuff you would expect from IBM.

As far as just staying on Linux, but working well across most Linuxdom, this appears to be possible in binary form, as evidenced by the variety of "for Linux (general)" type binary installers you will see from some vendors. Several chat, browser, game, meta-installers, etc. are published this way, but always by huge vendors who can spend the time to get this right. It is sort of amazing they can say "for Linux" and be generally confident that it will work, but this appears to be the case.

But...

I distribute my software as source with a build utility. I do this in C, Erlang, Python, Guile, etc. This gives me a lot more flexibility about whether it will run or not, and it is much easier to write a buildscript that makes sure the right things exist at build time than to make sure everything is in place at runtime. Once that exists it is trivial to write an auto-updater for your program if you distribute the source: source is usually a lot smaller than a binary that includes all the deps and other insanity. Using this method I haven't had much trouble reliably deploying across Unices (and sometimes Windows, but that's a bit more of a chore).

Enough childsplay, arm yourself!

When you are getting serious, like srsly srs, about fitting smoothly within the Linux world you distribute C sources or turn to a fully managed environment for a hackishly delightful language that is already prebuilt. If you are writing Python code, for example, you can check versions and know which CPython version yours works with, and generally expect some compatible version to exist on a given Linux (and this is much easier to check than a broad sweep of C libs/versions you might be using). Erlang, Guile, Python, Perl, CL, etc. are all very easy targets for this sort of deployment, and many of them have a central repository like CPAN or pip (or whatever) where users can run a command to pull signed source themselves when they want it, and know that things will generally work as you intended.

[Addendum: 1. Even Haskell can generally pull this off via Cabal -- though I would be cautious about doing that in a production environment. 2. There are totally different "release" deployment strategies with Erlang that guarantee your code carries a complete environment around with it. 3. Python goes a step further with virtual environments; not all runtimes help you out as much.]

This last bit about managed environments on Linux is freaking awesome. And, as a bonus, it allows you to define much more general dependencies, have them resolved automatically with no extra effort on your part, doesn't require writing a package per distro, and you can stop caring whether a system is 32 or 64 bit (generally, anyway).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.