可靠地在OSX上部署由Delphi生成的Dylib文件

6
我想在OSX上部署一个使用Delphi创建的.dylib文件,应该能够被第三方应用程序加载。这似乎是一个重复的问题,但是经过大量搜索,我找不到答案。问题在于.dylib需要libcgunwind.1.0.dylib,但是当从第三方应用程序运行时无法找到它。作为一个测试,我尝试将libcgunwind.1.0.dylib复制到usr/lib中,这个方法可行。当OSX无法定位.dylib时,它总是会在usr/lib中搜索。不幸的是,我不想这样做作为最终解决方案,因为它需要提升权限,并且似乎是处理一个简单问题的笨拙方式。

仔细检查后,我使用otool来检查我的.dylib文件,并得到了以下路径:@rpath/libcgunwind.1.0.dylib

问题在于,当你的.dylib被第三方应用程序运行时,无法预测会列出哪些路径在@rpath中。为了使其正常工作,应用程序必须始终提供libcgunwind.1.0.dylib的绝对路径。

显而易见的解决方案是使用install_name_tool@rpath替换为@loader_path。如果我的逻辑正确,这应该使我的.dylib总是能够找到libcgunwind.1.0.dylib,只要它们在同一个文件夹中。这是有道理的,因为.dylib应该负责找到它自己的依赖项。

所以,我尝试了以下命令行:

install_name_tool -change @rpath/libcgunwind.1.0.dylib @loader_path/libcgunwind.1.0.dylib libTest.dylib

并收到了这个消息:

install_name_tool: 文件排序不正确(本地重定位项位置不正确):libTest.dylib

我查找了这个错误信息,但是没有找到任何相关的信息。我猜测install_name_tool需要在gcc或者llvm编译的.dylib库中找到一些特定的惯例,而Delphi的编译器并没有提供这些惯例。

我在Delphi的编译器dccosx中进行了一些调查,并检查了Delphi发送给它的命令行参数,但是我没有找到任何有用的选项。这种使用libcgunwind.1.0.dylib的方式似乎是隐含在编译器中的,而且我无法进行调整。

我并不是在建议这是解决问题的正确方法,这只是我尝试过的最新方法。如果你能想出其他解决问题的方法,请分享你的想法!

1个回答

3
安装名称工具(install_name_tool)似乎需要按照特定的顺序排列 dylib 的某些部分,例如“本地重定位项”,然后是“符号表”,“本地符号”等等。错误消息意味着这种顺序不符合预期。
我的建议是尝试修补 dylib 文件。我经常在 OSX 可执行文件中这样做,因为我需要告诉它们与哪些 dylib 版本兼容。这可以修复 Delphi OSX 应用程序中的一些错误。dylib 的结构非常类似于可执行文件。我的经验是,修补这些文件并不像听起来那么复杂。
您可以在此找到文件结构的描述:https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
LC_LOAD_DYLIB 部分是您需要查看的内容。您应该能够将 dylib 名称替换为更长的名称,因为该部分通常具有一些额外填充。

有趣的解决方案。如果有人提出更简单的解决方案,我会保留赏金,但恐怕这可能是唯一的解决方案。我想,如果我能找到一种将其自动化到部署过程中的方法,那么这也不会太糟糕。 - AudioGL
好的,我尝试了这个补丁,它起作用了。但是我仍然犹豫不决,反复执行这个操作。你部署应用程序的流程是什么?你会制作打补丁工具吗? - AudioGL
我在我的OSX项目中有一个后构建事件:"D:\Dev\OSXPatcher.exe" "$(OUTPUTPATH)"。然后补丁会自动进行。 - Sebastian Z

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接