I have a very bizzare problem with GNU make. I have the following files:
a/x.html
b/Makefile
b/c/Makefile
The contents of a/x.html
are irrelevant. The contents of b/Makefile
are as follows:
SRC=../a
all: x.html
%.html: ${SRC}/%.html
rsync $< $@
The contents of b/c/Makefile
are the same, except for the definition of SRC
:
SRC=../../a
If I run make
in b/c/
the result is as expected:
rsync ../../a/x.html x.html
and x.html
gets copied from a/
to b/c/
.
However, if I run make
in b/
the output I get is several lines of:
make: stat: ../a/../a/.. (repeated many times) ../a/x.html: File name too long
It seems that make
is applying the rule for %.html
recursively, but why? Is there something obvious I am missing?
To build a target that matches the pattern %.html
(i.e. any target name that ends in .html
), make applies the rule if it can build the dependency (target built from the original target with ../a/
prepended).
x.html
. This matches the pattern %.html
, so the rule applies: make sees if it can build ../a/x.html
.../a/x.html
matches the pattern %.html
, so the rule applies: make sees if it can build ../a/../a/x.html
.../../a/x.html
matches the pattern %.html
, so the rule applies, etc.The stem character can match any part of a path, including directory separators.
You can see what make is trying by running make -r -d
(-d
to show debugging output, -r
to turn off built-in rules which would cause a huge amount of noise).
When you're in b/c
, this stops at step 2 because ../../a/x.html
exists but ../../../../a/x.html
doesn't.
One way to fix this is to list the files on which you want to act. You can build that list from the list of files that already exist in ../a
:
$(notdir $(wildcard ${SRC}/*.html)): %.html: ${SRC}/%.html
rsync $< $@
This has the downside that if the HTML files in ../a
are themselves built by a rule in b/Makefile
, then running make
in b
won't built them in a pristine source directory. This shouldn't be a problem though: it would be unusual to have a makefile in b
build things outside b
.
Another approach which doesn't have this defect is to use an absolute path.
%.html: $(abspath ${SRC})/%.html
rsync $< $@
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments