静态库和 Swift

Posted

技术标签:

【中文标题】静态库和 Swift【英文标题】:Static Library and Swift 【发布时间】:2015-06-22 23:06:45 【问题描述】:

所以我正在使用 Swift 开发一个 ios 项目,我想创建一个包含一些有用内容的静态库。

我的问题是,当我尝试在 Xcode(6.3 版)中构建我的库时,出现“构建失败”,然后是:/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: unknown option character 'X' in: -Xlinker

我从来没有见过这个,它不是我的第一个静态库。所以我想我可能与我只使用 Swift 类这一事实有关。

你们怎么看? 提前谢谢你。

【问题讨论】:

接受的答案不再准确。从 Xcode 9 beta 4 开始,Swift 可以在静态库中使用,尽管有些场景需要额外的配置。请参阅下面的答案。 【参考方案1】:

如上所述,Apple确实从 Xcode 9 Beta 4 开始允许在静态库中使用 Swift。

我们尝试在现有项目上使用基于 Objective-C 的目标和“子”静态库项目执行此操作,但一直遇到链接错误

ld: library not found for -lswiftSwiftOnoneSupport for architecture x86_64

还有

ld: library not found for -lswiftDispatch for architecture x86_64

这是因为主要目标(应用程序)试图仅针对 Objective-C 进行构建,而静态库并未告知它需要包含 Swift 库。这是因为应用目标的Build PhasesCompile Sources 部分中没有任何Swift 文件。

所以基本上您所要做的就是在该编译列表中添加至少一个.swift 文件,它会为您包含 Swift 库。它甚至不需要任何代码或值,它可以是一个空文件。

然后您可以开始将 Swift 文件添加到您的“子”静态库项目中。我会让它首先为您生成桥接头,然后您可以移动它并更改导入的内容(如果您移动它,请确保项目指向构建设置中的正确文件)。

您仍然应该记住,在 same 静态库中使用 Swift 和 Objective-C 可能会遇到问题。我建议阅读the Apple developer doc "Swift and Objective-C in the Same Project",了解如何解决将Objective-C 导入Swift(使用桥接头)以及如何在Objective-C 代码中使用Swift 文件(为您的库导入生成的-Swift.h)。

【讨论】:

就我而言,我看到的是ld: library not found for -lswiftCoreImage for architecture x86_64。这个答案解决了我的链接问题。 @afarnham 我认为它会为 Swift“核心”中的几乎每个库都这样做,因为它在从使用 Swift 的静态库中链接内容时尝试与它们链接。我之前尝试手动将每个 Swift 库包含在目标依赖项和其他构建阶段中;不用说这是一场噩梦……而且没有用。我希望 Apple 将其设为项目设置,这样您就不必准备一个虚拟文件来“欺骗”主要目标,但我猜这目前可行。 我只有一个混合了objective-c和swift的静态库,我无法编译项目(react-native):) 太棒了,只需添加一个空的 Swift 文件,所有这些错误都会消失。感谢您的帮助! 我羡慕@thibautnoah。我已经有这个问题好几个星期了!谢谢一百万!【参考方案2】:

Swift 没有 support static library

虽然正确的方法应该是创建框架,但有一个解决方法here。

【讨论】:

这很烦人。谢谢你的回答。 您好,由于 swift 不支持静态库,如何防止同事阅读我的代码? (这是关于加密数据的,所以知道的人越少越好)。我的应用也支持 ios 7,所以我想我不能使用框架,对吧? 可能需要更新到现在? swift 现在支持框架和静态库吗? 从objective c 项目中我们可以创建静态库,但是否可以从xcode 8 开始的Swift 项目中创建静态库 在 swift 3 中是否有任何使用静态库的解决方案,我有一个加密库,其中只有两个 .a 文件在供应商样本(用 Objective-c 编写)是工作文件,当我尝试使用那些使用桥接头的库,(显然桥接头配置很好,因为其他objective-c库工作正常),它不能抛出错误。任何人对此问题都有解决方案,然后请发布一些线索。【参考方案3】:

