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
关键修改点
- 修正
CFLAGS:替换错误的-o为实际编译选项,比如-Wall开启编译警告,-std=c99指定C语言版本,回归CFLAGS的正确用途。 - 明确链接输出:在生成
a.out的规则中,用-o $@直接指定输出文件($@代表当前目标,即a.out),参数逻辑更清晰。 - 优化clean规则:添加
-f避免文件不存在时触发报错,同时将最终可执行文件a.out加入清理列表。
修改后,Make会正确推导stack.o和main.o的编译命令,生成两个目标文件后再链接成最终的a.out。
内容的提问来源于stack exchange,提问作者user20344863
相关产品推荐
相关产品推荐

