D. J. Bernstein
Data structures and program structures
Rebuilding target files when source files have changed

Target files depend on nonexistent files

You finish writing dhcpd.c and vis.c, and you type make to compile your new dhcpd program. You rely on a GNU-make-dependent Makefile that reliably figures out the .h prerequisites for dhcpd.o and vis.o.

Oops! You forgot to create vis.h. You did have the line

     #include "vis.h"
in dhcpd.c and vis.c; however, because there was no vis.h in the current directory, the compiler included /usr/include/vis.h instead. This didn't stop the program from compiling and linking, but the lack of proper prototypes for your vis.c functions means that the program doesn't work.

After realizing your mistake, you create vis.h, and you type make again to recompile.

Problem: Nothing happens.

What went wrong?

Answer: make has no idea that dhcpd.o depends on the nonexistence of vis.h. It knew that dhcpd.o had to be recompiled if certain existing files were modified, but it didn't know that dhcpd.o had to be recompiled if certain nonexistent files were created.

As another example, suppose there's a rule saying ``to rebuild dhcpd.o, use the dhcpd.o.do script if that exists; otherwise use the default.o.do script.'' If dhcpd.o is built using default.o.do, then it certainly should be rebuilt if default.o.do changes, but it should also be rebuilt if dhcpd.o.do is created.

How does redo handle this?

With redo, nonexistent files are supported in the same way as existing source files. The build command
     redo-ifchange vis.h
means that the current target should be rebuilt if the existing file vis.h is modified (or removed); the build command
     redo-ifcreate vis.h
means that the current target should be rebuilt if the nonexistent file vis.h is created.

When redo is looking for the build script for dhcpd.o, it uses redo-ifcreate automatically. For example, if dhcpd.o.do doesn't exist but default.o.do does, redo automatically runs

     redo-ifcreate dhcpd.o
     redo-ifchange default.o.do
before running default.o.do.

Right now I don't have a tool to simulate the compiler's search for vis.h, /usr/include/vis.h, etc. I handle #include prerequisites in a simpler way: the line #include "vis.h" triggers an automatic

     redo-ifchange vis.h
and therefore requires vis.h in the current directory. I always write #include <vis.h> when I want the system's vis.h.