18

我一直在尝试将 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 <filename>] [-seg_addr_table_filename <file_system_path>] [-all_load] [-noall_load]

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

4

5 回答 5

16

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

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

于 2014-07-22T13:34:16.297 回答
3

我也一直在研究这个问题,这是我发现的:

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

因此,如果您打算构建一个利用 Swift 强大功能的库,请使用Cocoa Touch Framework而不是静态库。我已经写了创建框架项目和应用程序项目的步骤,你可以在这里找到。请注意,在该示例中,我创建了一个 Objective-C 框架项目。如果想要纯 Swift 框架项目,请选择Language Swift 。

在此处输入图像描述

另请注意,如果您希望将 Swift 框架导入到 Objective-C 项目中,或者混合使用这些语言,这里有很好的阅读Swift and Objective-C in the Same Project

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

于 2014-06-20T04:38:49.267 回答
2

看看这个威胁XCode5 模拟器:未知选项字符 `X' 在:-Xlinker

为了理解错误,您必须了解该命令试图做什么。

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

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

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 中指定的权利文件。

于 2014-06-05T17:39:38.637 回答
1

查看此博客(需要翻译)

http://andelf.github.io/blog/2014/06/25/write-swift-module-with-swift-cont/

于 2014-12-19T09:04:16.433 回答
0

我遇到了同样的问题,我确实找到了解决方案。'libtool' 由于 -Xlinker 属性而失败,该属性试图指定 Swift 模块 - 静态库似乎不支持。(我也认为这是Apple的错误/缺陷,但也许这是另一个线程的讨论)

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

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

唯一的缺点是没有生成 Swift 模块,但在我的情况下这并不重要,因为 Swift 仅在内部使用 - 我只有 Objective C 外部接口。

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

于 2015-02-05T13:15:23.307 回答