Reputation: 83
My goal is the following: I have a directory src
which contains markdown files (.md
). I want to run a command on each of these files so that the comments are removed and the edited files are stored in a separate directory. For this I want to use make
.
This is the Makefile
I have:
.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
While this works in general, I noticed that the command is executed on all files, even though I changed only one single file.
Example: I have 3 Files src/a.md
, src/b.md
and src/c.md
. Now I run make
and all files are correctly generated in the build
folder. Now I only edit c.md
and run make
again. I would expect that make
only "compiles" src/c.md
anew but instead all three files are compiled again. What am I doing wrong?
Upvotes: 0
Views: 113
Reputation: 12514
Your line
$(DSTS): $(SRCS)
is saying ‘All of the DSTS depend on all of the SRCS’, so whenever any one of the $(SRCS)
is newer than any of the $(DSTS)
, this pandoc
action will be run.
That's not what you want to express. What you want is something more like
$(BUILD_DIR)/%.md: $(SRC_DIRS)/%.md
pandoc --strip-comments -f markdown -i $< -t markdown -o $@
all: $(DSTS)
That says that all of the $(DSTS)
should be up to date, and the pattern rule teaches Make what each one depends on, and how to build it, if it is out of date.
(As a general point, looking your original rule, it's rarely the right thing to do to have multiple targets in a rule, as you have with $(DSTS)
; also note that in your original, $<
always refers only to the first of the dependencies in $(SRCS)
)
Upvotes: 2