iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Android——编译(三):android.bp的相关知识
  • 594
分享到

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

android 2023-08-21 08:08:33 594人浏览 八月长安
摘要

本文是最后一篇,主要介绍Android.bp。:转载自Android 编译之android.bp 作者:qiuxintai 链接:https://www.jianshu.com/p/f69d1c381182 来源:简书 著作权归作者所有。商

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

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

1. Ninja

1.1 Ninja简介

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

  • Ninja的输入文件被设计为由更高级的构建系统生成。

  • 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. Blueprint

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等等命令来构建模块。

3. kati

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. soong

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的规范格式包括:

  • 4个空格缩进。
  • 多元素列表的每个元素后的换行符。
  • 在lists和maps的结尾处始终包含一个逗号。

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

bpfmt -w .

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

  • kati可以将Android.mk文件转换成ninja文件。
  • androidmk可以将Android.mk文件转换成Android.bp文件
  • Blueprint可以将Android.bp文件转换成ninja文件。
  • Blueprint,kati,androidmk由Soong调用和协调,一起合作完成android源码的构建。

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

5. Android.bp

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.Android.bp实战

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,    },}

8. 结语

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

9.本文参考

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

--结束END--

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

本文链接: https://www.lsjlt.com/news/376791.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++ 生态系统中流行库和框架的贡献指南
    作为 c++++ 开发人员,通过遵循以下步骤即可为流行库和框架做出贡献:选择一个项目并熟悉其代码库。在 issue 跟踪器中寻找适合初学者的问题。创建一个新分支,实现修复并添加测试。提交...
    99+
    2024-05-15
    框架 c++ 流行库 git
  • C++ 生态系统中流行库和框架的社区支持情况
    c++++生态系统中流行库和框架的社区支持情况:boost:活跃的社区提供广泛的文档、教程和讨论区,确保持续的维护和更新。qt:庞大的社区提供丰富的文档、示例和论坛,积极参与开发和维护。...
    99+
    2024-05-15
    生态系统 社区支持 c++ overflow 标准库
  • c++中if elseif使用规则
    c++ 中 if-else if 语句的使用规则为:语法:if (条件1) { // 执行代码块 1} else if (条件 2) { // 执行代码块 2}// ...else ...
    99+
    2024-05-15
    c++
  • c++中的继承怎么写
    继承是一种允许类从现有类派生并访问其成员的强大机制。在 c++ 中,继承类型包括:单继承:一个子类从一个基类继承。多继承:一个子类从多个基类继承。层次继承:多个子类从同一个基类继承。多层...
    99+
    2024-05-15
    c++
  • c++中如何使用类和对象掌握目标
    在 c++ 中创建类和对象:使用 class 关键字定义类,包含数据成员和方法。使用对象名称和类名称创建对象。访问权限包括:公有、受保护和私有。数据成员是类的变量,每个对象拥有自己的副本...
    99+
    2024-05-15
    c++
  • c++中优先级是什么意思
    c++ 中的优先级规则:优先级高的操作符先执行,相同优先级的从左到右执行,括号可改变执行顺序。操作符优先级表包含从最高到最低的优先级列表,其中赋值运算符具有最低优先级。通过了解优先级,可...
    99+
    2024-05-15
    c++
  • c++中a+是什么意思
    c++ 中的 a+ 运算符表示自增运算符,用于将变量递增 1 并将结果存储在同一变量中。语法为 a++,用法包括循环和计数器。它可与后置递增运算符 ++a 交换使用,后者在表达式求值后递...
    99+
    2024-05-15
    c++
  • c++中a.b什么意思
    c++kquote>“a.b”表示对象“a”的成员“b”,用于访问对象成员,可用“对象名.成员名”的语法。它还可以用于访问嵌套成员,如“对象名.嵌套成员名.成员名”的语法。 c++...
    99+
    2024-05-15
    c++
  • C++ 并发编程库的优缺点
    c++++ 提供了多种并发编程库,满足不同场景下的需求。线程库 (std::thread) 易于使用但开销大;异步库 (std::async) 可异步执行任务,但 api 复杂;协程库 ...
    99+
    2024-05-15
    c++ 并发编程
  • 如何在 Golang 中备份数据库?
    在 golang 中备份数据库对于保护数据至关重要。可以使用标准库中的 database/sql 包,或第三方包如 github.com/go-sql-driver/mysql。具体步骤...
    99+
    2024-05-15
    golang 数据库备份 mysql git 标准库
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作