1. 程式人生 > Android開發 >iOS進階之路——理解 Xcode 編譯系統

iOS進階之路——理解 Xcode 編譯系統

本文來自 iOSTips ,作者 Vadim Bulavin

任何 iOS 原始碼在裝置上執行之前都需要編譯器的一系列處理,這個過程通常由 Xcode Build System 完成。在這篇文章中,我將介紹 Xcode Build System 的每一個部分。

為何要學編譯知識

說說 OCLint 、SwiftLint 實現原理是怎樣的? 如何編寫 Clang 外掛? Obfuscator-LLVM 在 iOS 中如何實現混淆加固? iOS 中 Bitcode 到底是如何優化 IPA 包的? 如果以上問題你都可以說個大概,請忽略本文,如果你對以上問題一知半解,但又很感興趣,那麼學習並掌握編譯原理相關知識的過程中,你便會自己找到答案,好了接下來我將大概的介紹 iOS 開發中需要了解的編譯流程。

語言處理系統

語言處理系統讓自己輸出一個可執行程式的一組任意源語言編寫的指令。它允許程式設計師使用高階語言而不是寫作機器程式碼大大減少了程式設計的複雜性。

我們日常使用的語言處理系統 iOS 或 macOS 開發 叫做 Xcode Build System。

Xcode Build System

Xcode 構建系統的主要目的是協調執行各種構建任務,最終將產生一個可執行程式。

Xcode 通過執行一系列編譯器工具集將 iOS 原始碼按一定的順序編譯連結生成可執行檔案,而無需你手動操作,關心編譯連結背後複雜的過程。

大部分的語言處理系統,包括 Xcode Build Sytem,包括以下 5 個部分:

  • Preprocessor

  • Compiler

  • Assembler

  • Linker

  • Loader

這五部分組合起來是下面的流程圖:

讓我們仔細看看每一個步驟。

作為一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流群:519832104 不管你是小白還是大牛歡迎入駐,分享經驗,討論技術,大家一起交流學習成長!

另附上一份各好友收集的大廠面試題,需要iOS開發學習資料、面試真題,可以新增iOS開發學習交流群,進群可自行下載!

Preprocessing

預處理步驟的目的是將你的程式做一些處理然後可提供給編譯器。它會處理巨集定義、發現依賴關係、解決前處理器指令。

Xcode 解決依賴關係通過底層 llbuild 構建系統。它是開源的,你可以在 Github swift-llbuild 頁面瞭解更多資訊。

Compiler

編譯器是一個程式,將一種語言的源程式用另一種語言對映到一個語義上等價的目標程式。換句話說,它轉換Swift、objective - C和C / C++ 程式碼到機器碼。

Xcode 使用兩個不同的編譯器:一個用於 Swift ,另一個用於Objective - C,Objective - C + +和 C / C++檔案。

clang 是蘋果官方的 C 語言編譯器。它是開源在:swift-clang。

swiftc 是 Xcode 用來編譯和執行 Swift 原始碼的 Swift 編譯器。

編譯器工作流程如下:

編譯器由兩個主要部分:前端和後端。

前端負責詞法分析,語法分析,生成中間程式碼;它還建立並管理符號表,收集關於源程式的資訊。

符號表儲存名稱的變數,函式,類,你的名字,每個符號對映到特定的資料。

編譯原理之美

Swift 編譯器,中間語言表示名為 Swift Intermediate Language(SIL)。它是用於進一步分析和優化的程式碼。不可能直接從 Swift 中間語言生成機器程式碼,因此 SIL 經歷了一系列轉變到 LLVM 中間表示。

後端以中間程式碼作為輸入,進行行架構無關的程式碼優化,接著針對不同架構生成不同的彙編程式碼。

Assembler

Assembler 翻譯開發者可讀的彙編程式碼為可重定位的機器碼,最終生成包含資料和程式碼的 Mach-O 檔案。

機器程式碼是一種數字語言,表示一組指令,可以直接由 CPU 執行。它被是可重定位的,因為無論目標檔案的地址空間在哪,它將執行的指令相對地址。

Mach-O 檔案是一種特殊的 iOS 和 MacOS 檔案格式,作業系統用它來描述物件檔案、可執行檔案和庫。它是一串位元組組合形成的有意義的程式塊,將執行在 ARM 處理器上或英特爾處理器。

Linker

連結器將各種物件檔案和庫連結合併為一個可以在 iOS 或 macOS 系統上執行的 Mach-O 可執行檔案。連結器主要有兩種檔案作為輸入,包括這些物件檔案的彙編程式和庫的幾種型別(.dylib,.tbd 和 .a)。

連結器的作用,就是完成變數、函式符號和其地址繫結這樣的任務。例如,如果在程式碼中使用 printf,連結器連結這個符號和 libc 庫 printf 函式實現的地方。通常在編譯階段通過建立符號表來解決不同物件檔案和庫的引用。

Loader

最後,載入程式是作業系統的一部分,將一個程式載入到記憶體中,並執行執行它。載入程式負責分配執行程式記憶體空間和初始化暫存器所需的初始狀態。

總結

作為 iOS 和 macOS 開發者我們主要使用 Xcode Build System 編譯構建我們的應用程式。它的主要元件是:預處理、編譯器、彙編器、聯結器和載入程式。Xcode 使用不同的編譯器(swiftc 和 clang)編譯 Swift 和 Objective-C。

對於初學者和經驗豐富的開發人員來說學習掌握 編譯原理基礎知識都頗有益處,這裡有一張宮文學老師《編譯原理之美》的關於編譯知識結構體系的思維導圖,可以拿來對每個知識點系統學習。