使用ndk-build编译.c与.S文件生成可执行文件失败求助
NDK编译C与汇编文件报错修复
错误信息
执行编译命令:
me@pc:~/temp/mydir$ /home/me/android-ndk-r21e/ndk-build V=3 NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk NDK_APPLICATION_MK=Application.mk
输出报错:
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-16. /home/me/android-ndk-r21e/build/core/build-binary.mk:475: warning: overriding recipe for target 'obj/local/arm64-v8a/objs/test_mod/src/test.o' /home/me/android-ndk-r21e/build/core/build-binary.mk:474: warning: ignoring old recipe for target 'obj/local/arm64-v8a/objs/test_mod/src/test.o' /home/me/android-ndk-r21e/build/core/build-binary.mk:475: warning: overriding recipe for target 'obj/local/arm64-v8a/objs/test_mod/src/test.o.commands.json' /home/me/android-ndk-r21e/build/core/build-binary.mk:474: warning: ignoring old recipe for target 'obj/local/arm64-v8a/objs/test_mod/src/test.o.commands.json' [arm64-v8a] Compile : test_mod <= test.S [arm64-v8a] Executable : test_mod ./obj/local/arm64-v8a/objs/test_mod/src/test.o: In function `assembly_func': /home/me/temp/mydir/./src/test.S:9: multiple definition of `assembly_func' ./obj/local/arm64-v8a/objs/test_mod/src/test.o:/home/me/temp/mydir/./src/test.S:9: first defined here /home/me/android-ndk-r21e/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/lib/aarch64-linux-android/21/crtbegin_dynamic.o: In function `_start_main': crtbegin.c:(.text+0x38): undefined reference to `main' crtbegin.c:(.text+0x3c): undefined reference to `main' clang++: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [/home/me/android-ndk-r21e/build/core/build-binary.mk:738: obj/local/arm64-v8a/test_mod] Error
现有文件内容
Android.mk
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := test_mod LOCAL_C_INCLUDES := inc/ LOCAL_SRC_FILES := \ src/test.c \ src/test.S include $(BUILD_EXECUTABLE)
test.c
#include <stdio.h> #include "test.h" int main(){ printf("main has been entered.\n"); int func = assembly_func(); return func; }
(注:原代码中printf字符串缺少换行符,已补充)
test.S
#include "test.h" .global assembly_func .section .text assembly_func: mov x0, #MY_NUM ret
test.h
#define MY_NUM 7 #ifndef __ASSEMBLER__ #include <stdint.h> // 补充该头文件,否则uint32_t会未定义 uint32_t assembly_func(); #endif
错误原因分析
- 目标文件冲突:
test.c和test.S文件名前缀相同,编译后都会生成test.o目标文件,导致ndk-build构建规则被重复覆盖(对应日志中的overriding recipe警告)。最终只有test.S被编译,test.c中的main函数未被处理,因此出现undefined reference to main错误。 - 重复符号定义:目标文件冲突导致构建系统错误地将同一个
test.o(来自test.S)重复加入链接步骤,引发assembly_func多次定义的问题。
修复步骤
- 重命名汇编文件:将
test.S改为asm_test.S(或其他不同前缀的名字),避免与test.c生成的目标文件重名。 - 更新Android.mk:修改
LOCAL_SRC_FILES中的汇编文件路径:LOCAL_SRC_FILES := \ src/test.c \ src/asm_test.S - 补充头文件依赖:在
test.h中加入#include <stdint.h>,确保uint32_t类型被正确识别。 - 设置APP_PLATFORM:在
Application.mk中添加APP_PLATFORM := android-21(或与NDK兼容的更高版本),消除默认平台版本的警告。
完成以上修改后重新执行ndk-build命令,即可正常生成可执行文件。
内容的提问来源于stack exchange,提问作者tronjo
相关产品推荐
相关产品推荐

