配套系列教学视频链接:

安卓系列教程之ROM系统开发-百问100ask


说明

系统:AOSP Android10.0

设备:Android x86模拟器

前言

由于make在编译时表现出效率不够高、增量编译速度慢等问题,Google在android 7.0版本引进了编译速度更快的soong来替代make。最开始,Ninja 是用于Chromium 浏览器中,Ninja 其实就是一个编译系统,类似make ,使用Ninja 主要目的就是因为其编译速度快, 本章节重点介绍Android.bp相关语法。


一, 介绍

Android 7.0之后希望用Android.bp替换Android.mk,bp简单的配置更方便Ninja文件的产生,而Blueprint和Soong 就此产生。Soong则是专为Android编译而设计的工具,Blueprint只是解析文件的形式,而Soong则解释内容的含义,最终将Android.bp转换成Ninja文件。 Blueprint和Soong都是由Golang写的项目。 从Android Nougat开始,prebuilts/go/目录下新增了Golang所需的运行环境,在编译时使用。

Android.mk可以引用Android.bp中的模块,反之Android.bp不能引用Android.mk中的模块, 以下显示为各个工具的关系图:

二,语法

官方参考:

https://android.googlesource.com/platform/build/soong/+/refs/heads/master/README.md

https://source.android.com/setup/build

Android.bp 文件很简单。它们不包含任何条件语句,也不包含控制流语句;每一个模块以模块类型开始,后面跟着一组模块的属性,以名值对(name: value)表示,类似JSON语句,每个模块都必须有一个name属性. 其属性值必须是全局唯一的,基本格式如下:

[module type] {

name: "[name value]",

[property1 name]:"[property1 value]",

[property2 name]:"[property2 value]",

}

最简单的Android.mk和Android.bp比对:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_CFLAGS+=-Wno-error\               -Wno-unused-parameter

LOCAL_SRC_FILES := main.c

LOCAL_MODULE := hello_test

include $(BUILD_EXECUTABLE)

cc_binary {

cflags: [

"-Wno-error",

"-Wno-unused-parameter",

],

srcs: ["main.c"],

name: "hello_test",

}

Soong系统其实会提供androidmk命令, 用于将Android.mk转换成Android.bp, 使用如下:

androidmk Android.mk > Android.bp

注意: soong的编译配置文件以.bp结尾,通常命名为Android.bp,但也有少数情况不以Android.bp命名。例如:external/libdrm/Android.sources.bp, frameworks/rs/support.bp。

1,模块

常见模块类型: 在Android源码中

build/soong/androidmk/cmd/androidmk/android.go

var moduleTypes = map[string]string{

"BUILD_SHARED_LIBRARY":        "cc_library_shared",

"BUILD_STATIC_LIBRARY":          "cc_library_static",

"BUILD_HOST_SHARED_LIBRARY":   "cc_library_host_shared",

"BUILD_HOST_STATIC_LIBRARY":    "cc_library_host_static",

"BUILD_HEADER_LIBRARY":        "cc_library_headers",

"BUILD_EXECUTABLE":            "cc_binary",

"BUILD_HOST_EXECUTABLE":       "cc_binary_host",

"BUILD_NATIVE_TEST":            "cc_test",

"BUILD_HOST_NATIVE_TEST":       "cc_test_host",

"BUILD_NATIVE_BENCHMARK":      "cc_benchmark",

"BUILD_HOST_NATIVE_BENCHMARK": "cc_benchmark_host",

"BUILD_JAVA_LIBRARY":             "java_library",

"BUILD_STATIC_JAVA_LIBRARY":      "java_library_static",

"BUILD_HOST_JAVA_LIBRARY":        "java_library_host",

"BUILD_HOST_DALVIK_JAVA_LIBRARY": "java_library_host_dalvik",

"BUILD_PACKAGE":                  "android_app",

}

预编译模块类型: Android.bp可以支持多种预编译模块类型,具体定义在Android源码:

build/soong/androidmk/cmd/androidmk/android.go:

var prebuiltTypes = map[string]string{

"SHARED_LIBRARIES": "cc_prebuilt_library_shared",

"STATIC_LIBRARIES": "cc_prebuilt_library_static",

"EXECUTABLES":      "cc_prebuilt_binary",

"JAVA_LIBRARIES":   "java_import",

"ETC":              "prebuilt_etc",

}

