29

In the event that a Makefile itself is changed, a safe bet would be to consider all targets out of date.

Is there a clever way to add this dependency? Are there any alternatives?

Matt Joiner
  • 112,946
  • 110
  • 377
  • 526
  • 1
    I asked the same question not too long ago: http://stackoverflow.com/questions/3871444/making-all-rules-depend-on-the-makefile-itself – reinierpost Nov 12 '10 at 09:00
  • Strange that it did not come up in a search, it's not even in related. – Matt Joiner Nov 12 '10 at 20:45
  • This might not be enough. What happens when variables change? (For example, you may need to do a _clean_ between a `make CDEFS=debug` and a `make CDEFS=release`.) – bobbogo Jan 06 '11 at 11:15

3 Answers3

11

Make sure the object files depend on the makefile:

$(OBJFILES) : Makefile

Where Makefile is the name of the make file.

2501
  • 25,460
  • 4
  • 47
  • 87
Per Knytt
  • 1,931
  • 1
  • 11
  • 14
  • I presume I am required to populate SRCFILES myself? – Matt Joiner Nov 11 '10 at 12:56
  • Yep. My question might sound a bit arrogant but what I meant to ask was what kind of properties you wanted from an alternative solution. I don't know of a way to make a dependency on "every target". – Per Knytt Nov 11 '10 at 13:22
7

A safe bet, but a terrible idea. Example: you're using automake and update Makefile.am to add a single source file. The correct response is to compile just the new file and link it in. In your scheme everything would be rebuilt.

Moreover, adding the dependency isn't going to do anything unless you touch the file, something like:

$(SRCS): Makefile
    touch $@

This will then trip up editors that use the mtime to detect concurrent modification (emacs is one example).

If you're doing something major, just run make clean all after doing the change.

Jack Kelly
  • 18,264
  • 2
  • 56
  • 81
  • I did not consider that the sources would be not be updated. But what if all the _targets_ depend on the Makefile? +1 for raising a good point. – Matt Joiner Nov 12 '10 at 02:41
  • @Matt Joiner: It would work (you would also have to include the transitive closure of all included .mk files), but you'd still have redundant recompilation, more often than not. Better to not bother: you then have short builds by default and the ability to do a full build if needed. If you put this in, you have no way to do the short build if you've made only a minor tweak. I know you do a lot of C++ stuff. You can't seriously suggest that the cost of a full rebuild of a C++ project is minor? – Jack Kelly Nov 12 '10 at 03:20
  • 1
    Why would you have to touch the Makefile? The rule is only run if Makefile is already newer than the object files. – Per Knytt Nov 12 '10 at 07:37
  • It's not touching the `Makefile`. It's touching the source file. If you don't touch the source file, it will always consider the source out of date, which means that it will recompile it every time `make` is invoked. – Jack Kelly Nov 13 '10 at 03:51
  • No, no, no. You *don't* use such a dependency when using `automake`! It's seldom I downvote an answer, especially one chosen by the asker, but this is a bad answer. This is a valid question for projects where you are using a custom `Makefile`. Personally, I try earnestly to avoid this and use `autotools` whenever possible, but I have a project now where this isn't feasible. – Daniel Santos Jul 05 '21 at 07:46
5

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