make searching for source in wrong directory

53 Views Asked by At

I searched quite a bit to find the solution for this but no luck. I have some source code that produces HTML and am using a Makefile for this. The directory structure is:

main/
main/Makefile
main/src
main/src/dox
main/src/dox/generate.rb
...

The relevant portion of the Makefile is:

sources := $(shell find src -name "*rb" )
pages := $(sources:src/%.rb=%.html)

all: $(pages)

%.html: src/%.rb
        ruby $< > $@

make -dr produces:

(snip)
Considering target file 'dox/generate.html'.
   File 'dox/generate.html' does not exist.
   Looking for an implicit rule for 'dox/generate.html'.
   Trying pattern rule with stem 'generate'.
   Trying implicit prerequisite 'dox/src/generate.rb'.
   Trying pattern rule with stem 'generate'.
   Trying implicit prerequisite 'dox/src/generate.rb'.
   Looking for a rule with intermediate file 'dox/src/generate.rb'.
    Avoiding implicit rule recursion.
   No implicit rule found for 'dox/generate.html'.
   Finished prerequisites of target file 'dox/generate.html'.
  Must remake target 'dox/generate.html'.
make: *** No rule to make target 'dox/generate.html', needed by 'build'.  Stop.`

How can I correct this?

Clearly, make is looking for the source file in the wrong directory, but the rule seems very simple and straightforward.

1

There are 1 best solutions below

7
John Bollinger On

Clearly, make is looking for the source file in the wrong directory but the rule seems very simple and straightforward.

"Wrong" in the sense of "not the directory you want it to look in", of course. There is no actual misbehavior here, in that make is behaving exactly as documented.

When make considers the pattern rule in the question for building target dox/generate.html, the pattern matches with stem dox/generate. When the target pattern does not have any literal directory components, as in this case, the leading directory portion of that stem gets special treatment:

When prerequisites are turned into file names, the directories from the stem are added at the front, while the rest of the stem is substituted for the '%'.

(GNU make manual)

This is how GNU make supports pattern rules structured for building targets in the same directory as their corresponding source, whatever directory that may be. This is the traditional approach for make-based build systems.

And that is why you see make looking for file dox/src/generate.rb when the stem is dox/generate.html and the prerequisite pattern is src/%.html.

It's unclear what other files you want to build with this rule, but possibly this is what you're looking for:

dox/%.html: src/dox/%.rb
        ruby $< > $@

When, as there, the target pattern does have an explicit leading directory component, the stem is treated as a flat string, with no special treatment of directory components.