电竞比分网-中国电竞赛事及体育赛事平台

分享

iOS進(jìn)階之路——理解 Xcode 編譯系統(tǒng)

 Coder編程 2021-12-23

本文來(lái)自 iOSTips ,作者 Vadim Bulavin

任何 iOS 源代碼在設(shè)備上運(yùn)行之前都需要編譯器的一系列處理,這個(gè)過(guò)程通常由 Xcode Build System 完成。在這篇文章中,我將介紹 Xcode Build System 的每一個(gè)部分。

為何要學(xué)編譯知識(shí)

說(shuō)說(shuō) OCLint 、SwiftLint 實(shí)現(xiàn)原理是怎樣的?
如何編寫(xiě) Clang 插件?
Obfuscator-LLVM 在 iOS 中如何實(shí)現(xiàn)混淆加固?
iOS 中 Bitcode 到底是如何優(yōu)化 IPA 包的?
如果以上問(wèn)題你都可以說(shuō)個(gè)大概,請(qǐng)忽略本文,如果你對(duì)以上問(wèn)題一知半解,但又很感興趣,那么學(xué)習(xí)并掌握編譯原理相關(guān)知識(shí)的過(guò)程中,你便會(huì)自己找到答案,好了接下來(lái)我將大概的介紹 iOS 開(kāi)發(fā)中需要了解的編譯流程。

語(yǔ)言處理系統(tǒng)

語(yǔ)言處理系統(tǒng)讓自己輸出一個(gè)可執(zhí)行程序的一組任意源語(yǔ)言編寫(xiě)的指令。它允許程序員使用高級(jí)語(yǔ)言而不是寫(xiě)作機(jī)器代碼大大減少了編程的復(fù)雜性。

我們?nèi)粘J褂玫恼Z(yǔ)言處理系統(tǒng) iOS 或 macOS 開(kāi)發(fā) 叫做 Xcode Build System。

Xcode Build System

Xcode 構(gòu)建系統(tǒng)的主要目的是協(xié)調(diào)執(zhí)行各種構(gòu)建任務(wù),最終將產(chǎn)生一個(gè)可執(zhí)行程序。

Xcode 通過(guò)運(yùn)行一系列編譯器工具集將 iOS 源碼按一定的順序編譯鏈接生成可執(zhí)行文件,而無(wú)需你手動(dòng)操作,關(guān)心編譯鏈接背后復(fù)雜的過(guò)程。

大部分的語(yǔ)言處理系統(tǒng),包括 Xcode Build Sytem,包括以下 5 個(gè)部分:

  • Preprocessor

  • Compiler

  • Assembler

  • Linker

  • Loader

這五部分組合起來(lái)是下面的流程圖:

讓我們仔細(xì)看看每一個(gè)步驟。

Preprocessing

預(yù)處理步驟的目的是將你的程序做一些處理然后可提供給編譯器。它會(huì)處理宏定義、發(fā)現(xiàn)依賴關(guān)系、解決預(yù)處理器指令。

Xcode 解決依賴關(guān)系通過(guò)底層 llbuild 構(gòu)建系統(tǒng)。它是開(kāi)源的,你可以在 Github swift-llbuild 頁(yè)面了解更多信息。

Compiler

編譯器是一個(gè)程序,將一種語(yǔ)言的源程序用另一種語(yǔ)言映射到一個(gè)語(yǔ)義上等價(jià)的目標(biāo)程序。換句話說(shuō),它轉(zhuǎn)換Swift、objective - C和C / C++ 代碼到機(jī)器碼。

Xcode 使用兩個(gè)不同的編譯器:一個(gè)用于 Swift ,另一個(gè)用于Objective - C, Objective - C + +和 C / C++文件。

clang 是蘋(píng)果官方的 C 語(yǔ)言編譯器。它是開(kāi)源在:swift-clang。

swiftc 是 Xcode 用來(lái)編譯和運(yùn)行 Swift 源代碼的 Swift 編譯器。

編譯器工作流程如下:

編譯器由兩個(gè)主要部分:前端和后端。

前端負(fù)責(zé)詞法分析,語(yǔ)法分析,生成中間代碼;它還創(chuàng)建并管理符號(hào)表,收集關(guān)于源程序的信息。

