android blueprint介绍

一 blueprint介绍

之前我们介绍,blueprint负责解析Android.bp文件内容,我的理解是blueprint类似一个处理相关语法的库文件,soong则是定义具体如何处理相应的语法以及命令实现。也就是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转换为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。每个目标已Module为单位,对于module的处理有注册mutator规则来处理,

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规则。

二 目录介绍

blueprint的目录结构如下:

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中实现,具体的实现步骤如下:

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".

结合之前的分析,大体执行流程是

- Runs microfactory.bash to build minibp microfactory.bash在soong_ui.bash中执行

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

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

上面两步对应的函数为runSoongBootstrap 和 runSoong(具体执行soong.bash)

- Runs build.ninja to build your code runNinja执行

看soong_build,用来生成最后的build.ninja,依赖blueprint 和soong等相关库。

bootstrap_go_binary {

name: "soong_build",

deps: [

"blueprint",

"blueprint-bootstrap",

"soong",

"soong-android",

"soong-env",

],

srcs: [

"main.go",

],

primaryBuilder: true,

}

三 blueprint重要函数

blueprint有几个函数比较重要,比如自定义一个module

my_module {

name: "myName",

foo: "my foo string",

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

}

可以使用如下函数进行自定义规则

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函数下都有 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规则没有soong复杂,soong_build添加了soong中定义的规则。

你可能感兴趣的:(android blueprint介绍)