基本的編譯過程分為四個步驟:
預處理(pre-process):把巨集替換,刪除注釋,展開標頭檔案,產生.i檔案。
編譯(compliling):把之前的.i檔案轉換成組合語言,產生.s檔案。
彙編(asembly):把組合語言檔案轉換為機器碼檔案,產生.o檔案。
鏈結(link):對.o檔案中的對於其他的庫的引用的地方進行引用,生成最後的可執行檔案(同時也包括多個.o檔案進行 link)。
然後通過解析 xcode 編譯 log,可以發現 xcode 是根據 target 分開進行編譯的。每個 target 的具體的編譯過程也可以通過展開 log 日誌獲得。基本的格式就是首先簡明一句說明要幹什麼,然後縮排的幾行說明具體的操作。比如:
(2) cd /.../dev/objcio/pods
setenv lang en_us.us-ascii
setenv path "..."
(4) -x objective-c-header
(5) -arch armv7
... configuration and warning flags ...
(6) -ddebug=1 -dcocoapods=1
... include paths and more ...
(7) -c
(8) /.../pods-ssziparchive-prefix.pch
(9) -o /.../pods-ssziparchive-prefix.pch.pch
就是在處理 pch 標頭檔案,首先切換到 pch 的目錄下,然後設定環境變數,然後啟動 clang 並進行一系列的配置。在這之後一般就會產生具體的.o
檔案作為產出(一般是有多個,針對不同的平台架構分別有乙個,不過一般緊接著會把這些聚合成乙個通用的 library。)。同時注意,不同的 target 也是有編譯順序的,具體的要看 target 之間的依賴關係。
在 xcode 編譯的過程中,大部分的命令都可以自解釋,不過仍有個別的命令直接看是看不出來幹嘛的,這裡解釋一下:
ld
:用於產生可執行檔案。
libtool
:產生 lib 的工具。
(這部分將會在之後的文章的編譯具體過程進行講解)
接下來就是編譯過程的控制,在 xcode 中可以通過build phases
,build settings
以及build rules
來進行控制。
build settings則是對編譯工作的細節進行設定,在這個視窗裡可以看見大量的設定選項,從編譯到打包再到**簽名都有,這裡要注意 settings 的 section 分類,同時一般通過右側的 inspector 就可以很好的理解選項的意義了。
最後,要說一下我們的工程檔案.pbxproj
,以上的所有的這些選項都儲存在這個檔案中。當然也包括 target 的資訊,專案所有檔案的資訊,這個檔案是乙個文字檔案,可以用文字編輯器開啟。裡頭的內容基本是可讀性比較強的。基本的思路很物件導向,每個東西都有屬性,如果屬性是另乙個物件,值就是那個物件的乙個『引用』,就是一串數字(唯一的)作為表示。每個物件都有這樣的引用。
首先,編譯器是做什麼的?編譯器是用來把源**檔案轉換為更為低階的語言的(同時還有語句的靜態分析),而 xcode 使用的clang 編譯器的作用就是把源**轉換為更為低階的 llvm ir(intermedia representation),這個 llvm ir 是作業系統無關的,然後 llvm 通過這個中間語言來進行下一步的二進位制檔案的產出。得益於 llvm 的三層架構,llvm 可以有多個輸入和輸出(llvm 的第一層架構是用於處理輸入的,第二層用於優化 ir ,第三層用於輸出)這裡遇到了乙個問題,不了解到底 clang 和 llvm 之間的關係是什麼,估計得明白編譯器是怎麼做的才能明白。
通常乙個編譯器可以編譯多種語言,生成多個平台的**,所以會劃分前端和後端。有時候還有中端的說法。
前端是語言相關的,輸出為抽象語法樹;後端是機器相關的,輸出為機器**。有些優化是機器無關的,這一部分可能被單列出來稱為中端。
以gcc為例,前端生成的中間語言為generic,之後轉化為gimple做機器無關的優化,最後轉化為rtl做機器相關優化並生成機器**。也就是說前段完成語法分析句法分析等相關的工作,並不會針對機器平台做想對應的優化。後端才是真正蟾蜍機器碼的部分。clang 只是乙個編譯器的前前端部分。而 llvm 這個術語不能一概而論,具體區別的在這篇部落格有講述。這三個部分就可以分別稱為前端、中端、後端。不過gimple階段是gcc 4之後才有的,gcc 3.x的版本優化全在rtl上。
而且實際實現的時候可能機器相關的優化也在gimple階段實現(反過來rtl也有機器無關優化),劃分不是那麼明確。
如果對編譯器本身產生了興趣,可以一方面可以看看編譯原理(程式猿的三大浪漫之一),然後另一方面可以自己了解乙個編譯器應該怎麼寫。
這裡有個知乎專欄
同時還有史丹福大學的公開課供學習參考。
Xcode 中的編譯過程以及編譯器
基本的編譯過程分為四個步驟 預處理 pre process 把巨集替換,刪除注釋,展開標頭檔案,產生.i檔案。編譯 compliling 把之前的.i檔案轉換成組合語言,產生.s檔案。彙編 asembly 把組合語言檔案轉換為機器碼檔案,產生.o檔案。鏈結 link 對.o檔案中的對於其他的庫的引用...
使用ccache加速xcode編譯過程
前面已經介紹過如何安裝ccache,這裡不廢話。要確保ccache 版本不低於3.19 brew install ccache head如果之前安裝了ccache release版本也沒有關係,因為ccache release版本已經是3.19了。如何安裝brew?前面也介紹過,不解釋。可googl...
xcode 環境設定,路徑以及編譯錯誤
接手乙個之前的ios專案,編譯出現一些問題,整理如下 1.lib 路徑問題 library search paths 靜態庫檔案路徑 a framework search paths 系統framework header search paths ios 預設新增都是絕對路徑 一般路徑頭都改為rec...