Multiple Remakes (GNU Make only)

2 minute read

GNU Make has an advanced feature called Makefile Remaking, which is documented in the GNU Manual, “How Makefiles are Remade,” and available at: https://www.gnu.org/software/make/manual/make.html#Remaking-Makefiles

To quote from the GNU Make description:

“Sometimes makefiles can be remade from other files, such as RCS or SCCS files. If a makefile can be remade from other files, you probably want make to get an up-to-date version of the makefile to read in.

“To this end, after reading in all makefiles, make will consider each as a goal target and attempt to update it. If a makefile has a rule which says how to update it (found either in that very makefile or in another one) or if an implicit rule applies to it (see section Using Implicit Rules), it will be updated if necessary. After all makefiles have been checked, if any have actually been changed, make starts with a clean slate and reads all the makefiles over again. (It will also attempt to update each of them over again, but normally this will not change them again, since they are already up to date.)”

This feature can be very useful for writing makefiles that automatically generate and read dependency information with each build. However, this feature can cause GNU Make to loop infinitely if the rule to generate a makefile is always out-of-date:

all: @echo $@ makefile: force @echo "# last updated: ’date’" >> $@ force:

In practice, a well-written makefile will not have out-of-date rules that cause it to regenerate. The same problem, however, can occur when Make detects a clock skew—most commonly due to clock drift between the system running Make and the file server hosting the current directory. In this case, Make continues to loop until the rule to rebuild the makefile is no longer out-of-date.

In the example below, DIR1 and DIR2 are both part of the source tree:

-include $(DIR1)/foo.dd all: @echo $@ $(DIR1)/foo.dd: $(DIR2)/bar.dd %.d: touch $@

If two directories are served by different file servers and the clock on the system hosting DIR2 is slightly faster than DIR1, then even though foo.dd is updated after bar.dd, it might appear to be older. On remaking, GNU Make will again see foo.dd as out-of-date and restart, continuing until the drift is unnoticeable.

eMake fully supports makefile remaking and can be configured to behave exactly as GNU Make. However, by default, to ensure builds do not loop unnecessarily while remaking, eMake limits the number of times it restarts a make instance to 10. If your build is looping unnecessarily, you might want to lower this value or disable remaking entirely by setting:

--emake-remake-limit=0