cmake文件介绍及用法

一、Android.mk(Legacy,但仍广泛使用)

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

6. 选择器(Arch/Platform 条件)

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 互操作

在 Android.bp 中引用 Android.mk

bp 复制代码
// Android.bp
cc_binary {
    name: "my_tool",
    srcs: ["tool.cpp"],
    // 引用 mk 中定义的库
    shared_libs: ["libmk_defined"],  // 在 mk 中定义的模块
}

Android.mk 中引用 Android.bp

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 选择器
可读性 较差(变量多) 较好(结构化)

相关推荐
寻寻觅觅☆5 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
fpcc5 小时前
并行编程实战——CUDA编程的Parallel Task类型
c++·cuda
小白同学_C5 小时前
Lab4-Lab: traps && MIT6.1810操作系统工程【持续更新】 _
linux·c/c++·操作系统os
今天只学一颗糖5 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
冬奇Lab6 小时前
Android系统启动流程深度解析:从Bootloader到Zygote的完整旅程
android·源码阅读
ceclar1236 小时前
C++使用format
开发语言·c++·算法
lanhuazui107 小时前
C++ 中什么时候用::(作用域解析运算符)
c++
charlee447 小时前
从零实现一个生产级 RAG 语义搜索系统:C++ + ONNX + FAISS 实战
c++·faiss·onnx·rag·语义搜索
不做无法实现的梦~7 小时前
ros2实现路径规划---nav2部分
linux·stm32·嵌入式硬件·机器人·自动驾驶
老约家的可汗7 小时前
初识C++
开发语言·c++