其他各种模块: 如果有源码, 并且已编译的可以查看:

out/soong/docs/soong_build.html

除了以上信息之外,需要知道的是, Android.mk和Android.bp之间的对应关系, 依然可以通过

build/soong/androidmk/cmd/androidmk/android.go来查看

func init() {

addStandardProperties(bpparser.StringType,

map[string]string{

"LOCAL_MODULE":                  "name",

"LOCAL_CXX_STL":                 "stl",

"LOCAL_MULTILIB":                "compile_multilib",

"LOCAL_ARM_MODE_HACK":           "instruction_set",

"LOCAL_SDK_VERSION":             "sdk_version",

"LOCAL_MIN_SDK_VERSION":         "min_sdk_version",

"LOCAL_NDK_STL_VARIANT":         "stl",

"LOCAL_JAR_MANIFEST":            "manifest",

"LOCAL_CERTIFICATE":             "certificate",

"LOCAL_PACKAGE_NAME":            "name",

"LOCAL_MODULE_RELATIVE_PATH":    "relative_install_path",

"LOCAL_PROTOC_OPTIMIZE_TYPE":    "proto.type",

"LOCAL_MODULE_OWNER":            "owner",

"LOCAL_RENDERSCRIPT_TARGET_API": "renderscript.target_api",

"LOCAL_NOTICE_FILE":             "notice",

....

}

2, 默认模块

soong提供了一系列xx_defaults模块类型,例如:cc_defaults, java_defaults, doc_defaults, stub_defaults等等。模块类型为xx_defaults的模块提供了一组可由其它模块继承的属性。其它模块可以通过添加属性

defaults:[":<default_module_name>"]来指定继承xx_defaults类型的模块定义的属性。因此,我们定义一个新模块时,可以通过将默认模块的属性放在name属性之后,其它属性之前,来合并两个模块的属性。

注意:cc_defaults默认模块可用于在多个模块中重复相同的属性

cc_defaults {// //默认模块名称

name: "default_module",

shared_libs: ["libz"],

stl: "none",

}

cc_binary {

name: "test1",

defaults: ["default_module"], //引用默认模块名称

srcs: ["src/test/test.c"],

}

cs 属性以字符串列表的形式指定用于编译模块的源文件。也可以使用模块引用语法 “:” 来引用生成源文件的其他模块(如filegroup或genrule模块)的输出,如Android源码中frameworks/base/core/java/Android.bp

filegroup {

name: "IKeyAttestationApplicationIdProvider.aidl",

srcs: ["android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl"],

}

filegroup {

name: "IDropBoxManagerService.aidl",

srcs: ["com/android/internal/os/IDropBoxManagerService.aidl"],

}

其他模块就可以引用: frameworks/base/libs/services/Android.bp

cc_library_shared {

name: "libservices",

srcs: [

":IDropBoxManagerService.aidl",

"src/content/ComponentName.cpp",

"src/os/DropBoxManager.cpp",

"src/os/StatsDimensionsValue.cpp",

"src/os/StatsLogEventWrapper.cpp",

],

....

}

3,类型

变量和属性是强类型,变量根据第一项赋值动态变化,以下变量的例子基本都可以在

frameworks/base/Android.bp中找到。

布尔值(true 或 false)

例如: undefined: true,

all_undefined: true,

整数 (int)

例如:javac_shard_size: 150,

字符串 ( "string" )

例如: api_filename: "test-api.txt",

字符串列表 (["string1", "string2"])

例如:libs: [

"ext",

"updatable_media_stubs",

],

映射 ({key1: "value1", key2: [ "value2" ]})

映射可以包含任何类型的值,包括嵌套映射。

例如:

check_api: {

current: {

api_file: "api/test-current.txt",

removed_api_file: "api/test-removed.txt",

},

},

4,变量

Android.bp文件可包含顶级变量赋值:

test_srcs = ["src/test.c"],

cc_binary {

name: "test",

srcs: test_srcs,

}

变量的作用域限定在声明它们的文件的其余部分,以及所有子 Blueprint 文件。可以使用 “=” 号赋值, 但是不能使用 “:=” 赋值。变量是不可变的,但有一个例外情况:可以使用 += 赋值将变量附加到别处,但只能在引用它们之前附加。

5,注释

Android.mk中可以进行注释,当然Android.bp里面也可以,Android.mk中使用"#"然后添加注释,Android.bp使用单行注释//和多行注释/* */两种方式。

6,运算符

可以使用 + 运算符附加字符串、字符串列表和映射。可以使用 + 运算符对整数求和。附加映射会生成两个映射中键的并集,并附加在两个映射中都存在的所有键的值。如:

附加字符串:

framework_docs_only_args = " -android -manifest $(location core/res/AndroidManifest.xml) "

xxx{

args: framework_docs_only_args + " -referenceonly -parsecomments",

}

附加字符串列表:

framework_docs_only_libs = [

"voip-common",

"android.test.mock",

"android-support-annotations",

],

doc_defaults {

name: "framework-docs-default",

libs: framework_docs_only_libs +

["stub-annotations"],

}

7,条件语句

Soong 不支持 Android.bp 文件中的条件语句。但是,编译规则中需要条件语句的复杂问题将在 Go(在这种语言中,您可以使用高级语言功能,并且可以跟踪条件语句引入的隐式依赖项)中处理。大多数条件语句都会转换为映射属性,其中选择了映射中的某个值并将其附加到顶级属性。

例如,要支持特定于架构的文件,参考system/core/libusbhost/Android.bp

cc_library {

name: "libusbhost",

vendor_available: true,

vndk: {

enabled: true,

},

host_supported: true,

srcs: ["usbhost.c"],

cflags: ["-Werror"],

export_include_dirs: ["include"],

target: {   //相当于if

android: {    //编译Android上运行的程序 相当于if

cflags: [

"-g",

"-DUSE_LIBLOG",

],

shared_libs: ["liblog"],

},

darwin: {    //编译darwin上运行的程序

enabled: false,

},

},

}

8,常见属性

name :"xxx", //模块的名称, 类似于Android.mk中的LOCAL_MODULE

srcs : ["test.c", "my.c"], //模块的源码,类似于Android.mk中的LOCAL_SRC_FILES,

//可以使用模块引用语法 “:” 来引用生成源文件的其他模块的输出

include_dirs :["./include/", "test/include"] ,//指定的头文件查找路径,类似于Android.mk中的LOCAL_C_INCLUDES

shared_libs :["liblog","libutils","], //编译时依赖的动态库,类似于Android.mk中的LOCAL_SHARED_LIBRARIES

static_libs : ["libbase", "libsepol"], // 编译时依赖的静态库,类似于Android.mk中的LOCAL_STATIC_LIBRARIES

subdirs : [“ndk”], //是一个文件级的顶层属性,指定后会查找次级目录下的Android.bp。

vendor: true, //编译出来放在/vendor目录下(默认是放在/system目录下)

cflags: ["-Wall","-Werror","-Wno-unused-parameter",],//编译flag,类似于Android.mk中的LOCAL_CFLAGS

export_include_dirs: [ "include",  "include/camera" ], //将指定的路径导出给其他模块使用

App模块中的属性:

platform_apis : 用 sdk 的 hide 的 api 來编译

certificate : 指定用的是什么签名,如上用的是 platform 签名。

jni_libs : 依赖使用的 JNI 库

libs : 工程中的 libs 库

static_libs : 静态库,其中 nearme_nfc 为下方定义的:java_import

optimize : 压缩配置,enabled 是否开启,obfuscate 是否开启混淆,proguard_flags_files 混淆规则配置文件

三,总结

Android.bp语法整体上类似json字符串, 相关语法可以通过参考系统的例子以及soong_build.html文件进行查阅。

Android 10 根文件系统和编译系统(十八):Android.bp语法相关推荐

  1. Android 10 根文件系统和编译系统(四):Android源码目录结构

    配套系列教学视频链接: Android 10.0 AOSP源码编译: https://www.100ask.net/detail/p_60a1e037e4b0adb2d864c6d8/6 Androi ...

  2. Android 10 根文件系统和编译系统(一):根文件系统目录结构

    配套系列教学视频链接: Android 10.0 AOSP源码编译:https://edu.csdn.net/course/detail/35479 Android 10.0 根文件系统和编译系统:h ...

  3. 基于eclipse的android项目实战—博学谷(十八)播放不同视频(网络视频)

    相信经过了这么长时间,小伙伴们应该都发现了博学谷这个项目存在问题,播放视频的时候,无论播放任何一个章节,他播放的视频都只是一个,也就是VideoPlayActivity.java里面写死的那个(myv ...

  4. 关闭数字健康 android 魅族,数字体验 篇二十八:精雕细刻,只为给魅友更好的选择,魅族16s Pro体验分享...

    数字体验 篇二十八:精雕细刻,只为给魅友更好的选择,魅族16s Pro体验分享 2019-09-06 17:31:22 14点赞 10收藏 15评论 当我还一直在称赞魅族16s所拥有的舒适手感表现时, ...

  5. android rootfs根文件系统挂载

    linux下文件目录为树状结构,文件系统挂载在虚拟系统的VFS各个目录下. VFS是Linux中的一个虚拟文件文件系统,也称为虚拟文件系统交换层(Virtual Filesystem Switch), ...

  6. Android开发笔记(一百三十八)文本输入布局TextInputLayout

    文本输入布局TextInputLayout TextInputLayout是MaterialDesign库中对编辑框EditText进行增强的一个控件.众所周知,EditText未输入字符时,我们可以 ...

  7. Android 10.0 系统服务之ActivityMnagerService-AMS启动流程-[Android取经之路]

    摘要:上一节我们讲完了SystemServer的启动过程,这一节接着上一节的步骤,来讲解ActivityManagerService的启动过程. ActivityManagerService简称AMS ...

  8. Android系统10 RK3399 init进程启动(十八) isLoggable日志级别输出控制

    配套系列教学视频链接: 安卓系列教程之ROM系统开发-百问100ask 说明 系统:Android10.0 设备: FireFly RK3399 (ROC-RK3399-PC-PLUS) 前言 在编写 ...

  9. Android开发笔记(一百一十八)自定义悬浮窗

    WindowManager 在前面< Android开发笔记(六十六)自定义对话框>中,我们提到每个页面都是一个Window窗口,许多的Window对象需要一个管家来打理,这个管家我们称之 ...

最新文章

  1. Redis缓存 ava-Jedis操作Redis,基本操作以及 实现对象保存
  2. linux系统无法用命令行,无法在Linux操作系统上从命令行启动Kitchen Pentaho作业
  3. Java中如何引用文档对象模型_在JAVA中使用文档对象模型DOM经验小结
  4. 百度搜索引擎优化指南3.0_深圳网站搜索引擎排名优化电话,百度优化排名费用_华阳网络...
  5. excel乘法公式怎么输入_python吊打Excel?那是你不会用!
  6. android recyclerview item自适应高度_web前端入门到实战:css让一个盒子的高度自适应屏幕剩余的部分...
  7. 多标签文本分类研究进展
  8. java+selenium实现web多系统登录
  9. Android入门笔记07
  10. 利用wordpress搭建自己的网站(百度云虚拟主机)
  11. python中的round
  12. linux引导界面背景,如何个性化syslinux引导界面背景照片
  13. 台式WIN7和os x yosemite 10.10.1懒人版双系统安装教程
  14. 【JSD2209-DAY02】数据基本类型
  15. stc 串口收发 c语言,STC12C5A60S2 串口中断接收程序
  16. 第四章 字体和格式相关
  17. 思维导图学习 | 第四篇:java学习特别篇,java正确的学习姿势
  18. html实现简单分享功能
  19. Orleans 2.0 官方文档 —— 4.5 Grains - 观察者
  20. hive 保留四位小数

热门文章

  1. java压缩文件耗时:30秒到1秒的优化过程
  2. 什么是云服务器ECS?云服务器ECS详解
  3. 艾永亮:酒店浮沉录,睡不明白的生意经
  4. eden区分配至s0、s1
  5. 中兴u31网管服务器,中兴通讯100G光网络网管解决方案——NetNumenTM U31(BN)
  6. win10计算机拒绝访问,Win10文件访问被拒绝如何解决?
  7. 使用github制作简历
  8. 《你好,数智新世界》系列访谈 对话数睿数据总裁刘超|企业级无代码赋能软件产业变革...
  9. MYSQL压力测试工具
  10. linux服务器怎么搭建简单的网站?linux搭建网站教程