使用 Swift Package Manager 管理 swift, cpp, c 和 objective-c 的混合编译

Swift Dec 01, 2019

swift_packages

creating-objc-cpp-packages-with-swift-package-manager

Xcode11 开始已经支持 SPM 项目,同时还支持 Xcode 传统项目后面简称Xcode项目中引用 SPM 项目,不过目前只能引用远程仓库。

SPM 项目相对 Xcode 传统项目,要更加轻盈,通过一个 Package.swift 配置文件,完成整个 Package 的依赖,构建,目标管理工作,这一点是 Xcode 项目无法比拟的。

言归正传,回到 SPM 管理 多语言混合项目上来,首先说明一点 Swift 和其他语言混合开发的背景,Swift 能够直接调用的语言仅限于 Objective-C (后面简称Objc) 和 C ,并不包含 C++ ,但是通过 ObjC 和 C 的封装,可以间接实现对 C++ 的调用。

SPM 概念梳理

为了更好地使用 SPM,我们需要说明一下 SPM 中的几个概念:Package, Product, Target, Dependency,同时还需要了解他们之间的关系。

Package 表示一个项目集,是 SPM 中的最高级概念。

Product 代表构建时,产生的生成物,构建生成物可以是:执行文件,程序库 和 系统库。Product 的类型,有: executable 和 library ,其中 library 类型氛围 dynamic 和 static。

Target 目标,这个概念在传统项目中很常见,它代表了一组管理的任何文件资源,也是构建中最小的集合单元。

Dependency 依赖,被依赖的可以是另一个 Package 或 Target

下面,我们通过一个实验项目来深入了解 SPM 的混合语言项目。

新建SPM 项目的步骤

mkdir swift-cxx
cd swift-cxx
swift package init
bash

默认情况下,SPM 会自动初始化一个和当前目录同名的包名: swift-cxx

Package.swift 的构成

Package.swift 代表一个 Package ,Package 由多个 Product 组成,每个 Product 在构建的时候,依赖多个不同的 Target 和来自外部的 Package (dependencies).

Tips
1. Swift 仅支持 ObjC 和 C 语言的直接调用,并不能直接调用 C++ 库,但Swift 可以通过 C或ObjC 的封装间接访问 C++ 库。

2. 每一个 Target 只能由纯 Swift , 或者 ObjC/ C/ C++ 编程语言构成,如果你有混合语言的程序库,就需要小心的将其按语言分离开。

3. 最后,Swift 只能引用由 C, ObjC 导出的 API 程序库,Swift 并不能直接和 C++ 交互。

Xcode11

Xcode 11 现在支持直接引用 SPM 项目作为依赖库,但仅限远程  git 仓库。

swift-package-manager/Usage.md at master · apple/swift-package-manager

Nicholas X.

山穷水复疑无路,柳暗花明又一村