You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

错误原因分析

  1. 目标文件冲突:test.c和test.S文件名前缀相同,编译后都会生成test.o目标文件,导致ndk-build构建规则被重复覆盖(对应日志中的overriding recipe警告)。最终只有test.S被编译,test.c中的main函数未被处理,因此出现undefined reference to main错误。
  2. 重复符号定义:目标文件冲突导致构建系统错误地将同一个test.o(来自test.S)重复加入链接步骤,引发assembly_func多次定义的问题。

修复步骤

  1. 重命名汇编文件:将test.S改为asm_test.S(或其他不同前缀的名字),避免与test.c生成的目标文件重名。
  2. 更新Android.mk:修改LOCAL_SRC_FILES中的汇编文件路径:
    LOCAL_SRC_FILES := \
        src/test.c \
        src/asm_test.S
    
  3. 补充头文件依赖:在test.h中加入#include <stdint.h>,确保uint32_t类型被正确识别。
  4. 设置APP_PLATFORM:在Application.mk中添加APP_PLATFORM := android-21(或与NDK兼容的更高版本),消除默认平台版本的警告。

完成以上修改后重新执行ndk-build命令,即可正常生成可执行文件。

内容的提问来源于stack exchange,提问作者tronjo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:02:47