Search code examples
c++linuxshared-librarieslibcdynamic-library

Bundle c++ application using libc.so.6


I'm Trying to make my executable portable on linux, to do this i need to copy all the shared library used by the program itself, to check which one do I need I use:

ldd program_name

The output of the program helps me find all the required .so, between these libraries there is:

libc.so.6 => /lib64/libc.so.6 (0x00007f5b61ac2000)

At this point I copied all the libraries in a folder called shared_libs and shipped them alongside the program to another pc, the problem arise when i do:

LD_LIBRARY_PATH=./shared_libs ./program_name

which gives:

[1]    4619 segmentation fault (core dumped)  LD_LIBRARY_PATH=./shared_libs ./program_name

I'm pretty sure that libc.so.6 is causing the problem because if I do:

LD_LIBRARY_PATH=./shared_libs ls

with just that library in the shared_libs folder, ls gives seg fault as well.

How can i bundle my application?

EDIT 1: Why i don't link statically everything?

I tried it, The only thing i got was headache...


Solution

  • to do this i need to copy all the shared library used by the program itself

    No, you don't. In particular, copying GLIBC simply doesn't work (as you've discovered).

    What you actually need is to build your program against an old enough (not newer than any of systems you distribute your program to) libc, and then depend on GLIBC ABI compatibility (which guarantees that programs linked against old GLIBC continue to run correctly when bound to newer GLIBC at runtime).

    This can be achieved by either building your program on an old system, or using a chroot, or building a "linux to older linux" cross-compiler.

    I'm pretty sure that libc.so.6 is causing the problem

    Correct. The reason this doesn't work is explained e.g. here.

    The problem is that GLIBC is composed of multiple binaries which all must match. And the path to one of these binaries (the ld-linux) is hard-coded into the program at static link time and can not be changed.