是否可以在C程序中硬编码共享库位置?

时间:2012-12-30 17:00:57

标签: c shared-libraries

通常,程序(在Linux中)使用LD_LIBRARY_PATH来定位它们的共享库,但是我想使用自定义路径,而不是永久地改变LD_LIBRARY_PATH。

基本上,bash-wrapper可以很容易地实现它:

#!/bin/sh
export LD_LIBRARY_PATH=/my_lib_path/
/my_bin_path/myprogram $*

(Bash只在此脚本中改变LD_LIBRARY_PATH而不是永久改变)

我想知道是否有可能在一个单一的可执行文件中使用纯C 执行相同的操作而没有丑陋的bash-hack。所有路径和库的确切名称在编译时都是已知的。

4 个答案:

答案 0 :(得分:4)

正如其他人所说,在链接程序时,您可以使用-Wl,-rpath为应用程序的库搜索路径添加特定路径。但是,如果您只想对特定库的路径进行硬编码,请在链接时使用该路径而不是使用-l选项。例如,代替-lfoo,只需在链接命令行上使用/opt/foo/lib/libfoo.so.1

答案 1 :(得分:3)

您无法在运行时更改LD_LIBRARY_PATH,动态加载程序在程序执行时会读取它并且永远不会再次检查它,您可以使用dlopen()来自己加载共享库:< / p>

dlopen("/path/to/shared/lib.so", RTLD_LAZY);

这只适用于加载库并在运行时使用dlsym()来查找符号,否则如果你在库中调用函数那些引用必须在加载时解析而AFAIK你必须使用像bashscript。

注意:如果你重新执行这个过程,可以在运行时更改LD_LIBRARY_PATH,我刚刚测试了这个并且它似乎工作,但它非常hackish,它可能是唯一的方法来执行它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);

答案 2 :(得分:3)

-rpath选项传递给ld,或通过编译器-Wl,-rpath传递。它允许您扩展搜索路径。它通常由希望从某个插件目录加载模块的可执行文件使用。您可以通过此方法添加任意数量的目录。

答案 3 :(得分:0)

我不认为这在执行时是可行的:在执行程序之前加载库...

但是你可以通过将选项-rpath传递给你的链接器

来在编译时完成它