从 Xcode 9 beta 4 开始,Xcode 原生支持带有 Swift 源代码的静态库。

【讨论】:

我必须做什么才能启用它?使用包含 swift 的静态库时,如何访问 Objective-c 项目中的标头? @HariKaramSingh 我在单独的答案中回答了 OP 问题和你的问题。 对我来说,这个问题在 Xcode 9.2 (9C40b) 上再次出现,在 pod update 之后。可能我正在使用的 swift pod 更改了设置。【参考方案4】:

Swift 消费者 -> Swift 静态库

Xcode 版本 10.2.1

创建 Swift 静态库

创建库项目或创建库目标

File -> New -> Project... -> Cocoa Touch Static Library
//or
Project editor -> Add a Target -> Cocoa Touch Static Library 

添加文件.swift

Select `.swift` file -> Select File Inspectors Tab -> Target Membership -> Select the target
//or
Project editor -> select a target -> Build Phases -> Compile Sources -> add files

构建库 - ⌘ 命令 + BProduct -> Build

注意 1:确保为与客户端代码相同的流程架构构建库。 注意 2:使用 publicopen 访问修饰符[About] 公开您应该对消费者可见的 API

查找生成的输出[Build location]

Products group -> lib<product_name>.a -> Show in Finder

目录包括

lib&lt;product_name&gt;.a – 内置静态库 &lt;product_name&gt;.swiftmoduleswiftmodule 描述了库的接口和编译器版本。该文件夹包括: .swiftdoc - 文档 .swiftmodule - 公共接口/定义

带有 Swift 静态库的 Swift 消费者

Drag and drop二进制进入Xcode项目[About]

Link Binary[Undefined symbols][Link vs Embed]

Project editor -> select a target -> General -> Linked Frameworks and Libraries -> add -> Add Others... -> point to `lib<target_name>.a` file
//or
Project editor -> select a target -> Build Phases -> Link Binary With Libraries -> add -> Add Others... -> point to `lib<target_name>.a` file

添加Library Search paths(LIBRARY_SEARCH_PATHS)[Library not found for][Recursive path]

Project editor -> select a target -> Build Settings -> Search Paths -> Library Search paths -> add path to the parent of `lib<target_name>.a` file

添加Import Paths[No such module][Recursive path]

Project editor -> select a target -> Build Settings -> Swift Compiler - Search Paths -> Import Paths -> add path to a folder with `.swiftmodule`

将模块导入Swift客户端代码[module_name]

import module_name

[More examples]

【讨论】:

我已经在自己的独立项目中构建了静态框架。我看到了.a 文件和.swiftmodule 文件夹。我应该将它们都拖到我的主机应用程序中,然后尝试查找路径。对吗? 抱歉,请问有什么注意事项吗? 你好@Honey,我会再次检查并提供信息 @Honey,回答您的问题,在构建库后,您应该执行 3 个步骤: 1. 将 .a 文件拖到您的主机应用程序中的 Linked Frameworks and Libraries 部分下。 2. 在Library Search paths 部分下指定.afine 的路径 3. 在Import Paths 部分下指定.swiftmodulefine 的路径。我刚刚检查了教程并更新了一篇文章。如果您有任何问题,请随时询问 @yoAlex5,非常感谢您详细而全面的解释。我唯一要补充的是,您不要忘记标记您的类和方法public 以使它们在其他目标中可用。没有它,您将能够导入库,但不能使用它的代码。另外,请注意inits 必须明确公开。

以上是关于静态库和 Swift的主要内容,如果未能解决你的问题,请参考以下文章

iOS XCode7制作.Framework动态库和.a静态库的总结

Flutter iOS OC 混编 Swift 遭遇动态库和静态库问题填坑

Swift 应用程序:导入静态库的框架时“缺少必需的模块”

动态库和静态库的区别

C语言里面的动态库和静态库

Linux下的静态库和动态库