@loader_path和@executable_path的起始路径

2022-11-30 17:36:24
标签: lc_rpath otool loader_path executable_path

项目里RPATH使用比较混乱,也基本很多同事不深究,只要库里设了能工作就行了。

二进制文件有各种 @executable_path和@loader_path然后拼上 ../Frameworks

../../Frameworks以及../../../Frameworks

这其实纯属瞎搞,根本没搞清楚哪个起作用。

于是清理工作开始。在过程中,有一个情况比较特殊,中间用了.framework。然后它里面有symbol link会造成理解的混乱。

先讲一下上面这两个东西的用法,网上文章比较多。大部分讲的都正确,总结一下,就是一般情况下,执行文件用@executable_path,库用@loader_path。然后它们代表的是可执行文件,库所在的路径,相当于二进制文件本身的Parent目录。所以@loader_path/Sibling.dylib 其实代表着和本身同目录的兄弟文件,以此类推。

@executable_path/../Frameworks 代表可执行文件本身的文件夹外层的文件夹下的Frameworks目录。

相对于MACOS的Frameworks

conanchen@ConanChen MacOS % cd ../Frameworks 

conanchen@ConanChen Frameworks % pwd

/Users/conanchen/Downloads/Fusion_Output_MAC_Release_AppleSilicon/Autodesk Fusion 360.app/Contents/Frameworks

     接下来讨论一下在带.framework的情况。

.framework

 

conanchen@ConanChen Frameworks % otool -L /Users/conanchen/Downloads/Fusion_Output_MAC_Release\ FSR/Frameworks/ClientFramework/ClientData.framework/ClientData

/Users/conanchen/Downloads/Fusion_Output_MAC_Release FSR/Frameworks/ClientFramework/ClientData.framework/ClientData:

@rpath/ClientFramework/ClientData.framework/ClientData (compatibility version 0.0.0, current version 0.0.0)

@rpath/Qt/QtRemoteObjects.framework/Versions/5/QtRemoteObjects (compatibility version 5.15.0, current version 5.15.2)

@rpath/ClientFramework/ClientCommon.framework/Versions/A/ClientCommon (compatibility version 0.0.0, current version 0.0.0)

可以看到,它的ID是在外层的快捷方式,引用ClientData的模块会去定位这个在外面的快捷方式,但加载的是符号链接所指向的真实文件。

ClientData本身的LC_RPATH,应该也只会对真实文件的所在的路径起作用,相对路径是以内部真实文件为基础的。

但别人加载ClientData却是引用的外层的快捷方式,所以各级引用库会看起来不一致,有的引用快捷方式所在路径,有的引用库真实路径。

经过测试,QT库所有的ID是指向内部真实文件的,并不是外面的快捷方式。

快捷方式可能用来给Framework升级用的,它永远指向真实文件的位置,编译的时候CMAKE可以引用外面的快捷方式,但是文件ID记录的是真实文件所在路径,而不是符号链接的位置。

但是ClientData明显不是这样,可以说是它错了或者不标准。

它引用其他ClientCommon的位置,也是一个真实文件的位置,这和QT是一致的。

QT应该是对的。QtGUI引用QtCore用@loader_path/../../../是正确的。ID和依赖都写的真实文件的路径。

对QT来说是用@loader_path/../../../来引用相对路径中的库引用,但是ClientData不是,它用的可执行文件那些多层的../../../Frameworks,这就已经挖了一个坑了,你一个库,其实正常情况不应该知道可执行文件和它内部的结构,只应该关注自己的位置。

otool -L binary 会显示ID和依赖的库

形如

@rpath/binarySelf

@rpath/binaryDependency

ID的作用是,别人引用它的时候,@rpath/binarySelf会被作为字符串写进别人的dependency。

而@rpath本身在加载的时候,会被otool -l binary所显示的LC_RPATH段所指示的路径所替代,LC_RPATH可以有多个,每个具体值以@exectuable_path或@loader_path开头。这些路径被用来替换@rpath,并查找每个binaryDependency。


 


 

 

阅读(0) 收藏(0) 转载(0) 举报/Report
相关阅读

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有