5

I am working on a project which I would like to be able to "ship" to other Linux based computers as a complete executable with no dependencies. (In order that I can copy just the 1 file to other systems, and then run that file on those systems.)

In the windows world, I think static linking is done just by passing -static to the compiler, perhaps with some other options for specific libraries*, if you are using Visual Studio.

*eg: Using SFML you also have to define SFML_STATIC for some reason?

Is this possible using gcc / g++, and if so how? I tried searching for this but didn't manage to find anything. I have heard before that this may be a non-trivial task.

Edits:

BasileStarynkevitch suggested compiling with the flag -static.

I don't know if this is what I want, but I wrote a test program to try it out:

#include <iostream>

int main()
{
    std::cout << "Link statically please" << std::endl;

    return 0;
}

And then compiled with:

g++ main.cpp -o a.out -static
g++ main.cpp -o b.out

The results are:

-rwxr-xr-x  1  1653098  a.out
-rwxr-xr-x  1     9167  b.out

So it looks like it might be working?

TonyD suggested a method of checking:

ldd a.out 
not a dynamic executable

ldd b.out
linux-vdso.so.1 =>  (0x00007fff3d5ac000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fce5e34a000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fce5df85000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fce5dc7e000)
/lib64/ld-linux-x86-64.so.2 (0x00007fce5e677000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fce5da67000)
FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225
  • 1
    It could be possible, but it might be unreasonable. Did you try to use `g++ -static` on Linux? – Basile Starynkevitch Aug 26 '15 at 10:45
  • @BasileStarynkevitch Can you elaborate on this point? – FreelanceConsultant Aug 26 '15 at 10:45
  • Did you consider publishing your code as free software? – Basile Starynkevitch Aug 26 '15 at 10:47
  • 1
    I'm afraid that's not possible, because some of the system binding libraries like glibc might be different on a different linux system. The usual way is to ship source packages and configure and compile them on the target system. – πάντα ῥεῖ Aug 26 '15 at 10:48
  • 1
    It's a good question, but no research effort.... – Tony Delroy Aug 26 '15 at 10:48
  • @TonyD I did google it, but didn't manage to find anything. – FreelanceConsultant Aug 26 '15 at 10:51
  • @user3728501 [sure?](https://www.google.de/search?q=linux+program+shipping&rlz=1Y3KTZR_deDE555DE555&oq=linux+program+shipping&aqs=chrome..69i57.36924j0j4&sourceid=chrome-mobile&espv=1&ie=UTF-8) – πάντα ῥεῖ Aug 26 '15 at 10:55
  • Hmmm... "GCC static" / feeling lucky works ok for me... in those docs - could at least explore `-static` and `-static-lib*` and explain how they meet or don't meet your needs. Anyway, given you now say you've created an `a.out` you suspect might work, why not use `ldd` to list the dynamic dependencies, as well as try it on some of the boxes you want to deploy to? – Tony Delroy Aug 26 '15 at 10:56
  • @TonyD I was not aware of the command ldd – FreelanceConsultant Aug 26 '15 at 10:59
  • 1
    @BasileStarynkevitch Why would I publish my code as free software? It isn't useful to anyone? This is a ridiculous question to ask. I want to move my code form machine to machine, within my organization - not sell it. – FreelanceConsultant Aug 26 '15 at 11:03
  • Because then you put the burden of compilation & packaging on users & distribution makers – Basile Starynkevitch Aug 26 '15 at 11:04
  • @BasileStarynkevitch What you are saying may be true but is not relevant in the context of what I want to do. I am not shipping anything on mass or to sell. I am just running several copies of a program, some of which someone else is running for me on different hardware. – FreelanceConsultant Aug 26 '15 at 11:09

2 Answers2

15

Is it possible to compile statically with gcc or g++ on Linux based systems?

It depends.

You might try to compile and link all your code with gcc -static or g++ -static. In several cases (e.g. pure command-line applications, like your hello world), it would work.

Linux distributions like a lot shared libraries. Most of them are using shared libraries extensively (notably for graphical applications). Read Drepper's How to Write Shared Libraries paper for more.

You might have some licensing issues. To simplify outrageously, it might be illegal (against the LGPL license) to ship code statically linked to some LGPL (or GPL) library. The evil is in the details.

Some core features, notably DNS related (e.g. getaddrinfo(3) & getnameinfo(3)) are internally using plugin techniques à la dlopen(3), so sort-of requires a dynamic libc.so (see nsswitch.conf(5) for more).

Some X11 things, in particular font related, are also expecting plugin related things (IIRC, Xft); perhaps SFML uses them. BTW, SFML is very probably installed as shared libraries, so you'll need to rebuild SFML from source code...

At last, a statically linked program might be more tied to some particular kernel version that a dynamically linked one (in principle, this is not the case). It might happen that you could have incompatibilities with very old or future kernels (but usually not).

See also ldd(1), file(1), pmap(1), proc(5), vdso(7)

It might be actually simpler to ship the source code to the target system, ask the sysadmin to install required dependencies, and build your code on the remote target (e.g. using ssh)

You could try to link statically most libraries but not all (e.g. link statically libstdc++.a and dynamically libc.so) by playing with GCC linking options. See this & that

Perhaps you'll first should try to link statically some SFML demo.... or simply scp your (dynamically linked) binary program and try to run it remotely (it might be able to run).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
3

Compiling with -static appears to work for basic c++ programs, probably all of the standard library?

However when using with other libraries, this may no longer work.

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225