我编译了一个CMake作为子项目的共享库,然后主应用程序链接到该库。库和应用程序位于我的主目录下的相同输出目录中。Linux:为什么加载程序找到我的共享库?
因为我在Linux上,我现在不明白为什么加载程序会看到我的库。
当我用ldd检查libs时,一切正常。但是,我的印象是,我必须设置LD_LIBRARY_PATH,以便我的应用程序可以从同一目录加载共享库。但我没有设置它,它仍然有效。为什么?
我编译了一个CMake作为子项目的共享库,然后主应用程序链接到该库。库和应用程序位于我的主目录下的相同输出目录中。Linux:为什么加载程序找到我的共享库?
因为我在Linux上,我现在不明白为什么加载程序会看到我的库。
当我用ldd检查libs时,一切正常。但是,我的印象是,我必须设置LD_LIBRARY_PATH,以便我的应用程序可以从同一目录加载共享库。但我没有设置它,它仍然有效。为什么?
也许您的构建过程在您的可执行文件中设置RPATH
以在同一目录中查找库。为了测试这个,尝试将可执行文件移动到不同的目录,然后查看是否可以运行它(或ldd
它)。
您还可以检查RPATH
在可执行在以下任一方式:
readelf -d the-exe | grep RPATH
objdump -x the-exe | grep RPATH
更多关于这一点,在这里看到:https://unix.stackexchange.com/questions/22926/where-do-executables-look-for-shared-objects-at-runtime
或者运行'readelf -d ./thebinary | grep RPATH'。 automake/autoconf通常会自动嵌入RPATH,因此您可以轻松地从项目文件夹中运行已编译的应用程序,并在'make install'期间重新链接它以排除RPATH(如果DESTDIR位于不需要RPATH的常见位置)我怀疑CMake有类似的automagic情报。 – nos
@nos:谢谢,我在'objdump'中加入了'readelf'的想法。 –
大概CMake的设置makefile文件添加为一个选项链接器来告诉它共享库在哪里。搜索'ld'选项'--rpath'。 –
那个.so是用'-L'和'-l'连接的吗?另一种方法是直接使用完整路径和名称链接到.so。如果CMAKE使用其完整路径和名称链接.so,则在加载时没有搜索。它只是使用相同的完整路径和名称。 – JSF
@JSF不,它似乎使用-Wl,-rpath。 – juzzlin