0

Consider the following Makefile which knows to clean and rebuild itself if the Makefile or its included configuration files config.mk or local.mk are changed:

include config.mk
-include local.mk

-include dummy.rebuild

all: ...
# other targets...

# https://stackoverflow.com/a/3892826/149138
dummy.rebuild: Makefile config.mk local.mk
    touch $@
    $(MAKE) -s clean

This works fine if config.mk and local.mk actually exist - if either is modified, the dummy.rebuild target fires and the project is rebuild.

However, imagine that local.mk is an optional file which may or may not exist. In the case that it doesn't exist, the dummy.rebuild rule never seems to run at all, even if the Makefile or config.mk is changed. This is different behavior than a normal rule where a dependency doesn't exist, usually you'd get an error like:

make: *** No rule to make target 'local.mk', needed by 'dummy.rebuild'.  Stop.

... but in the case of the dummy.rebuild target implicitly added as a target via inclusion, you just get:

make: Nothing to be done for 'all'.

How can I implement the makefile so that if any of Makefile, config.mk or local.mk are changed, the dummy.rebuild target is executed, where the local.mk file may not exist?

BeeOnRope
  • 60,350
  • 16
  • 207
  • 386

1 Answers1

2

I'm not entirely sure what you're trying to do, but maybe using this instead will give you the behavior you want:

local.mk := $(wildcard local.mk)

include $(local.mk)
  ...
dummy.rebuild: Makefile config.mk $(local.mk)
  ...

Using wildcard here expands to local.mk if the file exists, or the empty string if it doesn't exist so it will be ignored in all ways if it's not there.

MadScientist
  • 92,819
  • 9
  • 109
  • 136