符號(hào)表存儲(chǔ)名稱的變量,函數(shù),類(lèi),你的名字,每個(gè)符號(hào)映射到特定的數(shù)據(jù)。

編譯原理之美

Swift 編譯器,中間語(yǔ)言表示名為 Swift Intermediate Language(SIL)。它是用于進(jìn)一步分析和優(yōu)化的代碼。不可能直接從 Swift 中間語(yǔ)言生成機(jī)器代碼,因此 SIL 經(jīng)歷了一系列轉(zhuǎn)變到 LLVM 中間表示。

后端以中間代碼作為輸入,進(jìn)行行架構(gòu)無(wú)關(guān)的代碼優(yōu)化,接著針對(duì)不同架構(gòu)生成不同的匯編代碼。

Assembler

Assembler 翻譯開(kāi)發(fā)者可讀的匯編代碼為可重定位的機(jī)器碼,最終生成包含數(shù)據(jù)和代碼的 Mach-O 文件。

機(jī)器代碼是一種數(shù)字語(yǔ)言,表示一組指令,可以直接由 CPU 執(zhí)行。它被是可重定位的,因?yàn)闊o(wú)論目標(biāo)文件的地址空間在哪,它將執(zhí)行的指令相對(duì)地址。

Mach-O 文件是一種特殊的 iOS 和 MacOS 文件格式,操作系統(tǒng)用它來(lái)描述對(duì)象文件、可執(zhí)行文件和庫(kù)。它是一串字節(jié)組合形成的有意義的程序塊,將運(yùn)行在 ARM 處理器上或英特爾處理器。

Linker

鏈接器將各種對(duì)象文件和庫(kù)鏈接合并為一個(gè)可以在 iOS 或 macOS 系統(tǒng)上運(yùn)行的 Mach-O 可執(zhí)行文件。鏈接器主要有兩種文件作為輸入,包括這些對(duì)象文件的匯編程序和庫(kù)的幾種類(lèi)型(.dylib, .tbd 和 .a)。

鏈接器的作用,就是完成變量、函數(shù)符號(hào)和其地址綁定這樣的任務(wù)。例如,如果在代碼中使用 printf , 鏈接器鏈接這個(gè)符號(hào)和 libc 庫(kù) printf 函數(shù)實(shí)現(xiàn)的地方。通常在編譯階段通過(guò)創(chuàng)建符號(hào)表來(lái)解決不同對(duì)象文件和庫(kù)的引用。

Loader

最后,加載程序是操作系統(tǒng)的一部分,將一個(gè)程序加載到內(nèi)存中,并運(yùn)行執(zhí)行它。加載程序負(fù)責(zé)分配運(yùn)行程序內(nèi)存空間和初始化寄存器所需的初始狀態(tài)。

總結(jié)

作為 iOS 和 macOS 開(kāi)發(fā)者我們主要使用 Xcode Build System 編譯構(gòu)建我們的應(yīng)用程序。它的主要組件是:預(yù)處理、編譯器、匯編器、連接器和加載程序。Xcode 使用不同的編譯器(swiftc 和 clang)編譯 Swift 和 Objective-C。

對(duì)于初學(xué)者和經(jīng)驗(yàn)豐富的開(kāi)發(fā)人員來(lái)說(shuō)學(xué)習(xí)掌握 編譯原理基礎(chǔ)知識(shí)都頗有益處,這里有一張宮文學(xué)老師《編譯原理之美》的關(guān)于編譯知識(shí)結(jié)構(gòu)體系的思維導(dǎo)圖,可以拿來(lái)對(duì)每個(gè)知識(shí)點(diǎn)系統(tǒng)學(xué)習(xí)。

作為一個(gè)開(kāi)發(fā)者,有一個(gè)學(xué)習(xí)的氛圍跟一個(gè)交流圈子特別重要,這是一個(gè)我的iOS交流群:519832104 不管你是小白還是大牛歡迎入駐,分享經(jīng)驗(yàn),討論技術(shù),大家一起交流學(xué)習(xí)成長(zhǎng)!

另附上一份各好友收集的大廠面試題,需要iOS開(kāi)發(fā)學(xué)習(xí)資料、面試真題,可以添加iOS開(kāi)發(fā)學(xué)習(xí)交流群,進(jìn)群可自行下載!

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多