Android blueprint 代碼分析

? ?前面的文檔已經(jīng)大體介紹了blueprint苟呐,本篇則通過代碼分析blueprint讓大家更清楚的了解blueprint以及其語法讲弄。以及基于blueprint的語法生成的minibp和soong_build断医。

? blueprint主要是解析Blueprint文件翻譯成ninja語法文件萌腿。以build/blueprint/Blueprints文件內(nèi)容為例嘉竟,我們要解析的語法如下:

bootstrap_core_go_binary(

? ? name = "bpglob",

? ? deps = ["blueprint-pathtools"],

? ? srcs = ["bootstrap/bpglob/bpglob.go"],

)

生成的對應(yīng)的ninja文件如下:

? 可以看到最終策劃你改成的bpglob需要三部生成蓄坏,第一部編譯成bpblob.a其中依賴于bluprint-pathtools和bpglob.go,第二部是連接成a.out,第三部通過cp到對應(yīng)的bin的目錄下枫慷,完成一個module的解析让蕾。


? 解析一個Blueprint文件需要三步:

?第一步:注冊module也就是bootstrap_core_go_binary和內(nèi)容處理規(guī)則,如deps等或听。

? 第二步:解析Blueprint文件探孝,進行語法分析

? 第三步:分析module之間的依賴規(guī)則

? 第四步: 規(guī)則生成

? 第五步: 寫ninjia文件完成文件生成


第一步:注冊

? 整個解析過程需要一個context結(jié)構(gòu)體進行跟蹤,所以minibp和soong_build的入口都是如下誉裆,創(chuàng)建一個context

build/blueprint/bootstrap/bootstrap.go

ctx := blueprint.NewContext()

func NewContext() *Context {

ctx := &Context{

moduleFactories:? make(map[string]ModuleFactory),

moduleNames:? ? ? make(map[string]*moduleGroup),

moduleInfo:? ? ? make(map[Module]*moduleInfo),

moduleNinjaNames: make(map[string]*moduleGroup),

globs:? ? ? ? ? ? make(map[string]GlobPath),

fs:? ? ? ? ? ? ? pathtools.OsFs,

}

ctx.RegisterBottomUpMutator("blueprint_deps", blueprintDepsMutator)

return ctx

}

moduleFactories: 存儲著我們后面注冊的module如“bootstrap_core_go_binary”

moduleNames:

moduleInfo:

moduleNinjaNames:

globs: glob文件

下一步進入build/blueprint/bootstrap/command.go的Main中

? ? ctx.RegisterBottomUpMutator("bootstrap_plugin_deps", pluginDeps)

? ? ctx.RegisterModuleType("bootstrap_go_package",newGoPackageModuleFactory(bootstrapConfig))

ctx.RegisterModuleType("bootstrap_core_go_binary",newGoBinaryModuleFactory(bootstrapConfig, StageBootstrap))

ctx.RegisterModuleType("bootstrap_go_binary", newGoBinaryModuleFactory(bootstrapConfig, StagePrimary))

ctx.RegisterModuleType("blueprint_go_binary", newGoBinaryModuleFactory(bootstrapConfig, StageMain))

?ctx.RegisterTopDownMutator("bootstrap_stage", propagateStageBootstrap)

?ctx.RegisterSingletonType("bootstrap", newSingletonFactory(bootstrapConfig))

上面這些對應(yīng)的是blueprint的第一步顿颅,將bootstrap_core_go_binary注冊成modulefactory到config中去,具體的module結(jié)構(gòu)如下:

? ? ? 在這個過程中還有幾個注冊要注意一下RegisterBottomUpMutatorRegisterTopDownMutator足丢,從這兩個函數(shù)的字面意思看一個是TopDown從上往下粱腻,一個是BootomUP從下往上,初步推斷TopDown可能是我們解決moudle依賴斩跌,從上往下定義我們的mutator(變異)绍些,也就是我們的特殊規(guī)則,“RegisterTopDownMutator registers a mutator that will be invoked to propagate dependency info top-down between Modules. Each registered mutator is invoked in registration order (mixing TopDownMutators and BottomUpMutators) once per Module, and the invocation on any module willhave returned before it is in invoked on any of its dependencies.”從解釋看應(yīng)該是處理依賴規(guī)則而產(chǎn)生的耀鸦。而BottomUP柬批,從函數(shù)的解釋來看 “ RegisterBottomUpMutator registers a mutator that will be invoked to split Modules into variants. Each registered mutator is invoked in registration order (mixing TopDownMutators and BottomUpMutators) once per Module, will not be invoked on a module until the invocations on all of the modules dependencies have returned.”比如在Android.bp中大名鼎鼎的arch就屬于BotoomUP mutator,在arch使用中可以根據(jù)需要編譯成不同的指令袖订,這個應(yīng)該是針對一個module分成幾個目標時使用氮帐。還有一個RegisterSingletonType,這個主要是在生成build規(guī)則時使用 “RegisterSingletonType registers a singleton type that will be invoked to generate build actions. Each registered singleton type is instantiated and and invoked exactly once as part of the generate phase. Each registered singleton is invoked in registration order.”需要實現(xiàn)GenerateBuildActions洛姑,用來生成具體的規(guī)則

第二步 分析Blueprint文件

deps, errs := ctx.ParseBlueprintsFiles(bootstrapConfig.topLevelBlueprintsFile)

這個函數(shù)的主要作用是分析blueprint文件上沐,為每個模塊創(chuàng)建var module *moduleInfo,最后通過newErrs := c.addModule(module)添加到config中去楞艾。addModule主要實現(xiàn)如下参咙,可以看到

