本文转载自:

转自:http://note.qidong.name/2017/08/android-blueprint/

Android编译系统中的Android.bp、Blueprint与Soong

本文简单介绍Android Nougat(7.0)中引入的Android.bp,及其相关工具链。

简介

Android.bp,是用来替换Android.mk的配置文件。 它使用Blueprint框架来解析,最终转换成Ninja文件。

与Android.mk不同的是,Android.bp是纯粹的配置文件,不包含分支、循环等流程控制,也不能做算数、逻辑运算。 与此同时,Ninja文件也是如此。 这就产生了一些新的问题与需求——在Android项目上进行选择编译、解析配置、转换成Ninja等——Soong应运而生。 Soong其实就相当于Makefile编译系统的核心,即build/make/core/下面的内容。 它负责提供Android.bp的含义定义与解析,并将之转换为Ninja文件。。

此外,Soong还会编译产生一个androidmk命令,可以手动把Android.mk转换成Android.bp。 这只对无选择、循环等复杂流程控制的Android.mk生效。

BlueprintSoong都是由Golang写的项目。 从Android Nougat开始,prebuilts/go/目录下新增了Golang所需的运行环境,在编译时使用。

Android.bp以及相关支持,从Android Nougat开始加入,从Android Oreo(8.0)开始默认开启。 如果需要在Android Nougat的版本使用,需要在执行编译时添加变量。

make 'USE_SOONG=true'

单独编译blueprint

启用Soong以后,在Android编译最开始的准备阶段,会执行build/soong/soong.bash进行环境准备。 其中会先编译、安装Blueprintout目录下。 也就是说,在编译Android项目时,Android.bp相关工具链会自动编译,无需费神。

Soong是与Android强关联的一个项目,而Blueprint则相对比较独立,可以单独编译、使用。

编译Blueprint,首先要具备Golang环境。 然后,按照以下步骤执行命令。

  1. go get github.com/google/blueprint
  2. cd $GOPATH/src/github.com/google/blueprint
  3. ./bootstrap.bash
  4. ./blueprint.bash
  5. ls bin

在新生成的bin目录中,包含4个可执行文件:

  • bpfmt
  • bpmodify
  • microfactory
  • minibp

由于文档较少,甚至连帮助命令都不包括命令的描述,所以其作用只能望文生义。

工具链关系

Android.mk、Android.bp、Soong、Blueprint、Ninja,它们之间到底有什么关系? 以下用简单的方式表达这几个概念之间的作用关系。

  1. Android.bp --> Blueprint --> Soong --> Ninja
  2. Makefile or Android.mk --> kati --> Ninja
  3.  
  4. (Android.mk --> Soong --> Blueprint --> Android.bp)

Blueprint是生成、解析Android.bp的工具,是Soong的一部分。 Soong则是专为Android编译而设计的工具,Blueprint只是解析文件的形式,而Soong则解释内容的含义。

Android.mk可以通过Soong提供的androidmk转换成Android.bp,但仅限简单配置。 目前Oreo的编译流程中,仍然是使用kati来做的转换。

现存的Android.mk、既有的Android.bp,都会分别被转换成Ninja。 从Android.mk与其它Makefile,会生成out/build-<product_name>.ninja文件。 而从Android.bp,则会生成out/soong/build.ninja。 此外,还会生成一个较小的out/combined-<product_name>.ninja文件,负责把二者组合起来,作为执行入口。

最终,Ninja文件才是真正直接控制源码编译的工具。

Android.bp

样例与基本概念

  1. // Android.bp sample
  2. cc_defaults(
  3. deps = [
  4. "libc",
  5. ],
  6. )
  7.  
  8. cc_library(
  9. name = "cmd",
  10. srcs = [
  11. "main.c",
  12. ],
  13. )
  14.  
  15. subdirs = ["subdir1", "subdir2"]

前面的样例中,cc_library这种()前面的,就是模块(module)。 这里module的概念,直接对应Android.mk中module的概念。 而=前面的namesrcs等,就是该模块的属性(property)。

subdirs是一个文件级的顶层属性,指定后会查找次级目录下的Android.bp。 类似于Android.mk中常用的include $(call all-subdir-makefiles)

