【NDK开发】Android NDK 原生构建:ndk-build 与 CMake

文章目录

    • [一、ndk-build 构建系统](#一、ndk-build 构建系统)
      • [1.1 什么是 ndk-build 构建系统](#1.1 什么是 ndk-build 构建系统)
      • [1.2 核心配置文件](#1.2 核心配置文件)
      • [1.3 ndk-build 构建流程](#1.3 ndk-build 构建流程)
      • [1.4 ndk-build 最佳实践](#1.4 ndk-build 最佳实践)
    • [二、CMake 构建系统](#二、CMake 构建系统)
      • [2.1 什么是 CMake](#2.1 什么是 CMake)
      • [2.2 CMake 构建流程](#2.2 CMake 构建流程)
      • [2.3 CMakeLists.txt 配置示例](#2.3 CMakeLists.txt 配置示例)
    • 总结
    • 参考资料

一、ndk-build 构建系统

1.1 什么是 ndk-build 构建系统

ndk-build 是 Android NDK 的传统构建系统,基于 GNU Make 构建工具。它通过解析特定配置文件来编译原生代码,专为 Android 平台设计。

在使用过程中,通过 NDK 安装目录中的 ndk-build 脚本 驱动 GNU Make,读取 jni/ 下的 Application.mk 以及各处的 Android.mk 来编译项目。

1.2 核心配置文件

1.2.1 Android.mk - 模块级配置

Android.mk 文件位于项目 jni/ 目录的子目录中,用于向构建系统描述源文件和共享库。它实际上是一个微小的 GNU Makefile 片段,构建系统会将其解析一次或多次。Android.mk 文件用于定义 Application.mk、构建系统和环境变量所未定义的项目级设置。它还可替换特定模块的项目级设置。

makefile 复制代码
# 示例:定义原生共享库模块
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := native-lib
LOCAL_SRC_FILES := native-lib.cpp
LOCAL_LDLIBS    := -llog
include $(BUILD_SHARED_LIBRARY)
1.2.2 Application.mk - 项目级配置

Application.mk 定义项目全局设置,默认位于应用项目目录中的 jni/Application.mk 下。Application.mk配置目标ABI、标准库、最低 API 平台、STL、NDK 工具链与优化级别等

makefile 复制代码
# 示例:支持多种ABI架构
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
APP_STL := c++_static
APP_PLATFORM := android-24

1.3 ndk-build 构建流程

Android.mk 是 Makefile 片段,由 NDK 顶层 Makefile include ,在同一次 make 中与内置规则一起展开,由 GNU Make 直接完成编译链接。这与 CMake 的典型两阶段(先配置生成 Ninja 等构建文件,再执行 Ninja)不同。具体流程如下所示:

复制代码
源代码文件
    ↓
Android.mk + Application.mk
    ↓
ndk-build 解析配置
    ↓
生成完整的 GNU Makefile
    ↓
GNU Make 驱动构建过程
    ↓
编译 → 汇编 → 链接
    ↓
生成目标库文件 (lib*.so/lib*.a)

注意:ndk-build 会为每个 ABI 独立执行一套完整的构建流程:

复制代码
# Application.mk 中指定多个 ABI
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64

# 构建系统执行流程:
1. 加载配置,为 armeabi-v7a 解析 Android.mk
2. 生成 armeabi-v7a 专用的中间文件
3. 完成 armeabi-v7a 构建
4. 重复 1--3 步处理其他 ABI

1.4 ndk-build 最佳实践

复制代码
# 清晰的项目结构
jni/
├── Android.mk
├── Application.mk
├── common.mk (通用配置)
├── module1/
│   ├── Android.mk
│   └── src/
└── module2/
    ├── Android.mk
    └── src/

# 模块化配置
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)  # 清除之前变量
include $(LOCAL_PATH)/../common.mk  # 包含通用配置

二、CMake 构建系统

2.1 什么是 CMake

CMake 是跨平台的开源构建系统生成器,Android Studio 从 2.2 版本起将其作为 NDK 构建的推荐方式。CMake 不直接编译源码,而是生成 Ninja 等构建工具所需的构建脚本,再由后者执行实际编译与链接。

2.2 CMake 构建流程

CMake 在 Android NDK 场景下的大致流程如下:

复制代码
源代码文件
    ↓
CMakeLists.txt (用户配置)
    ↓
CMake + Android Toolchain
    ↓
生成 Ninja 构建文件 (build.ninja)
    ↓
Ninja 执行实际构建任务
    ↓
编译 → 链接 → 打包
    ↓
生成最终原生库文件

CMake 只需一次配置即可为所有目标 ABI 生成构建规则,相比 ndk-build 通常更高效。

2.3 CMakeLists.txt 配置示例

cmake 复制代码
# 最低 CMake 版本要求
cmake_minimum_required(VERSION 3.18.1)

# 项目定义
project("native-lib")

# 创建共享库
add_library(
    native-lib           # 库名称
    SHARED              # 共享库类型
    native-lib.cpp      # 源文件
)

# 链接系统库
target_link_libraries(
    native-lib
    log                 # Android日志库
    android             # Android NDK库
)

# 包含目录
target_include_directories(
    native-lib
    PRIVATE
    include
)

# 编译定义
target_compile_definitions(
    native-lib
    PRIVATE
    DEBUG=1
)

总结

CMake 是更现代、更跨平台的解决方案,而 ndk-build 是 Android 特定的传统方式。Google 现在推荐使用 CMake 进行新的 NDK 开发。

功能 Android.mk CMakeLists.txt
定义模块 LOCAL_MODULE := native-lib add_library(native-lib SHARED ...)
源文件 LOCAL_SRC_FILES := a.cpp b.cpp add_library(native-lib a.cpp b.cpp)
包含目录 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include target_include_directories(native-lib PRIVATE include)
链接库 LOCAL_LDLIBS := -llog -landroid target_link_libraries(native-lib log android)
编译标志 LOCAL_CFLAGS := -DDEBUG=1 target_compile_definitions(native-lib PRIVATE DEBUG=1)

参考资料

ndk-build 脚本 | Android NDK | Android Developers

相关推荐
成都大菠萝9 小时前
Android Car CarProperty 车辆信号链路
android
敲代码的鱼9 小时前
PDF 预览与签名批注写回 支持安卓 iOS 鸿蒙 UTS插件
android·前端·ios
时光足迹11 小时前
uni-app 视频通话实战:康复师与患者视频问诊的 6 个致命 Bug 与解决方案
android·ios·uni-app
Coffeeee15 小时前
闲聊几句,Android老哥们,你们多久没做技改需求了
android·程序员·代码规范
萝卜er16 小时前
Fragment 生命周期与状态恢复-《Android深水区(四)》
android
萝卜er16 小时前
Intent 显式、隐式与 PendingIntent-《Android深水区(五)》
android
Kapaseker18 小时前
一文吃透 Kotlin 集合操作符
android·kotlin
三少爷的鞋19 小时前
Main-safe:现代Android 架构真正的分水岭
android
沐怡旸1 天前
深入解析 Android Performance Analyzer (APA) 底层架构与技术原理
android
李斯维1 天前
从历史的角度看 Android 软件架构
android·架构·android jetpack