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

C程序Makefile无法生成stack.o问题求助

问题描述

我为C程序编写了如下Makefile,拥有stack.c和main.c两个源文件:

CC = gcc
CFLAGS = -o 
LDFLAGS = -lm 

OBJS = stack.o main.o

a.out: $(OBJS)
    $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS)

clean: 
    rm $(OBJS) 

执行make时仅生成了main.o,无法生成stack.o,执行输出如下:

gcc -o    -c -o stack.o stack.c
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'stack.o' failed
make: *** [stack.o] Error 1

期望Makefile能为main.c和stack.c分别生成目标文件,但目前仅生成了main.c对应的目标文件。

问题原因与解决方案

核心问题:CFLAGS的错误设置

CFLAGS的作用是传递编译选项(比如警告级别、C标准版本、宏定义等),你把它设成-o完全不符合其用途。

Make有默认的.c到.o的推导规则,模板为:

$(CC) $(CFLAGS) -c -o $@ $<

代入你的CFLAGS=-o后,编译命令变成:

gcc -o -c -o stack.o stack.c

这种参数顺序会让gcc混淆:第一个-o后无指定输出文件名,后续-c要求生成目标文件,但参数混乱导致gcc错误触发链接流程,而stack.c中没有main函数,因此报出undefined reference to main的错误。

修正后的Makefile

CC = gcc
# CFLAGS 设置编译选项,开启警告、指定C标准等
CFLAGS = -Wall -Wextra -std=c99
LDFLAGS = -lm 

OBJS = stack.o main.o

a.out: $(OBJS)
    $(CC) -o $@ $(OBJS) $(LDFLAGS)

clean: 
    rm -f $(OBJS) a.out

关键修改点

  1. 修正CFLAGS:替换错误的-o为实际编译选项,比如-Wall开启编译警告,-std=c99指定C语言版本,回归CFLAGS的正确用途。
  2. 明确链接输出:在生成a.out的规则中,用-o $@直接指定输出文件($@代表当前目标,即a.out),参数逻辑更清晰。
  3. 优化clean规则:添加-f避免文件不存在时触发报错,同时将最终可执行文件a.out加入清理列表。

修改后,Make会正确推导stack.o和main.o的编译命令,生成两个目标文件后再链接成最终的a.out。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:15:35