簡單聊聊Xcode 中的編譯過程和編譯原理

一般可以將編程語言分為兩種,編譯語言直譯式語言

像C++,Objective C都是編譯語言。編譯語言在執(zhí)行的時候,必須先通過編譯器生成機器碼,機器碼可以直接在CPU上執(zhí)行,所以執(zhí)行效率較高。

JavaScript,Python都是直譯式語言。直譯式語言不需要經(jīng)過編譯的過程,而是在執(zhí)行的時候通過一個中間的解釋器將代碼解釋為CPU可以執(zhí)行的代碼。所以,較編譯語言來說,直譯式語言效率低一些,但是編寫的更靈活。

iOS開發(fā)目前的常用語言是:Objective和Swift。二者都是編譯語言,換句話說都是需要編譯才能執(zhí)行的。二者的編譯都是依賴于Clang + LLVM.

基本的編譯過程大概分為四個步驟:

1.預(yù)處理(Pre-process):把宏替換,刪除注釋,展開頭文件,產(chǎn)生.i文件。

2.編譯(Compliling):把之前的.i文件轉(zhuǎn)換成匯編語言,產(chǎn)生.s文件。

3.匯編(Asembly):把匯編語言文件轉(zhuǎn)換為機器碼文件,產(chǎn)生.o文件。

4.鏈接(Link):對.o文件中的對于其他的庫的引用的地方進行引用,生成最后的可執(zhí)行文件(同時也包括多個.o文件進行 link)。

在 xcode 中可以通過?Build phases,Build settings以及?Build rules來進行控制。

Build phases主要是用來控制從源文件到可執(zhí)行文件的整個過程的,所以應(yīng)該說是面向源文件的,包括編譯哪些文件,以及在編譯過程中執(zhí)行一些自定義的腳本什么的。

Build rules主要是用來控制如何編譯某種類型的源文件的,假如說相對某種類型的原文件進行特定的編譯,那么就應(yīng)該在這里進行編輯了。同時這里也會大量的運用一些 xcode 中的環(huán)境變量,完整的官方文檔在這里:Build Settings Reference

Build settings則是對編譯工作的細節(jié)進行設(shè)定,在這個窗口里可以看見大量的設(shè)置選項,從編譯到打包再到代碼簽名都有,這里要注意 settings 的 section 分類,同時一般通過右側(cè)的 inspector 就可以很好的理解選項的意義了。

最后,要說一下我們的工程文件.pbxproj,以上的所有的這些選項都保存在這個文件中。當然也包括 target 的信息,項目所有文件的信息,這個文件是一個文本文件,可以用文本編輯器打開。里頭的內(nèi)容基本是可讀性比較強的?;镜乃悸泛苊嫦?qū)ο?,每個東西都有屬性,如果屬性是另一個對象,值就是那個對象的一個『引用』,就是一串數(shù)字(唯一的)作為表示。每個對象都有這樣的引用。

不管是OC還是Swift,都是采用Clang作為編譯器前端,LLVM(Low level vritual machine)作為編譯器后端.

1.編譯器前端

編譯器前端的任務(wù)是進行:語法分析,語義分析,生成中間代碼(intermediate representation )。在這個過程中,會進行類型檢查,如果發(fā)現(xiàn)錯誤或者警告會標注出來在哪一行。

2.編譯器后端

編譯器后端會進行機器無關(guān)的代碼優(yōu)化,生成機器語言,并且進行機器相關(guān)的代碼優(yōu)化。iOS的編譯過程,后端的處理如下

LVVM優(yōu)化器會進行BitCode的生成,鏈接期優(yōu)化等等。

LLVM機器碼生成器會針對不同的架構(gòu),比如arm64等生成不同的機器碼。

執(zhí)行一次XCode build的流程

·? 編譯信息寫入輔助文件,創(chuàng)建編譯后的文件架構(gòu)(name.app)

· 處理文件打包信息,例如在debug環(huán)境下

Entitlements:{

? ????? "application-identifier" = "app的bundleid";? ? "aps-environment" = development;

????}

·?執(zhí)行CocoaPod編譯前腳本?

? ??例如對于使用CocoaPod的工程會執(zhí)行CheckPods Manifest.lock

·?編譯各個.m文件,使用CompileC和clang命令。

· 鏈接需要的Framework,例如Foundation.framework,AFNetworking.framework,ALiPay.fframework

·編譯xib文件

·拷貝xib,圖片等資源文件到結(jié)果目錄

·編譯ImageAssets

·處理info.plist

·??執(zhí)行CocoaPod腳本

·拷貝Swift標準庫

·創(chuàng)建.app文件和對其簽名

如何提高項目編譯速度

一.查看編譯時間

對于XCode 8,關(guān)閉XCode,終端輸入以下指令

$ defaults writecom.apple.dt.XcodeShowBuildOperationDuration YES

然后,重啟XCode,然后編譯,就會顯示出編譯時間。

二 .代碼層面的優(yōu)化

? ? 1.forward declaration?所謂forward declaration,就是@class CLASSNAME,而不是#import CLASSNAME.h。這樣,編譯器能大大提高#import的替換速度。

????2.?對常用的工具類進行打包(Framework/.a). 打包成Framework或者靜態(tài)庫,這樣編譯的時候這部分代碼就不需要重新編譯了。? ??

? ? 3.常用頭文件放到預(yù)編譯文件里.? XCode的pch文件是預(yù)編譯文件,這里的內(nèi)容在執(zhí)行XCode build之前就已經(jīng)被預(yù)編譯,并且引入到每一個.m文件里了。

? ?4.Debug模式下,不生成dsym文件.dysm文件里存儲了調(diào)試信息,在Debug模式下,我們可以借助XCode和LLDB進行調(diào)試。所以,不需要生成額外的dsym文件來降低編譯速度。

? ?5.Debug開啟Build Active Architecture Only.在XCode -> Build Settings -> Build Active Architecture Only 改為YES。這樣做,可以只編譯當前的版本,比如arm7/arm64等等,記得只開啟Debug模式。這個選項在高版本的XCode中自動開啟了。

? ?6.ebug模式下,關(guān)閉編譯器優(yōu)化

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容