android blueprint介紹

一 blueprint介紹

之前我們介紹,blueprint負(fù)責(zé)解析Android.bp文件內(nèi)容,我的理解是blueprint類似一個處理相關(guān)語法的庫文件,soong則是定義具體如何處理相應(yīng)的語法以及命令實現(xiàn)。也就是soong借助于blueprint定義Android.bp語法,完成Android.bp的解析。

Blueprint is a meta-build system that reads in Blueprints files that describe modules that need to be built, and produces a Ninja (http://martine.github.io/ninja/) manifest describing the commands that need to be run and their dependencie。

通過上面的定義,blueprint將blueprint file轉(zhuǎn)換為ninja,如果要使用定制語法的話,需要使用golang自己進行自定義。blueprint語法如下:

cc_library {

name: "cmd",

srcs: [

"main.c",

],

deps: [

"libc",

],

}

subdirs = ["subdir1", "subdir2"]

Once all modules are read, Blueprint calls any registered Mutators, in registration order. Mutators can visit each module top-down or bottom-up, and modify them as necessar。每個目標(biāo)已Module為單位,對于module的處理有注冊mutator規(guī)則來處理,

After all Mutators have run, each module is asked to generate build rules based on property values, and then singletons can generate any build rules from the output of all modules.

還有一個singleton名詞,針對所有的module生成build規(guī)則。

二 目錄介紹

blueprint的目錄結(jié)構(gòu)如下:

bootstrapThe Blueprint bootstrapping mechanism is intended to enable building a source tree with minimal prebuilts.

bootstrap/bpdoc

bootstrap/bpglo bbpglob is the command line tool that checks if the list of files matching a glob has changed, and only updates the output file list if it has changed.bootstrap/minibp

bpfmt

bpmodify

deptools

gotestmain

gotestrunner

loadplugins

microfactory?Microfactory is a tool to incrementally compile a go program.microfactory/main

parser

pathtools

proptools

這里面比較重要的有bootstarp目錄,android需要先將blueprint和soong進行編譯,然后才能識別項目中的android.bp文件,如何生成blueprint和soong,就在bootstarp中實現(xiàn),具體的實現(xiàn)步驟如下:

step 1: 通過build/blueprint/http://build.ninja.in生成out/soong/.minibootstrap/build.ninja,其中out/soong/.minibootstrap/build.ninja用來生成minibp

step 2: minibp分析Android.bp用來生成out/soong/.bootstrap/build.ninja。其中的語法如下:

build ${g.bootstrap.buildDir}/.bootstrap/build.ninja: g.bootstrap.build.ninja $

${g.bootstrap.srcDir}/Android.bp | ${builder}

builder = ${g.bootstrap.BinDir}/minibp

extra = --build-primary

default ${g.bootstrap.buildDir}/.bootstrap/build.ninja

step 3:生成out/soong/build.ninja文件

build ${g.bootstrap.buildDir}/build.ninja: g.bootstrap.build.ninja $

${g.bootstrap.srcDir}/Android.bp | ${builder}

builder = ${g.bootstrap.BinDir}/soong_build

extra = $ -t

default ${g.bootstrap.buildDir}/build.ninja

out/soong/build.ninja是通過soong_build分析android目錄下Android.bp文件生成。

build ${g.bootstrap.BinDir}/soong_build: g.bootstrap.cp $

${g.bootstrap.buildDir}/.bootstrap/soong_build/obj/a.out || $

${g.bootstrap.buildDir}/.bootstrap/soong-android/test/test.passed $

${g.bootstrap.buildDir}/.bootstrap/soong-cc-config/test/test.passed $

${g.bootstrap.buildDir}/.bootstrap/soong-cc/test/test.passed $

${g.bootstrap.buildDir}/.bootstrap/soong-java/test/test.passed $

${g.bootstrap.buildDir}/.bootstrap/soong-python/test/test.passed

default ${g.bootstrap.BinDir}/soong_build

通過上面的分析可以得出,bootstarp主要作用就是編譯blueprint soong以及生成out/soong/build.ninja文件。因此bootstrap有個別稱叫 "primary builder".

結(jié)合之前的分析,大體執(zhí)行流程是

- Runs microfactory.bash to build minibp microfactory.bash在soong_ui.bash中執(zhí)行

- Runs the .minibootstrap/build.ninja to build .bootstrap/build.ninja

- Runs .bootstrap/build.ninja to build and run the primary builder

上面兩步對應(yīng)的函數(shù)為runSoongBootstrap 和 runSoong(具體執(zhí)行soong.bash)

- Runs build.ninja to build your code runNinja執(zhí)行

看soong_build,用來生成最后的build.ninja,依賴blueprint 和soong等相關(guān)庫。

bootstrap_go_binary {

name: "soong_build",

deps: [

"blueprint",

"blueprint-bootstrap",

"soong",

"soong-android",

"soong-env",

],

srcs: [

"main.go",

],

primaryBuilder: true,

}

三 blueprint重要函數(shù)

blueprint有幾個函數(shù)比較重要,比如自定義一個module

my_module {

name: "myName",

foo: "my foo string",

bar: ["my", "bar", "strings"],

}

可以使用如下函數(shù)進行自定義規(guī)則

func (c *Context) RegisterModuleType(name?string, factory?ModuleFactory)

type myModule struct {

properties struct {

Foo string

Bar []string

}

}

func NewMyModule() (blueprint.Module, []interface{}) {

module := new(myModule)

properties := &module.properties

return module, []interface{}{properties}

}

func main() {

ctx := blueprint.NewContext()

ctx.RegisterModuleType("my_module", NewMyModule)

// ...

}

blueprint具體的步驟如下:

A Context contains all the state needed to parse a set of Blueprints files

and generate a Ninja file. The process of generating a Ninja file proceeds

through a series of four phases. Each phase corresponds with a some methods

on the Context object

Phase Methods

------------ -------------------------------------------

1. Registration RegisterModuleType, RegisterSingletonType

2. Parse ParseBlueprintsFiles, Parse

3. Generate ResolveDependencies, PrepareBuildActions

4. Write WriteBuildFile

The registration phase prepares the context to process Blueprints files

containing various types of modules. The parse phase reads in one or more

Blueprints files and validates their contents against the module types that

have been registered. The generate phase then analyzes the parsed Blueprints

contents to create an internal representation for the build actions that must

be performed. This phase also performs validation of the module dependencies

and property values defined in the parsed Blueprints files. Finally, the

write phase generates the Ninja manifest text based on the generated build

actions.

可以看到在soong下每個init函數(shù)下都有 RegisterModuleType或者 RegisterSingletonType進行module注冊。具體的流程在build/blueprint/bootstrap/command.go

func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps?...string) {

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))

ctx.RegisterSingletonType("glob", globSingletonFactory(ctx))

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

if len(errs) > 0 {

fatalErrors(errs)

}

errs = ctx.ResolveDependencies(config)

extraDeps, errs := ctx.PrepareBuildActions(config)

err := ctx.WriteBuildFile(buf)

soong_build和minibp的入口都是在上面的Main中,只不過minibp規(guī)則沒有soong復(fù)雜,soong_build添加了soong中定義的規(guī)則。

最后編輯于
?著作權(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)容