【问题标题】:Statically link OpenSSL in XCode在 XCode 中静态链接 OpenSSL
【发布时间】:2015-06-19 17:19:20
【问题描述】:

我正在尝试在 XCode 命令行项目中链接 libssl.alibcrypto.a 静态库 [在 Link Binary With Libraries 下]。我在搜索路径中包含了 Openssl 头文件。

编译成功,但执行失败 dyld: Library not loaded: /usr/local/ssl/lib/libcrypto.1.0.0.dylib

当我静态链接它时,为什么它会寻找 dylib?如何解决这个问题?

任何帮助都将不胜感激。

【问题讨论】:

  • Anil - 这是 iOS、OS X 还是两者兼有?

标签: xcode openssl static-linking dylib


【解决方案1】:

当我静态链接它时,为什么它会寻找 dylib?如何解决这个问题?

Apple 的链接器使用 dylib 或共享对象(如果可用),无论您的链接器标志如何,例如 -rpath-Bstatic。他们甚至在不允许 dylib 的 iOS 上这样做!

一旦你知道它,它就是一个众所周知的问题:) 例如,请参阅Installing Crypto++ 5.6.2 on Mac OS X。 Crypto++ 与 Apple 的工具有同样的问题。

解决方法是停止 使用-L-l 选项,并直接链接目标文件或存档。存档只是对象文件的集合,因此您可以互换使用它们。

要为链接器指定目标文件或档案,请参阅Linking to an object file。在 Xcode 下,您将完全指定的存档名称(如 /usr/local/openssl-ios/lib/libcrypto.a)添加到 Other Linker FlagsOTHER_LDFLAGS Xcode 选项)。

将完整存档添加到 OTHER_LDFLAGS 时,我相信您只需逐字添加它没有任何开关,例如 -l-L。您可能需要-Wl (-Wl,/usr/local/openssl-ios/lib/libcrypto.a),但您不要使用-l (-l/usr/local/openssl-ios/lib/libcrypto.a)。 p>

当通过编译器驱动程序传递到链接器时,您使用 -Wl。如果直接调用链接器,则不需要-Wl,也不应该使用它。


第二个选项是将GCC_LINK_WITH_DYNAMIC_LIBRARIES 设置为YES。 Apple 似乎没有在Xcode Build Setting Reference 中记录它,但它显然在我的 Xcode 副本下。请参阅 Stack Overflow 上的 How to link a static library for iOS

我似乎记得过去在这方面遇到过问题。它是理论上应该可行但在实践中行不通的事情之一。


第三种选择是从 Xcode 下使用的所有路径中删除 dylib 或共享对象,这样 Xcode 在使用 -lcrypto 时不会意外找到它。


第四个选项是使用允许动态链接,但使用DYLD_LIBRARY_PATH 执行程序。它的 OS X 等效于 LD_LIBRARY_PATH,并确保加载您的 OpenSSL 副本(如 1.0.2),而不是系统的 OpenSSL 版本 (0.9.8)。

但我不喜欢这个选项,因为它需要你软件的用户做某事。


由于消息 dyld: Library not loaded: /usr/local/ssl/lib/libcrypto.1.0.0.dylib 的另一种可能性是对您的库副本进行代码签名。找到但没有加载它有点奇怪,所以我要把它扔在那里,以防它的 OS X 的 Code SigningGatekeeper Service...

要在 MAC Developer 程序下对您的库副本进行代码签名,只需:

codesign -fs "Johnny Developer" /usr/local/ssl/lib/libcrypto.so

【讨论】:

  • 非常感谢。 1)如果我在 OTHER_LINKER_FLAGS 中使用 -Wl,$path_to_lib.a ,即使我从“Link Binary With Library”中删除了库,它也可以工作。怎么可能?我希望 MAC 上预装的 openssl 不会干扰? 2) 默认情况下,openssl 是否总是安装在 MAC-OSX 上?如果是这样的话,如果我们直接使用它(使用 NSTask)而不涉及静态或动态链接的复杂性,它会有所不同。
  • 它正在选择正确的版本。我已经构建了静态库版本 1.0.2a,SSLeay_version 的输出是 1.0.2a 3 月 19 日。如果总是预先安装 openssl 是否有意义,那么我们可以通过 NSTask 直接调用 openssl 函数而不将其与项目链接?跨度>
  • "1.0.2a 19 Mar" - 1.0.2c 是最新版本,它修复了安全漏洞。 “如果预装了 openssl 是否有意义...” - Apple 的 OpenSSL 版本是 0.9.8。它缺乏大多数 EC 支持,TLS 1.1 和 TLS 1.2(等等)。你应该避免它。
  • “这怎么可能?” - 哦,我的错……是的,这行得通。它之所以有效,是因为您正在为链接器指定要链接到的目标文件。档案只是目标文件的集合。即使您使用了这个技巧,请确保您使用-I... 来指定该特定库的头文件。
  • 从 Xcode 9 升级到 Xcode 10 后,我遇到了类似的问题。我的 iOS 应用程序构建并启动,但在启动 openssl.framework image not found... 时出现 dyld 错误? ?我应该提一下,Xcode 10 (Swift 4.2) 的升级需要 pod repo updatepod install
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多