1. 最简示例
makefile
复制代码
# 文件路径:device/mycompany/mydevice/hello/Android.mk
LOCAL_PATH := $(call my-dir) # 获取当前目录路径
include $(CLEAR_VARS) # 清空所有 LOCAL_ 变量
LOCAL_MODULE := hello # 模块名称(最终生成 libhello.so 或 hello)
LOCAL_SRC_FILES := hello.c # 源文件列表
LOCAL_MODULE_TAGS := optional # 编译标签:optional/eng/debug/tests
include $(BUILD_EXECUTABLE) # 构建类型:可执行文件
2. 常用模块类型
| 类型 |
说明 |
示例 |
BUILD_EXECUTABLE |
可执行文件 |
/system/bin/hello |
BUILD_SHARED_LIBRARY |
动态库 (.so) |
/system/lib64/libhello.so |
BUILD_STATIC_LIBRARY |
静态库 (.a) |
编译时链接,不安装 |
BUILD_JAVA_LIBRARY |
Java 库 (.jar) |
系统框架库 |
BUILD_PACKAGE |
APK 应用 |
/system/app/Hello.apk |
BUILD_PREBUILT |
预编译文件 |
复制已有二进制文件 |
3. 完整 C/C++ 模块示例
makefile
复制代码
LOCAL_PATH := $(call my-dir)
# ========== 静态库 ==========
include $(CLEAR_VARS)
LOCAL_MODULE := libhello_core
LOCAL_SRC_FILES := core.cpp utils.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include \
$(TOP)/external/libxml2/include
LOCAL_CFLAGS := -Wall -Werror -O2 -DNDEBUG
LOCAL_CPPFLAGS := -std=c++14 -fexceptions
include $(BUILD_STATIC_LIBRARY)
# ========== 动态库(依赖上面的静态库)==========
include $(CLEAR_VARS)
LOCAL_MODULE := libhello
LOCAL_SRC_FILES := hello.cpp
LOCAL_STATIC_LIBRARIES := libhello_core
LOCAL_SHARED_LIBRARIES := libutils libcutils liblog
LOCAL_LDLIBS := -llog
LOCAL_MODULE_TAGS := optional
LOCAL_PROPRIETARY_MODULE := true # 放入 vendor 分区(Treble 要求)
LOCAL_VENDOR_MODULE := true
include $(BUILD_SHARED_LIBRARY)
# ========== 可执行文件 ==========
include $(CLEAR_VARS)
LOCAL_MODULE := hello_test
LOCAL_SRC_FILES := main.cpp
LOCAL_SHARED_LIBRARIES := libhello liblog
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/bin # 指定输出路径
include $(BUILD_EXECUTABLE)
4. 关键变量速查
| 变量 |
说明 |
示例 |
LOCAL_PATH |
当前文件目录 |
$(call my-dir) |
LOCAL_MODULE |
模块名(唯一) |
libcamera_hal |
LOCAL_SRC_FILES |
源文件列表 |
a.cpp b.cpp |
LOCAL_C_INCLUDES |
头文件搜索路径 |
$(LOCAL_PATH)/include |
LOCAL_CFLAGS |
C 编译选项 |
-Wall -O2 -DDEBUG |
LOCAL_CPPFLAGS |
C++ 额外选项 |
-std=c++17 |
LOCAL_SHARED_LIBRARIES |
依赖的动态库 |
libutils libbinder |
LOCAL_STATIC_LIBRARIES |
依赖的静态库 |
libhello_core |
LOCAL_MODULE_TAGS |
编译标签 |
optional eng tests |
LOCAL_MODULE_PATH |
输出路径 |
$(TARGET_OUT)/bin |
LOCAL_PROPRIETARY_MODULE |
标记为厂商私有 |
true(放 vendor) |
LOCAL_VENDOR_MODULE |
强制 vendor 分区 |
true |
LOCAL_INIT_RC |
关联 init.rc 脚本 |
hello.rc |
LOCAL_VINTF_FRAGMENTS |
HAL 接口声明 |
android.hardware.camera.xml |
5. 条件编译示例
makefile
复制代码
# 根据平台选择不同源文件
ifeq ($(TARGET_BOARD_PLATFORM),msm8953)
LOCAL_SRC_FILES += platform/qcom/msm8953.cpp
else ifeq ($(TARGET_BOARD_PLATFORM),mt6765)
LOCAL_SRC_FILES += platform/mtk/mt6765.cpp
else
LOCAL_SRC_FILES += platform/generic.cpp
endif
# 根据 debug 类型开启日志
ifeq ($(TARGET_BUILD_VARIANT),userdebug)
LOCAL_CFLAGS += -DLOG_DEBUG -DDUMP_BUFFER
else ifeq ($(TARGET_BUILD_VARIANT),eng)
LOCAL_CFLAGS += -DLOG_DEBUG -DDUMP_BUFFER -DENABLE_PROFILER
else # user
LOCAL_CFLAGS += -DLOG_ERROR_ONLY
endif
二、Android.bp(Blueprint,现代推荐)
Android 8.0+ 引入,替代 Android.mk,语法更清晰。
1. 最简示例
bp
复制代码
// 文件路径:device/mycompany/mydevice/hello/Android.bp
cc_binary {
name: "hello",
srcs: ["hello.c"],
cflags: ["-Wall", "-Werror"],
}
2. 常用模块类型
| 类型 |
说明 |
cc_binary |
C/C++ 可执行文件 |
cc_library_shared |
C/C++ 动态库 |
cc_library_static |
C/C++ 静态库 |
cc_library_headers |
仅头文件库 |
java_library |
Java 库 |
android_app |
APK 应用 |
prebuilt_etc |
预配置文件 |
prebuilt_shared_library |
预编译动态库 |
3. 完整 C/C++ 模块示例
bp
复制代码
// ========== 静态库 ==========
cc_library_static {
name: "libhello_core",
srcs: [
"core.cpp",
"utils.cpp",
],
cflags: [
"-Wall",
"-Werror",
"-O2",
],
cppflags: [
"-std=c++14",
"-fexceptions",
],
export_include_dirs: ["include"], // 导出头文件给依赖者
}
// ========== 动态库 ==========
cc_library_shared {
name: "libhello",
srcs: ["hello.cpp"],
static_libs: ["libhello_core"],
shared_libs: [
"libutils",
"libcutils",
"liblog",
],
cflags: ["-DNDEBUG"],
vendor: true, // 放入 vendor 分区
proprietary: true, // 厂商私有模块
}
// ========== 可执行文件 ==========
cc_binary {
name: "hello_test",
srcs: ["main.cpp"],
shared_libs: ["libhello"],
vendor: true,
init_rc: ["hello.rc"], // 关联 init 脚本
}
4. 关键属性速查
| 属性 |
说明 |
示例 |
name |
模块名(唯一) |
"libcamera_hal" |
srcs |
源文件列表 |
["a.cpp", "b.cpp"] |
cflags |
C/C++ 编译选项 |
["-Wall", "-DDEBUG"] |
cppflags |
C++ 专用选项 |
["-std=c++17"] |
local_include_dirs |
本地头文件路径 |
["include", "src"] |
export_include_dirs |
导出头文件路径 |
["include"] |
shared_libs |
依赖的动态库 |
["libutils"] |
static_libs |
依赖的静态库 |
["libhello_core"] |
header_libs |
头文件库依赖 |
["libhardware_headers"] |
vendor |
放入 vendor 分区 |
true |
proprietary |
厂商私有标记 |
true |
init_rc |
关联 init.rc |
["service.rc"] |
vintf_fragments |
HAL 接口 XML |
["interface.xml"] |
stem |
输出文件名(不同于 name) |
"camera.driver" |
enabled |
是否启用 |
false(条件禁用) |
5. 条件编译(Soong 配置)
bp
复制代码
// 使用 soong_config_module_type 实现条件编译
soong_config_module_type {
name: "cc_library_shared_custom",
module_type: "cc_library_shared",
config_namespace: "my_camera",
bool_variables: ["enable_ai_feature"],
properties: ["cflags", "srcs"],
}
cc_library_shared_custom {
name: "libcamera_ai",
srcs: ["camera_base.cpp"],
cflags: ["-O2"],
// 默认配置
soong_config_variables: {
enable_ai_feature: {
srcs: ["ai_engine.cpp", "neural_net.cpp"],
cflags: ["-DENABLE_AI", "-DUSE_NPU"],
},
},
}
在 BoardConfig.mk 中控制:
makefile
复制代码
SOONG_CONFIG_NAMESPACES += my_camera
SOONG_CONFIG_my_camera += enable_ai_feature
SOONG_CONFIG_my_camera_enable_ai_feature := true
bp
复制代码
cc_library_shared {
name: "libplatform_hal",
srcs: ["generic.cpp"],
// 针对特定架构
arch: {
arm: {
srcs: ["arm/optimized.cpp"],
cflags: ["-DARM_OPTIMIZED"],
},
arm64: {
srcs: ["arm64/optimized.cpp"],
},
x86: {
srcs: ["x86/simulation.cpp"],
},
},
// 针对特定平台
target: {
android_arm: {
cflags: ["-DANDROID_ARM"],
},
},
// 针对特定产品
product_variables: {
debuggable: {
cflags: ["-DDEBUG_BUILD"],
},
},
}
三、mk 与 bp 互操作
bp
复制代码
// Android.bp
cc_binary {
name: "my_tool",
srcs: ["tool.cpp"],
// 引用 mk 中定义的库
shared_libs: ["libmk_defined"], // 在 mk 中定义的模块
}
makefile
复制代码
# Android.mk
LOCAL_SHARED_LIBRARIES := libbp_defined # 可以引用 bp 中的模块
四、常用调试命令
bash
复制代码
# 查看模块是否被识别
m -n <模块名> # 干运行,看构建命令
m <模块名> # 编译指定模块
mm # 编译当前目录模块(需先 source/lunch)
mma # 编译当前目录及依赖
# 查看模块信息
bpfmt -w Android.bp # 格式化 bp 文件
bpprint <模块名> # 打印模块最终配置(需 soong 环境)
# 清理
m clean-<模块名>
五、快速对照表
| 功能 |
Android.mk |
Android.bp |
| 定义模块 |
include $(CLEAR_VARS) ... include $(BUILD_XXX) |
xxx { ... } |
| 模块名 |
LOCAL_MODULE |
name |
| 源文件 |
LOCAL_SRC_FILES |
srcs |
| 头文件路径 |
LOCAL_C_INCLUDES |
local_include_dirs |
| 编译选项 |
LOCAL_CFLAGS |
cflags |
| 动态库依赖 |
LOCAL_SHARED_LIBRARIES |
shared_libs |
| 静态库依赖 |
LOCAL_STATIC_LIBRARIES |
static_libs |
| Vendor 分区 |
LOCAL_PROPRIETARY_MODULE := true |
vendor: true |
| 条件编译 |
ifeq ... endif |
soong_config / arch 选择器 |
| 可读性 |
较差(变量多) |
较好(结构化) |