Xcode project
是一个仓库,该仓库包含了所有的文件,资源和用于生成一个或者多个products
的信息,那么比如我们从当前project要生成两个products A 和B,该从哪里设置A和B各自需要的信息呢?
答案是target,每一个 target
能够制定其自己的 build settings,指明了如何生成 products
target 的 build settings 会覆盖project 的build settings
如果我们每个target都需要debug和release两种环境,那么不同环境的设置又去哪里写明呢?
答案是可以在buildsettings中单独设置,
也可以在configurations中分别配置debug.xcconfig和release.xcconfig
我们已经用到了target 和 configurations,设置好之后,我现在想要在debug 模式下,运行target A,我应该如何通知xcode呢?
答案是scheme
至此,xcode 编译设置相关的三个基础我们都有所了解了:
1、build settings,分为project的build settings 和 target的 build settings
创建一个新的project,它自带了build settings,这些设置并不是存在.xcconfig文件中的,而是存在project.pbxproj 中的 XCBuildConfiguration
区块,可以通过Xcode 界面:TARGETS → Build Settings修改,也可以直接编辑 project.pbxproj
bash
YourProject.xcodeproj/
└── project.pbxproj # 所有工程配置的实际载体
project.pbxproj
包含 所有 Build Settings 的键值对 、文件引用、Target 定义等,这里为啥没有直接给开发者生成一个.xcconfig文件,我猜可能是xcode的开发者想要将基础配置内置,降低新手门槛,在需要满足一些高级要求时允许开发者使用 .xcconfig
机制,以达到配置隔离的目的
- Target 设置:针对特定构建目标
- .xcconfig:针对构建环境(Debug/Release)
- Project:全局默认值
2、project -> info -> configuration ,下文将其称为配置注册表

上图是没有cocoapods的配置注册表
配置注册表主要是对project或target绑定对应的.xcconfig,可以理解为这里是对debug/release环境、target、.xcconfig的整合
开发者没有自己创建.xcconfig,但是通过cocoapods引入了三方库的情况,
Pods 会生成配置文件(如 Pods-YourApp.debug.xcconfig
),并且会被自动加到配置注册表中

3、scheme,相对更好理解,主要是用来安排开发者现在要运行什么,比如运行的环境,target等
其实针对项目的设置基本就是这三个元素之间的组合
cocoaPods
在pod install
或pod update
过程中,当CocoaPods确定了要安装的每个Pod的版本和配置后,会为每个Pod生成相应的Support Files。这些文件由CocoaPods的Generator
类创建,特别是TargetEnvironmentSupportFilesGenerator
和TargetSupportFilesGenerator
等类负责生成。
css
Pods/
└── [Pod名称]/
└── Support Files/
├── [Pod名称]-dummy.m
├── [Pod名称].xcconfig
├── [Pod名称]-prefix.pch
├── [Pod名称]-umbrella.h
└── [Pod名称]-Info.plist
同样在pod install
或pod update
过程中,当所有Pod的target都生成后,CocoaPods会为整个Pods项目生成Target Support Files,包括聚合的xcconfig文件。这些文件由CocoaPods的AggregateTargetSupportFilesGenerator
和PodsProjectGenerator
等类生成。
xcconfig 、build settings的优先级
Target build settings 设置 > xcconfig设置 > Project build settings 设置
那么如果我是想在.xcconfig中设置other_ldflags, 如何在原来的基础上追加呢?这里就要聊到$(inherited)
在 Xcode 的构建系统中,$(inherited)
是一个特殊的变量,用于表示从更高层级继承的设置
另外.xcconfig可以通过#include指令形成链式继承。
举个例子在A.xcconfig中设置如下,并将其配置到配置注册表中
arduino
#include "B.xcconfig"
B.xcconfig中的内容
ini
OTHER_LDFLAGS = $(inherited) -framework "CoreData"
在target的build settings中如下设置在project 的build settings中如下设置
验证一下最终的other_ldflags的值
java
xcodebuild -target pasteEasy -configuration Debug -showBuildSettings | grep OTHER_LDFLAGSOTHER_LDFLAGS
= -framework "CoreVideo" -framework "CoreData" -framework "CoreGraphics"
从最终OTHER_LDFLAGS的值的顺序也可以看出继承的方向project build settings <- .xcconfig <- target build settings
当在 .xcconfig
文件中使用 $(inherited)
时,它代表的是当前配置层级之上(更低优先级)的设置。
具体来说,对于绑定到某个构建配置(如 Debug)的 .xcconfig
文件,其 $(inherited)
的值来自:
- target/Project 层级的 Build Settings(存储在
project.pbxproj
中) - Xcode 的默认构建设置
冲突
build setting中设置DEBUG_INFORMATION_FORMAT 为 DWARF.xcconfig中设置为dwarf-with-dsym查看最终值:
perl
xcodebuild -target pasteEasy -configuration Debug -showBuildSettings | grep DEBUG_INFORMATION_FORMAT
dwarf
继承顺序:最高优先级的target build settings都是从其他继承
- 当前构建配置对应的
.xcconfig
文件中的设置(例如Debug.xcconfig
中的OTHER_LDFLAGS
)
- target 层级的 Build Settings(存储在
project.pbxproj
中)
- Project 层级的 Build Settings(存储在
project.pbxproj
中) - Xcode 的默认构建设置
关注我,还能发现更多干货~