name := module.logicModule.Name()

c.moduleInfo[module.logicModule] = module

group := &moduleGroup{

name:? ? ? name,

ninjaName: ninjaName,

modules:? []*moduleInfo{module},

}

module.group = group

c.moduleNames[name] = group

c.moduleNinjaNames[ninjaName] = group

c.moduleGroups = append(c.moduleGroups, group)

第三步: 分析依賴

ResolveDependencies的主要作用是分析依賴的有效性,不要有循環(huán)依賴产徊,runMutators運行之前注冊的mutators

func (c *Context) ResolveDependencies(config interface{}) []error {

errs := c.updateDependencies()

errs = c.runMutators(config)

c.cloneModules()

c.dependenciesReady = true

return nil

}

這個函數(shù)包含三個調(diào)用昂勒,updateDependencies()這個函數(shù)主要是編譯每個module以及其依賴,檢查是否有循環(huán)依賴舟铜,如果有循環(huán)報錯。

在moduleinfo中通過一個雙向鏈表奠衔,建立之間的依賴關(guān)系


第二個調(diào)用就是runMutators谆刨,這個比較重要

func (c *Context) runMutators(config interface{}) (errs []error) {

for _, mutator := range mutators {

if mutator.topDownMutator != nil {

errs = c.runMutator(config, mutator, topDownMutator)

} else if mutator.bottomUpMutator != nil {

errs = c.runMutator(config, mutator, bottomUpMutator)

} else {

}

主要是調(diào)用topDownMutator和bottomUpMutator塘娶。這個比較難理解但是可以通過舉例來幫助理解,在Android.bp中“arch”屬于bootomupmutator痊夭,通過規(guī)則將目標分成幾個variants刁岸。 而topDownMutator則是從上往下依照dep訪問各個模塊并運行對應(yīng)規(guī)則。

第三個調(diào)用是cloneModules()她我,為每個module創(chuàng)建備份虹曙,這個比較簡單。

第四步:生成規(guī)則

生成規(guī)則函數(shù)在PrepareBuildActions()中番舆,其中規(guī)則的生成主要是由下面這個函數(shù)生成

depsModules, errs := c.generateModuleBuildActions(config, liveGlobals)

if len(errs) > 0 {

return nil, errs

}

generateModuleBuildActions中酝碳,通過調(diào)用具體的Module里面的mctx.module.logicModule.GenerateBuildActions(mctx)生成具體的規(guī)則,比較C語言 go語言的編譯規(guī)則等恨狈。

第五步: 生成目標文件(ninja文件)

最后一步就是寫ninjia文件疏哗,這個比較簡單,具體代碼如下

buf := bytes.NewBuffer(nil)

err := ctx.WriteBuildFile(buf)

if err != nil {

fatalf("error generating Ninja file contents: %s", err)

}

const outFilePermissions = 0666

err = ioutil.WriteFile(outFile, buf.Bytes(), outFilePermissions)

if err != nil {

fatalf("error writing %s: %s", outFile, err)

}

至此禾怠,一個blueprintfile到ninja文件就生成了返奉,我們可以使用ninja對我們的工程進行編譯了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吗氏,一起剝皮案震驚了整個濱河市芽偏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌弦讽,老刑警劉巖哮针,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異坦袍,居然都是意外死亡十厢,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門捂齐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛮放,“玉大人,你說我怎么就攤上這事奠宜“洌” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵压真,是天一觀的道長娩嚼。 經(jīng)常有香客問我,道長滴肿,這世上最難降的妖魔是什么岳悟? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上贵少,老公的妹妹穿的比我還像新娘呵俏。我一直安慰自己,他們只是感情好滔灶,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布普碎。 她就那樣靜靜地躺著,像睡著了一般录平。 火紅的嫁衣襯著肌膚如雪麻车。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天斗这,我揣著相機與錄音动猬,去河邊找鬼。 笑死涝影,一個胖子當(dāng)著我的面吹牛枣察,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播燃逻,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼序目,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了伯襟?” 一聲冷哼從身側(cè)響起猿涨,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎姆怪,沒想到半個月后叛赚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡稽揭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年俺附,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溪掀。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡事镣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出揪胃,到底是詐尸還是另有隱情璃哟,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布喊递,位于F島的核電站随闪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏骚勘。R本人自食惡果不足惜铐伴,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盛杰,春花似錦挽荡、人聲如沸藐石。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽于微。三九已至逗嫡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間株依,已是汗流浹背驱证。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留恋腕,地道東北人抹锄。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像荠藤,于是被迫代替她去往敵國和親伙单。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一 blueprint介紹 之前我們介紹哈肖,blueprint負責(zé)解析Android.bp文件內(nèi)容吻育,我的理解是blu...
    Little熊貓閱讀 5,619評論 0 5
  • 一 概述 1.1 編譯系統(tǒng)變化 隨著android工程越來越大,包含的module越來越多淤井,以makefile...
    Little熊貓閱讀 30,481評論 4 15
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理布疼,服務(wù)發(fā)現(xiàn),斷路器币狠,智...
    卡卡羅2017閱讀 134,672評論 18 139
  • 22年12月更新:個人網(wǎng)站關(guān)停游两,如果仍舊對舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,184評論 22 257
  • 一來二去混人緣 三番四次強買單 請來五六舊時友 七有八九給薄面 十在難安 【本文由“愛上瘦朵朵”發(fā)布,2017年0...
    時尚瘦身520閱讀 189評論 0 0