如何通过命令行排查 Jenkins CI 中 Xcode 的 iOS 平台缺失问题?
结论:先补齐平台组件,无需强行对齐版本号
Apple 的版本表列出了 Xcode 26.3 搭配 iOS 26.2 SDK,这是正常组合。版本号不同并不意味着 SDK 安装错误,也无需为了与 Xcode 对齐而寻找 iOS 26.3 SDK。Apple Xcode 版本与 SDK 对照表
日志中应先处理 iOS 26.2 is not installed:当前构建环境未将所需的 iOS 平台识别为可用。组件可能未安装完整或尚未完成初始化,也可能是 Jenkins 使用了不同的工具环境。仅凭现有输出无法确定原因。
simctl list 能列出一个 Simulator,说明设备记录存在,但还需检查 Landmarks scheme 能否使用它。生成 IPA 时,archive 应选择 iOS 真机平台目标,无需指定某台 Simulator。
1. 在 Jenkins 作业中确认实际使用的 Xcode
以下检查应由执行构建的 Jenkins 用户运行。如果 SSH 登录用户与 Jenkins 服务用户不同,两者看到的设备和用户环境可能有差异。
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
whoami
xcode-select -p
xcodebuild -version
xcrun --find xcodebuild
xcodebuild -showsdks
xcrun --sdk iphoneos --show-sdk-path
xcrun --sdk iphoneos --show-sdk-version
xcrun --sdk iphonesimulator --show-sdk-path
xcrun --sdk iphonesimulator --show-sdk-version
在实际执行构建的进程环境中设置 DEVELOPER_DIR,可以让 xcodebuild 和 xcrun 使用指定的 Xcode。若要修改整台机器的默认选择,可由管理员执行:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
原始检查中有两处容易误读:
xcode-select --version返回的是选择工具自身的版本,不能据此判断当前 Xcode 或 iOS SDK 版本。- 未指定
--sdk的xcrun --show-sdk-path已明确返回MacOSX.sdk,随后得到的默认平台版本不能用来判断 iOS SDK。
xcodebuild -showsdks 列出了 SDK,也不能单独证明所有构建所需组件都已就绪,还需结合显式 SDK 查询和后续 destination 检查。
2. 通过终端初始化 Xcode 并安装所需组件
准备 CI 节点时,先完成所选 Xcode 的首次初始化。该步骤可能需要管理员权限:
sudo /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -runFirstLaunch
然后在 Jenkins 构建用户的环境下执行:
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
xcodebuild -downloadPlatform iOS
Apple 提供 -downloadPlatform 下载平台对应的 Simulator runtime,并提供 -runFirstLaunch 安装必要的系统组件。这些命令可用于补齐环境,但不能保证将 SDK 改成指定版本。具体行为和可用选项以当前 Xcode 的帮助及命令输出为准。Apple Xcode 组件安装说明
执行结束后重新检查:
xcrun --sdk iphoneos --show-sdk-path
xcrun --sdk iphonesimulator --show-sdk-path
xcodebuild -project Landmarks.xcodeproj -scheme Landmarks -showdestinations
如果仍提示 iOS 26.2 is not installed,请保留初始化和下载命令的完整错误输出,继续检查安装是否失败、网络是否受限,以及 Jenkins 的 DEVELOPER_DIR 是否生效。确认 Xcode 安装包不完整后,再部署一份完整、兼容的 Xcode;不要手动向其目录复制其他版本的 SDK。
3. 用 scheme 的 destination 列表验证 Simulator
先查看 runtime 和可用设备:
xcrun simctl list runtimes -j
xcrun simctl list devices available
xcodebuild -project Landmarks.xcodeproj -scheme Landmarks -showdestinations
检查 runtime 是否被标记为不可用,或是否附有错误信息。设备处于 Shutdown 状态本身是正常的,表示它尚未启动。
如果 -showdestinations 确认原来的设备可用,可以使用 UDID,减少设备名称和 OS 版本字符串匹配带来的歧义:
xcodebuild clean \
-project Landmarks.xcodeproj \
-scheme Landmarks \
-destination 'platform=iOS Simulator,id=9B635DA7-3351-4A85-8E45-391134BA1903'
这个 UDID 仅适用于日志中的那台 CI 节点,设备重建后需要重新获取。
如果 simctl 能看到设备,而 scheme 仍不接受它,应继续检查平台可用性、项目的 SUPPORTED_PLATFORMS、deployment target,以及 runtime 对当前 Xcode、macOS 和主机架构的兼容性。改用 UDID 只能解决匹配歧义,无法修复缺失的平台组件。
4. 旧版系统测试需要安装兼容的 runtime
编译使用的 SDK、Simulator 启动的 runtime 和应用的最低部署版本是三个不同的配置。测试较旧 iOS 通常不需要将编译 SDK 降到相同版本,但应用的 deployment target 必须允许它在该系统上运行,较新的 API 也需要进行可用性判断。
Apple 文档提供了按版本下载 runtime 的参数,例如:
xcodebuild -downloadPlatform iOS -buildVersion 18.0
这里的 18.0 是命令格式示例。实际能否下载和运行,取决于 Apple 提供的资源、Xcode 版本及主机环境。下载失败不能直接说明命令语法错误。
需要缓存安装资源或部署到其他节点时,可以使用导出和导入流程:
xcodebuild -downloadPlatform iOS -exportPath "$HOME/Downloads/XcodePlatforms"
# 将路径替换为实际下载得到的 runtime 镜像
xcodebuild -importPlatform '/absolute/path/to/Simulator Runtime.dmg'
这些参数用于管理 runtime,不会任意替换当前 Xcode 的编译 SDK。Apple Simulator runtime 下载与导入说明
5. 生成 IPA 时使用真机平台归档
供 MDM/In-House 分发的应用应按 iOS 真机平台构建。平台组件恢复后,可以使用以下命令归档:
xcodebuild archive \
-project Landmarks.xcodeproj \
-scheme Landmarks \
-configuration Release \
-destination 'generic/platform=iOS' \
-archivePath "$PWD/build/Landmarks.xcarchive"
这条命令生成 .xcarchive。导出 IPA 还需要执行:
xcodebuild -exportArchive \
-archivePath "$PWD/build/Landmarks.xcarchive" \
-exportPath "$PWD/build/ipa" \
-exportOptionsPlist "$PWD/ExportOptions.plist"
示例假设项目存在 Release 配置,且已准备好适合分发方式的 ExportOptions.plist。其内容应按当前 Xcode 的 xcodebuild -help 和团队签名配置填写。Jenkins 用户还需要能访问相应证书、私钥及 provisioning profile。
真机归档无需启动 Simulator,但仍依赖可用的 iOS 平台组件。改成 generic/platform=iOS 后,如果仍提示平台未安装,应回到组件安装步骤排查。
6. 重复 runtime 条目是否就是故障原因?
现有日志只能证明 runtime 列表存在重复,无法据此认定它导致了平台缺失或归档失败。日志中的 iOS 26.3 与括号内的 26.3.1 也应分别保留,不能仅凭显示名称推断其完整版本和可用状态。
先查看 JSON 输出中的可用性及错误信息,再结合当前工具支持的 runtime 管理命令检查:
xcrun simctl list runtimes -j
xcrun simctl help runtime
确认具体 runtime 安装异常后,再安排修复或重新安装。仅凭重复名称批量删除 runtime,可能影响其他 CI 作业,也无法保证修复真机平台的 archive 错误。
备注:内容仅供参考。
