从零开始:在 Windows 上使用命令行编译 Android .so 动态库(NDK + CMake + Ninja)

🛠️ 从零开始:在 Windows 上使用命令行编译 Android .so 动态库(NDK + CMake + Ninja)

无需 Android Studio 构建系统,纯命令行搞定 Native 库编译

本文将手把手教你如何在 Windows + Git Bash 环境下,仅用命令行工具,基于 Android NDK、CMake 和 Ninja,编译出适用于 Android 的 .so 动态库。整个过程不依赖 Android Studio 的构建流程,适合集成到 CI/CD 或自定义构建脚本中。

✅ 前提条件

你已安装:

· Android SDK(包含 NDK 和 CMake)

· Git for Windows(提供 Git Bash 环境)

💡 如果你通过 Android Studio 安装了 SDK,默认路径通常为:

复制代码
C:\Users\<用户名>\AppData\Local\Android\Sdk

本文假设你的路径为:D:\AndroidSDK


🔧 第一步:确认你的工具路径

根据你的环境,确认以下两个关键组件的位置:

组件 路径示例

NDK D:\AndroidSDK\ndk\26.3.11579264

CMake D:\AndroidSDK\cmake\3.22.1

⚠️ 注意:NDK 版本建议 ≥ r21,CMake ≥ 3.18(Android 官方推荐)


📦 第二步:下载 Ninja(构建工具)

Android NDK 推荐使用 Ninja 作为构建后端(比 Make 更快、更可靠)。

  1. 访问 https://github.com/ninja-build/ninja/releases

  2. 下载 ninja-win.zip

  3. 解压得到 ninja.exe

  4. 将其放在项目目录下,例如:

    D:\ndkTest\ninja-win\ninja.exe

✅ Ninja 是单文件可执行程序,无需安装,无依赖。


📄 第三步:创建最小项目源码

在项目目录 D:\ndkTest 中创建两个文件:

  1. native-lib.c
c 复制代码
#include <jni.h>

JNIEXPORT jstring JNICALL
Java_com_example_myapp_MainActivity_stringFromJNI(JNIEnv *env, jobject thiz) {
    return (*env)->NewStringUTF(env, "Hello from C!");
}
  1. CMakeLists.txt
cmake 复制代码
cmake_minimum_required(VERSION 3.18.1)
project("native-lib")

add_library(native-lib SHARED native-lib.c)

find_library(log-lib log)
target_link_libraries(native-lib ${log-lib})

🖥️ 第四步:编写构建脚本 build.sh

在 D:\ndkTest 下创建 build.sh(使用 Git Bash):

bash 复制代码
#!/bin/bash

# === 配置路径 ===
NDK_PATH="/d/AndroidSDK/ndk/26.3.11579264"
CMAKE_BIN="/d/AndroidSDK/cmake/3.22.1/bin/cmake"
NINJA_BIN="/d/ndkTest/ninja-win/ninja.exe"

# === 构建参数 ===
ABI="arm64-v8a"     # 可选: armeabi-v7a, x86, x86_64
API_LEVEL=21
BUILD_DIR="build"
OUTPUT_DIR="libs"

# === 检查工具 ===
[ -f "$CMAKE_BIN" ] || { echo "❌ CMake not found"; exit 1; }
[ -f "$NINJA_BIN" ] || { echo "❌ Ninja not found"; exit 1; }

# === 清理并配置 ===
rm -rf "$BUILD_DIR"
"$CMAKE_BIN" \
  -G "Ninja" \
  -DCMAKE_MAKE_PROGRAM="$NINJA_BIN" \
  -DCMAKE_TOOLCHAIN_FILE="$NDK_PATH/build/cmake/android.toolchain.cmake" \
  -DANDROID_ABI="$ABI" \
  -DANDROID_PLATFORM="android-$API_LEVEL" \
  -DCMAKE_BUILD_TYPE=Release \
  -B "$BUILD_DIR" \
  -S .

# === 编译与输出 ===
cd "$BUILD_DIR"
"$CMAKE_BIN" --build . --parallel
cd ..

mkdir -p "$OUTPUT_DIR/$ABI"
cp "$BUILD_DIR/libnative-lib.so" "$OUTPUT_DIR/$ABI/"
echo "✅ 输出: $OUTPUT_DIR/$ABI/libnative-lib.so"

▶ 第五步:运行构建

在 Git Bash 中执行:

bash 复制代码
cd /d/ndkTest
chmod +x build.sh    # 赋予执行权限(可选)
./build.sh

成功后,你会在以下路径看到生成的动态库:

复制代码
libs/arm64-v8a/libnative-lib.so

🔍 验证结果

  1. 检查架构
bash 复制代码
file libs/arm64-v8a/libnative-lib.so
# 应显示: ELF 64-bit LSB shared object, ARM aarch64
  1. 查看符号(可选)
bash 复制代码
/d/AndroidSDK/ndk/26.3.11579264/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android-readelf -Ws libs/arm64-v8a/libnative-lib.so

🌟 优势总结

✅ 完全脱离 Android Studio 构建系统

✅ 支持多 ABI 快速切换

✅ 构建速度快(Ninja)

✅ 可集成到自动化脚本或 CI 流程


📌 常见问题

Q:为什么不用 make?

A:Git Bash 的 make 在某些精简版中缺失,而 Ninja 单文件、无依赖、官方推荐。

Q:如何支持 C++?

A:将源文件改为 .cpp,CMake 中会自动识别;如需手动指定,用 add_library(... your.cpp) 即可。

Q:如何打包成 AAR?

A:可配合 jar 命令将 jniLibs 打包,或使用 android.jar 工具链(进阶话题)。


相关推荐
2601_9574188011 分钟前
告别OTG碎片化!Android MTP协议深度解析与高性能通信方案
android
故渊at12 分钟前
第二板块:Android 四大组件标准化学理 | 第七篇:Activity 页面载体与任务栈算法
android·算法·生命周期·activity·任务栈
QING6181 小时前
Kotlin 协程新手指南 —— 协程上下文与调度器
android·kotlin·android jetpack
潘潘潘2 小时前
Android JAVA Socket 知识梳理
android
00后程序员张2 小时前
Jenkins 自动上传 IPA 到 App Store 把发布步骤融入 CI/CD
android·ios·小程序·https·uni-app·iphone·webview
Gary Studio2 小时前
复杂 SoC(RK3568)PCB 布局的五步
android·linux·硬件
plainGeekDev3 小时前
HttpURLConnection → OkHttp + Kotlin
android·java·kotlin
QING6183 小时前
Kotlin 协程新手指南 —— 协程基础与挂起函数
android·kotlin·android jetpack
2601_961766643 小时前
【分享】分身空间 2.3.7[特殊字符]生活工作互不打扰
android·生活
百度搜知知学社3 小时前
抖音双模块架构:兼容全安卓版本并支持登录
android·架构·安卓·登录·兼容性·抖音