我正在为OSX / iOS开发Swift框架。我需要生成RSA密钥并导出它们,而安全框架不允许在iOS上整齐地执行此操作,因此我将使用OpenSSL。
我检索了一个为两个平台(https://gist.github.com/6710405)构建OpenSSL的脚本。它运行完美,并为每个平台生成libcrypto.a
,libssl.a
和相应的标头。
我想将OpenSSL放在自己的框架中,并定义一个模块,以便在Swift中轻松使用它。
为简单起见,我们仅限于OSX。我创建了一个名为OpenSSL的新框架项目。我链接了两个库并添加了所有标题(作为公共标题)。我还添加了一个"复制文件"我复制并签署两个库的阶段。我创建了一个.modulemap
文件:
framework module OpenSSL {
header "rc2.h"
header "rc4.h"
header "aes.h"
[…]
header "x509v3.h"
header "dtls1.h"
export *
}
列出了OpenSSL的所有标头。我最初按字母顺序对标题进行了排序,但是有些#undef
导致了问题,所以我不得不重新排序几个标题然后编译(我根本不喜欢它!)。
回到原来的框架中,我添加了我的OpenSSL框架,导入了OpenSSL模块并写了几行:
import OpenSSL
func generateKeyPair() -> RSAKeyPair? {
var exponent = BN_new();
BN_set_word(exponent, 65537);
var rsa = RSA_new()
RSA_generate_key_ex(rsa, 2048, exponent, nil)
[…]
}
代码由Xcode完成,它看到模块的标题。当我尝试编译时,它会为一些(但不是全部)OpenSSL调用生成一些Undefined symbols for architecture x86_64:
。例如,它抱怨RSA_generate_key_ex
但不抱怨BN_set_word
或RSA_new()
(在RSA_generate_key_ex
之前声明了两行)。它不仅仅对RSA_generate_key_ex
失败,而其他一些调用在以后失败并出现相同的错误。
我已经设置了一个游乐场来检查这个。对RSA_new()
的一些调用正在返回,但操场无法找到RSA_generate_key_ex
的符号。
我快速建立了一个新的Objective-C项目,以经典方式添加了lib和头文件,并且相同的代码(在ObjC中)编译并运行没有问题。因此,我确信libs是使用所有需要的架构构建的(我用otool
进行了双重检查)。
我的框架有问题。我试图删除/添加"复制文件"阶段没有成功。我对.modulemap
文件的制作方式不满意,但我不知道它可能会导致此类问题。我不是框架制作方面的专家,所以也许有人知道会发生什么以及如何解决它?
答案 0 :(得分:2)
自己找到解决方案。像往常一样,框架中需要旧的-all_load
标志作为“其他链接器标志”。
此外,库不需要复制阶段。链接它们似乎就足够了。