Xcode 工程管理(Project、Target、xcconf
Project
xcodeproj
一般地,在 iOS 开发中最开始都会通过一个模板新建一个 Xcode Project,Project 会将开发应用程序所需的文件和资源组织起来。
创建一个 Project 后,可以看到Project 是一个后缀为 .xcodeproj
的包文件。通过 Xcode 打开工程可以在 project editor 中看到 Project 不同的设置项,分别为 Info
、Build Settings
和 Package Dependencies
。
-
Info
-
Deployment Target
设置工程的目标版本; -
Configurations
配置项,默认为 Debug(调试) 和 Release(发布),可以通过 Copy 其中任意一项进行新增配置,通过 xcconfig 文件进行绑定对应的project
或者target
。 -
Localization
国际化;
-
-
Build Settings
Build Settings (构建设置)中包含了构建选项、编译选项等等,构建设置提供构建 Product 所需的信息。对于在构建过程中执行的每个任务,构建设置控制该任务的执行方式。类似于 Key=Value 的形式,未编辑的情况,会从 iOS Default 继承。可参考Build settings reference
-
Package Dependencies
官方提供的一种 Swift 包管理的方式
在 project editor 左侧可以看到 Targets 列表,Project 和 Target 是一对多的关系。
pbxproj
打开 .xcodeproj
包文件可以看到真正管理文件和资源的是 .pbxproj
文件,在 Xcode 中能看见所有的公共配置信息都存在于 project.pbxproj
中,它本质上是一种旧风格的 Property List (Plist)文件。
project.pbxproj
使用 UUID 作为交叉引用的索引,保证每个配置信息对象的唯一性。整个文件内容类似 Map
,格式如下:
{
archiveVersion = 1;
classes = {
};
objectVersion = 55;
objects = {
}
rootObject =
}
第一层级总共有 5 个键值对,Key 分别为:archiveVersion
,classes
,objectVersion
,objects
和 rootObject
。其中所有的配置对象都放在 objects
对应的 Value
中,objects
对应的 Value
也是一个字典,Key
都为 UUID
,Value
依然是个字典。
section
objects
的键值对根据内容类型被分成了若干个 section,采用注释的方式分节也使得可读性更强。section 的数量跟工程有关,尤其是每个工程的 BuildPhase 和 Target 差别都很大。下面列出了一个 section 列表(非完整),主要包含:
- 跟文件相关的
BuildFile
,Group
和FileReference
; - 跟编译相关的
BuildPhase
和Build Configuration(List)
; - 以及一些
Target
和TargetDependency
。
PBXBuildFile
PBXBuildPhase
PBXAppleScriptBuildPhase
PBXCopyFilesBuildPhase
PBXFrameworksBuildPhase
PBXHeadersBuildPhase
PBXResourcesBuildPhase
PBXShellScriptBuildPhase
PBXSourcesBuildPhase
PBXContainerItemProxy
PBXFileElement
PBXFileReference
PBXGroup
PBXVariantGroup
PBXTarget
PBXAggregateTarget
PBXLegacyTarget
PBXNativeTarget
PBXProject
PBXTargetDependency
XCBuildConfiguration
XCConfigurationList
操作 .pbxproj 文件的工具
-
CocoaPods 写的 Ruby 解析库,用于修改引入 CocoaPods 的工程文件并保存为 XML 格式。CocoaPods 本身是很强大的,还可以用来操作
Xcode workspaces (.xcworkspace)
,configuration files (.xcconfig)
和Xcode Scheme files (.xcscheme)
。 -
强大的 Python 解析库,支持一定的修改操作,可输出 OpenStep 格式,但是顺序和注释内容无法完美还原,有些鸡肋。
-
用 Python 写的统一多设备生成的 UUID 的工具,主要用途是统一工程在多设备上生成的 UUID,避免工程文件冲突。
-
Ruby 写的解析库。
-
Cordova 基于它管理 Xcode 工程
Target
Target 是编译的模板,定义了要构建的 Product,它将构建 Product 所需的文件和资源组织成一系列可以执行的构建操作。不同的 Target,经过编译生成的Product
类型也可以不同,其会继承 Project
的 Build Setting
,并可重新设置自己的编译配置。
Build Settings
Target 的 Build Settings
在未编辑的情况下,默认继承 Project
的 Build Settings
,当对其进行编辑后,会覆盖 Project 的设置。如果需要同时继承 Project 设置,可以通过设置 $(inherited)
继承 Project 的 Build Settings
。
Tips: 在 Build Settings 中,点击 All 和 Levels,可以查看配置是在 Target 或者 Project,以及覆盖和继承情况。

xcconfig
扩展名为 .xcconfig
的文件是构建配置文件,也称为 xcconfig 文件,是一个纯文本文件,用于定义和覆盖 Project 或 Target 的特定构建配置的构建设置。
添加构建配置 (xcconfig) 文件
- 添加 xcconfig 文件

- 将配置设置文件映射到构建配置

- 将构建设置拖到配置设置文件中

编写 xcconfig 文件
-
语法
BUILD_SETTING_NAME = value
BUILD_SETTING_NAME
是构建设置的 Name,可以在Build settings reference查找,或者通过 Xcode 右侧的快速帮助检查器 查看Declaration

-
支持不同平台不同方式构建
BUILD_SETTING_DECLARATION_NAME[CONDITIONAL=CONDITION_VALUE] = VALUE_DEFINITION
CONDITIONAL CONDITION_VALUE sdk iphoneos10.2
arch arm64
例如:
OTHER_LDFLAGS[sdk=macosx*][arch=x86_64] = -lncurses
-
引用其他构建配置文件的设置
引用文件可以使用相对路径与绝对路径(最好以
$(SRCROOT)
为开始)#include "MyOtherConfigFile.xcconfig"
在引用其它文件后防止被覆盖,可以使用
$(inherited)
BUILD_SETTING_DECLARATION_NAME = $(inherited) ADDITIONAL_VALUE
Build Settings 优先级
Target .xcconfig
> Target
> Project.xcconfig
> Project
> System Default Values

Scheme
Scheme(方案)指定了要构建的 Target
、Configuration
以及要执行的操作 Action
,因此 每个 Target 可以有多个 Scheme,Xcode 会自动为每个 Target 创建一个 Scheme。

Workspace
Workspace 直译工作空间,其文件格式为 xcworkspace
,可以将工作空间用作多个相关项目的容器。Xcode将检测工作区中多个 Target 之间的隐式链接依赖关系,并通过 Scheme 以正确的顺序构建 Target。
Workspace、Project、Target、Scheme、Build Configuration 之间的联系

工程多环境配置方案
多 Configurations
通过多个 xcconfig 文件 配合 Configurations,实现不同的环境下编译选项的个性化配置,生成不同的 Products
多 Targets
多 Target 配置,适用于生成有代码或者资源差异的 Product 时:
- 通过在 project editor 左侧对原有 Target 进行 Duplicate,复制一份同样的 Target;
- 修改引用资源、编译代码文件以及
bundleId
等配置信息 - 新增 Scheme 绑定新增的 Target