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

新手用Makefile编译多二进制报错:No rule to make target s1_c1.o

问题解决:编译多二进制程序的Makefile修正

你的报错核心原因是目标依赖的.o文件路径不匹配:s1_c1.o指向当前目录的对象文件,但你的源文件./challenges/s1_c1.c生成的对象文件是./challenges/s1_c1.o,Make找不到当前目录下的s1_c1.c来生成s1_c1.o,所以报错。

以下是修正后的完整Makefile:

# 二进制程序名称
BINARY=s1_c1 s1_c2 s1_c3
# 输出目录
BINDIR=./bin

CODEDIRS=./challenges ./src 
INCDIRS=. ./include/

COMPILER=gcc
OPT=-O2 
DEBUG=-Og 
DEPFLAGS=-MP -MD

CFLAGS1=-Wall -g $(foreach D, $(INCDIRS), -I$(D)) $(DEBUG) $(DEPFLAGS)
CFLAGS2=-Wall $(foreach D, $(INCDIRS), -I$(D)) $(DEPFLAGS)

# 所有C源文件
CFILES=$(foreach D, $(CODEDIRS), $(wildcard $(D)/*.c))
# challenges目录下的主程序源文件
MAINCFILES=$(filter ./challenges/%, $(CFILES))
# 所有对象文件
OBJECTS=$(patsubst %.c,%.o,$(CFILES))
# challenges目录下的主程序对象文件
MAINOBJECTS=$(filter ./challenges/%, $(OBJECTS))
# src目录下的库对象文件
LIBOBJECTS=$(filter ./src/%, $(OBJECTS))
# 依赖文件
DEPFILES=$(patsubst %.c,%.d,$(CFILES))

# 确保bin目录存在
$(BINDIR):
	mkdir -p $@

# 所有目标:先创建bin目录,再生成二进制程序
all: $(BINDIR) $(addprefix $(BINDIR)/, $(BINARY))
.PHONY: all clean

# 批量生成二进制程序规则:每个二进制依赖库对象和对应的主程序对象
$(BINDIR)/%: $(LIBOBJECTS) ./challenges/%.o
	$(COMPILER) -o $@ $^

# 通用编译规则:从.c生成.o
%.o: %.c
	$(COMPILER) $(CFLAGS1) -c -o $@ $<

# 包含依赖文件,自动处理头文件变化
-include $(DEPFILES)

clean:
	rm -rf $(BINDIR) $(OBJECTS) $(DEPFILES)

关键修改点说明:

  • 路径匹配修正:将二进制目标的依赖从s1_c1.o改为./challenges/s1_c1.o,同时用$(BINDIR)/%和./challenges/%.o的模式匹配,批量处理所有二进制程序,避免重复写规则。
  • 输出目录处理:新增$(BINDIR)目标确保bin目录存在,所有二进制程序生成到./bin目录下。
  • 编译命令错误修复:把(-o)改成正确的-o。
  • 简化变量逻辑:用filter替代复杂的foreach+if,直接筛选目录下的文件,更简洁高效。
  • 依赖文件引入:添加-include $(DEPFILES),让Make自动处理头文件修改后的重编译。
  • clean规则更新:删除bin目录,同时清理所有对象文件(包括challenges下的.o)。

额外优化建议:

如果需要区分主程序和库文件的编译参数,可以给主程序对象单独写规则:

./challenges/%.o: ./challenges/%.c
	$(COMPILER) $(CFLAGS2) -c -o $@ $<

这样主程序用CFLAGS2,库文件用CFLAGS1编译。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 18:05:35