以下编译:
g++ -L../../lib -o my_prog my_prog.cpp -ltest1 -ltest2
其中../../lib
包含libtest1.so和libtest2.so的符号链接
但是当我运行程序时出现错误:“加载共享库时出错:libtest1.so:无法打开共享对象文件:没有这样的文件或目录”,我不确定符号链接是否是罪魁祸首。
在运行时发生的事情与rpath有关。
你可能想要(不是真的推荐,请参阅this)在运行可执行文件之前适当地设置LD_LIBRARY_PATH
,或者更好的是你想在链接时设置可执行文件的rpath(例如通过将-Wl,--rpath $(realpath ../../lib/)
传递给执行链接的g++
命令。
阅读Drepper的How to write shared libraries论文和Program Library HowTo
选项-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
),表示包含应用程序可执行文件的目录。因此,位于somedir / app中的应用程序可以使用gcc -Wl,-rpath,'$ORIGIN/../lib'
进行编译,以便在somedir / lib中找到关联的共享库,无论somedir位于目录层次结构中的哪个位置。这有助于创建不需要安装到特殊目录中的“交钥匙”应用程序,但可以将其解压缩到任何目录中,并仍然可以找到自己的共享库。