- 开发工具
- CLI
- 移动开发
【免费下载链接】xtool
Cross-platform Xcode replacement. Build and deploy iOS apps with SwiftPM on Linux, Windows, macOS.
导读
本文面向希望在 Linux、Windows(WSL) 与 macOS 上参与 xtool 开发的贡献者,完整讲解如何从源码构建调试版本、各平台的依赖与代码签名配置、开发期调试手段,以及基于 Swift-DocC 与 Netlify 的文档更新流程。读完本文,你将掌握 xtool 的make构建体系、调试环境变量、DocC 文档预览与提交审查的完整闭环,可直接上手提交代码与文档改动。
说明:xtool 是一个跨平台的 Xcode 替代品,可用 SwiftPM 在 Linux、Windows、macOS 上构建和部署 iOS 应用。仓库根目录的 CONTRIBUTING.md 规定了通用的 issue 与 PR 流程(包括 AI 辅助贡献的"理解、披露、负责"三原则),而本文的主体 Documentation/Contributing/README.md 聚焦开发过程本身。
1. 总体开发流程:make即入口
xtool 的开发构建统一由仓库根目录的 Makefile 驱动。项目要求贡献者在修改代码后,尽可能在 macOS 和 Linux 两个平台都完成测试,若还能在 Windows + WSL 上验证则更理想。文档原文明确指出:"When making code changes, please make sure to test them on both macOS and Linux if possible. If you can also test on Windows with WSL, that is ideal."
在项目目录下直接运行make即可触发当前平台的开发构建。Makefile 通过检测uname -s是否为Darwin来分流(Makefile):
- 在 macOS 上,
all目标委托给mac; - 在其它平台(Linux)上,
all目标委托给linux。
ifeq ($(IS_MAC),1) @+$(MAKE) mac else @+$(MAKE) linux endifLinux 的linux目标执行swift build --product xtool $(ALL_SWIFTFLAGS)(Makefile),默认使用-c debug构建配置;通过RELEASE=1 make可切换到-c release。macOS 侧则通过xcodebuild install产出 .app 包并生成符号链接./macOS/Build/xtool。
此外,Makefile 还提供了clean(清理构建产物)、lint(SwiftLint 静态检查,版本从.swiftlint.yml读取并按平台自动下载对应二进制)、reload(更新 Xcode 工程并重启 Xcode)等辅助目标,详情见 Makefile。
2. macOS 平台构建:代码签名身份检测与 Xcode 工程
2.1 前置条件:Xcode 与签名身份
在 macOS 上开发 xtool,首先需要装好 Xcode。由于 xtool 在 macOS 上被打包为 .app bundle(以便添加 entitlements 并使用钥匙串,见 macOS/README.md),构建过程会涉及代码签名。
首次运行make时,构建系统会自动探测你的 codesigning identity。如果系统里有多个可用身份,你会看到交互式提示,要求选择一个开发团队;选定的团队 ID 会被保存到./macOS/Support/Private-Team.xcconfig。之后可以用make team重新更新该配置(或直接手改文件)。
签名身份探测逻辑位于 scripts/select-identity.sh:
names=($(security find-identity -vp codesigning | grep -E '(?:iPhone Developer|Apple Development):' | cut -d'"' -f2 | uniq))其核心步骤是:
- 用
security find-identity -vp codesigning列出所有可用于代码签名的身份; - 筛选出
iPhone Developer:或Apple Development:前缀的证书; - 若只有一个,直接采用;若有多个,则交互式列出编号供选择,并将选择结果通过
openssl x509从证书 subject 中提取OU=(Organizational Unit)字段作为 Team ID 返回。
Makefile 中对应生成规则为(Makefile):
$(TEAM_CONFIG): ifeq ($(DEVELOPMENT_TEAM),) @mkdir -p macOS/Support @team=$$(./scripts/select-identity.sh); \ echo "DEVELOPMENT_TEAM = $$team" > $@ else @mkdir -p macOS/Support echo "DEVELOPMENT_TEAM = $(DEVELOPMENT_TEAM)" > $@ endif可见通过DEVELOPMENT_TEAM=... make可以强制指定团队,跳过交互提示。
2.2 构建产物与 Xcode 工程
构建完成后,mac目标会:
- 用
xcodebuild install(跳过宏校验与插件校验)安装XToolMacscheme; - 在
./macOS/Build/xtool创建一个指向XcodeInstall/xtool.app/Contents/Resources/bin/xtool的符号链接; - 同时通过 xcodegen 在
./macOS/XToolMac.xcodeproj生成 Xcode 工程,方便贡献者直接在 Xcode 中打开、编辑和调试。
mac: project @rm -rf macOS/Build/XcodeInstall @set -o pipefail && cd macOS && \ xcodebuild install \ -skipMacroValidation -skipPackagePluginValidation \ -scheme XToolMac -destination generic/platform=macOS \ -derivedDataPath Build/DerivedData \ DSTROOT="$$PWD"/Build/XcodeInstall INSTALL_PATH=/ \ $(ALL_XCFLAGS) $(XC_FORMAT) @ln -fs XcodeInstall/xtool.app/Contents/Resources/bin/xtool macOS/Build/xtool如果构建输出过长,Makefile 在安装了xcbeautify时会自动对xcodebuild输出做格式化(VERBOSE=1可关闭)。
工程配置文件由 macOS/Support/Base.xcconfig 统一管理,其中通过#include? "Private-Team.xcconfig"引入上述团队配置(?表示文件不存在也不报错),并开启了ENABLE_HARDENED_RUNTIME = YES与自动签名;macOS/project.yml 则是 XcodeGen 的工程定义,指定了bundleIdPrefix: sh.xtool、部署目标 macOS 14.0 以及Resources/xtool的复制阶段。
3. Linux 平台构建:依赖、Docker 开发环境与 AppImage
3.1 系统依赖与 Dockerfile
在 Linux 上构建需要若干系统依赖,具体清单可直接参考仓库根目录的 Dockerfile。该文件以swift:${SWIFT_VERSION}-jammy(默认 Swift 6.4.0,选择 22.04 是遵循 AppImage 的"在支持的最老系统上构建"建议)为基础,安装了:
- 基础编译链:
build-essential、git、autoconf、automake、libtool-bin、pkg-config; - 网络/压缩库:
libssl-dev、curl libcurl4-openssl-dev、libxml2、zip unzip、liblzma-dev zlib1g-dev。
Dockerfile 随后从源码构建了libimobiledevice生态(libplist 2.6.0、libimobiledevice-glue 1.3.1、libusbmuxd 2.1.0、libtatsu 1.0.4、libimobiledevice),这是 xtool 在 Linux 上与 iOS 设备通信(USB/网络)的关键依赖。开发镜像(dev阶段)还做了两件特殊配置:
# Docker doesn't support FUSE ENV APPIMAGE_EXTRACT_AND_RUN=1 # Use the host's usbmuxd. socat forward: TCP-LISTEN:27015 ... UNIX-CLIENT:/var/run/usbmuxd ENV USBMUXD_SOCKET_ADDRESS=host.docker.internal:27015APPIMAGE_EXTRACT_AND_RUN=1:绕过 Docker 对 FUSE 的不支持;USBMUXD_SOCKET_ADDRESS:让容器内的 libusbmuxd 通过网络端口访问宿主机的 usbmuxd 服务。
3.2 在 Docker 内开发
文档原文建议:"It's often easiest to develop within Docker itself",详见 Linux/README.md。Docker 工作流的要点如下:
- 宿主机需安装
usbmuxd(macOS 上预装;Ubuntu/Debian 用sudo apt-get install usbmuxd); - 用
docker compose run --rm xtool进入容器 shell,仓库根目录会以绑定挂载方式出现在容器内的/xtool; - 为了让容器访问 iOS 设备,宿主机需保持运行 socat 转发命令,把本地 usbmuxd 的 unix socket 转发到 TCP 27015 端口:
socat -dd TCP-LISTEN:27015,range=127.0.0.1/32,reuseaddr,fork UNIX-CLIENT:/var/run/usbmuxd3.3 发布构建:AppImage
xtool 的 Linux CLI 以 AppImage 形式分发。运行Linux/build.sh即可输出到packages/目录(脚本逻辑见 Linux/build.sh):先swift build -c release并strip,再下载 linuxdeploy 工具,将可执行文件、desktop 文件与图标打包成xtool-$(uname -m).AppImage。若宿主机没有fusermount,脚本同样会设置APPIMAGE_EXTRACT_AND_RUN=1。
4. 开发期调试:环境变量全解析
调试相关内容集中在 Documentation/Contributing/Debugging.md,用法统一为环境变量前缀形式,例如:
XTL_DEBUG_ERRORS=1 xtool ...下面对照源码逐一展开这些变量的实际生效位置与原理。
4.1 通用调试
XTL_DEBUG_ERRORS=1:xtool 出错时默认只打印面向用户的友好错误描述;设置该变量后,会在catch块中以String(reflecting: error)输出完整的错误详情(含ERROR DETAILS:前缀)。实现见 Sources/XToolSupport/XTool.swift。
4.2 磁盘 / 临时目录
XTL_DEBUG_TMP=1:日志记录 xtool 创建/销毁临时目录的时机。在 Sources/XUtils/TemporaryDirectory.swift 中,创建目录后会用stderrPrint("Created TemporaryDirectory: ...")输出路径,同时禁用自动清理(_delete()在 debug 模式下直接跳过),方便你保留现场检查目录内容。XTL_TMPDIR:控制临时目录的存放位置。优先级为XTL_TMPDIR→TMPDIR→ 平台默认值。平台默认值有讲究:- Linux 上,默认使用
$XDG_CACHE_HOME(否则~/.cache)下的xtool目录,而非/tmp。源码注释解释了原因:/tmp常是 tmpfs,而~/.swiftpm在 ext4 上,FileManager.copyItem底层走sendfile(2),跨文件系统拷贝会返回 EINVAL,导致swift sdk install在 Linux Mint 等发行版上失败(issue #181); - macOS 上,使用系统临时目录下的
sh.xtool。
临时目录根还会在启动时通过 PID 锁文件清理历史遗留目录(
pruneOrphans),详见 Sources/XUtils/TemporaryDirectory.swift。- Linux 上,默认使用
4.3 网络调试
XTL_DEV_LOG=<regex>:正则匹配 AppStoreConnect API 的 operation ID,命中的请求会打印响应状态码和响应体。设为XTL_DEV_LOG='.*'可匹配全部请求。实现位于 Sources/XKit/DeveloperServices/OpenAPI/LoggingMiddleware.swift,该中间件在拦截到响应后,先用firstMatch判断 operation ID 是否命中正则,命中则输出状态并消费 body。XTL_DISABLE_TLS_VALIDATION=1:关闭所有 HTTP 请求的 TLS 证书校验,常用于配合 MITM 代理抓包分析 API 请求。源码中在 Linux 侧(AsyncHTTPClient)将tlsConfiguration.certificateVerification置为.none(AsyncHTTPClient+HTTP.swift),在 Darwin 侧(URLSession)则对认证质询直接返回URLCredential(trust:)(URLSession+HTTP.swift)。注意:该选项仅在排查问题时临时使用,关闭 TLS 校验普遍不安全。XTL_HTTP_PROXY=<host>:<port>:仅非 Darwin 平台生效,例如XTL_HTTP_PROXY=localhost:8080,将 HTTP 客户端指向代理(实际解析逻辑在 AsyncHTTPClient+HTTP.swift,按最后一个冒号切分 host 与 port)。Darwin(macOS/iOS)上则改用系统代理配置。
补充调试手段:仓库还提供了可选的 Xcode 真实对照测试。运行 integration-tests/run.sh 可以在 Docker 内(或本机)安装精简版 SDK 后用 bats 跑冒烟测试,验证如
xtool --version、xtool new后能产出带LC_BUILD_VERSION/platform ios的可执行文件、以及 slim SDK 不可原地更新等行为(见 integration-tests/suite/smoke.bats)。
5. 文档更新:DocC 与 Netlify 预览
5.1 文档存放与构建
xtool 的官方文档由Swift-DocC构建,源文件位于 Documentation/xtool.docc,其中包含:
- 技术文档文章:
xtool.md、Installation-Linux.md、Installation-macOS.md、Control.md、Appex.md; - 交互式教程:
xtool.tutorial与First-app.tutorial及配套的First-app-code代码片段、Resources图片资源。
构建脚本为 Documentation/build.sh:优先通过xcrun -f docc定位 DocC 二进制(xcrun不可用时退回docc),并对xtool.docc执行convert或preview命令,附带--enable-experimental-code-block-annotations等实验性开关。
5.2 本地预览与 CI 预览
在 Makefile 中,文档相关目标为(Makefile):
docs: ./Documentation/build.sh docs-preview: ./Documentation/build.sh previewmake docs:完整转换生成静态文档;make docs-preview:启动本地 DocC 预览服务,供你在编辑 DocC bundle 时即时查看渲染效果。
提交 Pull Request 后,CI 会自动为 PR 生成Netlify Deploy Preview,打开该预览即可看到改动在正式站点上的真实效果。Netlify 的构建配置位于 netlify.toml,要点是:
[build] base = "Documentation/" publish = "xtool.docc/.docc-build" command = "./build.sh" environment = { SWIFT_VERSION = "6.4.0" }将base设为Documentation/是为了避免 Netlify 在仓库根目录执行swift build(那会构建超出需要的 target),只构建 DocC 文档;ignore规则则让纯文档改动之外的提交跳过 Netlify 构建。此外该文件还定义了若干 302 重定向,如/→/documentation/xtool/,保证旧 URL 与旧教程路径仍可访问。
6. 提交前的检查清单(实践建议)
综合文档原文与仓库工程实践,一个完整的贡献流程建议按如下顺序自查:
- 构建验证:至少在当前平台
make一次;若条件允许,分别在 macOS 与 Linux(或 WSL)各跑一遍;Docker 下可用docker compose run --rm xtool进入统一环境; - 签名配置:macOS 下确认
./macOS/Support/Private-Team.xcconfig中的DEVELOPMENT_TEAM正确(多证书时首次构建会交互选择,可用make team重选); - 代码质量:运行
make lint(SwiftLint)消除告警,必要时用make clean后重构建; - 功能验证:涉及 Apple 开发者服务或设备交互的改动,可借助
XTL_DEV_LOG、XTL_DISABLE_TLS_VALIDATION(配合代理抓包)与XTL_HTTP_PROXY定位网络问题,用XTL_DEBUG_TMP/XTL_TMPDIR排查临时目录相关故障; - 文档改动:修改 Documentation/xtool.docc 后运行
make docs-preview本地预览,并留意 PR 的 Netlify Deploy Preview 与正式站点的一致性。
结语
从make构建入口、macOS 签名身份自动检测、Linux 的 libimobiledevice 依赖与 Docker 开发环境,到一系列XTL_*调试变量和 DocC + Netlify 文档工作流,xtool 的贡献链路完整且可操作。对于想要深入这个跨平台 iOS 开发工具内部的开发者而言,Documentation/Contributing/Debugging.md 是一份浓缩的调试速查表,而 Makefile、Dockerfile 与 Sources 中的对应实现则是理解其工程细节的最佳入口。
- 开发工具
- CLI
- 移动开发
【免费下载链接】xtool
Cross-platform Xcode replacement. Build and deploy iOS apps with SwiftPM on Linux, Windows, macOS.
相关推荐
DevToys 源码构建与贡献指南:跨平台编译、调试与本地化实战
DevToys 源码构建与贡献指南:跨平台编译、调试与本地化实战 导读 本文以 DevToys 官方贡献文档( CONTRIBUTING.md https://
开发工具桌面应用跨平台Watchman 贡献者指南:从源码构建到测试与文档提交的完整工作流
Watchman 贡献者指南:从源码构建到测试与文档提交的完整工作流 本篇指南以 Watchman 官方 Contributing 文档为骨架,结合当前仓库的构
开发工具后端glTF 2.0 规范文档体系:AsciiDoc 源码结构、本地构建与贡献工作流全解析
glTF 2.0 规范文档体系:AsciiDoc 源码结构、本地构建与贡献工作流全解析 glTF 2.0 规范(The glTF 2.0 Specificati
图形学
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考