【資料圖】
Xcode的構(gòu)建過程本質(zhì)上是執(zhí)行一系列構(gòu)建任務(wù)。如:代碼檢測,編譯代碼,鏈接目標(biāo)文件,拷貝資源(圖片, plist, nib)文件,代碼簽名等。大部分任務(wù)是執(zhí)行命令行工具,如(clang編譯、 ld鏈接、 codesign簽名, altool上傳)。這些工具使用xcode項目的配置信息,根據(jù)特定的順序執(zhí)行。bulid System的工作就是創(chuàng)建構(gòu)建任務(wù),并協(xié)調(diào)這些任務(wù)按照正確的順序執(zhí)行。構(gòu)建任務(wù)的順序是任務(wù)之間的依賴關(guān)系定的。如有2個類文件,A文件和B文件, B文件使用了A文件的方法,引入了A文件。那么他們的編譯任務(wù)是編譯A,再編譯B,等都編譯好,將兩個.o文件進行鏈接。我們每次構(gòu)建項目是對一個具體的 Target發(fā)起的,每個Target擁有自己的文件和編譯規(guī)則,在項目里可以存在多個子項目,這導(dǎo)致了在編譯的時候如果使用了 Cocoapods 或者擁有多個 target 的項目會先編譯依賴庫,然后再編輯當(dāng)前項目。如果使用的workspace開發(fā),會遍歷里面管理的項目,找到Target的依賴進行編譯,然后再編譯當(dāng)前項目。這些依賴庫的Target的編譯過程和我們項目的編譯流程是一樣的。
Xcode編譯流程編譯準(zhǔn)備階段1.創(chuàng)建編譯計劃,檢查依賴: 檢查當(dāng)前項目中使用的依賴庫是否已經(jīng)安裝并能夠被正確地引用;確定編譯順序,如工程A下有子工程B,類C中引用了類D,要根據(jù)依賴關(guān)系創(chuàng)建編譯計劃,先編譯獨立的類,子項目;再編譯有依賴的類和主項目。2.創(chuàng)建構(gòu)建產(chǎn)物過程中和結(jié)束時需要的目錄
編譯階段1.寫輔助文件:創(chuàng)建app包目錄,后面編譯后的文件都會被放入app包目錄中;將項目的文件結(jié)構(gòu)寫成.hmap映射文件,方便后面引用查詢使用;生成.hmap文件:當(dāng)編譯器處理.h文件時,它會生成一個.hmap文件,包含了所有的.h文件及其對應(yīng)的目標(biāo)文件的信息。這些信息將被用來加速下一次編譯過程。.hmap文件通常被存儲在Derived Data目錄下。2.運行預(yù)設(shè)腳本:Cocoapods 會預(yù)設(shè)一些腳本,當(dāng)然你也可以自己預(yù)設(shè)一些腳本來運行。這些腳本都在 Build Phases 中可以看到;【"[CP] Check Pods Manifest.lock","Copy Pods Resources"】3.編譯文件:針對每一個文件進行編譯,先編譯.Swift后編譯.m文件,可以查看每個文件的編譯時間以及error和warning。編譯源碼文件是編譯階段的重點,它會生成 Mach-O類型的.o文件。這過程涉及到了 LLVM三相設(shè)計的 的完整流程:編譯前端、優(yōu)化器、編譯后端。4.鏈接文件:將項目中的多個可執(zhí)行文件合并成一個文件;鏈接分為動態(tài)鏈接和靜態(tài)鏈接,這2項也是程序員必須要面對的2個重要概念,這個原理衍生了很多重要的應(yīng)用場景,如:iOS原生代碼的熱更新,啟動性能優(yōu)化,APP瘦身的符號剪裁等。5.拷貝資源文件:將項目中的資源文件拷貝到目標(biāo)app包;6.編譯,鏈接 storyboard 文件:storyboard 文件也是會被編譯的;項目中的 storyboard 會被編譯成一個二進制文件,包含了界面的所有信息和結(jié)構(gòu),這個文件的后綴名為 .storyboardc。.storyboardc 文件會在鏈接階段被鏈接到最終的應(yīng)用程序中,以展示應(yīng)用程序的用戶界面。7.編譯 xib 文件:。 xib 文件會先解析成 XML 格式的文件,然后編譯成二進制格式的文件,即 nib 文件。編譯后的 nib 文件會被打包到應(yīng)用程序的 bundle 中。8.編譯 Asset 文件:我們的圖片如果使用 Assets.xcassets 來管理圖片,那么這些圖片將會被編譯成機器碼,除了 icon 和 launchImage;9.運行 Cocoapods 腳本:將在編譯項目之前已經(jīng)編譯好的依賴庫和相關(guān)資源拷貝到包中。10.將 Swift 標(biāo)準(zhǔn)庫拷貝到包中11.生成 .app 包12.對包進行簽名13.完成打包
XCode中項目的結(jié)構(gòu)關(guān)系Target:表示一種產(chǎn)物類型,它有很多設(shè)置可以做細(xì)節(jié)修改,如:Build Settings, Build Phases, Build Rules。
Configuration:構(gòu)建變體,如每個Target下默認(rèn)就有2個構(gòu)建變體Debug, Release。 這2個構(gòu)建變體的設(shè)置內(nèi)容都可以進行修改,如Deubeg下不產(chǎn)生DSYM符號文件加速編譯,Release下產(chǎn)生DSYM符號文件用于排查線上問題。
Scheme:產(chǎn)物生成驅(qū)動器,定義了產(chǎn)物生成的組成過程,Target和Configuaration是靜態(tài)的配置定義,Scheme是對這些定義的消費。
Project:是直接容器,它直接管理者代碼文件,資源文件,腳本文件等。它可以引入其他Project作為它的依賴。
WorkSpace:它是管理Project的項目容器,在它下面管理的Project可以通過依賴而使用,如A,B是WorkSpace下的兩個Project, A在它的Frameworks,Libraries..下點擊“+”添加B的產(chǎn)物就可以使用了。如果使用cocopods時,這些會被自動做。
編譯性語言與解釋性語言解釋性語言:邊解釋邊運行。特點是調(diào)試快,運行慢。 解釋器在運行的時候把代碼逐行做詞法分析,語法分析,語義分析,生成可執(zhí)行的中間碼,然后執(zhí)行中間碼。
編譯性語言:先編譯成可以在CPU上直接運行的機器碼,再執(zhí)行。特點是運行快,調(diào)試慢。 通過編譯器(采用三相設(shè)計:編譯器前端,LLVM IR中間碼優(yōu)化器,編譯器后端),將代碼字符串做詞法分析,語法分析,語義分析,生成中間碼IR。 然后把IR中間碼交給優(yōu)化器做優(yōu)化。 IR優(yōu)化器處理完后把結(jié)果交給編譯器后端編譯成不同架構(gòu)(arm64, i386)的可執(zhí)行文件。
三相設(shè)計假如有N種語言(C、OC、C++、Swift…)的前端,同時也有M個架構(gòu)(模擬器、arm64、x86…)的Target,是否就需要 N × M 個編譯器?三相架構(gòu)的價值就體現(xiàn)出來了,通過共享優(yōu)化器的中轉(zhuǎn),很好的解決了這個問題。假如你需要增加一種語言,只需要增加一種前端;假如你需要增加一種處理器架構(gòu),也只需要增加一種后端,而其他的地方都不需要改動。
LLVM的組成在Xcode編譯iOS項目的時候,都是使用的LLVM,其實在編寫代碼以及調(diào)試的時候都在接觸LLVM提供的功能,例如:代碼的亮度(Clang)、實時代碼檢查(Clang)、代碼提示(Clang)、debug斷點調(diào)試(LLDB)。LLVM項目是模塊化和可重用的編譯器和工具鏈技術(shù)的集合。LLVM主要的子項目有一下幾個:
1.LLVM核心庫:LLVM提供一個獨立的鏈接代碼優(yōu)化器,為許多流行CPU(以及一些不太常見的CPU)的代碼生成支持。這些庫是圍繞一個指定良好的代碼表示構(gòu)建的,稱為LLVM中間表示(“LLVM IR”)。LLVM還可以充當(dāng)JIT編譯器 - 它支持x86 / x86_64和PPC / PPC64程序集生成,并具有針對編譯速度的快速代碼優(yōu)化。
2.LLVM IR 生成器Clang:Clang是LLVM的一個前端,它是LLVM的C / C ++ / Objective-C編譯器,旨在提供驚人的快速編譯(例如,在調(diào)試配置中編譯Objective-C代碼時比GCC快3倍),非常有用的錯誤和警告消息以及提供構(gòu)建優(yōu)秀源代碼工具的平臺。
3.LLDB項目:LLDB項目以LLVM和Clang提供的庫為基礎(chǔ),提供了一個出色的本機調(diào)試器。它使用Clang AST和表達式解析器,LLVM JIT,LLVM反匯編程序等,以便提供“正常工作”的體驗。在加載符號時,它也比GDB快速且內(nèi)存效率更高。
4.lld項目:lld項目旨在成為clang / llvm的內(nèi)置鏈接器。目前,clang必須調(diào)用系統(tǒng)鏈接器來生成可執(zhí)行文件。
參考文章:
https://blog.csdn.net/dangyalingengjia/article/details/103336421https://blog.csdn.net/Future_One/article/details/81882359http://chuquan.me/2021/02/16/understand-ios-xcode-build-process/https://xilankong.github.io/ios開發(fā)基礎(chǔ)/2020/07/29/Xcode-build過程都做了什么.html
標(biāo)簽: