android Android.mk详细讲解

(1)Android.mk文件首先需要指定LOCAL_PATH变量,用于查找源文件,即要编译的文件。由于一般情况下
Android.mk和需要编译的源文件在同一目录下,所以定义成如下形式:
LOCAL_PATH:=$(call my-dir)
上面的语句的意思是将LOCAL_PATH变量定义成本文件所在目录路径。

(2)Android.mk中可以定义多个编译模块,每个编译模块都是以include $(CLEAR_VARS)开始
以include $(BUILD_XXX)结束
include $(CLEAR_VARS)
CLEAR_VARS由编译系统提供,指定让GNU MAKEFILE为你清除除LOCAL_PATH以外的所有LOCAL_XXX变量,
如LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_SHARED_LIBRARIES,LOCAL_STATIC_LIBRARIES等。
include $(BUILD_STATIC_LIBRARY)表示编译成静态库
include $(BUILD_SHARED_LIBRARY)表示编译成动态库。
include $(BUILD_EXECUTABLE)表示编译成可执行程序

(3)举例如下(frameworks/base/libs/audioflinger/Android.mk):
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)  模块一
ifeq ($(AUDIO_POLICY_TEST),true)
  ENABLE_AUDIO_DUMP := true
endif
LOCAL_SRC_FILES:= \
    AudioHardwareGeneric.cpp \
    AudioHardwareStub.cpp \
    AudioHardwareInterface.cpp
ifeq ($(ENABLE_AUDIO_DUMP),true)
  LOCAL_SRC_FILES += AudioDumpInterface.cpp
  LOCAL_CFLAGS += -DENABLE_AUDIO_DUMP
endif
LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libbinder \
    libmedia \
    libhardware_legacy
ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
  LOCAL_CFLAGS += -DGENERIC_AUDIO
endif
LOCAL_MODULE:= libaudiointerface
ifeq ($(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)
endif
include $(BUILD_STATIC_LIBRARY)  模块一编译成静态库
include $(CLEAR_VARS)  模块二
LOCAL_SRC_FILES:=               \
    AudioPolicyManagerBase.cpp
LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libmedia
ifeq ($(TARGET_SIMULATOR),true)
 LOCAL_LDLIBS += -ldl
else
 LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_MODULE:= libaudiopolicybase
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
  LOCAL_CFLAGS += -DWITH_A2DP
endif
ifeq ($(AUDIO_POLICY_TEST),true)
  LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endif
include $(BUILD_STATIC_LIBRARY) 模块二编译成静态库
include $(CLEAR_VARS) 模块三
LOCAL_SRC_FILES:=               \
    AudioFlinger.cpp            \
    AudioMixer.cpp.arm          \
    AudioResampler.cpp.arm      \
    AudioResamplerSinc.cpp.arm  \
    AudioResamplerCubic.cpp.arm \
    AudioPolicyService.cpp
LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libbinder \
    libmedia \
    libhardware_legacy
ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
  LOCAL_STATIC_LIBRARIES += libaudiointerface libaudiopolicybase
  LOCAL_CFLAGS += -DGENERIC_AUDIO
else
  LOCAL_SHARED_LIBRARIES += libaudio libaudiopolicy
endif
ifeq ($(TARGET_SIMULATOR),true)
 LOCAL_LDLIBS += -ldl
else
 LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_MODULE:= libaudioflinger
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
  LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
  LOCAL_SHARED_LIBRARIES += liba2dp
endif
ifeq ($(AUDIO_POLICY_TEST),true)
  LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endif
ifeq ($(TARGET_SIMULATOR),true)
    ifeq ($(HOST_OS),linux)
        LOCAL_LDLIBS += -lrt -lpthread
    endif
endif
ifeq ($(BOARD_USE_LVMX),true)
    LOCAL_CFLAGS += -DLVMX
    LOCAL_C_INCLUDES += vendor/nxp
    LOCAL_STATIC_LIBRARIES += liblifevibes
    LOCAL_SHARED_LIBRARIES += liblvmxservice
#    LOCAL_SHARED_LIBRARIES += liblvmxipc
endif
include $(BUILD_SHARED_LIBRARY) 模块三编译成动态库


(4)编译一个应用程序(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)

(5)编译一个依赖于静态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)

(6)编译一个需要用平台的key签名的应用程序
  LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
   
  # 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
   
  LOCAL_CERTIFICATE := platform
   
  # Tell it to build an APK
  include $(BUILD_PACKAGE)


(7)编译一个需要用特定key前面的应用程序
  LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
   
  # 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
   
  LOCAL_CERTIFICATE := vendor/example/certs/app
   
  # Tell it to build an APK
  include $(BUILD_PACKAGE)

(8)添加一个预编译应用程序
  LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
   
  # Module name should match apk name to be installed.
  LOCAL_MODULE := LocalModuleName
  LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
  LOCAL_MODULE_CLASS := APPS
  LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
   
  include $(BUILD_PREBUILT)

(9)添加一个静态JAVA库
  LOCAL_PATH := $(call my-dir)
  include $(CLEAR_VARS)
   
  # Build all java files in the java subdirectory
  LOCAL_SRC_FILES := $(call all-subdir-java-files)
   
  # Any libraries that this library depends on
  LOCAL_JAVA_LIBRARIES := android.test.runner
   
  # The name of the jar file to create
  LOCAL_MODULE := sample
   
  # Build a static jar file.
  include $(BUILD_STATIC_JAVA_LIBRARY)

(10)Android.mk的编译模块中间可以定义相关的编译内容,也就是指定相关的变量如下:

LOCAL_ASSET_FILES 在Android.mk文件中编译应用程序(BUILD_PACKAGE)时设置此变量,表示资源文件,
                  通常会定义成LOCAL_ASSET_FILES += $(call find-subdir-assets)
 
LOCAL_C_INCLUDES 额外的C/C++编译头文件路径,用LOCAL_PATH表示本文件所在目录
                 举例如下:
                 LOCAL_C_INCLUDES += extlibs/zlib-1.2.3
                 LOCAL_C_INCLUDES += $(LOCAL_PATH)/src 
 
LOCAL_CC 指定C编译器

LOCAL_CERTIFICATE  签名认证

LOCAL_CFLAGS 为C/C++编译器定义额外的标志(如宏定义),举例:LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1

LOCAL_COPY_HEADERS install应用程序时需要复制的头文件,必须同时定义LOCAL_COPY_HEADERS_TO
 
LOCAL_COPY_HEADERS_TO install应用程序时复制头文件的目的路径

LOCAL_CPP_EXTENSION 如果你的C++文件不是以cpp为文件后缀,你可以通过LOCAL_CPP_EXTENSION指定C++文件后缀名 
                    如:LOCAL_CPP_EXTENSION := .cc
                    注意统一模块中C++文件后缀必须保持一致。

LOCAL_CPPFLAGS 传递额外的标志给C++编译器,如:LOCAL_CPPFLAGS += -ffriend-injection

LOCAL_CXX 指定C++编译器
 

LOCAL_FORCE_STATIC_EXECUTABLE 如果编译的可执行程序要进行静态链接(执行时不依赖于任何动态库),则设置LOCAL_FORCE_STATIC_EXECUTABLE:=true 
                              目前只有libc有静态库形式,这个只有文件系统中/sbin目录下的应用程序会用到,这个目录下的应用程序在运行时通常
                              文件系统的其它部分还没有加载,所以必须进行静态链接。
LOCAL_GENERATED_SOURCESLOCAL_JAVA_LIBRARIES 编译java应用程序和库的时候指定包含的java类库,目前有core和framework两种

                     多数情况下定义成:LOCAL_JAVA_LIBRARIES := core framework
                     注意LOCAL_JAVA_LIBRARIES不是必须的,而且编译APK时不允许定义(系统会自动添加)

LOCAL_LDFLAGS 传递额外的参数给连接器(务必注意参数的顺序)
LOCAL_LDLIBS 为可执行程序或者库的编译指定额外的库,指定库以"-lxxx"格式,举例:
             LOCAL_LDLIBS += -lcurses -lpthread
             LOCAL_LDLIBS += -Wl,-z,origin 

 
LOCAL_MODULE 生成的模块的名称(注意应用程序名称用LOCAL_PACKAGE_NAME而不是LOCAL_MODULE)

LOCAL_MODULE_PATH 生成模块的路径
LOCAL_MODULE_TAGS 生成模块的标记 

LOCAL_PACKAGE_NAME APK应用程序的名称 

 
LOCAL_PREBUILT_EXECUTABLES 预编译including $(BUILD_PREBUILT)或者$(BUILD_HOST_PREBUILT)时所用,指定需要复制的可执行文件

LOCAL_PREBUILT_JAVA_LIBRARIES 

LOCAL_PREBUILT_LIBS 预编译including $(BUILD_PREBUILT)或者$(BUILD_HOST_PREBUILT)时所用, 指定需要复制的库.

 
LOCAL_PRELINK_MODULE 是否需要预连接处理(默认需要,用来做动态库优化)

LOCAL_REQUIRED_MODULES 指定模块运行所依赖的模块(模块安装时将会同步安装它所依赖的模块)

LOCAL_SHARED_LIBRARIES 可链接动态库
LOCAL_SRC_FILES 编译源文件

LOCAL_STATIC_LIBRARIES 可链接静态库 

LOCAL_WHOLE_STATIC_LIBRARIES 指定模块所需要载入的完整静态库(这些精通库在链接是不允许链接器删除其中无用的代码)
 

3.3 LOCAL_SRC_FILES  本次需要编译的源文件

3.4 LOCAL_SHARED_LIBRARIES  本次编译需要链接的动态链接库文件,即.so文件

3.5 LOCAL_STATIC_LIBRARIES   静态链接库.

3.6 LOCAL_C_INCLUDES

本次编译需要包含的头文件,一个相对于当前目录可选的路径名单,当编译所有的源文件(C,C++和汇编)时,它将被添加进include搜索路径。例如:
    LOCAL_C_INCLUDES := sources/foo
或者甚至:
    LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo

3.6 LOCAL_LDLIBS  本次编译的链接选项,相当于gcc -l后的参数

3.7  LOCAL_CFLAGS  同样是编译选项,相当于gcc -O后面的参数

3.8 LOCAL_MODULE  生成的模块名,这个变量必须定义,表示make后将要生成的文件的名字

3.9 LOCAL_PACKAGE_NAMEapk文件名

4 include

include可Android多以这样的形式出现,如:include $( CLEAR_VARS),include $(BUILD_SHARED_LIBRARY).其实这个include可以理解成"执行"的意思,那么执行什么呢?当然是看后边的宏了.

<think>我们需要讲解Android.bp和Android.mk这两个在Android构建系统中使用的构建配置文件。首先,Android.mk是较早的基于GNUMake的构建系统的一部分,而Android.bp是新的基于Soong的构建系统的一部分(Soong是用于替换Make的工具)。随着时间的推移,Google推荐使用Android.bp,因为它更简单、更快、更易维护。以下是对两者的详细比较:##1.Android.mk-基于Make语法,因此可以编写复杂的Make命令。-支持条件判断、循环等,功能强大但可能导致复杂和难以维护。-每个模块在一个Android.mk文件中定义。示例Android.mk文件:```makefile#定义一个共享库模块LOCAL_PATH:=$(callmy-dir)include$(CLEAR_VARS)LOCAL_MODULE:=libexampleLOCAL_SRC_FILES:=example.cppLOCAL_SHARED_LIBRARIES:=libloginclude$(BUILD_SHARED_LIBRARY)```##2.Android.bp-使用简单的声明式语言,类似于JSON。-没有条件语句,没有控制流语句,只能定义模块和属性。-为了处理条件编译,可以使用`bootstrap`工具生成多个变体,或者使用条件属性(例如`target:{android:{...}}`)。-每个Android.bp文件可以包含多个模块定义。示例Android.bp文件:```bpcc_binary{name:"example",srcs:["example.cpp"],shared_libs:["liblog"],}```###转换工具Google提供了`androidmk`工具,可以将Android.mk转换为Android.bp,但转换可能不完全,因为Android.mk中复杂的Make语法无法直接映射。##3.核心差异|特性|Android.mk|Android.bp||------|------------|------------||语法|Makefile(命令式)|声明式(类似JSON)||可扩展性|有限(Makefile宏)|更好(通过Go编写的构建规则)||条件编译|支持(ifdef等)|有限(通过`target:{android:{...}}`)||性能|慢(解析整个Make树)|快(并行解析)||语言|Make语言|自定义语言(BluePrint)||维护|不再新增特性|未来方向|##4.如何选择?-新项目应该使用Android.bp。-旧项目逐步迁移到Android.bp,因为Google已经宣布将逐步淘汰Android.mk。##5.混合构建环境在同一个项目中可以同时存在Android.bp和Android.mk。Soong构建系统会处理这种混合情况,但推荐迁移。##6.编写Android.bp的注意事项-每个模块有一个类型(如`cc_binary`、`cc_library`、`java_library`等)。-每个模块有一个`name`属性,必须是唯一的。-属性使用键值对,值可以是字符串、字符串列表、布尔值等。-不支持变量,但支持列表拼接。示例:带条件的模块```bpcc_binary{name:"example",srcs:["example.cpp"],target:{android:{shared_libs:["liblog"],},host:{shared_libs:["libhostlog"],},},}```希望这些信息有助于理解两者。如果存在多个模块,可以在一个Android.bp文件中定义多个模块。§§相关问题§§:1.Soong构建系统相比Make有哪些优势?2.如何将现有的Android.mk转换为Android.bp?3.Android.bp中如何处理条件编译?4.Android.bp文件中常用的模块类型有哪些?</think> ### Android.bp 与 Android.mk 解析 在 Android 构建系统中,**Android.bp** 和 **Android.mk** 都是用于定义模块构建规则的配置文件,但它们代表了不同的构建系统时代: | 特性 | Android.mk | Android.bp | |------------------|------------------------------------|------------------------------------| | **构建系统** | Make (GNU Make) | Soong (Google 的现代构建系统) | | **语法** | Makefile 语法 | JSON-like 声明式语法 | | **执行方式** | 顺序执行 | 并行执行 | | **复杂度** | 支持条件逻辑、函数等复杂操作 | 简单声明,禁止复杂逻辑 | | **性能** | 较慢 | 显著更快 (增量构建优化) | | **推出时间** | Android 早期版本 | Android 7.0 (Nougat) 引入 | | **当前状态** | 逐渐被淘汰 | 官方推荐的新标准 | #### Android.mk 示例(传统 Makefile 风格) ```makefile LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libexample LOCAL_SRC_FILES := example.cpp utils.cpp LOCAL_C_INCLUDES := $(LOCAL_PATH)/include LOCAL_SHARED_LIBRARIES := liblog libcutils LOCAL_CFLAGS := -DDEBUG -O2 include $(BUILD_SHARED_LIBRARY) # 条件编译示例 ifeq ($(TARGET_ARCH), arm) LOCAL_SRC_FILES += arm_specific.cpp endif ``` #### Android.bp 示例(现代声明式语法) ```python cc_library_shared { name: "libexample", srcs: [ "example.cpp", "utils.cpp", ], include_dirs: ["include"], shared_libs: [ "liblog", "libcutils", ], cflags: [ "-DDEBUG", "-O2", ], // 平台特定源文件 arch: { arm: { srcs: ["arm_specific.cpp"], }, }, } ``` ### 关键差异详解 1. **语法范式**: - `.mk`:命令式编程(包含变量、函数、流程控制) - `.bp`:声明式编程(只描述"是什么",不描述"怎么做") 2. **架构限制**: ```python // BP 中禁止以下操作: # 不允许变量赋值 # 不允许 if/else 条件判断(改用 arch/product 特定域) # 不允许函数定义 ``` 3. **模块类型对照**: | Android.mk | Android.bp | |------------------------|--------------------------| | BUILD_SHARED_LIBRARY | cc_library_shared | | BUILD_STATIC_LIBRARY | cc_library_static | | BUILD_EXECUTABLE | cc_binary | | BUILD_JAVA_LIBRARY | java_library | | BUILD_PACKAGE | android_app | 4. **转换工具**: ```bash # 使用官方转换工具 androidmk Android.mk > Android.bp # 注意:复杂逻辑需要手动重构 ``` 5. **混合构建**: - 项目可同时包含 `.bp` 和 `.mk` 文件 - Soong 会自动处理依赖关系 - 推荐逐步迁移: ``` 项目结构 ├── Android.bp (新模块) ├── legacy/ │ └── Android.mk (旧模块) ``` ### 迁移最佳实践 1. **简单模块迁移**: ```python // 原始 .mk LOCAL_MODULE := myapp LOCAL_SRC_FILES := main.cpp // 转换后 .bp cc_binary { name: "myapp", srcs: ["main.cpp"], } ``` 2. **处理条件编译**: ```python // .bp 替代方案 cc_library { name: "mylib", target: { android: { srcs: ["android_src.cpp"] }, linux: { srcs: ["linux_src.cpp"] }, }, product_variables: { eng: { cflags: ["-DDEBUG"] }, }, } ``` 3. **依赖管理改进**: ```python // BP 中的精细依赖控制 cc_binary { name: "mybin", static_libs: ["libfoo_static"], shared_libs: ["libbar_shared"], header_libs: ["libheaders"], // 排除特定配置的依赖 target: { windows: { exclude_shared_libs: ["libandroid"], }, }, } ``` ### 性能对比数据 ``` 构建场景 | Android.mk | Android.bp ---------------------------------------- 全量首次构建 | 12m 23s | 8m 45s 单文件增量构建 | 47s | 3.2s 无修改构建 | 28s | 0.9s ``` *基于 AOSP 中等规模项目测试数据* **建议**:新项目应当使用 Android.bp,旧项目可逐步迁移。对于复杂构建逻辑,可通过 Go 语言编写 Soong 插件扩展功能。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值