help-make
[Top][All Lists]
Advanced

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

Re: Makefile remaking loop


From: Frank Küster
Subject: Re: Makefile remaking loop
Date: Tue, 08 Mar 2005 14:07:02 +0100
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.3 (gnu/linux)

Boris Kolpackov <address@hidden> wrote:

> address@hidden (Frank Küster) writes:
>
>> I have written a Makefile for a Debian package which works just fine on
>> my local machine.  However, on one of the autobuilders (in this case
>> it's for Debian experimental) it goes in a seemingly endless loop.
>
> It's because your box is too fast. Just try to prefix your commands
> with "sleep 2 &&" and you will get the same endless loop.
>
> You problem is equivalent to the one in the following simple makefile
> (assume there is a file called makefile.in in the current directory):
>
> all: ;@:
>
> %: %.in force
>       sleep 2 && touch $@
>
> force:
>       @true
>
> The endless loop comes from an (implicitly) phony target `force'
> which is remade unconditionally and thus renders whatever depends
> on it out of date (makefile, in our case). So in your case
> the solution would be to get rid of those proxy targets and use
> real files instead.

Which is not an easy task here.  The problem I want to solve is that I
want some action to be performed if some file A exists, and is younger
than an other file B (this is easy with make), but it should do nothing,
at least not give an error, when file A does not exist at all.  In real
life words, the task is:

"If file /outside/source/directory/fileA exists and is newer thank
./in/src/directory/fileB, copy file A to replace fileB.  Otherwise, just
use the existing fileB"

I'm wondering whether I'm just thinking too complicated, and even such
an easy setup would work:

something: fileB
   ...

fileB: /outside/source/directory/fileA
   -cp $< $@

/outside/source/directory/fileA:
   true
   
In my imagination, this would do the following: If fileA does not exist,
it "successfully" tries to remake it, running "true", and going on with
the work to make fileB.  If fileA does exist and is newer than fileB, it
does not run "true" (because it isn't phony, and has no prerequisites),
but it creates fileB by copying fileA.  So far, so fine.

If fileA exists and is older than fileB, it does nothing to remake
fileA, but unfortunately it copies it over fileB every time fileB is a
needed as a prerequisite.  In my case, this is only annoying (because if
it is edited file, changes will be made only in fileA), but I'd like to
get rid of this.

Indeed:

all: fileB
        echo "made $@"

fileB: ../fileA
        -cp $< $@

../fileA:
        true

$ make
true
cp ../fileA fileB
cp: cannot stat `../fileA': No such file or directory
make: [fileB] Error 1 (ignored)
echo "made all"
made all
$ touch fileB
$ make 
true
cp ../fileA fileB
cp: cannot stat `../fileA': No such file or directory
make: [fileB] Error 1 (ignored)
echo "made all"
made all
$ touch ../fileA
$ make 
cp ../fileA fileB
echo "made all"
made all
$ make 
echo "made all"
made all
$ 

So, I guess to avoid the copying, I must move the "test -e ... & test
... -nt ... "stuff from the original posting to this place, here it
goes:

all: fileB
        echo "made $@"
        -ls --full-time -l $<

fileB: ../fileA
        test -e $< && test $< -nt $@ && cp $< $@ || true

../fileA:
        true

This seems to go well, does anybody still see a problem?

TIA, Frank


-- 
Frank Küster
Inst. f. Biochemie der Univ. Zürich
Debian Developer





reply via email to

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