this is my first stackoverflow question, so I will try to do it well.
Context:
I would like to provide a program that could work on every Linux distribution (for example, a program that will use C ++ 11 running on a system that does not have a C ++ 11 library). To do this, I would like to copy all the libraries that are used by my program and put them in a folder with an executable file, so it can use these libraries instead of the system one.
I have 2 environments for testing: - Opensuse, with (GNU libc) 2.19 - Ubuntu, with (Ubuntu EGLIBC 2.17-Oubuntu5.1) 2.17
I will compile my program under Opensuse and run it under Ubuntu. A program works well when it uses the default library.
Project:
Here is main.c:
int main(int ac, char **av) { printf("Hello World !\n"); }
Here is the tree of my folder under Opensuse (the same in Ubuntu without main.c et exec.sh):
+ project | +
And finally, here is ldd and readelf when I run the program with simple compilation:
> gcc main.c -o a.out > ldd ./a.out linux-vdso.so.1 (0x00007fff85f57000) libc.so.6 => /lib64/libc.so.6 (0x00007f1fdaaaf000) /lib64/ld-linux-x86-64.so.2 (0x00007f1dae75000) > readelf -d a.out | grep "library\|Library" 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
I did some research and finally found this post which explain ld-linux.so a bit.
Here is the script that I use to compile:
#!/bin/bash dir=`pwd` execName="a.out" libDir="/lib" linker="ld-linux-x86-64.so.2" gcc main.c -o ${execName} -Wl,--rpath=${dir}${libDir} -Wl,--dynamic-linker=${dir}${libDir}/${linker}
When I run my a.out compiler using a script on my Opensuse, I got the following:
> ./a.out Hello World ! > ldd ./a.out linux-vdso.so.1 (0x00007f3222e27000) libc.so.6 => /path/to/project/lib/libc.so.6 (0x00007f3222a7e000) /path/to/project/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x000073222e2b000) > readelf -d a.out | grep "library\|Library" 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000001d (RUNPATH) Library runpath: [/path/to/project/lib]
Problem:
Now, when I run this a.out executable (compiled under Opensuse) on my Ubuntu, I got the following output:
> ./a.out ./a.out: Permission denied. > ldd ./a.out linux-vdso.so.1 (0x00007fff5b5fe000) libc.so.6 => /path/to/project/lib/libc.so.6 (0x00007f47df480000) /path/to/project/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f47df82a000) > readelf -d a.out | grep "library\|Library" 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000001d (RUNPATH) Library runpath: [/path/to/project/lib]
I always refuse this permission when I run the executable, and I donโt know why.
I transfer my a.out and my lib folder from Opensuse to Ubuntu with Filezilla, and a.out is not executable after this transfer, so I need to do:
chmod 755 a.out
I have the same tree under Opensuse and Ubuntu 2 libraries in the lib folder are the default library from Opensuse
Any help in resolving the denial, or another way to do what I want, would be welcome. Thanks in advance for your help!
Note. I cannot use LD_PRELOAD, since you need to be root in order to use it, this will not work for what I want to do. I would also like to avoid static compilation, but if this is the only solution, I will think about it