2015-06-19 79 views
4

我正在尝试链接libssl.alibcrypto.a静态库在XCode命令行项目[在链接二进制库下]。我已将Openssl头文件包含在搜索路径中。静态链接XCode中的OpenSSL

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

为什么当我静态链接它时会寻找dylib?这怎么解决?

任何帮助将是可观的。

+0

Anil - 这是iOS,OS X还是两者? – jww

回答

5

为什么在我静态链接它时寻找dylib?这怎么解决?

苹果的连接器使用如果可用的dylib或共享对象,不管你的连接标志像-rpath-Bstatic的。他们甚至在iOS上执行此操作,但不允许使用dylib!

一旦你知道它的一种众所周知的问题:)请参阅,例如,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_LDFLAGS Xcode选项)。

当添加完整存档到OTHER_LDFLAGS,我相信你只是将它加入逐字没有任何开关,就像-l-L。您可能需要-Wl-Wl,/usr/local/openssl-ios/lib/libcrypto.a),但你使用-l-l/usr/local/openssl-ios/lib/libcrypto.a)。

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


第二选项是设置GCC_LINK_WITH_DYNAMIC_LIBRARIESYES。苹果公司似乎没有在Xcode Build Setting Reference中记录它,但它明显在我的Xcode副本下。请参阅Stack Overflow上的How to link a static library for iOS

我似乎记得过去有这个问题。它是理论上应该起作用但在实践中不起作用的那些事情之一。


第三种选择是去除在Xcode下使用的所有路径的dylib或共享对象,以便利用-lcrypto时Xcode的不小心找到它。


第四选择是使用允许动态链接,但与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开发人员程序的代码签名您的副本,只是:

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

非常感谢。 1)如果我在OTHER_LINKER_FLAGS中使用-Wl,$ path_to_lib.a,即使我从“Link Binary With Library”中删除这些库,它也能正常工作。这怎么可能?我希望预装在MAC上的openssl不会干扰? 2)是否默认安装在MAC-OSX上的openssl?如果我们直接使用它(使用NSTask)而不进入静态或动态链接的复杂性,那么它会起作用。 – Abhinav

+0

它正在挑选正确的版本。我已经构建了静态库版本1.0.2a,并且SSLeay_version的输出是1.0.2a 3月19日。如果openssl是预安装的,那么我们可以直接通过NSTask直接调用openssl函数,而无需将其与项目链接起来,这也是有意义的吗? – Abhinav

+0

*“1.0.2a 3月19日”* - 1.0.2c是最新版本,它有安全错误修复。 *“如果openssl预装了,是否有意义......” - 苹果公司的OpenSSL版本是0.9.8。它缺乏大多数EC支持,TLS 1.1和TLS 1.2(等等)。你应该避免它。 – jww