如何在 Xcode 中将库与 rpath 链接?
Posted
技术标签:
【中文标题】如何在 Xcode 中将库与 rpath 链接?【英文标题】:How do I link libraries with rpath in Xcode? 【发布时间】:2020-05-07 18:43:29 【问题描述】:我在任何地方都找不到此信息。我的系统中安装了一些库,因此它可以在我的计算机上运行,但我想将这些库与我的应用程序一起分发。我看到的问题是 otool 显示系统库的绝对路径,因此当我将二进制文件复制到其他机器时,即使我将它们放在“运行路径搜索路径”中添加的目录中,也找不到它们。我有一个本地库(位于项目目录中),它与@rpath 前缀链接。其他系统库的链接方式相同,但它们具有 otool 显示的绝对路径。如何强制它们与 @rpath 前缀链接?
【问题讨论】:
【参考方案1】:这部分回答了我的问题:How to set dyld_library_path in Xcode
我尝试将其自动化,所以当添加任何新库时,它会正确设置,但我放弃了(天哪,为什么必须这么复杂!?)
【讨论】:
【参考方案2】:TL;DR
使用install_name_tool -change
肯定会为引用的框架/库设置@rpath
。但是,它不会更改库本身的名称。
为此,您需要使用install_name_tool -id
。
使用我目前正在处理的一个项目的粗略示例,其中QtGui.framework
(其中包括QtCore
等)是一个名为serialplot.app
的应用程序包中的捆绑框架。
首先运行 install_name_tool -change
以修复 serialplot
应用程序二进制文件调用的 QtGui
(和 QtCore
等)的相对路径
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/MacOS/serialplot
... (omitted commands for clarity)
$ install_name_tool -change /usr/local/opt/qt@5/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/MacOS/serialplot
以及install_name_tool -change
修复由QtGui
本身调用的QtCore
的相对路径
$ install_name_tool -change /usr/local/Cellar/qt@5/5.15.2/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore serialplot.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui
现在在应用程序二进制文件上运行otool -L
serialplot.app/Contents/MacOS/serialplot:
@rpath/qwt.framework/Versions/6/qwt (compatibility version 6.2.0, current version 6.2.0)
@rpath/QtSvg.framework/Versions/5/QtSvg (compatibility version 5.15.0, current version 5.15.2)
@rpath/QtWidgets.framework/Versions/5/QtWidgets (compatibility version 5.15.0, current version 5.15.2)
@rpath/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2)
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106)
/System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0)
@rpath/QtSerialPort.framework/Versions/5/QtSerialPort (compatibility version 5.15.0, current version 5.15.2)
@rpath/QtNetwork.framework/Versions/5/QtNetwork (compatibility version 5.15.0, current version 5.15.2)
@rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2)
所以一切看起来都很好,@rpath
被用于QtGui
(以及其他 Qt 框架)。
但是,在应用程序包内捆绑的 QtGui
上运行 otool -L
会显示
serialplot.app/Contents/Frameworks/QtGui.framework/QtGui:
/usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2)
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1671.10.106)
/System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 1.0.0)
@rpath/QtCore.framework/Versions/5/QtCore (compatibility version 5.15.0, current version 5.15.2)
/System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
/System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics (compatibility version 64.0.0, current version 1247.4.1)
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1560.12.0)
/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 50.1.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1560.12.0)
/System/Library/Frameworks/CoreText.framework/Versions/A/CoreText (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
请注意(如您所说)使用的是绝对路径 (/usr/local/opt/qt@5/lib/
),而不是 @rpath
$ otool -L serialplot.app/Contents/Frameworks/QtGui.framework/QtGui
serialplot.app/Contents/Frameworks/QtGui.framework/QtGui:
/usr/local/opt/qt@5/lib/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2)
...
现在运行install_name_tool -id
$ install_name_tool -id @rpath/QtGui.framework/Versions/5/QtGui serialplot.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui
otool -L
的输出现在可以满足您的需求
$ otool -L serialplot.app/Contents/Frameworks/QtGui.framework/QtGui
serialplot.app/Contents/Frameworks/QtGui.framework/QtGui:
@rpath/QtGui.framework/Versions/5/QtGui (compatibility version 5.15.0, current version 5.15.2)
...
是的,它很复杂,也很烦人,但只要有一点耐心,它就可以完美地编写脚本。
有关此特定示例的更多详细信息,请参阅我关于此项目的博客:Porting serialplot to OS X
【讨论】:
以上是关于如何在 Xcode 中将库与 rpath 链接?的主要内容,如果未能解决你的问题,请参考以下文章
在 Windows 中将 VS2005 静态库与 gcc 链接
在 Scons 中将“-W1,-rpath=\$ORIGIN”替换为“-W1,-rpath,\$ORIGIN”