我有一个示例项目的makefile,不幸的是,当项目中的任何单个文件发生更改时,它会强制重新构建。我对makefile没有很多经验,所以我不确定如何解决这个问题。
makefile将要编译的文件定义为单个变量SRCS
,如下所示。当然,这个列表中有大约40个文件,在很多不同的目录中。
SRCS = \
../../src/file1.c \
../../src/file2.c
然后它定义了从每个.o
文件生成的每个.c
文件的构建规则。
$(OBJ_PATH)/%.o: $(SRCS)
$(CC) $(FLAGS) $(filter %/$(subst .o,.c,$(notdir $@)), $(SRCS)) -o $@
根据make运行-d
选项,当单个.c
文件发生更改时,必须再次编译所有目标文件,因为$(SRCS)
被定义为上面的依赖项。
如何更改此权限,如果单个文件只更改,则必须再次编译1 .o
文件?
答案 0 :(得分:2)
你的食谱是由熟悉makefile的人写的;这几乎是正确的。一个更正是将$(filter)
语句移动到先决条件行。在这种情况下,这就是它需要的地方。
一旦它出现,您需要进行一些额外的调整,您可以在手册中阅读。所以,像这样:
PERCENT := %
.SECONDEXPANSION:
$(OBJ_PATH)/%.o: $$(filter $$(PERCENT)/$$(subst .o,.c,$$(notdir $$@)), $(SRCS))
$(CC) $(FLAGS) $< -o $@
答案 1 :(得分:2)
这样的事也行。
SRCS = \
../../src/file1.c \
../../src/file2.c
# Set prerequisites for each output .o file from the matching .c file
$(foreach src,$(SRCS),$(eval $(OBJ_PATH)/$(notdir $(src:.c=.o)): $(src)))
# Create pattern rule with no additional prerequisites.
$(OBJ_PATH)/%.o:
$(CC) $(FLAGS) $< -o $@
所以在我看来,在某种意义上,更微小的变化将是:
$(OBJ_PATH)/%.o: $(SRCS)
file='$(filter %/$(subst .o,.c,$(notdir $@)), $?)'; [ "$$file" ] && \
$(CC) $(FLAGS) "$$file" -o $@
答案 2 :(得分:2)
另一种解决方案是使用vpath
。示例代码:
OBJ_PATH := build
SRCS := \
src/foodir/foo.c \
src/bardir/bar.c
OBJS := $(addprefix $(OBJ_PATH)/,$(notdir $(SRCS:%.c=%.o)))
vpath %.c $(dir $(SRCS))
all: $(OBJS)
$(OBJ_PATH)/%.o: %.c
$(CC) $(FLAGS) $< -o $@
答案 3 :(得分:0)
通常在Makefile中,您不会将特定的.c文件作为依赖项。
通常,您将.o文件列为主可执行文件的依赖项。
制定内部规则以确定如何从.c文件构建.o文件, 您可以使用自己的特殊规则覆盖这些规则,或者通常只更改一些规则 配置变量就足够了。
关于make的完整教程比我想在此框中输入的时间长,但有很多可用的快速网络搜索。