0
votes

So, I have a Makefile with 2 pattern rules, one of them is a terminal Match-Anything; the target is about.html (for example):

vpath %.md $(SOURCE_DIR)
HEADER := assets/navbar.part

%.html : %.md $(HEADER)
        pandoc [...] $< -o $@

%::
        cp $(SOURCE_DIR)/$@ $@

If I execute make assets/navbar.part, and then make about.html (for example), everything works fine (navbar.part uses the match anything, and about.html uses the first rule). But if I try to make about.html without having navbar.part present, make does:

  1. Find the prerequisite about.md
  2. ?? Gives up on fulfilling $(HEADER)
  3. Tries to use the match anything rule to generate about.html

I was expecting that make would:

  1. Find the prerequisite about.md
  2. Make the prerequisite $(HEADER) using the match-anything rule
  3. With all the prerequisites fulfilled, finally execute the first rule

From reading the debug trace, it seems like Make never really tries to fulfill the $(HEADER) prerequisite:

Considering target file 'about.html'.
 File 'about.html' does not exist.
 Looking for an implicit rule for 'about.html'.
 Trying pattern rule with stem 'about'.
 Trying implicit prerequisite 'about.md'.
 Found prerequisite 'about.md' as VPATH '../website/about.md'
 Trying rule prerequisite 'assets/navbar.part'.
 Trying pattern rule with stem 'about.html'.
 Found an implicit rule for 'about.html'.
  Considering target file 'about.md'.
   Finished prerequisites of target file 'about.md'.
  No need to remake target 'about.md'; using VPATH name '../website/about.md'.
 Finished prerequisites of target file 'about.html'.
Must remake target 'about.html'.
cp -f ../website/about.html about.html

Any ideas?

1

1 Answers

1
votes

After digging the manual, I found section 10.8 that states:

For each pattern rule in the list:

  • Find the stem s, which is the nonempty part of t or n matched by the ‘%’ in the target pattern.
  • Compute the prerequisite names by substituting s for ‘%’; if the target pattern does not contain a slash, append d to the front of each prerequisite name.
  • Test whether all the prerequisites exist or ought to exist. (If a file name is mentioned in the makefile as a target or as an explicit prerequisite, then we say it ought to exist.)

Because the $(HEADER) does not meet the definition of ought to exist:

  • No file exists when the rule is tried
  • No rule with that explicit target exists

it fails; however, it suceeds if we try to make specifically $(HEADER), and then try to make about.html it suceeds, because by then $(HEADER) is an existing file.