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

使用Make编译多路径代码时出现"No rule to make target"错误求助

问题描述

尝试使用Make编译程序,编写的Makefile代码如下:

INC_DIR = ./include
BIN_DIR = ./bin
SRC_DIR = ./src1 ./src2 ./src3
OBJ_DIR = ./obj

SRC = $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
OBJ = $(patsubst %.c,${OBJ_DIR}/%.o,$(notdir ${SRC}))
TARGET1 = main
BIN_TARGET1 = ${BIN_DIR}/${TARGET1}
 CC = gcc
 CFLAGS = -g -Wall -I${INC_DIR}
 CFLAGS += -DLOG_USE_COLOR
 ${BIN_TARGET1}:${OBJ}
    $(CC) $(OBJ) -o $@
${OBJ_DIR}/%.o:$(foreach dir,$(SRC_DIR),$(dir)/%.c)
    $(CC) $(CFLAGS) -c $< -o $@
.PHONY:clean
clean:
    rm -rf ${BIN_TARGET1}
    rm -rf ${OBJ_DIR}/*.o
    @echo ${SRC}

执行Make后得到报错:

make: *** No rule to make target 'obj/main.o', needed by 'bin/main'.  Stop.
问题原因与修复方案

核心问题

你的模式规则 ${OBJ_DIR}/%.o:$(foreach dir,$(SRC_DIR),$(dir)/%.c) 存在逻辑错误:当Make尝试匹配obj/main.o时,会把模式展开为src1/main.c src2/main.c src3/main.c,这意味着Make会认为所有这三个文件都必须存在才能生成obj/main.o,但实际上你只需要其中一个存在的源文件来编译对应的目标文件。

修复方法

方案1:使用VPATH指定源文件搜索路径

修改Makefile,添加VPATH变量告诉Make去哪里找源文件,同时简化模式规则:

INC_DIR = ./include
BIN_DIR = ./bin
SRC_DIR = ./src1 ./src2 ./src3
OBJ_DIR = ./obj

# 指定源文件搜索路径
VPATH = $(SRC_DIR)

SRC = $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
OBJ = $(patsubst %.c,${OBJ_DIR}/%.o,$(notdir ${SRC}))
TARGET1 = main
BIN_TARGET1 = ${BIN_DIR}/${TARGET1}
CC = gcc
CFLAGS = -g -Wall -I${INC_DIR}
CFLAGS += -DLOG_USE_COLOR

${BIN_TARGET1}:${OBJ}
	$(CC) $(OBJ) -o $@

# 简化模式规则,VPATH会自动搜索SRC_DIR下的源文件
${OBJ_DIR}/%.o:%.c
	$(CC) $(CFLAGS) -c $< -o $@

.PHONY:clean
clean:
	rm -rf ${BIN_TARGET1}
	rm -rf ${OBJ_DIR}/*.o
	@echo ${SRC}

方案2:使用静态模式规则匹配对应源文件

如果不想用VPATH,可以通过静态模式规则明确关联每个目标文件和对应的源文件:

INC_DIR = ./include
BIN_DIR = ./bin
SRC_DIR = ./src1 ./src2 ./src3
OBJ_DIR = ./obj

SRC = $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))
# 保留源文件的完整路径,方便后续匹配
OBJ = $(patsubst %.c,${OBJ_DIR}/%.o,$(notdir ${SRC}))
# 建立源文件和目标文件的映射
SRC_OBJ_MAP = $(foreach src,$(SRC),$(OBJ_DIR)/$(notdir $(src:.c=.o)):$(src))

TARGET1 = main
BIN_TARGET1 = ${BIN_DIR}/${TARGET1}
CC = gcc
CFLAGS = -g -Wall -I${INC_DIR}
CFLAGS += -DLOG_USE_COLOR

${BIN_TARGET1}:${OBJ}
	$(CC) $(OBJ) -o $@

# 使用静态模式规则,逐个匹配源文件和目标文件
$(SRC_OBJ_MAP)
	$(CC) $(CFLAGS) -c $< -o $@

.PHONY:clean
clean:
	rm -rf ${BIN_TARGET1}
	rm -rf ${OBJ_DIR}/*.o
	@echo ${SRC}

额外注意事项

  • 确保obj和bin目录已经存在,如果不想手动创建,可以在Makefile中添加创建目录的规则:
    ${OBJ_DIR} ${BIN_DIR}:
    	mkdir -p $@
    
    然后在目标规则中依赖这些目录:
    ${BIN_TARGET1}:${OBJ_DIR} ${BIN_DIR} ${OBJ}
    	$(CC) $(OBJ) -o $@
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:23:14