报错dyld: Library not loaded原因:链接时和运行时都需要指定动态库路径(利用@rpath指定运行时动态库路径)

最近在mac上写了一个动态库,然后又写了一个可执行文件来链接它并使用该动态库。链接时一切正常,但是在执行生成的可执行文件时出现了下面的链接报错:

dyld: Library not loaded: ./obj/libtest.dylib

Referenced from: /Users/zeng/Workspace/practice_make/generate_lib/./test

Reason: image not found

可以看到,链接器没有正常载入应该的动态库。

我用mac下的otool工具查看了一些可执行文件test的链接情况,如下:

otool -L test

test:

./obj/libtest.dylib (compatibility version 0.0.0, current version 0.0.0)

/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)

第一条结果显示,我想链接的动态库的地址是./obj/...,这下我知道问题出在哪了。

我的动态库文件分明是在路径./source/obj/下,我链接时指定的-L中也是这么指定的。可在可执行文件test中,却显示动态库路径是./obj下,分明就不对嘛,难怪运行时无法载入呢。

我搜了些资料,理解如下(不一定正确哈仅供参考):

其实这涉及到所谓的动态库的install-name的问题。在生成动态库.so时它默认会有一个install-name(这个名称也可以人为指定),这个install-name往往是不具备完备的路径的。当编译可执行文件时,我们虽然不需要链接到动态库(直到运行时才动态链接),但还是需要用-L和-l指定用到的动态库,这个过程的效果之一是把这个install-name写到可执行文件中去(就是上面的./obj/libtest.dylib这个东西),那么运行时就可以默认到这个名字对应的路径下去找动态库。

但由于默认的install-name的路径是不完备的(就可执行文件所在的位置而言),或者说动态库文件与当前的可执行文件不在同一路径下,所以运行可执行文件时只根据install-name找不到动态库。此时就需要人为的指定一下动态库路径了,一般来说有三种方法。

第一种,就是在命令行中执行:export DYLD_LIBRARY_PATH=./obj告诉链接器去这里找。

第二种,就是修改可执行程序中的install-name,使其指向动态库文件所在的位置。具体做法见下面第一个链接。

第三种,就是在生成动态库的时候指定其install-name为@rpath/libxx.so,这样,之后在生成可执行文件指定-L,-l,-Wl,-rpath时写入可执行文件的install-name就是带全路径的动态库名。我理解为这里动态库的install-name中的@rpath就是个占位符,表示之后在使用动态库的时候,指定动态库路径就能自动替换掉这个占位符,使可执行文件能正常地动态链接。

 

所以,链接时查找的位置和运行时查找的位置是两码事:

-L指定编译链接时的搜索目录;

-Wl,-rpath指定程序运行时加载的共享库搜索目录

 

更详细的解释(说得非常清楚),见:

https://www.cnblogs.com/liubaocheng999/p/4285256.html

 

更官方和准确的文档见:

stack overflow上有个相关问题:

https://stackoverflow.com/questions/29809069/dyld-library-not-loaded-on-os-x

讲动态库的:

https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/OverviewOfDynamicLibraries.html#//apple_ref/doc/uid/TP40001873-SW3

讲Run-Path Dependent Libraries的:

https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html#//apple_ref/doc/uid/TP40008306-SW1

你可能感兴趣的:(报错dyld: Library not loaded原因:链接时和运行时都需要指定动态库路径(利用@rpath指定运行时动态库路径))