为什么make要重新编译所有文件?



我的目标如下:我有一个目录src,其中包含markdown文件(.md)。我想在每个文件上运行一个命令,以便删除注释,并将编辑过的文件存储在单独的目录中。我想用make

这是我的Makefile:

.PHONY: clean all
BUILD_DIR := build
SRC_DIRS := src
SRCS := $(shell find $(SRC_DIRS) -name *.md)
DSTS := $(patsubst $(SRC_DIRS)/%.md,$(BUILD_DIR)/%.md,$(SRCS))
all: $(DSTS)
# The aim of this is to remove all my comments from the final documents
$(DSTS): $(SRCS)
pandoc --strip-comments -f markdown -i $< -t markdown -o $@
clean:
rm $(BUILD_DIR)/*.md

虽然这通常有效,但我注意到该命令在所有文件上执行,即使我只更改了一个文件。

例子:我有3个文件src/a.md,src/b.mdsrc/c.md。现在我运行make,所有文件都在build文件夹中正确生成。现在我只编辑c.md并再次运行make。我希望make只"编译"。src/c.md重新编译,而是重新编译所有三个文件。我做错了什么?

你的台词

$(DSTS): $(SRCS)

表示"所有DSTS都依赖于SRCS的所有",因此每当$(SRCS)中的任何一个比$(DSTS)中的任何一个更新时,此pandoc动作将运行。

那不是你想表达的。你想要的是更像

的东西
$(BUILD_DIR)/%.md: $(SRC_DIRS)/%.md
pandoc --strip-comments -f markdown -i $< -t markdown -o $@
all: $(DSTS)

这就是说所有的$(DSTS)都应该是最新的,模式规则教导Make每个依赖什么,以及如何构建它,如果它过时了。

(一般来说,看看你的原始规则,在规则中有多个目标很少是正确的,就像你在$(DSTS)中所做的那样;还要注意,在您的原始代码中,$<总是只引用$(SRCS)中依赖项的第一个

最新更新