- 开发工具
- 构建工具
【免费下载链接】swift-package-manager
The Package Manager for the Swift Programming Language
导读
本指南基于 Utilities/mk-toolchain/README.md 展开,讲解 Swift Package Manager(SwiftPM)开发者如何在 macOS 上通过mk-toolchain脚本,把开发工作区(Xcode Workspace)中构建出的PackageDescription、PackagePlugin、swift-package、swift-build、swift-test、swiftpm-testing-helper、sourcekit-lsp等产物,拼装成一个自定义.xctoolchain工具链。读者完成本文后可独立搭建"改 Manifest/Plugin API → 一键重建工具链 → 在 VSCode Swift 中即时验证"的开发闭环,并用 Swift 测试与补全体验来验收 Manifest 与 Plugin API 的人机工效(ergonomics)改动。
背景:为什么要自制工具链
修改包清单(Package.swift所依赖的PackageDescriptionAPI)或插件(PackagePluginAPI)时,最自然的验证方式是在一个真实的 Swift 包工程里"边改边用",观察 API 手感是否顺畅、补全提示是否准确。但 Xcode 的XcodeDefault.xctoolchain中打包的是发布版 Manifest/Plugin 运行库,直接修改后无法立即生效。
原文档给出的最佳实践是:把开发工作区构建出的产物,通过软链接替换到一份工具链副本中,形成自定义工具链,再用TOOLCHAINS环境变量让 VSCode Swift 语言服务器与swift命令选中它。这样你在源码上做的每次改动,都能在一个真实包工程中立刻被补全、编译和测试验证,而不是停留在单元测试的抽象断言里。
前置准备:组织开发工作区
原文档推荐将 SwiftPM 开发常用的三个仓库克隆到同一目录:
git clone https://github.com/swiftlang/swift-build git clone https://github.com/swiftlang/swift-package-manager git clone https://github.com/swiftlang/sourcekit-lsp- swift-package-manager:SwiftPM 本体,产出
swift-package、swift-build、swift-test、swiftpm-testing-helper,以及PackageDescription/PackagePlugin两个 API 框架(见 Sources/CMakeLists.txt 中的相关目标); - swift-build:新一代构建系统 Swift Build(仓库内以
container:../../swift-build的方式被引用,见 Utilities/SwiftPM+SwiftBuild.xcworkspace/contents.xcworkspacedata),产出swift-build可执行文件与llbuild框架; - sourcekit-lsp:为编辑器提供索引、补全与诊断的语言服务器,负责把新 API 的补全带给 VSCode。
说明:原文档针对 macOS + Xcode 的流程,并明确欢迎其他宿主平台(如 Linux/Windows)的开发者贡献等价工具。本文严格限定在 macOS 环境下描述。
创建 xcworkspace
在同一目录下创建myNewFeature.xcworkspace,并在其中新建contents.xcworkspacedata,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <Workspace version = "1.0"> <FileRef location = "group:swift-build"> </FileRef> <FileRef location = "group:swift-package-manager"> </FileRef> <FileRef location = "group:sourcekit-lsp"> </FileRef> </Workspace>仓库中 Utilities/SwiftPM+SwiftBuild.xcworkspace/contents.xcworkspacedata 提供了一个真实范例(它以container:../../swift-build与container:../../swiftpm的相对形式引用仓库),可用于对照。这里group:前缀表示引用的是工作区内的子目录,而非绝对磁盘路径。
配置 Xcode Scheme 与构建产物
用 Xcode 打开该 xcworkspace,新建一个 Scheme,并在其 Build 阶段加入以下 Target:
PackageDescription PackagePlugin swift-package swift-build swift-test swiftpm-testing-helper sourcekit-lsp各 Target 的职责与源码对应关系如下:
| Target | 产物 | 仓库源码入口 |
|---|---|---|
PackageDescription | Manifest API 框架/模块,Package.swift依赖它 | Sources/Runtimes/PackageDescription |
PackagePlugin | Plugin API 框架/模块,插件目标依赖它 | Sources/Runtimes/PackagePlugin |
swift-package | swift package命令 | Sources/swift-package/Entrypoint.swift |
swift-build | 新一代构建系统命令swift build | Sources/swift-build/Entrypoint.swift |
swift-test | swift test命令 | Sources/swift-test/Entrypoint.swift |
swiftpm-testing-helper | 测试运行辅助程序 | Sources/swiftpm-testing-helper/Entrypoint.swift |
sourcekit-lsp | 语言服务器(来自 swift-build 仓库相邻克隆) | sourcekit-lsp 仓库 |
构建完成后,产物会落入 Xcode 的 DerivedData 目录。mk-toolchain脚本通过通配符定位它们(见下文脚本解析)。
运行 mk-toolchain 脚本生成自定义工具链
构建 Scheme 成功之后,在同时包含三个 git 仓库与 xcworkspace 文件的目录中运行本仓库的脚本:
./Utilities/mk-toolchain/mk-toolchain脚本(Utilities/mk-toolchain/mk-toolchain,zsh 实现)按以下顺序工作:
- 推导名称:
name=$(basename *.xcworkspace .xcworkspace),即取当前目录中唯一的.xcworkspace名(如myNewFeature); - 定位源工具链:
src=$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain,即当前xcode-select指向的 Xcode 内置工具链; - 定位构建产物:从
~/Library/Developer/Xcode/DerivedData/${name}-*/Build/Intermediates.noindex/InstallIntermediates/macosx/Products/Debug目录读取产物; - 拷贝底子:
ditto $src $dest把整份XcodeDefault.xctoolchain复制到~/Library/Developer/Toolchains/${name}.xctoolchain(目标路径不存在时由脚本创建,覆盖已存在的同名工具链); - 补充 llbuild:把 Swift Build 构建出的
llbuild.framework拷入工具链的usr/lib/swift/pm/llbuild/,供 swift-build 运行时链接; - 软链接二进制:把
swift-package、swift-build、swift-test、sourcekit-lsp链接到工具链的usr/bin/; - 替换 Manifest/Plugin API:清空
usr/lib/swift/pm/ManifestAPI/与usr/lib/swift/pm/PluginAPI/,再分别将 DerivedData 中的PackageDescription.swiftmodule、PackageDescription.framework、PackagePlugin.swiftmodule、PackagePlugin.framework以及CompilerPluginSupport.swiftmodule软链接进去; - 写入 Info.plist:删除原有
ToolchainInfo.plist,生成带有别名swift、CFBundleIdentifier等于工作区名、以及OverrideBuildSettings(OTHER_SWIFT_FLAGS中追加-plugin-path $(TOOLCHAIN_DIR)/usr/lib/swift/host/plugins、SWIFT_DEVELOPMENT_TOOLCHAIN=YES、SWIFT_USE_DEVELOPMENT_TOOLCHAIN_RUNTIME=YES)的Info.plist; - 冒烟自检:依次执行
TOOLCHAINS=$name swift --version与TOOLCHAINS=$name swift build --version,确认新工具链可被swift命令识别。
脚本的关键校验点
脚本内含三道检查,便于排错:
derivedData为空时提示"请从包含 xcworkspace 的目录运行";- 源工具链不存在(
! -d $src)时报Source toolchain not found; - DerivedData 目录不存在(
! -d $derivedData)时报Derived data not found,此时需检查 Scheme 是否真的执行了 Install 构建(InstallIntermediates 路径),或 DerivedData 路径通配是否与实际 Xcode 布局一致。
与源码的对应关系
Manifest/Plugin API 在工具链中的位置并非随意选择。ToolchainConfiguration.swift(Sources/PackageModel/ToolchainConfiguration.swift)中的LibraryLocations在初始化时会基于swiftc路径推导lib/swift/pm/ManifestAPI与lib/swift/pm/PluginAPI;而 Sources/PackageModel/UserToolchain.swift 在查找这些框架时依次尝试"工具链内lib/swift/pm下的 ManifestAPI/PluginAPI 框架""PackageFrameworks目录""应用根目录",最终回退到基于swiftCompilerPath推导。因此mk-toolchain把框架放进usr/lib/swift/pm/正是 SwiftPM 运行时能够发现它们的标准路径。
重要提醒:Xcode 升级后需重建
原文档特别强调:每次 Xcode 升级后都要重新运行mk-toolchain。因为脚本是从"当前xcode-select选中的 Xcode"拷贝XcodeDefault.xctoolchain的,工具链副本中携带的 SDK 文件与运行时(swiftc、标准库、swift-plugin-server等,后者在 Darwin 上由 Sources/PackageModel/UserToolchain.swift 通过xcrun --find swift-plugin-server定位)必须与宿主机 Xcode 版本一致,否则会出现版本错配导致的链接或运行失败。
用新工具链验证 Manifest/Plugin API 改动
1. 初始化插件包
在任意新目录中创建 build tool 插件类型包:
swift package init --type build-tool-plugin--type build-tool-plugin是swift package init支持的包类型之一,与empty、library、executable、tool、command-plugin、macro并列,定义于 Sources/Workspace/InitPackage.swift 的PackageType枚举中。
2. 用 TOOLCHAINS 环境变量在 VSCode 中激活
TOOLCHAINS=myNewFeature code .TOOLCHAINS的值即你为 xcworkspace 起的名字(对应工具链Info.plist中的CFBundleIdentifier与目录名~/Library/Developer/Toolchains/myNewFeature.xctoolchain)。Swift 工具链查找机制会依据该变量在~/Library/Developer/Toolchains下按名称定位工具链,swift命令与语言服务器都会被指向新工具链。
3. 逐项验收清单
原文档给出了一个完整的功能验收顺序,逐条执行即可确认工具链可用:
- 包解析:确认 VSCode 能成功解析该包(无红色诊断);
- 构建:执行包构建并确保成功;
- 测试:添加测试用例,确认测试被发现并能运行(
swift test经由swift-test入口,其测试运行辅助程序即swiftpm-testing-helper,实现在 Sources/swiftpm-testing-helper/Entrypoint.swift,它负责以--test-bundle-path动态加载测试包并调用其中的main); - Manifest 补全:编辑
Package.swift,新增一个 target,观察补全是否提示出各 target 函数——这正是验证PackageDescriptionAPI 改动的核心场景; - 插件补全:编辑插件 Swift 文件,在
createBuildCommands函数中对context与target参数做补全,确认PackagePluginAPI 的新增符号能被 sourcekit-lsp 索引到。
全部通过,即说明你已拥有一个"改动源码 → 重新构建 Scheme → 重跑 mk-toolchain → 在示例包中即时验证"的完整测试环境。
常见问题排查
- Derived data not found:检查 Scheme 是否包含 Install 阶段,或 Xcode 的 DerivedData 目录名与
${name}-*通配不匹配(可把~路径换成实际的DerivedData/<workspace名>-<hash>验证); - 补全不生效:确认 VSCode 启动时确实携带了
TOOLCHAINS环境变量(在已打开窗口内用TOOLCHAINS=myNewFeature swift --version复核版本);必要时重启语言服务器,让它重新扫描工具链; - Xcode 升级后链接失败:重新运行
mk-toolchain重建工具链副本,保证 SDK 与运行库版本一致; - Linux/Windows 支持:当前脚本是 macOS + Xcode 专用(zsh、
ditto、xcode-select均依赖 macOS),其他平台需要等价工具,仓库欢迎此类贡献。
小结
mk-toolchain把"修改PackageDescription/PackagePluginAPI"与"在真实包工程中体验这些 API"直接连通:Xcode Scheme 产出二进制与框架,脚本将它们在XcodeDefault.xctoolchain副本中以软链接形式替换,最终通过TOOLCHAINS环境变量交付给swift与 VSCode。配合 Utilities/mk-toolchain/README.md 中约定的五项验收(解析、构建、测试、Manifest 补全、插件补全),开发者可以在迭代 API 时第一时间获得真实的使用反馈,这正是 SwiftPM 团队验证 Manifest 与 Plugin API 人机工效的标准方式。
- 开发工具
- 构建工具
【免费下载链接】swift-package-manager
The Package Manager for the Swift Programming Language
相关推荐
理解usearch的实时索引更新:增量构建与合并策略
理解usearch的实时索引更新:增量构建与合并策略 usearch是一个高性能的开源搜索与聚类引擎,支持向量和字符串搜索,适用于C++、Python、Java
向量数据库搜索引擎NsEmuTools开发者工具链配置:调试与测试环境搭建
NsEmuTools开发者工具链配置:调试与测试环境搭建 作为一款功能强大的NS模拟器管理工具,NsEmuTools为开发者提供了完整的工具链支持。本文将详细介
桌面应用开发工具tiny11builder开发环境搭建:PowerShell脚本调试与测试流程
tiny11builder开发环境搭建:PowerShell脚本调试与测试流程 项目概述 tiny11builder是一个用于构建精简版Windows 11镜像
操作系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考