tech-toolchain archive

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

Re: bsd.lib.mk question



On Tue, Jun 07, 2011 at 06:45:32AM +1000, matthew green wrote:
>

> > > SRCS=     a.c b.c
> > > 
> > > a.c b.c:
> > >   echo 'int foo;' > ${.TARGET}
> > 
> > > If you run that, you will see two calls for echo.
> > 
> > But your commands don't (well, your command doesn't) build two files;
> > it builds only one.  Naturally make has to run it again for the other.
> > 
> > Try, instead,
> > 
> > a.c b.c:
> >     echo 'int foo;' > a.c
> >     echo 'int foo;' > b.c
> > 
> > You'll find - well, I find, at least - that it runs the command set
> > only once.
> 
> make -j is the problem.  eg:
> 
> xotica ~> make -f a.mk -j10 b.c a.c
> --- b.c ---
> --- a.c ---
> --- b.c ---
> echo 'int foo;' > a.c
> --- a.c ---
> echo 'int foo;' > a.c
> --- b.c ---
> echo 'int foo;' > b.c
> --- a.c ---
> echo 'int foo;' > b.c

I believe that I've seen this in the Heimdal makefiles that I put
together recently.  It results in indeterministic behaviour which
is a tad suboptimal insofar as you sometimes rebuild files multiple
times but sometimes you do not.  It may be the cause of an occasional
build failure.

Let's take the following example.  We expect to create two files
named c and d which contain "foo\n".  The all: rule simply tests
to ensure that the files contain the correct data.  The rule ``a
b'' generates the two files using separate commands, the first two
of which truncates the file to zero length and the last two put
data into the file.  This is not dissimilar to many applications
which will open and truncate the files before filling them with
data.

all: c d
        if [ ! -s c ]; then                             \
                echo File c is zero length;             \
                exit 1;                                 \
        fi
        if [ ! -s d ]; then                             \
                echo File d is zero length;             \
                exit 1;                                 \
        fi

a b:
        echo -n > a
        echo -n > b
        echo foo > a
        echo foo > b

c: a
        cp a c

d: b
        cp b d

clean:
        rm -f a b

This Makefile will sometimes exhibit the ``correct'' behaviour but if
you use -j 2 then it will occasionally fail.

So, the question is: is it right to expect that this works?

--
    Roland Dowdeswell                      http://Imrryr.ORG/~elric/


Home | Main Index | Thread Index | Old Index