I'm learning how to use make
and makefiles, so I wrote this little file:
%.markdown: %.html
pandoc -o $< $@
But when I run make
, all I get is make: *** No targets. Stop.
What's going on?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityYou problem is that make
doesn't know about your targets.
You can run your above Makefile with make stackoverflow.markdown
for example and it will work.
make
only, however, will fail, since you only specified how to create your targets, but not which.
As leiaz point's out the above pattern rule is called an implicit rule.
SRC = $(wildcard *.html)
TAR = $(SRC:.html=.markdown)
.PHONY: all clean
all: $(TAR)
%.markdown: %.html
pandoc -o $< $@
clean:
rm -f $(TAR)
SRC
get's all source files (those ending in .html
) via Makefile's wildcard
.
TAR substitutes each source file listed in SRC
with a target ending with .markdown
instead of .html
.
.PHONY lists non-physical targets that are always out-of-date and are therefore always executed - these are often all
and clean
.
The target all
has as dependency (files listed on the right side of the :
) all *.markdown
files. This means all these targets are executed.
%.markdown: %.html
pandoc -o $< $@
This snippet says: Each target ending with .markdown
is depended on a file with the same name, except that the dependency is ending with .html
. The wildcard %
is to be seen as a *
like in shell. The %
on the right side, however, is compared to the match on the left side. Source.
Note that the whitespace sequence infront of pandoc
is a TAB, since make
defines that as a standard.
Finally, the phony clean
target depicts how to clean your system from the files you've created with this Makefile. In this case, it's deleting all targets (those files that were named *.markdown
.
makefile
create files from scratch or it only updates existing files? Because when I delete the generated files, it stops to work. Silly question I know, but this is Newfoundland to me ^^"
Pattern rules are implicit rules.
You have no targets defined in your Makefile. You can specify the target on the command line : make something.markdown
will use the recipe to create something.markdown
from something.html
.
Or you can add to your Makefile a rule specifying default targets.
all: file1.markdown file2.markdown
all: *.markdown
When you run just make
, the first target of the first rule is the default goal. It doesn't need to be called all
.
So above, the target all
have all the files you want to make as prerequisites, so when you make all
, it will make all the listed files.
pandoc
command. Make is notoriously picky about those being a tab and not spaces..SUFFIXES: .markdown .html