如何通过命令行使用NDK与Makefile编译Android C++代码
用NDK+Makefile命令行编译C++ Android代码
完全理解你的想法——Android Studio的多层项目结构、各种配置文件确实容易让人头大,尤其是当你只想专注于NDK的C++开发时,用命令行+Makefile确实是更轻量化的选择。下面我一步步教你怎么实现:
1. 先做好准备工作
- 下载并解压Android NDK到你喜欢的路径,比如
~/android-ndk-r26 - 设置环境变量
NDK_ROOT指向这个路径,比如在bash里可以临时设置:export NDK_ROOT=~/android-ndk-r26;如果要永久生效,把这行加到~/.bashrc或~/.zshrc里即可
2. 编写你的C++代码
先创建一个简单的测试文件main.cpp,用来验证编译流程:
#include <android/log.h> #define LOG_TAG "NDK_TEST" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) int main() { LOGD("Hello from NDK Makefile!"); return 0; }
3. 编写核心的Makefile
创建一个名为Makefile的文件,内容如下,我会逐行标注关键说明:
# 指定目标ABI,比如arm64-v8a(主流64位设备)、armeabi-v7a(旧32位设备)、x86_64等 TARGET_ABI := arm64-v8a # 从NDK中获取对应ABI的工具链路径(linux-x86_64是你的电脑架构,换成macos-arm64如果是M系列Mac) TOOLCHAIN := $(NDK_ROOT)/toolchains/llvm/prebuilt/linux-x86_64 # 指定C和C++编译器,末尾的29是Android API级别,可按需修改(比如33) CC := $(TOOLCHAIN)/bin/aarch64-linux-android29-clang CXX := $(TOOLCHAIN)/bin/aarch64-linux-android29-clang++ # 编译选项:-g保留调试信息,-O2开启优化,指定目标架构和API CFLAGS := -g -O2 -target aarch64-linux-android29 CXXFLAGS := $(CFLAGS) -std=c++17 # 指定C++标准,按需改成c++11/c++20 # 链接选项:链接Android系统的log库(如果不需要日志可以去掉) LDFLAGS := -llog # 最终生成的可执行文件名称 TARGET := ndk_test # 你的源文件列表,多个文件用空格分隔 SRCS := main.cpp # 默认编译目标 all: $(TARGET) # 编译规则:用C++编译器把源文件编译成可执行文件 $(TARGET): $(SRCS) $(CXX) $(CXXFLAGS) $(SRCS) -o $(TARGET) $(LDFLAGS) # 清理编译产物的规则 clean: rm -f $(TARGET)
4. 执行编译
在终端进入代码和Makefile所在的目录,直接运行:
make
如果一切顺利,你会得到一个名为ndk_test的可执行文件。
5. 测试可执行文件(可选)
把编译好的文件推到安卓设备上运行验证:
# 推送到设备的临时目录 adb push ndk_test /data/local/tmp/ # 赋予执行权限 adb shell chmod +x /data/local/tmp/ndk_test # 运行程序 adb shell /data/local/tmp/ndk_test # 查看日志输出 adb logcat -s NDK_TEST
这时你就能看到代码里打印的Hello from NDK Makefile!日志了。
额外提示
- 如果需要编译多个ABI,可以修改Makefile,用变量循环或者写多个独立的编译目标
- 项目有多个源文件时,只需要更新
SRCS列表,比如SRCS := main.cpp utils.cpp network.cpp - 要链接自定义静态库/动态库的话,在
LDFLAGS里添加路径和库名,比如-L./libs -lmylib
内容的提问来源于stack exchange,提问作者ndk




