一、build 日志
在 Xcode 的 Report navigator
中可以看到 build 日志(如下圖所示)湃番。
每一行任務就是一個 task夭织,每個 task顯示的信息有狀態(tài)、任務名吠撮、耗時摔癣,點擊最右邊的箭頭,可以展開每條任務的執(zhí)行細節(jié)纬向。類似這種格式:
CompileC /Users/xianglongchen/Library/Developer/Xcode/DerivedData/Playground_iOS-hfqoqrhlwhirthhjzanxhdrxyfoz/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/SDWebImage.build/Objects-normal/x86_64/UIView+WebCacheOperation.o /Users/xianglongchen/Desktop/Playground_iOS/Pods/SDWebImage/SDWebImage/UIView+WebCacheOperation.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler (in target: SDWebImage)
cd /Users/xianglongchen/Desktop/Playground_iOS/Pods
export LANG=en_US.US-ASCII
...
可以看到上面的任務細節(jié)中其實就是由很多條 shell 命令組成的,包括 CompileC
戴卜、Ld
等逾条。
題外話:在 build log 中可以看到 Xcode 在構(gòu)建過程中會在 DerivedData 這個目錄下生成一些臨時數(shù)據(jù)
二、build 流程設(shè)置
1. Build Phases
Build Phases 從一個高層面上展示了整個構(gòu)建過程投剥,我們可以在 Build Phases 里設(shè)置各個 Phases 的配置項师脂,也可以新加一個或者多個 Build Phase。
上圖中所示的工程一共有 5 個 Phases江锨,build 時會按照其指定的順序執(zhí)行:
- Target Dependencies:用來告訴 build system 在開始構(gòu)建當前 target 之前需要先構(gòu)建好哪些 target
- [CP]Check Pods Manifest.lock:這是 CocoaPods 自動添加的一個 phase吃警,因為項目中使用了 CocoaPods
- Compile Sources:告訴 build system 哪些資源需要參與編譯
- Link Binary With Libraries:告訴 build system 在當前 target 的所有源碼編譯成目標文件后要跟哪些庫鏈接
- Copy Bundle Resources:拷貝靜態(tài)資源(比如圖片、字體)到 app bundle 中
自定義 Build Phases
就像 CocoaPods 所做的那樣啄育,我們可以添加自定義的 Phases酌心,自定義 Build Phases 可以用來執(zhí)行腳本、拷貝資源等等挑豌。
2. Build Rules
Build Rules 用來指定不同文件類型分別應該如何被編譯安券。通常情況下,我們不需要修改默認的規(guī)則氓英,但是如果你想為一些新的文件類型添加自定義處理侯勉,你可以添加新的編譯規(guī)則。
3. Build Settings
在 Build Settings 中铝阐,我們可以設(shè)置每一個具體的 build 任務的細節(jié)址貌。
Build Settings 中提供的選項非常豐富,涉及到了 build 的每個階段,從編譯到鏈接再到代碼簽名和打包练对。
更詳細介紹的見 Xcode Build System Guide(最新版的 Build Settings Reference 可以在 Xcode Help中查看: 1. In Xcode, choose Help > Xcode Help, or open the Xcode Help website.2. Search for “build settings.”)遍蟋。
Tips:
在 Xcode 的 build setting 里面也可以通過 “option+鼠標左鍵雙擊” 來顯示幫助彈窗。
三锹淌、Project 文件
我們在前面所討論的所有設(shè)置最終都會被保存到 Xcode Project 文件中去匿值,Xcode Project 文件的格式是 .xcodeproj
,這個文件實際上是一個文件夾赂摆。
平時我們基本上不會去看這個 .xcodeproj
文件的細節(jié)挟憔,除非你在 git merge 時遇到了沖突(嚴格上來講是 .xcodeproj
文件夾中的 project.pbxproj
文件)。
我們可以把這個 project.pbxproj
文件在文本編輯器中打開烟号,這個文件中的內(nèi)容的可讀性還是比較高的绊谭。
下面是一個示例項目的 project.pbxproj
文件簡化后的內(nèi)容(只保留了 PBXProject
部分的內(nèi)容):
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
/* End PBXBuildRule section */
/* Begin PBXFileReference section */
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
/* End PBXNativeTarget section */
/* Begin PBXProject section */
856951B22201BD8C0098E0BE /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1000;
ORGANIZATIONNAME = xianglongchen;
TargetAttributes = {
856951B92201BD8C0098E0BE = {
CreatedOnToolsVersion = 10.0;
};
};
};
buildConfigurationList = 856951B52201BD8C0098E0BE /* Build configuration list for PBXProject "Playground_iOS" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 856951B12201BD8C0098E0BE;
productRefGroup = 856951BB2201BD8C0098E0BE /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
856951B92201BD8C0098E0BE /* Playground_iOS */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
/* End XCConfigurationList section */
};
rootObject = 856951B22201BD8C0098E0BE /* Project object */;
}
可以看到這個 project.pbxproj
文件中的內(nèi)容非常清晰,甚至還有注釋汪拥,仔細對比一下达传,跟 Xcode 中打開時的信息可以一一對應起來,包括文件目錄結(jié)構(gòu)迫筑、build settings宪赶、build phases、build rules脯燃、target 等搂妻。
當你需要自動添加文件到 Xcode 工程中來時,可能就需要好好了解一下這個 project.pbxproj
文件了辕棚,不過已經(jīng)有不少大神們踩過坑了欲主,目前已知的一些不錯的解決方案:
- CocoaPods/Xcodeproj:CocoaPods 官方提供的工具,使用 Ruby 編寫的
- 使用代碼為 Xcode 工程添加文件:Draveness 的文章逝嚎,強烈推薦閱讀扁瓢,親測有效
- pbxprojHelper--Xcode工程文件助手
- venmo/synx
- Xcodeproj: 使用 ruby 自由的修改Xcode 工程文件
- alunny/node-xcode:一個 nodejs 工具,在 React Native 官方項目中有過應用
參考
- Build Process - objc.io(推薦)
- Xcode Build System Guide(最新版的 Build Settings Reference 可以在 Xcode Help中查看: 1. In Xcode, choose Help > Xcode Help, or open the Xcode Help website.2. Search for “build settings.”)
- The Xcode Build System
- Xcode中的 workspace, project, target 和 scheme
- Building an iOS App Without Xcode's Build System
- What's inside the Derived Data folder?
- 修改 xcodeproj 文件