27

When I change a Makefile, its rules may have changed, so they should be reevaluated, but make doesn't seem to think so.

Is there any way to say, in a Makefile, that all of its targets, no matter which, depend on the Makefile itself? (Regardless of its name.)

I'm using GNU make.

reinierpost
  • 8,425
  • 1
  • 38
  • 70

3 Answers3

17

This looks like one more simple, useful, logical thing that Make should be able to do, but isn't.

Here is a workaround. If the clean rule is set up correctly, Make can execute it whenever the makefile has been altered, using an empty dummy file as a marker.

-include dummy

dummy: Makefile
    @touch $@
    @$(MAKE) -s clean

This will work for most targets, that is targets that are actual files and that are removed by clean, and any targets that depend on them. Side-effect targets and some PHONY targets will slip through the net.

Beta
  • 96,650
  • 16
  • 149
  • 150
  • 1
    Nice trick, but if I want all my dependencies to be remade (which takes about 30 minutes in my present project) I'll call `make clean` myself. – reinierpost Oct 11 '10 at 07:46
  • That raises the related question: how to automatically generate rules for `make clean`? My present Makefile has none. – reinierpost Oct 11 '10 at 07:47
  • 15
    @reinierpost: wait a minute. Don't you want all of the dependencies to be remade, if the makefile has been altered? Don't you want them all to depend on the makefile itself? Wasn't that the whole point? – Beta Oct 12 '10 at 07:19
  • @reinierpost: As for generating a `clean` rule, it sounds as if you are solving the wrong problem. How many targets do you have? – Beta Oct 12 '10 at 07:20
  • @Beta : Yes that is pretty much the whole point, sorry. I was hoping for a solution that doesn't clean out old results before I explicitly ask for them to be remade (I often make specific targets with this Makefile) but I never specified this. I have about 300 rules, half of which are implicit. – reinierpost Oct 12 '10 at 08:03
  • @reinierpost: You want the option to continue to run binaries that are out of date? I don't think there's any clean way to do that. As for writing a `clean` rule, it really is best to do it by hand; don't worry about the implicit rules, just organize the real targets into sensible lists and use those. That way when you add a target you can just add it to a list or two, and not have to modify the `clean` rule. – Beta Oct 13 '10 at 05:24
  • @Beta: they are not binaries, but text files. (I realize make isn't suited for what I'm trying to do with it.) How do you summarize 115 implicit make rules in "a list or two"? – reinierpost Oct 13 '10 at 07:33
  • 1
    @reinierpost: Using Make for text files is unusual, but not anathema. There might be a good workaround for you problem, but the *exact* solution you want does not exist. And you misread what I wrote about lists: there might be dozens of lists, but a new target would be on only one or two of them. – Beta Oct 14 '10 at 17:25
  • @Beta: ah, OK. Well, I much prefr generic rules, that are not tied to specific filenames, so I use implicit rule patterns instead of lists. For this project I've discovered that make is basically too restricted in its expressive power and I'm tempted to write my own in an actual programming language. – reinierpost Oct 15 '10 at 23:49
  • I've accepted this answer for lack of a better one (there are actually no `clean` rules in the 200+-rule Makefile I want this for). – reinierpost Apr 24 '14 at 09:12
  • @Beta: I get an error: `Makefile: dummy: no such file or directory`. How should the `clean` rule be set up correctly? – jvriesem Jun 11 '14 at 19:30
  • @jvriesem: Put a hyphen in front of the `include` directive. I'll edit the Answer. – Beta Jun 11 '14 at 21:00
  • If you use includes, you might want to use $(MAKEFILE_LIST) instead of just Makefile. https://www.gnu.org/software/make/manual/html_node/Special-Variables.html – armb Oct 21 '19 at 18:20
10

Since GNU make version 4.3 it is now possible with the use of those two special variable:

  1. .EXTRA_PREREQS
    • To add new prerequisite to every target
  2. MAKEFILE_LIST
    • To get the path of the make file

To have every target depend on the current make file:

Put near the top of the file (before any include since it would affect the MAKEFILE_LIST) the following line:

.EXTRA_PREREQS:= $(abspath $(lastword $(MAKEFILE_LIST)))

To have every target depend on the current make file and also the make files which were included

Put the following line at the end of your file:

    .EXTRA_PREREQS+=$(foreach mk, ${MAKEFILE_LIST},$(abspath ${mk}))
elarivie
  • 175
  • 3
  • 7
2

The only answer I know to this is to add makefile explicitly to the dependencies. For example,

%.o: %.c makefile
        $(CC) $(CFLAGS) -c $<
S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
Norbert S
  • 275
  • 2
  • 14
  • 3
    Good idea to add `$(CPPFLAGS)` to the rule, to match the corresponding [implicit rule](https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html#Catalogue-of-Rules) – juanchopanza Feb 04 '17 at 10:55