探索 Xcode 高级项目配置
Explore advanced project configuration in Xcode
2021年6月10日
一句话判断
Xcode 13 的项目配置改进让 xcconfig 文件变得更好用——条件化构建设置和配置变量的继承机制终于像样了。
这场 Session 讲了什么
Session 深入讲解了 Xcode 项目配置的高级用法,重点在 .xcconfig 文件和构建设置(Build Settings)的管理。Xcode 13 对 xcconfig 的语法做了增强,支持更灵活的条件化配置和变量继承。
主要内容包括:xcconfig 文件的条件化赋值语法(如 ONLY_ACTIVE_ARCH[config=Debug] = YES),让你在一个配置文件中处理不同构建配置的差异;构建设置的继承链——Target 继承 Project,Project 继承 xcconfig,理解这个链路对解决”设置被谁覆盖了”至关重要;以及新的 xcconfig include 机制,支持模块化的配置文件组织。
Session 还分享了大型项目的配置管理最佳实践——如何用 xcconfig 替代在 Xcode GUI 中手动设置构建参数,如何用脚本自动生成配置文件,以及如何在 CI 中覆盖特定设置。
值得深挖的点
xcconfig 的条件化赋值
之前 xcconfig 的条件化只能按 SDK 和架构(如 [sdk=iphoneos*])。Xcode 13 扩展了条件语法,支持按构建配置(config)、SDK(sdk)和架构(arch)的任意组合。这意味着你可以写 OTHER_SWIFT_FLAGS[config=Release][sdk=iphoneos*] = -O,只在 Release 配置的 iOS 设备构建中启用优化。这比维护多个 xcconfig 文件或用脚本生成要清晰得多。
include 链的调试
xcconfig 文件支持 #include 其他 xcconfig 文件,形成配置继承链。当你有 Base.xcconfig -> Debug.xcconfig -> CI.xcconfig 这样的链时,某个设置的最终值取决于整条链上的赋值。Xcode 13 在 Build Settings 面板中增加了”Resolved”列,显示每个设置的最终值和来源。这解决了一个老痛点——之前你必须手动翻遍所有 xcconfig 文件才能知道某个设置为什么是这个值。
代码片段
条件化 xcconfig 设置
// Base.xcconfig — 基础配置
PRODUCT_NAME = $(TARGET_NAME)
SWIFT_VERSION = 5.5
// Debug.xcconfig — 继承基础配置
#include "Base.xcconfig"
// 只在 Debug 配置中生效的设置
ONLY_ACTIVE_ARCH = YES
DEBUG_INFORMATION_FORMAT = dwarf
SWIFT_OPTIMIZATION_LEVEL = -Onone
// 条件化:只在模拟器 Debug 构建中启用
OTHER_SWIFT_FLAGS[config=Debug][sdk=iphonesimulator*] = -DEXAMPLE $(inherited)
模块化 xcconfig 组织
// 项目结构:
// Configs/
// ├── Base.xcconfig # 所有目标共享的基础设置
// ├── iOS-Base.xcconfig # iOS 特定设置
// ├── Debug.xcconfig # Debug 配置
// ├── Release.xcconfig # Release 配置
// └── CI.xcconfig # CI 覆盖设置
// CI.xcconfig
#include "Release.xcconfig"
// CI 环境覆盖
CODE_SIGNING_ALLOWED = NO
VALIDATE_PRODUCT = NO
用脚本自动生成配置
// build_scripts/generate_xcconfig.sh
#!/bin/sh
// 从环境变量生成 xcconfig
cat > Configs/Generated.xcconfig <<EOF
API_BASE_URL = ${API_BASE_URL:-https://api.example.com}
APP_VERSION = $(agvtool what-marketing-version -terse1)
BUILD_NUMBER = ${BUILD_NUMBER:-1}
EOF
// 在 Xcode Build Phase 中运行:
// Run Script Phase:
// "${SRCROOT}/build_scripts/generate_xcconfig.sh"
最佳实践
新项目: 从一开始就用 xcconfig 管理构建设置,不要在 Xcode GUI 中手动设置。按”基础共享 + 平台特定 + 配置特定”三层组织 xcconfig 文件。所有环境相关的设置(API URL、Feature Flag)放在 Generated.xcconfig 中由脚本生成。
已有项目: 把 Xcode GUI 中手动设置的构建参数逐步迁移到 xcconfig。先从最常改动的设置开始(版本号、API URL),再处理编译选项。迁移过程中利用 Build Settings 的 Resolved 视图确认值没有被意外覆盖。
还有什么值得关注
- xcconfig 中
$(inherited)的优先级:后面的设置覆盖前面的,同级别则 xcconfig 覆盖 Target 设置。 - Xcode 13 在 Build Settings 搜索栏中支持按设置来源过滤。
- 新的
xcodebuild -showBuildSettings输出格式更可读,方便在脚本中解析。