android blueprint介绍

作者: Little熊猫 | 来源:发表于2018-01-31 09:11 被阅读0次

    一 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介绍

        本文链接:https://www.haomeiwen.com/subject/nlaczxtx.html