Android 10 根文件系统和编译系统(十八):Android.bp语法 |
您所在的位置:网站首页 › 模块编译是什么 › Android 10 根文件系统和编译系统(十八):Android.bp语法 |
配套系列教学视频链接:
安卓系列教程之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:[":"]来指定继承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文件进行查阅。 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |