在Android开发中,make命令是构建系统的核心工具,主要用于编译、打包整个系统或模块,Android的构建系统基于GNU Make和Soong(新版本)两种技术栈,其中make命令主要用于处理传统的Android.mk文件,实现对C/C++代码的编译和模块管理,本文将详细解析make命令的使用方法、核心参数、工作流程及常见场景。

make命令的基本使用
make命令通过读取Makefile文件(在Android中主要是Android.mk和Android.bp)来确定编译目标和依赖关系,在Android源码根目录下执行make
命令时,默认会编译整个系统,开发者可以通过指定目标模块或参数来控制编译范围。
make bootimage
:仅编译启动镜像。make -j4
:使用4个并行任务加速编译,-j
后的数字通常根据CPU核心数设置(建议-j$(nproc)
)。make showcommands
:显示详细的编译命令,便于调试。
Android构建系统的核心文件
Android构建系统的核心是Android.mk文件,它定义了模块的属性和依赖关系,以下是一个典型的Android.mk示例:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libexample LOCAL_SRC_FILES := example.c LOCAL_C_INCLUDES := $(LOCAL_PATH)/include LOCAL_SHARED_LIBRARIES := libcutils include $(BUILD_SHARED_LIBRARY)
关键变量说明:
LOCAL_MODULE
:定义模块名,最终生成libexample.so
。LOCAL_SRC_FILES
:指定源文件路径。LOCAL_C_INCLUDES
:添加头文件搜索路径。LOCAL_SHARED_LIBRARIES
:声明依赖的动态库。BUILD_SHARED_LIBRARY
:表示生成动态库,还可选择BUILD_STATIC_LIBRARY
(静态库)或EXECUTABLES
(可执行文件)。
make命令的核心参数
Android的make命令支持多种参数以控制编译行为,以下是常用参数的总结:

参数 | 说明 | 示例 |
---|---|---|
TARGET_PRODUCT |
指定目标产品 | make TARGET_PRODUCT=aosp_x86 |
TARGET_BUILD_TYPE |
构建类型(user/userdebug/debug) | make TARGET_BUILD_TYPE=debug |
WITHOUT_CHECK_API |
跳过API检查 | make WITHOUT_CHECK_API=true |
droid |
默认编译整个系统 | make droid |
clean |
清理编译产物 | make clean |
snod |
重新打包系统镜像 | make snod |
make命令的工作流程
- 解析Android.mk:构建工具递归遍历各目录下的Android.mk文件,生成模块描述信息。
- 依赖分析:根据模块间的依赖关系(如
LOCAL_SHARED_LIBRARIES
)构建依赖图。 - 编译执行:调用GCC/Clang编译源文件,生成.o目标文件,再链接成.so或可执行文件。
- 打包生成:将编译后的模块、资源等打包成系统镜像(如system.img、boot.img)。
常见场景与技巧
-
单模块编译:
若仅需编译特定模块,可通过make <模块名>
实现,例如make libutils
会编译libutils模块及其依赖。 -
增量编译:
修改源码后重新执行make
,构建系统会自动跳过未修改的模块,大幅缩短编译时间。 -
交叉编译:
Android使用交叉编译工具链(如aarch64-linux-android-clang
),可通过make showcommands
查看实际编译命令。 -
环境变量配置:
在.bashrc
中设置export OUT=out
可指定编译输出目录,默认为out/target/product/<设备名>
。(图片来源网络,侵删)
常见问题与解决方案
-
编译报错“No rule to make target”:
通常因模块名拼写错误或Android.mk未正确声明模块,需检查LOCAL_MODULE
是否与make命令中的目标一致。 -
依赖库未找到:
确保依赖库已在Android.mk中通过LOCAL_SHARED_LIBRARIES
声明,且已执行make <依赖库名>
。
相关问答FAQs
Q1: 如何查看Android系统中所有可编译的模块列表?
A1: 执行make showtargets
命令,会输出所有可用的模块目标列表,包括预置库、可执行文件等,也可通过grep "include \$(BUILD_" device/*/vendor/*/Android.mk
扫描所有Android.mk文件中的模块定义。
Q2: make命令与Soong(mm/mmm)的区别是什么?
A2: make命令基于GNU Make和Android.mk,主要用于大型系统级编译;而Soong(通过mm
或mmm
命令调用)使用Android.bp文件,语法更简洁,支持并行度更高,逐渐成为Android构建系统的主流方案,对于新项目,推荐使用Soong,但维护旧代码时仍需掌握make命令。