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

RISC-V GCC编译报错:main.o已生成但无main函数,提示undefined reference to 'main'

RISC-V编译链接错误:undefined reference to 'main'

问题场景

使用RISC-V GCC工具链为微控制器编译项目,项目包含多文件及一个main.c,main.c代码如下:

int main(void)
{
    return 0;
}

错误信息

编译时链接器抛出错误:

riscv-none-embed/bin/ld.exe : in startup.S : undefined reference to 'main'

排查结果

  • 编译器已生成main.o目标文件,但该文件中未包含main函数
  • 对main.o执行nm工具得到如下输出:
0000018e t .L0
00000196 t .L0
0000019c t .L0
000001a4 t .L0
000001aa t .L0
000001c2 t .L0
000001c4 t .L0
000001c8 t .L0
000001ce t .L0
000001ce t .L0
00000076 t .L4
00000104 t .L5
000001e7 N .LASF0
000001ac N .LASF1
00000224 N .LASF10
000000e1 N .LASF11
.
.
.
00000469 N .LASF57
000000e9 N .LASF58
00000151 N .LASF59
0000008a N .LASF6
000004a2 N .LASF60
0000026c N .LASF61
00000000 d some_global_variable
00000000 T some_function0
0000017c T some_function1
00000110 T some_function2
00000050 T some_function3
         U some_function4
         U some_function5

注:所有some_functionX及全局变量均来自其他C文件,未在main.c中定义

Makefile核心内容(已脱敏)

STARTUP_FILE := $(ROOT_DIR)/../startup.S
STARTUP_OBJ := $(ROOT_DIR)/../startup.o

TOOL_DIR := $(ROOT_DIR)/../../riscv_gcc/riscv-none-embed-gcc/bin
GCC         := $(TOOL_DIR)/riscv-none-embed-gcc-10.2.0
LD          := $(TOOL_DIR)/riscv-none-embed-ld
GDB         := $(TOOL_DIR)/riscv-none-embed-gdb
OBJCOPY     := $(TOOL_DIR)/riscv-none-embed-objcopy
OBJDUMP     := $(TOOL_DIR)/riscv-none-embed-objdump
READELF     := $(TOOL_DIR)/riscv-none-embed-readelf
CODESIZE    := $(TOOL_DIR)/riscv-none-embed-size 
NMINFO      := $(TOOL_DIR)/riscv-none-embed-nm


LIB := $(LIB_DIR)/lib$(TARGET).a
ELF := $(BIN_DIR)/$(TARGET).elf
BIN := $(BIN_DIR)/$(TARGET).bin
HEX := $(BIN_DIR)/$(TARGET).hex
DASM := $(BIN_DIR)/$(TARGET).dasm

EN_OPTIMIZE = -O0
OPTFLAGS    := -march=rv32imc -mabi=ilp32 -mno-strict-align --specs=nano.specs $(EN_OPTIMIZE)
AFLAGS      := -D__STACK_SIZE=$(STACK_SIZE) -nostartfiles --entry Reset_Handler
LDFLAGS     := $(LINKER_FILE) -Xlinker -Map=$(BIN_DIR)/$(TARGET).map -L$(LIB_DIR)
LDFLAGS     += -falign-functions=4 -falign-jumps -falign-loops -falign-labels
# The -MMD flags additionaly creates a .d file as header dependency with the same name as the .o file.
CFLAGS      := -g -Wall -MMD -Wtype-limits -Woverflow -Wabsolute-value -Wno-unused-label $(INC_DIR) $(EN_OPTIMIZE)
CFLAGS      += -falign-functions=4 -falign-jumps -falign-loops -falign-labels -mno-relax



.PHONY: all
all: $(ELF) $(BIN) $(HEX) $(DASM)


# build object files
$(OBJ): $(SRC)
ifeq ($(wildcard $(OBJ_DIR)),)
    mkdir -p $(OBJ_DIR)
endif
    $(GCC) $(CFLAGS) -c $< -o $@



# Build the library .a 
$(LIB): $(OBJ)
ifeq ($(wildcard $(LIB_DIR)),)
    mkdir -p $(LIB_DIR)
endif
    $(TOOL_DIR)/riscv-none-embed-ar -crs $@ $(OBJ)


# Build .elf
$(ELF): $(LIB) $(OBJ)
ifeq ($(wildcard $(BIN_DIR)),)
    mkdir -p $(BIN_DIR)
endif
    $(GCC) $(CFLAGS) $(STARTUP_FILE) $(LDFLAGS) $(AFLAGS) -l$(TARGET) -o $@


# Build .bin
$(BIN): $(ELF)
ifeq ($(wildcard $(BIN_DIR)),)
    mkdir -p $(BIN_DIR)
endif
    $(OBJCOPY) -O binary $< $@


# Build .hex
$(HEX): $(ELF)
ifeq ($(wildcard $(BIN_DIR)),)
    mkdir -p $(BIN_DIR)
endif
    $(OBJCOPY) -O ihex $< $@


#Build disassembly file .dasm
$(DASM): $(ELF)
ifeq ($(wildcard $(BIN_DIR)),)
    mkdir -p $(BIN_DIR)
endif
    $(OBJDUMP) -d -S $< > $@



.PHONY: clean
clean:
    rm -rf $(OUTPUT_DIR)

排查与解决方向

  1. 检查main.c是否被纳入编译:确认Makefile中SRC变量包含main.c,$(OBJ)对应的目标文件列表里存在正确的main.o(而非其他文件重名覆盖)
  2. 验证库文件内容:用ar t $(LIB)命令查看静态库lib$(TARGET).a,确认main.o被正确打包进库中
  3. 调整链接顺序:链接时库文件-l$(TARGET)应放在引用它的文件之后,将链接命令修改为$(GCC) $(CFLAGS) $(STARTUP_FILE) $(LDFLAGS) $(AFLAGS) -l$(TARGET) -o $@改为$(GCC) $(CFLAGS) $(STARTUP_FILE) $(LDFLAGS) $(AFLAGS) -l$(TARGET) -o $@(若startup.S依赖库中符号,库需后置)
  4. 排查宏定义干扰:检查main.c及引用的头文件,是否存在#define main之类的宏重命名main函数
  5. 确认编译选项无异常:虽然使用-O0,但排查是否存在-ffunction-sections配合--gc-sections导致未被识别引用的main被误删

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 16:14:54