小工具知识网

当前位置: 首页 > 行业知识 > Android 编译的配置文件:android.mk 和android.bp

行业知识

Android 编译的配置文件:android.mk 和android.bp

2026-11-04 13:14:09 来源:互联网转载

Android.bp文件首先是Android系统的一种编译配置文件,是用来代替原来的Android.mk文件的。在Android7.0以前,Android都是使用make来组织各模块的编译,对应的编译配置文件就是Android.mk。在Android7.0开始,Google引入了ninja和kati来编译,为什么引入ninja?因为随着Android越来越庞大,module越来越多,编译时间也越来越久,而使用ninja在编译的并发处理上较make有很大的提升。Ninja的配置文件就是Android.bp,Android系统使用Blueprint和Soong工具来解析Android.bp转换生成ninja文件。为了兼容老的mk配置文件,Android当初也开发了Kati 工具来转换mk文件生成ninja,目前Android Q里边,还是支持Android.mk方式的。相信在将来的版本中,会彻底让mk文件废弃,同时Kati也就淘汰了,只保留bp配置方式,所以我们要提前学习bp。Blueprint和Soong工具的源码在Android/build/目录下,我们可以通过查阅相关代码来学习。

Make 和 Soong 比较

Make 示例

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := libxmlrpc++LOCAL_MODULE_HOST_OS := linuxLOCAL_RTTI_FLAG := -frttiLOCAL_CPPFLAGS := -Wall -Werror -fexceptionsLOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/srcLOCAL_SRC_FILES := $(call \     all-cpp-files-under,src)include $(BUILD_SHARED_LIBRARY)

 Soong 示例

cc_library_shared {     name: “libxmlrpc++”,     rtti: true,     cppflags: [           “-Wall”,           “-Werror”,           “-fexceptions”,     ],     export_include_dirs: [“src”],     srcs: [“src/**/*.cpp”],     target: {           darwin: {                enabled: false,           },     },}

android.mk

android.mk 一般位于工程目录中以“LOCAL_PATH := $(call my-dir)”开始,每个mk 可以编译多个应用以inclue $(CLEAR_VARS) 开始,include $(BUILD_XXX)结束,BUILD_XXX 为此应用的类型.

