automake
[Top][All Lists]
Advanced

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

simple recipe for multiple outputs in manual is parallel-unsafe?


From: Dave Goodell
Subject: simple recipe for multiple outputs in manual is parallel-unsafe?
Date: Fri, 14 Oct 2011 11:31:16 -0500

(I'm posting this to automake@ because I consider this a documentation issue in 
automake, not necessarily a question/bug w.r.t. make itself)

Section 27.9 of the current automake manual suggests two make idioms for 
correctly handling tools that produce multiple outputs when using parallel 
make.  It additionally shows several flawed idioms to illustrate why the 
correct recipes are the way they are.

https://www.gnu.org/software/automake/manual/automake.html#Multiple-Outputs

The simpler of the two "correct" recipes seems to be incorrect in my testing.  
It results in the "foo" script being run twice, although sequentially AFAICT.  
So even if it's not technically unsafe it is certainly wasteful and unintuitive 
behavior.

Here's my test Makefile and the contents of my "foo" script:

----8<----
% cat Makefile
all: archive.zip

archive.zip: data.c data.h
        zip archive.zip data.c data.h

data.c data.h: data.foo
        @echo start_time=`date`
        ./foo $<
        @echo end_time=`date`

data.h: data.c

# run "make bootstrap" to create the original source file
bootstrap:
        date > data.foo

clean:
        rm -f data.c data.h archive.zip

.PHONY: all clean bootstrap

% cat foo
#!/bin/sh

sleep 2
cat $1 > data.c
cp -p data.c data.h
----8<----

To run it, you just need to run "make bootstrap" first to put the fake source 
file in place.

Here's the output I get from "make -j4 --debug=bj":

----8<----
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i386-apple-darwin10.0
Reading makefiles...
Updating goal targets....
 File `all' does not exist.
   File `archive.zip' does not exist.
     File `data.c' does not exist.
    Must remake target `data.c'.
     File `data.h' does not exist.
start_time=Thu Oct 13 17:57:59 CDT 2011
./foo data.foo
end_time=Thu Oct 13 17:58:01 CDT 2011
 File `all' does not exist.
   File `archive.zip' does not exist.
     File `data.h' does not exist.
    Must remake target `data.h'.
start_time=Thu Oct 13 17:58:01 CDT 2011
./foo data.foo
end_time=Thu Oct 13 17:58:03 CDT 2011
 File `all' does not exist.
   File `archive.zip' does not exist.
  Must remake target `archive.zip'.
zip archive.zip data.c data.h
  adding: data.c (stored 0%)
  adding: data.h (stored 0%)
 File `all' does not exist.
Must remake target `all'.
Successfully remade target file `all'.
----8<----

You can see that "foo" is invoked twice, although the two executions don't seem 
to overlap.  My intuition was that make would notice that data.h existed after 
data.c was remade.

If this is expected behavior then the automake manual should probably be 
updated to point out that "foo" will be invoked twice, since most people will 
want to opt for the more involved lock-based solution that only runs "foo" 
once.  If it's unexpected behavior, can someone point out what I'm doing wrong 
in my test Makefile/program?

Thanks,
-Dave




reply via email to

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