You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过命令行使用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

火山引擎 最新活动