下面介绍一下android.mk的主要参数:
  • LOCAL_MODULE_TAGS (android 10 取消这个参数)

            此参数会影响到库生成后的存放位置.

    LOCAL_MODULE_TAGS :=user eng tests optionaluser: 指该模块只在user版本下才编译eng: 指该模块只在eng版本下才编译tests: 指该模块只在tests版本下才编译optional:指该模块在所有版本下都编译
    • LOCAL_PRELINK_MODULE

              Prelink利用事先链接代替运行时链接的方法来加速共享库的加载,它不仅可以加快起动速度,还可以减少部分内存开销,是各种Linux架构上用于减少程序加载时间、缩短系统启动时间和加快应用程序启动的很受欢迎的一个工具。程序运行时的动态链接尤其是重定位(relocation)的开销对于大型系统来说是很大的。

      变量设置为false那么将不做prelink操作LOCAL_PRELINK_MODULE := false
      • LOCAL_MODULE_RELATIVE_PATH 

        指定动态库的相对路径,以各自编译对象放置的目录为参考。

      • LOCAL_MODULE_PATH:

        目标的安装路径LOCAL_PATH := $(call my-dir)

      • TARGET_ROOT_OUT:表示根文件系统。

      • TARGET_OUT:表示system文件系统。

      • TARGET_OUT_DATA:表示data文件系统。

      • LOCAL_CFLAGS  : C语言编译时额外选项,

        #-Wno-unused- 加上对应的变量或参数类型,即可忽略当前警告,编译通过。LOCAL_CFLAGS += -Wno-unused-const-variable \                   -Wno-unused-variable \                -Wno-unused-parameter
        • LOCAL_CXXFLAGS : C++语言编译时额外选项
        • LOCAL_SRC_FILES :指定源文件位置
        • LOCAL_CC :指定C 编译器
        • LOCAL_CXX : 指定 C++ 编译器
        • LOCA_C_INCLUDES :编译c c++ 所需额外头文件
        • LOCAL_STATIC_LIBRARIES 编译时所需静态库列表
        • LOCAL_SHARTED_LIBRARIES 编译时所需共享库列表
        • LOCAL_JAVA_LIBRARIES 编译时所需JAVA类库
        • BUILD_HOST_XXX ,BUILD_STATIC_XXX ,BUILD_XXX : 各种形式的编译模版,如生成设备端,HOST端,动态库,可执行文件,文档等。

          android.mk 的常用模版

          • NDK C++
             1.必须以LOCAL_PATH开头,用于在开发树种查找源文件# 2.my-dir为宏,由编译系统提供,返回包含Android.mk文件的目录路径LOCAL_PATH := $(call my-dir)  # 1.CLEAR_VARS由build system提供,指向一个指定的GNU Makefile# 2.负责清理LOCAL_xxx变量,但不清理LOCAL_PATH# 3.由于所有编译文件都是同一个GNU Makefile解析和执行,变量是全局的,所以清理后才能避免相互影响include $(CLEAR_VARS) # 1.包含要编译的源文件LOCAL_SRC_FILES := src/1.cpp src/2.cpp src/3.cpp \                   src/4.cpp src/5.cpp src/6.cpp# 打印信息方法$(info $(LOCAL_SRC_FILES))$(warning $(LOCAL_SRC_FILES))$(error $(LOCAL_SRC_FILES))# 1.追加要搜索的头文件目录LOCAL_C_INCLUDES += itf/# 1.android系统编译环境配置成debug时加入test工程# 2.envsetup.sh中choosecombo第一个参数配置2即是debug模式ifeq ($(TARGET_BUILD_TYPE), debug)  # 获取test目录下所有cpp文件  define all-cpp-files-under          # 1.$(patsubst ,,):查找中单词是否符合,如果匹配,则以替换。        # 2.%通配符,表示任意长度字符串  $(patsubst ./%,%, $(shell cd $(LOCAL_PATH)/test;find $(1) -name "*.cpp" -or -name "*.cc" -and -not -name ".*"))    endef     define all-test-cpp-files    $(call all-cpp-files-under,.)    endef    LOCAL_SRC_FILES += $(call all-test-cpp-files)   LOCAL_C_INCLUDES += test/includeendif# 1.依赖的动态链接库 # 2.LOCAL_SHARED_LIBRARIES一般是先找编译好的,找不到就编译得到# 3. LOCAL_LDLIBS 一般用于链接系统编译的库# 4. LOCAL_LDFLAGS 一般用于链接第三方库,库要包含扩展名LOCAL_SHARED_LIBRARIES := liblogLOCAL_LDLIBS := $(LOCAL_PATH)/src/liblogLOCAL_LDFLAGS := $(LOCAL_PATH)/src/libthird.so# 1.指定可识别cpp文件的扩展名,只能选择一种,不支持混合LOCAL_CPP_EXTENSION:=.cc .cpp .cxx# 1.定义要生成的模块名字,这里命名为myModule# 2.build system会自动添加适当的前缀和后缀,例如生成动态库则为libmyModule.soLOCAL_MODULE := myModule # 1.指定install路径# 2.optional: out/target/product/OK6410/symbols/system/# 3.eng:  out/target/product/Ok6410/system/LOCAL_MODULE_TAGS := optional # 1.keep_symbols:保留动态库中的符号信息# 2.false:去掉动态库中的符号表等调试信息LOCAL_STRIP_MODULE := keep_symbols LOCAL_INIT_RC := myModule.rc # 1.可选设置,在编译C/C++源码时附加编译选项# 2.比如编译时附加搜索头文件目录的选项,如下所示。这种方法比LOCAL_C_INCLUDES要好,可以被ndk-debug使用# Wall:所有的警告信息,Werror:所有的错误信息, Wunused:所有的未使用变量信息,Wunreachable-code:所有的未找到定义的信息LOCAL_CFLAGS += -ILOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code# 1.分别编译成动态库、静态库、可执行native程序方法# 2.实际使用中选择一个即可# 3.主要作用是收集自从上次调用include $(CLEAR_VARS)后的所有LOCAL_xxx信息include $(BUILD_SHARED_LIBRARY)include $(BUILD_STATIC_LIBRARY)include $(BUILD_EXECUTABLE) 
            • 多模块(frameworks/base/libs/audioflinger/Android.mk)
              LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)  模块一ifeq ($(AUDIO_POLICY_TEST),true)  ENABLE_AUDIO_DUMP := trueendifLOCAL_SRC_FILES:= \    AudioHardwareGeneric.cpp \    AudioHardwareStub.cpp \    AudioHardwareInterface.cppifeq ($(ENABLE_AUDIO_DUMP),true)  LOCAL_SRC_FILES += AudioDumpInterface.cpp  LOCAL_CFLAGS += -DENABLE_AUDIO_DUMPendifLOCAL_SHARED_LIBRARIES := \    libcutils \    libutils \    libbinder \    libmedia \    libhardware_legacyifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)  LOCAL_CFLAGS += -DGENERIC_AUDIOendifLOCAL_MODULE:= libaudiointerfaceifeq ($(BOARD_HAVE_BLUETOOTH),true)  LOCAL_SRC_FILES += A2dpAudioInterface.cpp  LOCAL_SHARED_LIBRARIES += liba2dp  LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP  LOCAL_C_INCLUDES += $(call include-path-for, bluez)endifinclude $(BUILD_STATIC_LIBRARY)  模块一编译成静态库include $(CLEAR_VARS)  模块二LOCAL_SRC_FILES:=               \    AudioPolicyManagerBase.cppLOCAL_SHARED_LIBRARIES := \    libcutils \    libutils \    libmediaifeq ($(TARGET_SIMULATOR),true) LOCAL_LDLIBS += -ldlelse LOCAL_SHARED_LIBRARIES += libdlendifLOCAL_MODULE:= libaudiopolicybaseifeq ($(BOARD_HAVE_BLUETOOTH),true)  LOCAL_CFLAGS += -DWITH_A2DPendififeq ($(AUDIO_POLICY_TEST),true)  LOCAL_CFLAGS += -DAUDIO_POLICY_TESTendifinclude $(BUILD_STATIC_LIBRARY) 模块二编译成静态库include $(CLEAR_VARS) 模块三LOCAL_SRC_FILES:=               \    AudioFlinger.cpp            \    AudioMixer.cpp.arm          \    AudioResampler.cpp.arm      \    AudioResamplerSinc.cpp.arm  \    AudioResamplerCubic.cpp.arm \    AudioPolicyService.cppLOCAL_SHARED_LIBRARIES := \    libcutils \    libutils \    libbinder \    libmedia \    libhardware_legacyifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)  LOCAL_STATIC_LIBRARIES += libaudiointerface libaudiopolicybase  LOCAL_CFLAGS += -DGENERIC_AUDIOelse  LOCAL_SHARED_LIBRARIES += libaudio libaudiopolicyendififeq ($(TARGET_SIMULATOR),true) LOCAL_LDLIBS += -ldlelse LOCAL_SHARED_LIBRARIES += libdlendifLOCAL_MODULE:= libaudioflingerifeq ($(BOARD_HAVE_BLUETOOTH),true)  LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP  LOCAL_SHARED_LIBRARIES += liba2dpendififeq ($(AUDIO_POLICY_TEST),true)  LOCAL_CFLAGS += -DAUDIO_POLICY_TESTendififeq ($(TARGET_SIMULATOR),true)    ifeq ($(HOST_OS),linux)        LOCAL_LDLIBS += -lrt -lpthread    endifendififeq ($(BOARD_USE_LVMX),true)    LOCAL_CFLAGS += -DLVMX    LOCAL_C_INCLUDES += vendor/nxp    LOCAL_STATIC_LIBRARIES += liblifevibes    LOCAL_SHARED_LIBRARIES += liblvmxservice#    LOCAL_SHARED_LIBRARIES += liblvmxipcendifinclude $(BUILD_SHARED_LIBRARY) 模块三编译成动态库
              • 编译一个应用程序(APK)
                 LOCAL_PATH := $(call my-dir)  include $(CLEAR_VARS)     # Build all java files in the java subdirectory-->直译(建立在java子目录中的所有Java文件)  LOCAL_SRC_FILES := $(call all-subdir-java-files)     # Name of the APK to build-->直译(创建APK的名称)  LOCAL_PACKAGE_NAME := LocalPackage     # Tell it to build an APK-->直译(告诉它来建立一个APK)  include $(BUILD_PACKAGE)
                • 编译一个依赖于静态Java库(static.jar)的应用程序
                    LOCAL_PATH := $(call my-dir)  include $(CLEAR_VARS)     # List of static libraries to include in the package  LOCAL_STATIC_JAVA_LIBRARIES := static-library     # Build all java files in the java subdirectory  LOCAL_SRC_FILES := $(call all-subdir-java-files)     # Name of the APK to build  LOCAL_PACKAGE_NAME := LocalPackage     # Tell it to build an APK  include $(BUILD_PACKAGE)

                  android.bp

                  bp 文件相对mk来说文件结构更加清晰,写法更加简单。

                  参考:

                  Soong 构建系统  |  Android 开源项目  |  Android Open Source Project

                  Build Docs (storage.googleapis.com)

                  文件一般以模块类型开头:

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

                  模块类型有:apex_defaults aidl_interface ,cc_binary ,cc_defaults,cc_library_static 等

                  在模块内部都必须定义 name 属性,并且这个属性必须全局唯一,仅有两个例外情况是命名空间和预构建模块中的 Android.bp 属性值,这两个值可能会重复。

                  srcs 属性以字符串列表的形式指定用于构建模块的源文件。您可以使用模块引用语法 ":" 来引用生成源文件的其他模块的输出,如 genrule 或 filegroup。

                  类型

                  变量和属性是强类型,变量根据第一项赋值动态变化,属性由模块类型静态设置。支持的类型为:

                  • 布尔值(true 或 false)
                  • 整数 (int)
                  • 字符串 ("string")
                  • 字符串列表 (["string1", "string2"])
                  • 映射 ({key1: "value1", key2: ["value2"]})

                    条件语句

                    Soong 不支持 Android.bp 文件中的条件语句。但是,编译规则中需要条件语句的复杂问题将在 Go中处理。大多数条件语句都会转换为映射属性,其中选择了映射中的某个值并将其附加到顶级属性。

                    例如,要支持特定于架构的文件,请使用以下命令:

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

                    默认模块

                    默认模块可用于在多个模块中重复使用相同的属性。例如:

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

上一篇:龙族幻想服务器怎么升级?

下一篇:破局数据分析滞后难题,赋能企业高速增长的指标管理解决方案