One possibility is to load the auxiliary libraries that you need into a “private” location, and then alter the headers of your program to search that location.
Mimic your target environment
- Install a VM on your own machine running the same CentOS build as the hosting company. This means the same CentOS release and same CPU architecture. (
cat /etc/*-release
should give you the one piece of information; uname -a
will give you the other. Specifically, you want to ensure that you have a similar/same C library version; /lib/libc.so.?
should be executable and give you some details about the C library in use.)
- Install the requisite packages using YUM on your virtual host.
- Ensure that your binary executable works.
Figure out what the target environment is missing
Run ldd /usr/bin/your-app
to obtain the list of libraries to which it refers.
Specifically, to clean up that list:
ldd /usr/bin/your-app | cut -d '(' -f 1 | cut -d '>' -f 2 | sed -e 's,[ \t],,g' | sort | uniq > my-required-libs
Log in to the remote server and copy the file over; then run something like:
#!/bin/sh
missing-libs
for lib in $(< my-required-libs )
do
if [ -f "$lib" ]
then
echo "OK $lib"
else
echo "NO $lib"
echo "$lib" >> missing-libs
fi
done
Copy missing-libs
back to your virtual host and mkdir
a folder named e.g. ~/my-app/lib
; then cp $(<missing-libs) /home/myself/my-app/lib
NOTE, that you will need to create this exact path on your shared host, including the user name and so forth — so if your writable directory on the shared host is /home/myself
make sure that this directory is under /home/myself
on the virtual host as well.
Alter the executable's RPATH to point to your alternate library location
Find your application executable file and alter its headers using chrpath
(you will probably need to yum install chrpath
in your virtual machine, as this is an unusual program to need):
chrpath --list /usr/bin/your-app
If that reports any existing RPATH, then you'll want to PREPEND the path ~/my-app/lib to that RPATH with a :
— e.g. if chrpath --list
showed /usr/lib/my-app/plugins
you might use /home/myself/my-app/lib:/usr/lib/my-app/plugins
. In the more usual case, just use --replace
with the name of the directory into which you've copied the prerequisite libraries.
chrpath --replace ~/my-app/lib /usr/bin/your-app
Now, copy the executable with the new RPATH and the directory full of supporting libraries to your shared host.
This is all “friendly” to a multi-user shared-hosting set-up, unlike other solutions using e.g. chroot
jails.
Alternatively, create an LD_LIBRARY_PATH wrapper
If chrpath
doesn't work for your set-up (e.g. extremely strict SELinux contexts), you may be able to skip the chrpath
step and instead do something like:
mv ~/my-app/bin/my-app ~/my-app/bin/my-app.real
and make a wrapper script like
#!/bin/sh
export LD_LIBRARY_PATH=/home/myself/my-app/lib
exec /home/myself/my-app/bin/my-app.real
… and replace the original binary's name with this script.
Note, in theory, you can replace almost any library this way, but when libraries require data files in particular places (e.g. /etc
) or dynamically invoke sub-libraries from system locations (e.g. /usr/lib64
), you may be faced with having to recompile them with new paths in their ./configure
scripts or editing their sources in ways that are probably not worth the effort in all but the most extreme cases.
EG: Things that are unfriendly to relocating in this way: libc
and Pluggable Authentication Modules.