Makefile applies a rule recursively even if it shouldn't

Nikola Benes

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?

Gilles 'SO- stop being evil'

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).

  1. You ask to build x.html. This matches the pattern %.html, so the rule applies: make sees if it can build ../a/x.html.
  2. ../a/x.html matches the pattern %.html, so the rule applies: make sees if it can build ../a/../a/x.html.
  3. ../../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.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Printf even though it shouldn't

From Dev

Wildcard domain in limits.conf applies to root user but shouldn't

From Dev

Makefile says target is empty but it shouldn't be

From Dev

Delegated event triggering even when it shouldn't

From Dev

The CSS rule doesn't applies any effect when JavaScript is executed

From Dev

Makefile runs code that a compile-time #if says it shouldn't

From Dev

Makefile runs code that a compile-time #if says it shouldn't

From Dev

SQL IF block code causing error even though it shouldn't execute

From Dev

if condition in try block always turns out true even if it shouldn´t

From Dev

Having trouble with a while loop, it breaks, even though it shouldn't

From Dev

React Native Integration Tests Always Passing (even when they shouldn't)

From Dev

HTML button that's submitting an empty field even though it shouldn't be

From Dev

Why does Java *sort* HashMap entries even though it shouldn't?

From Dev

Xubuntu reopens last session applications even though it shouldn't

From Dev

if condition in try block always turns out true even if it shouldn´t

From Dev

Script tries to create files even though it shouldn't have to?

From Dev

One template breaks another, even when it shouldn't match

From Dev

DateTime::createFromFormat is returning false even though it shouldn't

From Dev

Tensorflow learning XOR with linear function even though it shouldn't

From Dev

.htaccess rewrites even if redirectmatch applies

From Dev

.htaccess rewrites even if redirectmatch applies

From Dev

Makefile generic target rule

From Dev

Complex pattern rule in Makefile

From Dev

Makefile generic rule not working

From Dev

Rule not recognized in makefile?

From Dev

Implict rule cancellation in Makefile

From Dev

Makefile no rule for target

From Dev

makefile rule and separate directories

From Dev

Java Future.isDone returning true, even though it shouldn't, which halts program progress

Related Related

  1. 1

    Printf even though it shouldn't

  2. 2

    Wildcard domain in limits.conf applies to root user but shouldn't

  3. 3

    Makefile says target is empty but it shouldn't be

  4. 4

    Delegated event triggering even when it shouldn't

  5. 5

    The CSS rule doesn't applies any effect when JavaScript is executed

  6. 6

    Makefile runs code that a compile-time #if says it shouldn't

  7. 7

    Makefile runs code that a compile-time #if says it shouldn't

  8. 8

    SQL IF block code causing error even though it shouldn't execute

  9. 9

    if condition in try block always turns out true even if it shouldn´t

  10. 10

    Having trouble with a while loop, it breaks, even though it shouldn't

  11. 11

    React Native Integration Tests Always Passing (even when they shouldn't)

  12. 12

    HTML button that's submitting an empty field even though it shouldn't be

  13. 13

    Why does Java *sort* HashMap entries even though it shouldn't?

  14. 14

    Xubuntu reopens last session applications even though it shouldn't

  15. 15

    if condition in try block always turns out true even if it shouldn´t

  16. 16

    Script tries to create files even though it shouldn't have to?

  17. 17

    One template breaks another, even when it shouldn't match

  18. 18

    DateTime::createFromFormat is returning false even though it shouldn't

  19. 19

    Tensorflow learning XOR with linear function even though it shouldn't

  20. 20

    .htaccess rewrites even if redirectmatch applies

  21. 21

    .htaccess rewrites even if redirectmatch applies

  22. 22

    Makefile generic target rule

  23. 23

    Complex pattern rule in Makefile

  24. 24

    Makefile generic rule not working

  25. 25

    Rule not recognized in makefile?

  26. 26

    Implict rule cancellation in Makefile

  27. 27

    Makefile no rule for target

  28. 28

    makefile rule and separate directories

  29. 29

    Java Future.isDone returning true, even though it shouldn't, which halts program progress

HotTag

Archive