[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

The trap in Node: Automatic Prerequisites

From: Nathan H Zook
Subject: The trap in Node: Automatic Prerequisites
Date: Tue, 13 Feb 2001 16:02:03 -0500

The documentation in  Node: Automatic Prerequisites may easily mislead a
naive user (such as myself) into a nasty trap.  Basically, the trap is to
mix code and data, where I (now) consider the makefiles to be code and the
other targets data.  The trap is set with the following snippet:

%.o %.d : %.c
     set -e; $(CC) -MD -c $(CPPFLAGS) $($*_CCFLAGS) $< \

include $(sources:.c=.d)

The trap springs if the $*_CCFLAGS variable is read from a built file,
which is also included:

RULES : $(sources:.c=.mk)
     rm -rf .RULES
     for file in $^ ; do \
          echo >>RULES "TTARG := $$file" ; \
          cat  >>RULES $$file.mk ; \
     echo >>RULES "TTARG :="

include RULES

Now suppose we issue the command `make main.o`, where main.c and main.mk
exist, with main.mk new.  Make see that both RULES and main.d are out of
date and included.  It therefore builds both.  Having built the included
files, it reexecs, only to find that all targets have been built--so it

The problem is that main.o was built with the old value for main_CCFLAGS,
from the old RULES file, rather than the new value from the new main.mk
file.  Worse, the file will not be rebuilt until some other trigger occurs.

I see two solutions.  The bad one is to drop %.d from the list of buildable
targets.  For this class of files, data that is (precisely) one generation
old is acceptable.  This leads to other problems, for instance, if a .d
file were to be deleted and then an included file were updated--especially
if include $(sources:.c=.d) line were preceeded with a dash, which it will
almost always be, to avoid having to touch newfile.d by hand.

The better solution is to insist that the .d files and the .o files be
generated by separate rules.

I think that this situation merits a discussion and a reminder:  DON'T MIX

Might it also be useful to inform users that included files are built from
the bottom of the file up?


Top of my "want" list:
1) A special target (.NOBUILTINS ?) to duplicate the functionality of the
command line -r switch.
2) A command line option (--build ?) to consider all targets out of date.
Probably would not apply to makefiles not specified as targets on command

I would also like to be able to specify (though a shell script whose output
sets $? ?) more general tests for out-of-dateness.


Nathan Zook

A foolish consistency is the hobgoblin of little minds
-- Emerson

A foolish inconsistency is the hobgoblin of program designs
-- Nathan Zook

reply via email to

[Prev in Thread] Current Thread [Next in Thread]