我有兴趣在一些使用我自己编译的OpenSSL的应用程序中使用网络模块附带的Qt网络功能。我想在osx,ios和android中使用这个应用程序。实现这一目标的正确方法是什么?通过qt网站的Qt5二进制安装,我能够部署到Android和OSX,但我无法部署到iOS。要更改iOS工具包,我创建了一个环境变量OPENSSL_LIBS并将其设置为我的iOS openssl编译,但我无法将编译链接到该版本(它保持链接到我的系统安装的OpenSSL)。
论坛中有人说我需要使用openssl-linked配置选项编译Qt,但是我还没有能够使用它。有人可以指示如何继续处理以下任何一项:使用二进制Qt5安装链接到不同的OpenSSL版本,或者从链接到不同版本的OpenSSL的源编译Qt5。
答案 0 :(得分:2)
我想在osx,ios和android中使用这个应用程序。实现这一目标的正确方法是什么?
Mac OS X和iOS是孩子们的问题。 Apple工具的问题是:1)链接器不支持rpath
和-Bstatic
之类的内容; 2)链接编辑器不尊重rpath
和LD_PRELOAD
。
对于(1),链接器将静默删除rpath
。此外,-Bstatic
被忽略。因此,如果可用,您将始终链接到共享对象或dylib,并且它可能是错误的。
在Mac OS X上与OpenSSL链接时,您很可能会获得一个系统dylib:
$ find /usr/ -iname libssl*
/usr//lib/libssl.0.9.7.dylib
/usr//lib/libssl.0.9.8.dylib
/usr//lib/libssl.dylib
对于(2),链接编辑器没有rpath
且不尊重LD_PRELOAD
,因此您将再次链接到系统库。
症状通常是模糊的失败,因为程序是针对OpenSSL 1.0.1编译的,而它在运行时与0.9.8链接。数据结构有时会有所不同,因此您会发现无意义的模糊崩溃。这是我所谈论的一个完美的例子:Coredump when compiling python with a custom openssl version。
解决此问题的方法是省略-L
,-lssl
和-lcrypto
。相反,您应指定存档的完整路径。例如,在Mac OS X上,我必须指定/usr/local/ssl/lib/libssl.a
和/usr/local/ssl/lib/libcrypto.a
。
静态存档只是*.o
个文件的集合。您应该尝试在"其他对象文件"中指定存档路径。如果你不能,那么尝试添加其他库。我知道如何在Makefile项目,Eclipse项目和Xcode项目中完成它,但我不知道如何在QtCreator下完成它。但Laszlo Papp告诉你如何在Adding object (.o) files to qtcreator project处进行。
以下是Xcode下的类似示例,其中我链接到Crypto ++而不是OpenSSL。但是,请注意我指定了存档的完整路径。 (这是一个Xcode项目,我在设备上遇到错误,因为它无法加载Crypto ++共享对象。)
您还必须确保根据您的OpenSSL版本编译和链接其他OpenSSL依赖库。我通常采用相同的方法 - 针对静态存档编译依赖库(即使它意味着代码膨胀)。例如,我有一个libevent
项目链接到我的静态版本的OpenSSL;我的项目链接到我的静态版本的OpenSSL。它很糟糕,但它是你必须要做的,直到Apple修复它们破碎的连接器。
Linux的表现要好得多,您可以使用rpath
或LD_PRELOAD
。但是,既然你正在为苹果公司跳过箍,你可能会在各地做同样的事情。
无论您做什么,不要在Apple平台上使用-L
,-lssl
和-lcrypto
。 Xcode永远不会正确,即使在iOS上,你想要使用的唯一库是静态存档。显然,Xcode开发人员没有得到备忘录,Apple QA也没有测试过什么(新的)。