文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android——编译(三):android.bp的相关知识

2023-08-21 08:11

关注

本文是最后一篇,主要介绍android.bp。:转载自Android 编译之android.bp

作者:qiuxintai
链接:https://www.jianshu.com/p/f69d1c381182
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

1.1 Ninja简介

Ninja 是一个专注于速度的小型构建系统。它与其他构建系统在两个主要方面不同:(是个系统,管理构建的)

Ninja基于汇编,专注于速度,不支持分支、循环等流程控制,也不支持逻辑运算,但它允许以其它语言如来维护这些复杂的编译流程和逻辑。

例如,我们可以采用Makefile, go, python等等来维护编译的流程和逻辑。

1.2 Ninja的构建文件

虽然Ninja的构建文件是可读的(human-readable),但是手写不是特别方便。我们可以先来看一段ninja文件的内容:

# This file is used to build ninja itself.# It is generated by configure.py.ninja_required_version = 1.3# The arguments passed to configure.py, for rerunning it.configure_args = root = .builddir = buildcxx = g++ar = arcflags = -g -Wall -Wextra -Wno-deprecated -Wno-missing-field-initializers $-Wno-unused-parameter -fno-rtti -fno-exceptions -fvisibility=hidden $-pipe '-DNINJA_PYTHON="python"' -O2 -DNDEBUG -DUSE_PPOLL $-DNINJA_HAVE_BROWSE -I.ldflags = -L$builddirrule cxx  command = $cxx -MMD -MT $out -MF $out.d $cflags -c $in -o $out  description = CXX $out  depfile = $out.d  deps = gccrule ar  command = rm -f $out && $ar crs $out $in  description = AR $outrule link  command = $cxx $ldflags -o $out $in $libs  description = LINK $out

可以看到,ninja的构建文件,书写起来是不很方便的,所以,我们需要一些ninja构建文件的生成器。

这些生成器就是一些元构建系统(meta-build system),例如Blueprint、CMake等等。

Ninja的基于底层实现使其非常适合嵌入到这些功能更强大的构建系统中。

更多ninja构建文件的生成器,可参考:List of generators producing ninja build files。

Ninja用于构建Google Chrome浏览器,Android,LLVM的一部分。由于CMake可在大多数平台上运行,并且可以生成多种格式的项目文件,包括Ninja。所以Ninja也可以作为CMake的底层实现,在许多其他项目中使用。

1.3 Ninja的下载和使用

Ninja的最新版本为v1.10.2,于2020年11月23日发布:Ninja release v1.10.2。
当然我们也可以下载ninja源码自行编译:

$ git clone git://github.com/ninja-build/ninja.git && cd ninja$ git checkout release$ cat README

Ninja的设计哲学和设计背景,是否以及如何在项目中使用Ninja,Ninja的平台支持以及Ninja详细的语言语义等等更多Ninja相关的知识,请参考:
Ninjia使用手册

2.1 Blueprint简介

Blueprint 是一个元构建系统,该系统读取Blueprint文件来描述需要构建的模块,并生成一个Ninja清单来描述需要运行的命令及其依赖项。

在大多数构建系统使用内置规则或特定领域语言来描述将模块描述转换为构建规则的逻辑。

Blueprint将其委托给使用Go编写的针对每个项目的构建逻辑。

对于大型,异构项目,这允许以高级语言维护固有、复杂的构建逻辑,同时仍可以通过修改易于理解的Blueprint文件来对单个模块进行简单更改。

2.2 android中的Blueprint

前面在Ninja的构建文件一节我们提到了,Blueprint是ninja构建文件的生成器。android 编译系统soong集成了Blueprint,Blueprint可将我们编写的android.bp解析生成一个ninja构建文件

我们在编译一个模块时,只需要将这个模块的android.bp文件配置好,编译系统会自动为这个模块生成ninja清单,最终使用ninja来调用gcc、clang、java、dex、aapt2等等命令来构建模块。

kati 是Google开发的一个实验性的GNU make clone,kati的主要目标是加快Android的增量构建。目前,kati本身并不能提供更快的构建。 而是将Makefile转换为ninja。一开始kati是用go语言开发的,但作者发现使用go写的有性能问题,后来作者又用C++进行了重写,也就是kati变成了ckati(作者的原文描述可以查看android源码目录下的:build/kati/INTERNALS.md)。后续提到kati时,如不特别指出,即是指ckati。

简单点说,kati就是一个转换工具,它可以将Makefile和.mk文件转换为ninja

