bug-make
[Top][All Lists]
Advanced

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

Re: Bug#218367: make: strange behavior with multi-target rules


From: Paul D. Smith
Subject: Re: Bug#218367: make: strange behavior with multi-target rules
Date: Sat, 21 Feb 2004 17:50:42 -0500

%% Manoj Srivastava <address@hidden> writes:

  ms> I have always thought that a normal (non-pattern) rule with
  ms> multiple targets gets run multiple times, once per each target
  ms> that is out of date.

That's correct.

  ms> MODULES := Blah Bleh
  ms> SOURCES := $(addsuffix .sml,$(MODULES)) 
  ms> TEX := $(addsuffix .tex,$(MODULES)) 
  ms> modules.tex : $(TEX)
  ms>   cat $(TEX) > modules.tex
  ms> $(TEX) : $(SOURCES)
  ms>   ./bin/plit $(SOURCES)

  ms> I have files Blah.sml and Bleh.sml.
  ms> Surprise #1: make modules.tex runs the last rule _once_ (which happens
  ms> to be what I want in this case).

That's because of the way make processes the makefile.  First, it builds
Blah.tex, but that command also updates Bleh.tex.  So, when make comes
around looking to decide if Bleh.tex needs to be updated, it doesn't
have to be because it's already up to date, so make doesn't run the rule
again.

The best way to see this problem is to try a parallel build: in that
case often make will try to invoke the script once for each target, in
parallel.

  ms> Surprise #2: add a flag to the command, so now the last rule is

  ms> $(TEX) : $(SOURCES)
  ms>   ./bin/plit -n $(SOURCES)

  ms> touch one of the .sml files, make modules.tex again.  Now plit
  ms> runs twice!

I don't know what the -n flag does so I can't say: I can't find any docs
for "plit" via Google or on my system.  Maybe it doesn't actually update
the files with -n?

Needless to say I can't reproduce this behavior with a simplified
makefile that doesn't invoke plit but rather just uses touch, etc. to
try to mimic its behavior.

  ms> Surprise #3: refactor like this

  ms> $(TEX) : junk

  ms> junk: $(SOURCES)
  ms>   ./bin/plit -n $(SOURCES)

  ms> touch Blah.sml.  Now make modules.tex runs the last rule (once), but
  ms> not the first rule (for modules.tex itself), even though it clearly is
  ms> out of date!

I can only assume that you created a file "junk" by hand in this
directory during your testing: no other explanation fits the facts as
you describe them.

This makefile is broken, because you never have any command that updates
the file "junk".

If that file "junk" doesn't exist already then make will always run the
plit script every time, regardless of the relative timestamps of the
.sml files, and then it will always update modules.tex.

If that file "junk" does exist, then it will re-run "plit" if any of the
.sml files is newer than the file "junk".  But since the script doesn't
update "junk" itself, make doesn't consider the two .tex files out of
date (they are still newer than their prerequisite, "junk") so it
doesn't rebuild modules.tex.

If you change your rule so that it updates "junk", all will work as you
expect:

    $(TEX): junk

    junk: $(SOURCES)
        ./bin/plit -n $(SOURCES)
        @touch $@

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <address@hidden>          Find some GNU make tips at:
 http://www.gnu.org                      http://make.paulandlesley.org
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist




reply via email to

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