Normally, programs (in Linux) use LD_LIBRARY_PATH to locate their shared libraries, but I want to use a custom-path, without permanently altering LD_LIBRARY_PATH.
Basically, a bash-wrapper can achieve it easily:
#!/bin/sh
export LD_LIBRARY_PATH=/my_lib_path/
/my_bin_path/myprogram $*
(Bash only alters LD_LIBRARY_PATH within this script and not permanently)
I was wondering if it is possible to do the same thing in pure C in one single executable without the ugly bash-hack. All paths and the exact names of the libraries are known at compile-time.
Shared libraries (also called dynamic libraries) are linked into the program in two stages. First, during compile time, the linker verifies that all the symbols (again, functions, variables and the like) required by the program, are either linked into the program, or in one of its shared libraries.
By definition, every shared library system provides a way for executables to depend on libraries, so that symbol resolution is deferred until runtime.
A shared library or shared object is a file that is intended to be shared by multiple programs. Symbols used by a program are loaded from shared libraries into memory at load time or runtime.
✔️ A program compiled with static libraries is portable because it can be taken to another computer without the need to take the libraries with you.
Pass the -rpath
option to ld
, or, via your compiler -Wl,-rpath
. It allows you to extend the search path. It is commonly used by executable that wish to load modules from some plugin directory. You may add as many directories as you want via this method.
As others have said, when linking the program you can use -Wl,-rpath
to add specific paths to the library search path for the application. However, if you just want to hard-code the path for a specific library, use that when linking rather than using the -l
option. For instance, instead of -lfoo
, just use /opt/foo/lib/libfoo.so.1
on the linking command line.
You can't change LD_LIBRARY_PATH
at runtime, the dynamic loader reads it once when the program is executed and never checks it again, you could use dlopen() instead to load the shared library yourself:
dlopen("/path/to/shared/lib.so", RTLD_LAZY);
This will only work if you load the library and use dlsym()
at runtime to look-up symbols otherwise if you call functions in the library those references must be resolved at load time and AFAIK you have to use something like the bashscript.
Note: It's possible to change LD_LIBRARY_PATH
in runtime if you re-execute the process, I've just tested this and it seems to work, but it's very hackish, it's possibly the only way to do it in C
:
void *handle;
// first time check if path is not set
if (getenv("LD_LIBRARY_PATH")==NULL) {
//set it and re-execute the process
setenv("LD_LIBRARY_PATH", "/path/to/lib/", 1);
execl(argv[0], argv[0], NULL);
}
// open the shared library the second time
handle = dlopen("test.so", RTLD_LAZY);
printf("%p\n", handle);
dlclose(handle);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With