1
votes

I'm using Gnu Make 3.81, and getting an error trying to match a pattern rule that also has a variable in it.

Here's the smallest example I could come up with:

YYMMDD:=$(shell date +%y%m%d)
TMP_DIR:=/tmp/$(YYMMDD)

# create a temporary directory, and put a "source" file in it
$(TMP_DIR):
    mkdir $(TMP_DIR)
    echo something > $(TMP_DIR)/somefile.orig

# to build an "object" file in the temp dir, process the "source" file
$(TMP_DIR)/%.new: $(TMP_DIR)/%.orig
    wc -l $< > $@

atarget: $(TMP_DIR) $(TMP_DIR)/somefile.new

Then when I run make atarget, I get:

mkdir /tmp/141021
echo something > /tmp/141021/somefile.orig
make: *** No rule to make target `/tmp/141021/somefile.new', needed by `atarget'.  Stop.

Shouldn't this work? it seems like the pattern rule should match this just fine.

1

1 Answers

1
votes

It's because make doesn't know that the .orig file exists: you have a rule that builds $(TMP_DIR) but make doesn't know that this rule also builds $(TMP_DIR)/somefile.orig. So when make is trying to match the pattern rule it will see that the .orig file doesn't exist and it doesn't have any way that it knows how to make that file, so the pattern doesn't match, and after that there's no way to build the .new file.

You should write:

$(TMP_DIR)/%.orig:
        mkdir -p $(TMP_DIR)
        echo $* > $@

then it will work.