静态链接与Swift,XCode6-Beta

我一直在尝试将一个Obj-C库移植到Swift,我遇到了一个问题,当Swift代码在项目中时,链接器无法构建静态库。

作为最小的再现器,进入XCode6并创建一个新的iOS静态库。 它会给你一个带有空白.h和.m文件的项目。 这将编译好。 然后,将新的.swift文件添加到项目中(创建或不创建标题桥)。 这也应该编译好,但在链接期间失败:

Libtool /Users/alexkarantza/Library/Developer/Xcode/DerivedData/Test-alenfoymgkewlghfjjvizjjuvign/Build/Products/Debug-iphonesimulator/libTest.a normal i386 cd /Users/alexkarantza/Workspace/Test export IPHONEOS_DEPLOYMENT_TARGET=8.0 export PATH="/Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode6-Beta.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin" /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static -arch_only i386 -syslibroot /Applications/Xcode6-Beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk -L/Users/alexkarantza/Library/Developer/Xcode/DerivedData/Test-alenfoymgkewlghfjjvizjjuvign/Build/Products/Debug-iphonesimulator -filelist /Users/alexkarantza/Library/Developer/Xcode/DerivedData/Test-alenfoymgkewlghfjjvizjjuvign/Build/Intermediates/Test.build/Debug-iphonesimulator/Test.build/Objects-normal/i386/Test.LinkFileList -ObjC -L/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator -Xlinker -rpath -Xlinker /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator -Xlinker -force_load -Xlinker /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a -Xlinker -sectalign -Xlinker __SWIFT -Xlinker __ast -Xlinker 4 -Xlinker -sectcreate -Xlinker __SWIFT -Xlinker __ast -Xlinker /Users/alexkarantza/Library/Developer/Xcode/DerivedData/Test-alenfoymgkewlghfjjvizjjuvign/Build/Intermediates/Test.build/Debug-iphonesimulator/Test.build/Objects-normal/i386/Test.swiftmodule -o /Users/alexkarantza/Library/Developer/Xcode/DerivedData/Test-alenfoymgkewlghfjjvizjjuvign/Build/Products/Debug-iphonesimulator/libTest.a error: /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: unknown option character `X' in: -Xlinker Usage: /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-sacLT] [-no_warning_for_no_symbols] Usage: /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -dynamic [-] file [...] [-filelist listfile[,dirname]] [-arch_only arch] [-o output] [-install_name name] [-compatibility_version #] [-current_version #] [-seg1addr 0x#] [-segs_read_only_addr 0x#] [-segs_read_write_addr 0x#] [-seg_addr_table ] [-seg_addr_table_filename ] [-all_load] [-noall_load] 

如果我的目标是模拟器或设备,就会发生这种情况。 看起来可能在项目中使用Swift文件导致它使用通常为可执行文件保留的链接器选项,即使目标是静态库? 我不太了解构建选项,以了解这是否是测试版中的错误,或者我应该配置的一些选项。 在这样一个微不足道的例子中,构建将合法地失败似乎是值得怀疑的。 有什么想法吗?

为了在评论中进行一些讨论之后回答我自己的问题,根本不可能构建包含Swift代码的静态库。 我在Beta 4中写这篇文章,发行说明仍然在“Xcode 6 beta 4中的已知问题”中说:

Xcode不支持构建包含Swift代码的静态库。 (17181019)

我一直在看这个问题,这是我发现的:

首先,在Xcode 6 Beta中,当您创建Cocoa Touch静态库时没有语言选择,默认情况下该语言设置为Objective-C,虽然您可以将Swift文件添加到项目中,但它会像您的问题一样给出错误结果。 我的解释是,苹果打算避免创建Swift静态库。

因此,如果您打算构建一个利用Swiftfunction的库,请使用Cocoa Touch Framework而不是Static Library。 我已经编写了创建框架项目和应用程序项目的步骤,您可以在此处找到它。 请注意,在该示例中,我创建了一个Objective-C框架项目。 如果想要纯粹的Swift框架项目,请选择Language Swift

在此处输入图像描述

另请注意如果您希望将Swift框架导入到Objective-C项目中,或者混合使用这些语言,可以在同一项目中阅读Swift和Objective-C

希望这会给你一个好方向。

看看这个威胁XCode5模拟器:-Xlinker中的未知选项字符“X”

为了理解错误,您必须了解命令尝试执行的操作。

在这种情况下,它使用Libtool,它是libtool的略微改变版本。 在命令行中指定了一些选项,但我们要查找的是目标文件,并将其作为-o选项传入,其参数为/ Users / jr / ios / app / iCozi / build / DevOnly-iphonesimulator / libCozi \ Common \ Code.a,以及我们正在生成的库的类型,在这种情况下它是-static。 两个选项一起明确声明您正在创建静态库归档。

因为你正在创建一个静态库存档,你实际上唯一要做的就是获取.o文件和可能的.a文件并将它们转换成另一个.a文件。 这可以大致等同于从一组文件(.o)创建.zip文件,以及其他.zip文件(.a)的内容。 在进行此归档时,您可以执行的操作非常少,例如,您无法指定在构建静态归档时需要隐式链接的库,您无法指定您将需要授权。

libtool抱怨是因为它不理解正在传入的静态库所使用的选项。在这种情况下,选项是:

-Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker /Users/jr/ios/app/iCozi/build/iCozi.build/DevOnly-iphonesimulator/Cozi \ Common \ Code.build/Cozi \ Common \ Code.xcent

当您尝试在权利文件中链接时,这些是存在的选项,这意味着某些选项指定使用权利文件。 在这种情况下,您自己找到了正确的解决方案,即删除项目设置中指定的权利文件 – >代码签名 – >代码签名权利 – > DevOnly。

我遇到了同样的问题,我确实找到了解决方案。 ‘libtool’因为-Xlinker属性而失败,它试图指定Swift模块 – 静态库似乎不支持它。 (我也认为这是苹果公司的错误/缺陷,但也许这是对另一个主题的讨论)

我所做的是将整个libtool命令复制/粘贴到终端,删除所有’-XLinker …’参数,令人惊讶的是从命令行构建成功。

我的静态库项目包括Objective-C和Swift源代码,它们都被“打包”到生成的静态库中!

唯一的缺点是没有生产Swift模块,但在我的情况下没有关系,因为Swift只在内部使用 – 我只有Objective C外部接口。

我认为也可以通过沿生成的静态库复制生成的静态lib桥接头来公开Swift’接口’。

Interesting Posts