以下编译:
g++ -L../../lib -o my_prog my_prog.cpp -ltest1 -ltest2
其中../../lib
包含指向libtest1.so和libtest2.so的符号链接
但是运行程序时出现错误:“加载共享库时出错:libtest1.so:无法打开共享库文件:没有这样的文件或目录”,并且不确定符号链接是否是罪魁祸首。 >
答案 0 :(得分:2)
选项-L
用于链接器ld
在链接过程中找到.a
和.so
。
选项-Wl,-rpath=
用于动态链接程序 ld.so,以便在运行应用程序时找到.so
。当所需的共享库不在-Wl,-rpath=
中指定的(标准系统)目录中时,您需要使用/etc/ld.so.conf
。
使用$ORIGIN
动态链接器变量使rpath相对于可执行文件的路径:
g++ -L../../lib -Wl,-rpath='${ORIGIN}/../../lib' -o my_prog my_prog.cpp -ltest1 -ltest2
请注意确保${ORIGIN}
不会被shell或您的makefile 扩展(这就是为什么用单引号引起来的原因)。
$ORIGIN
和rpath
ld.so
在rpath规范($ORIGIN
或${ORIGIN}
)中理解字符串DT_RPATH
(或等效地DT_RUNPATH
),以表示包含应用程序可执行文件的目录。 。因此,可以使用gcc -Wl,-rpath,'$ORIGIN/../lib'
编译位于somedir / app中的应用程序,以便无论somedir在目录层次结构中的位置如何,都可以在somedir / lib中找到关联的共享库。这有助于创建“交钥匙”应用程序,这些应用程序不需要安装到特殊目录中,而可以解压缩到任何目录中,并且仍然可以找到自己的共享库。
答案 1 :(得分:1)
运行时发生的事情与rpath有关。
您可能希望(不建议这样做,请参见this)在运行可执行文件之前适当地设置LD_LIBRARY_PATH
,或者更好的是,您希望在链接可执行文件时设置可执行文件的rpath(例如,通过传递{ {1}}到-Wl,--rpath $(realpath ../../lib/)
命令进行链接。
阅读Drepper的How to write shared libraries论文和Program Library HowTo