一 概述 1.1 編譯系統(tǒng)變化 隨著android工程越來越大,,包含的module越來越多,,以makefile組織的項目編譯花費的時間越來越多。谷歌在7.0開始引入了ninja進行編譯系統(tǒng)的組織,。相對于make來說ninja在大的項目管理中速度和并行方面有突出的優(yōu)勢,,因此谷歌采用了ninja來取代之前使用的make。但是現(xiàn)有的android項目還是由makefile組織,,因此谷歌引入了kati將makefile翻譯成ninja文件,。 從Android 7.0開始,android的編譯系統(tǒng)發(fā)生了變化,,之前依賴Makefile組織編譯系統(tǒng),,從7.0開始逐步引入了kati soong(optional未正式使用,需要USE_SOONG=true開啟),,將Android.mk文件轉(zhuǎn)化成ninja文件,,使用ninja文件對編譯系統(tǒng)進行管理。 從8.0開始,,android 引入了Android.bp文件來替代之前的Android.mk文件,,不同于Android.mk,Android.bp只是純粹的配置文件,,不包括分支,、循環(huán)等流程控制,。在android項目上如何進行選擇編譯、解析配置,、轉(zhuǎn)換成ninja等,,Soong就被創(chuàng)造出來,將Android.bp轉(zhuǎn)換為ninja文件進行管理,。 同時,,Soong還會編譯長生一個androidmk命令可以手動將Android.mk轉(zhuǎn)換成Android.bp文件。 1.2 代碼位置 Kati的位置是在build/kati/中,,平臺也自帶編譯好的ckati Soong的位置在build/soong,它和build/blueprint同時期作用,,他們之間的系統(tǒng)關(guān)系如下: Blueprint更像是一個庫,專門來翻譯blueprint文件,,關(guān)于Blueprint文件格式可以參考build/blueprint/Blueprints文件,,soong是在blueprint上面的擴展,基于blueprint的語法定制產(chǎn)生Android.bp語法,,解析Android.bp文件生成ninja文件,。 Blueprint和Soong都是有Go語言寫的項目,從7.0開始在prebuilts/go/目錄下新增了go語言的運行環(huán)境,,在編譯是使用,。 1.3 Android ninja組織 在編譯過程中,將所有的android.bp文件搜集成out\soong\build.ninja.d , 并以此為基礎(chǔ)生成out\soong\build.ninja規(guī)則,。 由所有的Android.mk生成build-aosp_arm.ninja文件,。通過combined-aosp_arm.ninja將兩個文件組織起來。 builddir = out include out/build-aosp_arm.ninja include out/soong/build.ninja build out/combined-aosp_arm.ninja: phony out/soong/build.ninja 通過編譯的LOG,,首先搜集所有的bp文件生成build.ninja,,然后搜集所有的mk文件生成build-aosp-arm.ninja文件。 out/soong/.bootstrap/bin/soong_build out/soong/build.ninja out/build-aosp_arm-cleanspec.ninja is missing, regenerating... out/build-aosp_arm.ninja is missing, regenerating... [1/894] including out/soong/Android-aosp_arm.mk ... 經(jīng)過試驗表明,,soong處理后的bp文件生成build.ninja的同時還包含out/soong/Android-aosp_arm.mk,,這個文件是編譯完成后模塊的安裝腳本,負責(zé)將模塊安裝到對應(yīng)位置,。比如我們現(xiàn)在處理的vndk相關(guān)vendor處理就是在這個目錄下進行的。 在out/soong目錄下有兩個文件.minibootstrap/build.ninja 和.bootstrap/build.ninja兩個目錄,。.minibootstrap/build.ninja 主要是用來編譯blueprint和生成.bootstrap/build.ninja,。而.bootstrap/build.ninja主要是生成 soong相關(guān)工具和out/soong/build.ninja文件。 二 編譯流程 2.1 make 流程 當(dāng)我們在android 總目錄下make時,,默認尋找當(dāng)前Makefile并找到all目標進行編譯操作,,這個是默認的make機制。當(dāng)android更換為ninja是,,在總目錄下進行make時進行如何的流程呢,。 同老的make機制一樣,,make找到總目錄下的Makefile $ cat Makefile include build/make/core/main.mk Makefile內(nèi)容沒有改變,同樣是進入到main.mk中,,剛開始幾行有了明顯的變化 ifndef KATI host_prebuilts := linux-x86 ifeq ($(shell uname),Darwin) host_prebuilts := darwin-x86 endif .PHONY: run_soong_ui run_soong_ui: +@prebuilts/build-tools/$(host_prebuilts)/bin/makeparallel --ninja build/soong/soong_ui.bash --make-mode $(MAKECMDGOALS) .PHONY: $(MAKECMDGOALS) $(sort $(MAKECMDGOALS)) : run_soong_ui @#empty else # KATI 其中MAKECMDGOALS這個命名是make執(zhí)行時后面的參數(shù)賦值,,也就是我們執(zhí)行任何make的時候都是執(zhí)行run_soong_ui這個目標,這樣android從Makefile切換為soong進行了編譯流程,,后面跟make就沒有關(guān)系了,。 2.2 mm流程 當(dāng)我們單獨編譯某個模塊時,在這個模塊目錄下輸入mm命令進行編譯,,在build/envsetup.sh看一下具體實現(xiàn)過程: function mm() { local T=$(gettop) local DRV=$(getdriver $T) # If we're sitting in the root of the build tree, just do a # normal build. if [ -f build/soong/soong_ui.bash ]; then _wrap_build $DRV $T/build/soong/soong_ui.bash --make-mode $@ else ONE_SHOT_MAKEFILE=$M _wrap_build $DRV $T/build/soong/soong_ui.bash --make-mode $MODULES $ARGS 流程上同make差不多只不過目標,,是單獨模塊組成。 同時在mm一個單獨模塊是,,生成獨立的ninja文件 combined--aosp_arm-frameworks_native_libs_gui_Android.mk.ninja 和 build- aosp_arm-frameworks_native_libs_gui_Android.mk.ninja 2.3 Soong流程 在介紹soong編譯流程之前,,先介紹幾個命令以便我們后續(xù)編譯流程的理解,在out/soong/host/linux-x86/bin目錄下,,有幾個命令是soong用到的,, soong_ui: soong編譯的入口 androidmk: 后面的Android.bp用到,Android.mk一鍵轉(zhuǎn)換為android.bp 在out/soong/.bootstrap/bin目錄下有幾個 out/soong/.bootstrap/bin$ ls bpglob gotestmain gotestrunner loadplugins minibp soong_build soong_env minibp: 在bootstrap是用到 soong_build :這個很重要,,主要是將bp文件轉(zhuǎn)換為ninja文件 通過上文的分析,,當(dāng)我們make命令敲下去的時候,主要是執(zhí)行 prebuilts/build-tools/$(host_prebuilts)/bin/makeparallel --ninja build/soong/soong_ui.bash --make-mode $(MAKECMDGOALS) soong_ui.bash腳本主要是執(zhí)行如下: build_go soong_ui android/soong/cmd/soong_ui //生成soong_ui命令 cd ${TOP} exec "$(getoutdir)/soong_ui" "$@" //soong_ui入口,,執(zhí)行soong流程 比如我們執(zhí)行make systemimage,,到這邊就變成了soong_ui –make-mode systemimage soong_ui代碼在build/soong/cmd/soong_ui/main.go 下,主要流程如下: func main() { log := logger.New(os.Stderr) defer log.Cleanup() if len(os.Args) < 2 || !inList("--make-mode", os.Args) { log.Fatalln("The `soong` native UI is not yet available.") } build.Build(buildCtx, config, build.BuildAll) 主要執(zhí)行soong/ui/build/build.go,,從build.go就可以看到執(zhí)行soong的大體流程 看一下各個流程 Step 1: runMakeProductConfig 主要配置編譯參數(shù) Step 2: runSoongBootstrap 這個主要是為后面編譯工具的使用 ckati soong做環(huán)境搭建 runSoong 對工具進行編譯 /.minibootstrap/build.ninja - Run minibp to generate .bootstrap/build.ninja (Primary stage) - Run minibp to generate .minibootstrap/build.ninja.in /.bootstrap/build.ninja - Build any bootstrap_go_binary rules and dependencies -- usually the primary builder and any build or runtime dependencies. - Run the primary builder to generate build.ninja 同時還會生成out/soong/build.ninja Step 3: 運行step2生成的ckati,,搜集所有的Android.mk文件生成ninja文件,也就是前面提到的 out/build-aosp_arm.ninja Step4: 將out/soong/build.ninja 和out/build-aosp_arm.ninja 合成為combined-aosp_arm.ninja Step5: 運行runNinja 解釋combined-aosp_arm.ninja 運行編譯過程 三 ninja使用我們可以使用ninja 和生成的combined-aosp_arm.ninja 編譯工程或者某一個module. $ ./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-aosp_arm.ninja 同在工程中make一個效果 編譯systemimage或者bootimage $ ./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-aosp_arm.ninja systemimage 上面這樣做的目的是,,不用重新生成ninja文件,,直接進行編譯,節(jié)省部分時間,。這是在沒有修改Makefile的前提下一 概述 1.1 編譯系統(tǒng)變化 隨著android工程越來越大,,包含的module越來越多,以makefile組織的項目編譯花費的時間越來越多,。谷歌在7.0開始引入了ninja進行編譯系統(tǒng)的組織,。相對于make來說ninja在大的項目管理中速度和并行方面有突出的優(yōu)勢,因此谷歌采用了ninja來取代之前使用的make,。但是現(xiàn)有的android項目還是由makefile組織,,因此谷歌引入了kati將makefile翻譯成ninja文件。 從Android 7.0開始,,android的編譯系統(tǒng)發(fā)生了變化,,之前依賴Makefile組織編譯系統(tǒng),,從7.0開始逐步引入了kati soong(optional未正式使用,需要USE_SOONG=true開啟),,將Android.mk文件轉(zhuǎn)化成ninja文件,,使用ninja文件對編譯系統(tǒng)進行管理。 從8.0開始,,android 引入了Android.bp文件來替代之前的Android.mk文件,,不同于Android.mk,Android.bp只是純粹的配置文件,,不包括分支,、循環(huán)等流程控制。在android項目上如何進行選擇編譯,、解析配置,、轉(zhuǎn)換成ninja等,Soong就被創(chuàng)造出來,,將Android.bp轉(zhuǎn)換為ninja文件進行管理,。 同時,Soong還會編譯長生一個androidmk命令可以手動將Android.mk轉(zhuǎn)換成Android.bp文件,。 1.2 代碼位置 Kati的位置是在build/kati/中,,平臺也自帶編譯好的ckati Soong的位置在build/soong,它和build/blueprint同時期作用,他們之間的系統(tǒng)關(guān)系如下: Blueprint更像是一個庫,,專門來翻譯blueprint文件,,關(guān)于Blueprint文件格式可以參考build/blueprint/Blueprints文件,soong是在blueprint上面的擴展,,基于blueprint的語法定制產(chǎn)生Android.bp語法,,解析Android.bp文件生成ninja文件。 Blueprint和Soong都是有Go語言寫的項目,,從7.0開始在prebuilts/go/目錄下新增了go語言的運行環(huán)境,,在編譯是使用。 1.3 Android ninja組織 在編譯過程中,,將所有的android.bp文件搜集成out\soong\build.ninja.d , 并以此為基礎(chǔ)生成out\soong\build.ninja規(guī)則,。 由所有的Android.mk生成build-aosp_arm.ninja文件。通過combined-aosp_arm.ninja將兩個文件組織起來,。 builddir = out include out/build-aosp_arm.ninja include out/soong/build.ninja build out/combined-aosp_arm.ninja: phony out/soong/build.ninja 通過編譯的LOG,,首先搜集所有的bp文件生成build.ninja,然后搜集所有的mk文件生成build-aosp-arm.ninja文件,。 out/soong/.bootstrap/bin/soong_build out/soong/build.ninja out/build-aosp_arm-cleanspec.ninja is missing, regenerating... out/build-aosp_arm.ninja is missing, regenerating... [1/894] including out/soong/Android-aosp_arm.mk ... 經(jīng)過試驗表明,soong處理后的bp文件生成build.ninja的同時還包含out/soong/Android-aosp_arm.mk,,這個文件是編譯完成后模塊的安裝腳本,,負責(zé)將模塊安裝到對應(yīng)位置,。比如我們現(xiàn)在處理的vndk相關(guān)vendor處理就是在這個目錄下進行的。 在out/soong目錄下有兩個文件.minibootstrap/build.ninja 和.bootstrap/build.ninja兩個目錄,。.minibootstrap/build.ninja 主要是用來編譯blueprint和生成.bootstrap/build.ninja,。而.bootstrap/build.ninja主要是生成 soong相關(guān)工具和out/soong/build.ninja文件。 二 編譯流程 2.1 make 流程 當(dāng)我們在android 總目錄下make時,,默認尋找當(dāng)前Makefile并找到all目標進行編譯操作,,這個是默認的make機制。當(dāng)android更換為ninja是,,在總目錄下進行make時進行如何的流程呢,。 同老的make機制一樣,make找到總目錄下的Makefile $ cat Makefile include build/make/core/main.mk Makefile內(nèi)容沒有改變,,同樣是進入到main.mk中,,剛開始幾行有了明顯的變化 ifndef KATI host_prebuilts := linux-x86 ifeq ($(shell uname),Darwin) host_prebuilts := darwin-x86 endif .PHONY: run_soong_ui run_soong_ui: +@prebuilts/build-tools/$(host_prebuilts)/bin/makeparallel --ninja build/soong/soong_ui.bash --make-mode $(MAKECMDGOALS) .PHONY: $(MAKECMDGOALS) $(sort $(MAKECMDGOALS)) : run_soong_ui @#empty else # KATI 其中MAKECMDGOALS這個命名是make執(zhí)行時后面的參數(shù)賦值,也就是我們執(zhí)行任何make的時候都是執(zhí)行run_soong_ui這個目標,,這樣android從Makefile切換為soong進行了編譯流程,,后面跟make就沒有關(guān)系了。 2.2 mm流程 當(dāng)我們單獨編譯某個模塊時,,在這個模塊目錄下輸入mm命令進行編譯,,在build/envsetup.sh看一下具體實現(xiàn)過程: function mm() { local T=$(gettop) local DRV=$(getdriver $T) # If we're sitting in the root of the build tree, just do a # normal build. if [ -f build/soong/soong_ui.bash ]; then _wrap_build $DRV $T/build/soong/soong_ui.bash --make-mode $@ else ONE_SHOT_MAKEFILE=$M _wrap_build $DRV $T/build/soong/soong_ui.bash --make-mode $MODULES $ARGS 流程上同make差不多只不過目標,是單獨模塊組成,。 同時在mm一個單獨模塊是,,生成獨立的ninja文件 combined--aosp_arm-frameworks_native_libs_gui_Android.mk.ninja 和 build- aosp_arm-frameworks_native_libs_gui_Android.mk.ninja 2.3 Soong流程 在介紹soong編譯流程之前,先介紹幾個命令以便我們后續(xù)編譯流程的理解,,在out/soong/host/linux-x86/bin目錄下,,有幾個命令是soong用到的, soong_ui: soong編譯的入口 androidmk: 后面的Android.bp用到,,Android.mk一鍵轉(zhuǎn)換為android.bp 在out/soong/.bootstrap/bin目錄下有幾個 out/soong/.bootstrap/bin$ ls bpglob gotestmain gotestrunner loadplugins minibp soong_build soong_env minibp: 在bootstrap是用到 soong_build :這個很重要,,主要是將bp文件轉(zhuǎn)換為ninja文件 通過上文的分析,當(dāng)我們make命令敲下去的時候,,主要是執(zhí)行 prebuilts/build-tools/$(host_prebuilts)/bin/makeparallel --ninja build/soong/soong_ui.bash --make-mode $(MAKECMDGOALS) soong_ui.bash腳本主要是執(zhí)行如下: build_go soong_ui android/soong/cmd/soong_ui //生成soong_ui命令 cd ${TOP} exec "$(getoutdir)/soong_ui" "$@" //soong_ui入口,,執(zhí)行soong流程 比如我們執(zhí)行make systemimage,到這邊就變成了soong_ui –make-mode systemimage soong_ui代碼在build/soong/cmd/soong_ui/main.go 下,,主要流程如下: func main() { log := logger.New(os.Stderr) defer log.Cleanup() if len(os.Args) < 2 || !inList("--make-mode", os.Args) { log.Fatalln("The `soong` native UI is not yet available.") } build.Build(buildCtx, config, build.BuildAll) 主要執(zhí)行soong/ui/build/build.go,,從build.go就可以看到執(zhí)行soong的大體流程 看一下各個流程 Step 1: runMakeProductConfig 主要配置編譯參數(shù) Step 2: runSoongBootstrap 這個主要是為后面編譯工具的使用 ckati soong做環(huán)境搭建 runSoong 對工具進行編譯 /.minibootstrap/build.ninja - Run minibp to generate .bootstrap/build.ninja (Primary stage) - Run minibp to generate .minibootstrap/build.ninja.in /.bootstrap/build.ninja - Build any bootstrap_go_binary rules and dependencies -- usually the primary builder and any build or runtime dependencies. - Run the primary builder to generate build.ninja 同時還會生成out/soong/build.ninja Step 3: 運行step2生成的ckati,搜集所有的Android.mk文件生成ninja文件,,也就是前面提到的 out/build-aosp_arm.ninja Step4: 將out/soong/build.ninja 和out/build-aosp_arm.ninja 合成為combined-aosp_arm.ninja Step5: 運行runNinja 解釋combined-aosp_arm.ninja 運行編譯過程 三 ninja使用我們可以使用ninja 和生成的combined-aosp_arm.ninja 編譯工程或者某一個module. $ ./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-aosp_arm.ninja 同在工程中make一個效果 編譯systemimage或者bootimage $ ./prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-aosp_arm.ninja systemimage 上面這樣做的目的是,,不用重新生成ninja文件,直接進行編譯,節(jié)省部分時間,。這是在沒有修改Makefile的前提下 |
|
來自: astrotycoon > 《待分類》