17

When I use GCC, I can build program on my Ubuntu 15.04 using this:

-static-libgcc -static-libstdc++

And compiled binary can run on "stock" Ubuntu 14.04 without any external packages, only standard updates.

Is there possibility do build with this static linking to library with clang?

Most common answers:

  • using test ubuntu rep (ppa:ubuntu-toolchain-r/test)
  • update server
  • recompile on target server
  • don't use GCC

is not suitable for me.

Just can I do this with clang for run it on Ubuntu 14.04.3 LTS?

vladon
  • 8,158
  • 2
  • 47
  • 91
  • Doesn't this work? `-static -lstdc++` – Ashkan Dec 25 '15 at 09:25
  • @Ashkan No, unfortunately. – vladon Dec 25 '15 at 09:27
  • 2
    @vladon Options `-static-libgcc -static-libstdc++` works fine with me with clang++ 3.6. – Danh Dec 25 '15 at 11:06
  • @Danh Simple program like hello world also compiles for me, but for big program there are warnings: `clang: warning: argument unused during compilation: '-static-libgcc'` and `clang: warning: argument unused during compilation: '-static-libstdc++'` – vladon Dec 25 '15 at 13:32
  • @vladon there are linking flags, not compilation, hence warnings. – keltar Dec 25 '15 at 14:01
  • @keltar Hmmm... How to run clang linker? I thought it's `clang++ -static-libgcc -static-stdc++ -std=c++14 test.cpp -o test`. – vladon Dec 25 '15 at 14:17
  • @vladon yes something like that. I meant if your program have multiple files, this flags should only be used once on linking phase, not on compilation for each file. – keltar Dec 25 '15 at 14:20
  • @keltar Oh, yes, it works! :-) Write your comment an answer for bounty :-) – vladon Dec 25 '15 at 14:54

2 Answers2

19

clang is compatible with gcc on this matter. Basically for hello-world program that uses iostream to ensure libstdc++ requirement (actual lib versions may vary between distributions):

$ clang++ test.cpp
$ ldd ./a.out
        linux-vdso.so.1 (0x00007ffec65c0000)
        libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/libstdc++.so.6 (0x00007ff937bb6000)
        libm.so.6 => /lib64/libm.so.6 (0x00007ff9378b6000)
        libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/libgcc_s.so.1 (0x00007ff93769e000)
        libc.so.6 => /lib64/libc.so.6 (0x00007ff9372fe000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ff937f3e000)

Here is a dependency for libstdc++ and libgcc_s. But if you add -static-libgcc -static-libstdc++:

$ clang++ test.cpp -static-libgcc -static-libstdc++
$ ldd ./a.out
        linux-vdso.so.1 (0x00007ffe5d678000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fb8e4516000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fb8e4176000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fb8e4816000)

That still leaves dependency on libc, but that is a different question.

clang: warning: argument unused during compilation: '-static-libstdc++' means clang ignored this flag, because flag is useless in current situation. First two examples that coming to mind is compiling C code (which obviously don't depend on libstdc++), or issuing compile-only command without linking (-c flag). Since .o file cannot hold information about static or dynamic linking, this flag have to be specified on linking phase (and, to avoid warning, only on linking phase).

keltar
  • 17,711
  • 2
  • 37
  • 42
2

Instead of using -static-libstdc++ or -static-libgcc, just use clang's -static flag. It will produce a non dynamic executable, with everything it needs linked in statically.

On my test program, it produces:

[root@interserver ogrerobot.com]# ldd ./CppUtilsSpikes  
not a dynamic executable
zertyz
  • 601
  • 6
  • 9