android源码目录下的:prebuilts/build-tools下有预置的kati,Android 7.0及以上版本,编译源码时会自动使用kati。大多数情况下,我们不会直接使用kati,但如果你还想了解更多kati的相关信息,可以访问:https://github.com/google/kati。也可以查看android源码目录下的 build/kati/INTERNALS.md 和 build/kati/README.md。

4.1 soong简介

在android 6.0版本之前,编译android源码采用的是基于make的编译系统(make-based build system),也就是android的各个库、APK等等目标文件都是采用make来构建的。 但是,由于make在编译时表现出效率不够高、增量编译速度慢等问题,Google在android 7.0版本引进了编译速度更快的soong来替代make。

Soong集成了Ninja, 而Ninja专注于速度,没有条件或流程控制语句,也不支持逻辑运算。但它允许以其它语言如来维护这些复杂的编译流程和逻辑。例如,我们可以继续采用makefile, 或者采用go语言来维护编译流程和逻辑。

上面已经提到了Ninja,Blueprint, kati等等好几种工具,为了完整、快速的构建一个android系统,就需要一个“管家”来协调这些工具。例如,将.bp转换成ninja时使用Blueprint, 将Makefile转换成ninja时使用kati。这个选择转换工具、选择解析框架、解析维护构建逻辑的“管家”就是soong。

编译android源码时,soong也会被自动使用,我们可以和原来一样:

首先,source build/envsetup.sh。

然后,lunch选择target。

最后,使用m、mm、mmm或者make来编译指定的模块或者整个系统。

但是,m、mm、mmm或者make最终都会使用soong来编译。

因为source之后,build/envsetup.sh中已经将make指向soong了