模块是可以继承属性的。 cc_defaults就是一个文件中所有模块的父模块,可以指定公用的属性。 在以上代码中,cc_library模块虽然没有指定,但已经包含了deps属性。

语法

Blueprint文件的语法比较简单,毕竟只是配置文件。

变量与属性都是动态强类型的,赋值时确定。 变量类型只有四种。

  1. Bool(truefalse
  2. 字符串Strings(”string”)
  3. 字符串列表(["string1", "string2"]
  4. 映射关系Map({key1: "value1", key2: ["value2"]}

注释方式,与Golang类似。 支持行注释// line与块注释/* block */

操作符除了赋值的=以外,只有+

常用工具

虽然编译过程中的相关很多,不过在开发过程中可能需要手动执行的命令却不多。

一个是格式化工具bpfmt。 与gofmt类似,可以格式化Blueprint文件。 (其实,代码基本上都是从gofmt复制而来。)

例如,格式化当前目录及其递归子目录下的所有Android.bp:

bpfmt -w .

另一个是androidmk,负责转换Android.mk为Android.bp。 其实,现阶段没有必要学会写Android.bp,通过写Android.mk来转换也行。

androidmk Android.mk > Android.bp

Android.mk转换Android.bp实例

下面,以一个AOSP上的简单模块,system/core/sdcard/Android.mk,来做为案例。

  1. LOCAL_PATH := $(call my-dir)
  2.  
  3. include $(CLEAR_VARS)
  4.  
  5. LOCAL_SRC_FILES := sdcard.cpp fuse.cpp
  6. LOCAL_MODULE := sdcard
  7. LOCAL_CFLAGS := -Wall -Wno-unused-parameter -Werror
  8. LOCAL_SHARED_LIBRARIES := libbase libcutils libminijail libpackagelistparser
  9.  
  10. LOCAL_SANITIZE := integer
  11.  
  12. include $(BUILD_EXECUTABLE)

这是一个编译二进制可执行文件的小模块,内容非常简单。 通过执行androidmk Android.mk > Android.bp,可以转换成Android.bp。

  1. cc_binary {
  2. srcs: [
  3. "sdcard.cpp",
  4. "fuse.cpp",
  5. ],
  6. name: "sdcard",
  7. cflags: [
  8. "-Wall",
  9. "-Wno-unused-parameter",
  10. "-Werror",
  11. ],
  12. shared_libs: [
  13. "libbase",
  14. "libcutils",
  15. "libminijail",
  16. "libpackagelistparser",
  17. ],
  18. sanitize: {
  19. misc_undefined: ["integer"],
  20. },
  21. }

可以看出,虽然行数变多,但其实含义更明确了。 这个名为sdcard的模块,源码有两个cpp文件,依赖库有四个。 cc_binary,就相当于include $(BUILD_EXECUTABLE)。 转换前后,该有的信息都在,只是表达方式变化了而已。

注意:如果Android.mk中包含复杂的逻辑,则转换结果会有问题,详见结果文件中的注释。

至于Android.bp支持多少像cc_binarycc_library这样的模块,每个模块又支持多少像namecflags这样的属性, 则只能去查找Soong的文档。

文档

目前(2017年),整个Android.bp工具链,都处于文档极度缺失的阶段。 除了官方那点可怜的README以外,基本只能去看代码与注释,参考其它已经存在的Android.bp。

另外,在已经使用Soong编译的项目中,out/soong/.bootstrap/docs/soong_build.html描述了所有的可用模块及其属性。 这多少缓解了两眼一抹黑症状,不算太过难受。 实际上,整个Soong仍然处于发展期,Google肆无忌惮地修改,完全没考虑兼容。 在8.0.0写的Android.bp,也许在8.0.1就会编译失败。 这或许是文档与编译绑定的真意吧。 等Soong完全成熟了,也许Android开发官网,就会有详尽的信息。

本站提供了从AOSP的android-8.0.0-r9,编译出来的一个soong_build.html,仅供参考。

Android编译系统中的Android.bp【转】的更多相关文章

  1. Android编译系统中的Android.bp

    https://www.cnblogs.com/bluestorm/p/10895005.html Android.bp,是用来替换Android.mk的配置文件. 它使用Blueprint框架来解析 ...

  2. 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统(瘋耔修改篇二)

    第四章.Android编译系统与定制Android平台系统 4.1Android编译系统 Android的源码由几十万个文件构成,这些文件之间有的相互依赖,有的又相互独立,它们按功能或类型又被放到不同 ...

  3. 在Android系统中修改Android.mk使其同时编译rgb2565和rgb2888(向out/host/linux-x86/bin/下新增加一个工具命令)【转】

    本文转载自:http://blog.csdn.net/mu0206mu/article/details/7514559 在Android系统中修改android.mk使其同时编译rgb2565和rgb ...

  4. android应用中去android市场去评分的功能实现(吐槽一波个人应用上线...)

    一般的app可能会有这中功能,在应用中去android商店评分来提高排名,前段时间也把我的博客园上传到商店,这里不得不吐槽一些android商店的开放平台. 酷派,vivo,oppo,联想不支持个人开 ...

  5. 在Android Studio中打开Android Device Monitor时报错的解决方法

    在Android Studio中打开Android Device Monitor时报以下错误时(Android-SDK\tools\lib\monitor-x86_64\configuration\1 ...

  6. 【转】在Android Studio中下载Android SDK的两种方式(Android Studio3.0、windows)

    在Android Studio中下载Android SDK的两种方式(Android Studio3.0.windows) 方式一.设置HTTP Proxy1. 打开Settings2. 点击HTTP ...

  7. Android编译系统中的Kconfig,Makefile,.config编译系统浅析

    在对Android进行编译时,用的就是Linux下的Makefile和Kconfig编译系统,对整个系统进行编译.当然还包括很多配置命令,比如make defconfig, make oldconfi ...

  8. Android: NDK中的Android.mk和Application.mk

    1. 简介 Android.mk  可用来描述要编译的某个具体模块的相关信息.比如:指定编译该模块时所需要的源文件.编译该模块时要链接的库文件.该模块编译完成后生成的库的名字等等.Applicatio ...

  9. 手把手教android studio中安装Android Butterknife Zelezny (转)

    原文地址:http://blog.csdn.net/xin917480852/article/details/51176524 用来快速生成findViewById() 安装方法: 打开Android ...

随机推荐

  1. Oracle 23的用户管理

    创建用户的语法格式 Create user <user_name> Identified by<password> Default tabespace<default t ...

  2. c#中枚举类型的定义与使用

    介绍枚举是一个指定的常数,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举.定义默认基数从O开 ...

  3. 关于hibernate一级缓冲和二级缓冲

    关于一级缓冲和二级缓冲的内容,在面试的时候被问起来了,回答的不是很满意,所以有专门找了些有关这方面的文章加以理解 出自:http://blog.csdn.net/zdp072/article/deta ...

  4. CSS3 transition-timing-function 深入理解和技巧

    基础 语法: transition-timing-function : ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier( ...

  5. 代码审查Code Review

    代码审查清单 常规项 代码能够工作么?它有没有实现预期的功能,逻辑是否正确等. 所有的代码是否简单易懂? 代码符合你所遵循的编程规范么?这通常包括大括号的位置,变量名和函数名,行的长度,缩进,格式和注 ...

  6. Shader2.0常用语义

    POSITION: 获取模型顶点的信息.NORMAL: 获取法线信息TEXCOORD(n):        高精度的从顶点传递信息到片段着色器COLOR:     表示低精度从顶点传递信息到片段着色器 ...

  7. 随机模拟(MCMC)

    http://cos.name/2013/01/lda-math-mcmc-and-gibbs-sampling/ http://blog.csdn.net/lin360580306/article/ ...

  8. eclipse maven install没反应解决办法

    .打开eclipse的Window菜单-->java-->Installed JREs .点击用的jdk,edit,在Default VM arguments里面填入-Dmaven.mul ...

  9. OpenVPN 服务端(pritunl)的一些运维经验

    1.当服务端部署在docker中,重启机器之后,docker服务会启动,pritunl的docker容器也会跟着自动启动.但此时,一些系统服务还未完全启动成功,导致会有一些pritunl server ...

  10. 20165305 苏振龙《Java程序设计》第八周学习总结

    第十二章 •如果想在main()以外独立设计流程,可以撰写类操作java.lang.Runnable接口,流程的进入点是操作在run()方法中. •如果想要加装主线程,就要创建 Thread 实例,要 ...