I'm doing some C programming on a machine for which I don't have root access. I've compiled some shared libraries that I'm linking to, but because I cannot install the libraries in the typical location (/usr/local/lib
) I have to explicitly specify the location of the libraries each time I compile and run. 开发者_运维百科When compiling, this simply means adding the -L
flag to the gcc
command, but for program execution it's a lot more annoying. Either I must add the non-standard directory to LD_LIBRARY_PATH
in each session, or I must add LD_PRELOAD=/path/to/libs
to the beginning of the execute command.
Is there a better way to do this on a machine for which I don't have root access?
BTW, the machine is running Red Hat 4.1.
There are several solutions, from better to worse:
- Use
$ORIGIN
, e.g.gcc main.o -L../lib -lfoo -Wl,-rpath='$ORIGIN'/../lib
- Use target RPATH, e.g.
gcc main.o -L../LIB -lfoo -Wl,-rpath=/home/user/lib
- Set
LD_LIBRARY_PATH
from your.bashrc
or.profile
Solution 1 allows you to install the binary anywhere, so long as you move the binary and the libraries together, e.g. my-app/bin/a.out and my-app/lib/{needed-shared-libs}.so. It also allows for multiple versions of the application and their set of shared libs.
Solution 2 works fine if you only need one set of shared libs, and never wish to move them around.
Solution 3 affects every application you run, and may cause some of them to bind to your shared libraries instead of the system ones. That may cause them to crash, fail with unresolved symbols, or cause you other pain. To exacerbate, the problem will only happen to you and nobody else, so you'll have hard time getting help for it.
You can add the environment variables to your .bashrc
(or whatever file your shell sources when you log-in).
If you set the environment variable LD_RUN_PATH
when you compile and link your program, then that search path will be baked in to the executable, and the dynamic linker will search it at runtime.
Using LD_LIBRARY_PATH or LD_PRELOAD is pretty much how to do this. To fix this, rename your program from myprog to myprog-exe, and create a shell script that looks like this called myprog:
#!/bin/sh
export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH
`dirname $0`/myprog-exe
This way, when someone runs myprog, it will really run the shell script which then runs myprog.
精彩评论