function get_make_command(){    # If we're in the top of an Android tree, use soong_ui.bash instead of make    if [ -f build/soong/soong_ui.bash ]; then        # Always use the real make if -C is passed in        for arg in "$@"; do            if [[ $arg == -C* ]]; then                echo command make                return            fi        done        echo build/soong/soong_ui.bash --make-mode    else        echo command make    fi}function make(){    _wrap_build $(get_make_command "$@") "$@"}function m(){    local T=$(gettop)    if [ "$T" ]; then        _wrap_build $T/build/soong/soong_ui.bash --make-mode $@    else        echo "Couldn't locate the top of the tree.  Try setting TOP."        return 1    fi}function mm(){    local T=$(gettop)    # If we're sitting in the root of the build tree, just do a    # normal build.    if [ -f build/soong/soong_ui.bash ]; then        _wrap_build $T/build/soong/soong_ui.bash --make-mode $@    else        # Find the closest Android.mk file.        local M=$(findmakefile)        local MODULES=        local GET_INSTALL_PATH=        local ARGS=        # Remove the path to top as the makefilepath needs to be relative        local M=`echo $M|sed 's:'$T'/::'`        if [ ! "$T" ]; then            echo "Couldn't locate the top of the tree.  Try setting TOP."            return 1        elif [ ! "$M" ]; then            echo "Couldn't locate a makefile from the current directory."            return 1        else            local ARG            for ARG in $@; do                case $ARG in                  GET-INSTALL-PATH) GET_INSTALL_PATH=$ARG;;                esac            done            if [ -n "$GET_INSTALL_PATH" ]; then              MODULES=              ARGS=GET-INSTALL-PATH-IN-$(dirname ${M})              ARGS=${ARGS//\//-}            else              MODULES=MODULES-IN-$(dirname ${M})              # Convert "/" to "-".              MODULES=${MODULES//\//-}              ARGS=$@            fi            if [ "1" = "${WITH_TIDY_ONLY}" -o "true" = "${WITH_TIDY_ONLY}" ]; then              MODULES=tidy_only            fi            ONE_SHOT_MAKEFILE=$M _wrap_build $T/build/soong/soong_ui.bash --make-mode $MODULES $ARGS        fi    fi}function mmm(){    local T=$(gettop)    if [ "$T" ]; then        local MAKEFILE=        local MODULES=        local MODULES_IN_PATHS=        local ARGS=        local DIR TO_CHOP        local DIR_MODULES        local GET_INSTALL_PATH=        local GET_INSTALL_PATHS=        local DASH_ARGS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^-.*$/')        local DIRS=$(echo "$@" | awk -v RS=" " -v ORS=" " '/^[^-].*$/')        for DIR in $DIRS ; do            DIR_MODULES=`echo $DIR | sed -n -e 's/.*:\(.*$\)/\1/p' | sed 's/,/ /'`            DIR=`echo $DIR | sed -e 's/:.*//' -e 's:/$::'`            # Remove the leading ./ and trailing / if any exists.            DIR=${DIR#./}            DIR=${DIR%/}            if [ -f $DIR/Android.mk -o -f $DIR/Android.bp ]; then                local TO_CHOP=`(\cd -P -- $T && pwd -P) | wc -c | tr -d ' '`                local TO_CHOP=`expr $TO_CHOP + 1`                local START=`PWD= /bin/pwd`                local MDIR=`echo $START | cut -c${TO_CHOP}-`                if [ "$MDIR" = "" ] ; then                    MDIR=$DIR                else                    MDIR=$MDIR/$DIR                fi                MDIR=${MDIR%/.}                if [ "$DIR_MODULES" = "" ]; then                    MODULES_IN_PATHS="$MODULES_IN_PATHS MODULES-IN-$MDIR"                    GET_INSTALL_PATHS="$GET_INSTALL_PATHS GET-INSTALL-PATH-IN-$MDIR"                else                    MODULES="$MODULES $DIR_MODULES"                fi                MAKEFILE="$MAKEFILE $MDIR/Android.mk"            else                case $DIR in                  showcommands | snod | dist | *=*) ARGS="$ARGS $DIR";;                  GET-INSTALL-PATH) GET_INSTALL_PATH=$DIR;;                  *) if [ -d $DIR ]; then                         echo "No Android.mk in $DIR.";                     else                         echo "Couldn't locate the directory $DIR";                     fi                     return 1;;                esac            fi        done        if [ -n "$GET_INSTALL_PATH" ]; then          ARGS=${GET_INSTALL_PATHS//\//-}          MODULES=          MODULES_IN_PATHS=        fi        if [ "1" = "${WITH_TIDY_ONLY}" -o "true" = "${WITH_TIDY_ONLY}" ]; then          MODULES=tidy_only          MODULES_IN_PATHS=        fi        # Convert "/" to "-".        MODULES_IN_PATHS=${MODULES_IN_PATHS//\//-}        ONE_SHOT_MAKEFILE="$MAKEFILE" _wrap_build $T/build/soong/soong_ui.bash --make-mode $DASH_ARGS $MODULES $MODULES_IN_PATHS $ARGS    else        echo "Couldn't locate the top of the tree.  Try setting TOP."        return 1    fi}

使用make构建项目,主要工作是编写Makefile;

类似的,使用soong构建项目,主要工作是编写bp文件。关于bp文件我们会在接下来的第5节中详细介绍。

4.2 androidmk

soong中还集成了一个非常有用的工具androidmk。androidmk可以将android.mk转换成android.bp。我们可以使用androidmk来转换代码中已有的android.mk,以此来减少重写android.bp的工作量。例如,我们将一个Android.mk转换成Android.bp:

androidmk Android.mk > Android.bp

注意:androidmk工具可以转换变量,模块,注释和某些条件,但是自定义的Makefile规则,复杂的条件语句或其它的额外的include语句,必须手动转换。

在现有版本,由于kati工具的存在,继续使用android.mk也是没有问题的。但是,也许在将来的某一天,Google可能会不再支持Makefile。因此,建议新增的模块采用android.bp,存量的android.mk,在条件允许的情况下,也应当尽量转换成android.bp

4.3 bpfmt

为了方便格式化,Soong还包含了一个用于格式化Android.bp文件的工具bpfmt,类似于gofmt。 以一个简单的bp文件为例:

cc_binary {    name: "gzip",    srcs: [        "src/test/minigzip.c",        "src/test/utils.c",    ],    shared_libs: ["libz"],    stl: "none",}

Android.bp的规范格式包括:

我们可以使用bpfmt工具来规范格式化Android.bp文件。例如,要递归地格式化当前目录中的所有Android.bp文件:

bpfmt -w .

4.4 ninja,Blueprint,kati,androidmk与Soong的关系和作用

它们的关系示意图如下:
在这里插入图片描述

5.1 bp文件的命名与文件格式

soong的编译配置文件以.bp结尾,通常命名为Android.bp,但也有少数情况不以Android.bp命名。例如:frameworks/rs/support.bp。与Makefile一样,使用soong编译前,会遍历所有以bp为后缀名的文件。因此,soong的编译配置文件只要以.bp结尾即可。

5.2 模块(module)

bp文件中的模块(module) 以模块类型(module type)开头,后面跟着一系列的属性(property)。每个模块都必须具有一个属性名为name的属性,并且name的属性值在所有Android.bp文件中必须是唯一的。bp文件的内容与JSON、Bazel BUILD很像,模块的格式为:

[module type] {    name: "[name value]",    [property1 name]:"[property1 value]",    [property2 name]:"[property2 value]",}

一个简单的bp文件:

cc_binary {    name: "gzip",    srcs: ["src/test/minigzip.c"],    shared_libs: ["libz"],    stl: "none",}常见的模块类型有:cc_library,cc_library_headers,cc_library_shared,cc_library_static,android_app,android_app_certificate,java_library,java_library_static,java_sdk_library等等。

soong预置了一系列的模块类型和属性,芯片原厂也会添加一些自定义的模块类型和属性,例如,MTK平台就定义了一些以mtk开头的模块类型。如果想了解更多,已有源码并且已编译的可以查看:out/soong/docs/soong_build.html。如果没有源码,也可查看AOSP的在线文档:$AOSP/out/soong/docs/soong_build.html

5.2.1 默认模块(defaults)

soong提供了一系列xx_defaults模块类型,例如:cc_defaults, java_defaults, doc_defaults, stub_defaults等等。模块类型为xx_defaults的模块提供了一组可由其它模块继承的属性。其它模块可以通过添加属性`defaults:[“ <:default_module_name>”]“来指定继承xx_defaults类型的模块定义的属性。因此,我们定义一个新模块时,可以通过将默认模块的属性放在name属性之后,其它属性之前,来合并两个模块的属性。
例如:

java_defaults {    name: "framework-defaults",    installable: true,    srcs: [        // From build/make/core/pathmap.mk FRAMEWORK_BASE_SUBDIRS        "core/java*.java",        "graphics/java*.java",        "location/java*.java",        "lowpan/java*.java",        "media/java*.java",    ]    //......省略无关}java_library {    name: "framework",    defaults: ["framework-defaults"],    javac_shard_size: 150,}java_library {    name: "framework-annotation-proc",    defaults: ["framework-defaults"],    // Use UsedByApps annotation processor    plugins: ["unsupportedappusage-annotation-processor"],}

这个例子中,模块aidl_mapping在srcs属性中引用了framework-defaults。

5.2.2 引用模块

一个模块可以通过它的模块名来引用。在默认模块这一小节中,其实我们已经引用过了其它模块了。这里我们再来一个例子:

cc_binary {    name: "app",    shared_libs: ["libfoo"],}

例子中,libfoo模块必须存在才有效,并且在构建树中有且仅有一个libfoo模块时才有效。

5.3 文件列表

一个属性的属性值为一系列文件时,属性值也可以采用全局匹配模式和输出路径扩展。

全局匹配模式可以包含普通的Unix通配符*,例如“ * .java”。

全局匹配模式也可以包含单个**通配符作为路径元素,它将匹配零个或多个路径元素。 例如,java / ** / *。java将匹配 java/Main.java 和 java/com/android/Main.java。

输出路径扩展采用:module或:module {.tag}格式,其中module是生成输出文件的模块的名称,并且扩展为这些输出文件的列表。 使用可选的{.tag}后缀,模块可以根据tag生成不同的输出列表。
例如:

// AIDL interface between storaged and framework.jarfilegroup {    name: "storaged_aidl",    srcs: [        "binder/android/os/IStoraged.aidl",    ],    path: "binder",}java_library_static {    name: "services.core.unboosted",    srcs: [        "java*.java",        ":storaged_aidl",    ],    //......省略无关}

5.4 类型和变量

Android.bp文件中,变量和属性是强类型的,变量是基于首次分配动态地创建的,属性是根据模块类型静态地创建的。 支持的类型有:

Bool (true or false)Integers (int)Strings ("string")Lists of strings (["string1", "string2"])Maps ({key1: "value1", key2: ["value2"]})

maps可以是任何类型的值,包括嵌套maps。 Lists和Map的最后一个值后面可能带有逗号。
字符串可以使用\“包含双引号,例如” cat \“ a b \”“。

5.5 注释

Android.bp文件可以和C/C++的注释类似,可以包含多行注释和单行注释。

多行注释:/ * 注释 * /
单行注释://注释。

5.6 运算符

Android.bp文件可以使用+运算符附加字符串,字符串列表和映射。 整数可以使用+运算符求和。 追加映射会在两个映射中生成键的并集,并追加两个映射中都存在的任何键的值。
例如:

cc_test {    name: "libandroidfw_tests",    host_supported: true,    defaults: ["libandroidfw_defaults"],    cppflags: [        // This is to suppress warnings/errors from gtest        "-Wno-unnamed-type-template-args",    ],    srcs: [        // Helpers/infra for testing.        "tests/CommonHelpers.cpp",        "tests/TestHelpers.cpp",        "tests/TestMain.cpp",        // 省略无关部分    ],    static_libs: ["libgmock"],    target: {        android: {            srcs: [                "tests/BackupData_test.cpp",                "tests/ObbFile_test.cpp",            ],            shared_libs: common_test_libs + ["libui"],        },        host: {            static_libs: common_test_libs + ["liblog", "libz"],        },    },    data: ["tests/data*.apk"],}

注意:
除了上述介绍的内容之外,Soong还包含了包、命名空间、名称解析、可见性、soong配置变量等等内容。但是,我在Android 9.0和Android 10.0两份源码中都没有找到合适的例子,本人也不是很理解,为避免误导他人,这些内容就不介绍了,如果想了解更多,请参考:https://android.googlesource.com/platform/build/soong/

6. Android.mk和Android.bp的区别

Android.mk文件通常可以包含多个同名模块(例如,用于库的静态(static)和共享(shared)版本,用于不同主机(host)的版本,用于不同设备(device)版本)。

Android.bp文件的每个模块都需要唯一的名称,但是单个模块可以构建为多个变体。例如,通过添加host_supported:true。 包含多个同名模块的Android.mk被androidmk转换成Android.bp之后,将生成多个冲突的模块,这些模块必须手动处理,将同名模块改为一个具有多个变体的模块,这些在target:{android:{},host:{}}块内的变体可以有区别,例如,引用不同的源文件,不同架构的共享库文件等等。

Soong故意不支持Android.bp文件中的大多数条件。 Google建议从构建中删除大多数条件。Soong将本地支持的大多数条件将转换为map属性。 构建模块时,将选择map中的属性之一,并且将其值追加到模块顶层的同名属性中。
例如,要支持特定于体系结构的文件:

cc_library {    ...    srcs: ["generic.cpp"],    arch: {        arm: {            srcs: ["arm.cpp"],        },        x86: {            srcs: ["x86.cpp"],        },    },}

为arm平台构建时,将构建generic.cpp和arm.cpp。 在为x86平台构建时,将构建generic.cpp和x86.cpp。

7.1 编译APP

以DocumentsUI为例(为看起来清晰,有整理和部分删减):

android_app {    name: "DocumentsUI",    manifest: "AndroidManifest.xml",    srcs: [       "src*.java",    ],    resource_dirs: [        "res",    ],    static_libs: [        "androidx.appcompat_appcompat",        "androidx.recyclerview_recyclerview",    ],    privileged: true,    certificate: "platform",    optimize: {        proguard_flags_files: ["proguard.flags"],    },    sdk_version: "system_current",    min_sdk_version: "28",    target_sdk_version: "28",    required: ["privapp_whitelist_com.android.documentsui"],}

可以看到,Android.bp非常简洁,而且命名很清晰,基本上看属性名就知道是起什么作用的。这里只列出了android_app的常用属性,并没有将它的所有属性列出来,开发过程中如果需要配置APP的其它属性,请参考:out/soong/docs/soong_build.html。如果没有源码,也可查看AOSP的在线文档:$AOSP/out/soong/docs/soong_build.html

7.2 编译java库

java_library {    name: "updatable-media",    srcs: [        ":updatable-media-srcs",    ],    aidl: {        export_include_dirs: [            "apex/java",        ],        // It would be great if we don't need to add include_dirs for public        // parcelable classes. Find a better way.        include_dirs: [            // To refer:            // android.os.Bundle            // android.os.ResultReceiver            "frameworks/base/core/java",        ],    },    permitted_packages: [        "android.media",    ],    installable: true,    // Make sure that the implementaion only relies on SDK or system APIs.    no_framework_libs: true,    libs: [        // The order matters. android_system_* library should come later.        "framework_media_annotation",        "android_system_stubs_current",    ],}

7.3 编译java静态库

java_library_static {    name: "services.core.unboosted",    aidl: {        include_dirs: [            "frameworks/native/aidl/binder",            "system/core/storaged/binder",            "system/netd/server/binder",            "system/vold/binder",        ],    },    srcs: [        "java*.java",        ":netd_aidl",        ":netd_metrics_aidl",        ":installd_aidl",        ":storaged_aidl",        ":vold_aidl",        ":mediaupdateservice_aidl",        "java/com/android/server/EventLogTags.logtags",        "java/com/android/server/am/EventLogTags.logtags",    ],    libs: [        "services.net",        "android.hardware.light-V2.0-java",        "android.hardware.power-V1.0-java",        "android.hardware.tv.cec-V1.0-java",        "android.hidl.manager-V1.0-java",    ],    static_libs: [        "time_zone_distro",        "time_zone_distro_installer",        "android.hardware.authsecret-V1.0-java",        "android.hardware.broadcastradio-V2.0-java",        "android.hardware.health-V1.0-java",        "android.hardware.health-V2.0-java",        "android.hardware.weaver-V1.0-java",        "android.hardware.biometrics.fingerprint-V2.1-java",        "android.hardware.oemlock-V1.0-java",        "android.hardware.tetheroffload.control-V1.0-java",        "android.hardware.vibrator-V1.0-java",        "android.hardware.configstore-V1.0-java",        "android.hardware.contexthub-V1.0-java",    ],}

7.4 编译共享库(shared)

cc_library_shared {    name: "libbluetooth_jni",    compile_multilib: "first",    srcs: [        "bluetooth_socket_manager.cc",        "com_android_bluetooth_btservice_AdapterService.cpp",        "com_android_bluetooth_hfp.cpp",        "com_android_bluetooth_hfpclient.cpp",        "com_android_bluetooth_a2dp.cpp",        "com_android_bluetooth_a2dp_sink.cpp",        "com_android_bluetooth_avrcp_controller.cpp",        "com_android_bluetooth_avrcp_target.cpp",        "com_android_bluetooth_hid_host.cpp",        "com_android_bluetooth_hid_device.cpp",        "com_android_bluetooth_hearing_aid.cpp",        "com_android_bluetooth_pan.cpp",        "com_android_bluetooth_gatt.cpp",        "com_android_bluetooth_sdp.cpp",        "IUserManager.cc",        "permission_helpers.cc",    ],    header_libs: ["libbluetooth_headers"],    include_dirs: [        "libnativehelper/include/nativehelper",        "system/bt/types",    ],    shared_libs: [        "libandroid_runtime",        "libbinder",        "libbluetooth-binder",        "libchrome",        "libnativehelper",        "liblog",        "libutils",    ],    static_libs: [        "libbluetooth-types",        "libcutils",    ],    cflags: [        "-Wall",        "-Werror",        "-Wextra",        "-Wno-unused-parameter",    ],    sanitize: {        scs: true,    },}

7.5 编译静态库(static)

cc_library_static {    name: "libmedia_player2_util",    defaults: [ "libmedia_defaults" ],    srcs: [        "AudioParameter.cpp",        "BufferingSettings.cpp",        "DataSourceDesc.cpp",        "MediaCodecBuffer.cpp",        "Metadata.cpp",        "NdkWrapper.cpp",    ],    shared_libs: [        "libbinder",        "libcutils",        "liblog",        "libmediandk",        "libnativewindow",        "libmediandk_utils",        "libstagefright_foundation",        "libui",        "libutils",    ],    export_shared_lib_headers: [        "libbinder",        "libmediandk",    ],    header_libs: [        "media_plugin_headers",    ],    include_dirs: [        "frameworks/av/media/ndk",    ],    static_libs: [        "libstagefright_rtsp",        "libstagefright_timedtext",    ],    export_include_dirs: [        "include",    ],    cflags: [        "-Werror",        "-Wno-error=deprecated-declarations",        "-Wall",    ],    sanitize: {        misc_undefined: [            "unsigned-integer-overflow",            "signed-integer-overflow",        ],        cfi: true,    },}

Google在Android N就引入了Soong,目的是替换make。但是,很遗憾的是截止到Android Q,甚至Android R,它们的源码中都还存在大量的Makefile。也许make就是构建语言里的C语言,无论世界如何发展变化,它的生命力依然旺盛。未来的很长一段时间内Android.bp和Android.mk可能会一直共存,一起完成Android系统源码的构建。这并不代表我们可以不用去学习Android.bp,技术总是不断的发展,我们则需要不断的学习才能适应技术的发展。

https://android.googlesource.com/platform/build/soong/
https://android.googlesource.com/platform/build/soong/+/HEAD/docs/best_practices.md#network-access

作者:qiuxintai
链接:https://www.jianshu.com/p/f69d1c381182
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

来源地址:https://blog.csdn.net/weixin_45264425/article/details/127138579

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