bug-make
[Top][All Lists]
Advanced

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

Re: The bugs in make v3.82


From: Paul Smith
Subject: Re: The bugs in make v3.82
Date: Tue, 28 Sep 2010 17:41:39 -0400

On Tue, 2010-09-28 at 18:42 +0400, Alexander Kornilov wrote:
> Could you, please, review my new example (bug_0001_fixed.zip
> attached)?
> 
> But some issue still present on Windows platform:
> 
> Preconditions: 'Obj' directory present as dependency of target (see
> example from attachment).
> 
> Obj/%.d: %.cpp makefile Obj
> 
> 1. Execute make. File Obj/test1.d Obj/test2.d Obj/test3.d was
> generated;
> 2. Delete file Obj/test2.d;
> 3. Execute make again.
> 
> Expected result:
>   Only Obj/test2.d generated.
> 
> Actual result (Windows platform):
>   File Obj/test1.d Obj/test2.d Obj/test3.d generated again on Windows
> platform.

Please keep it on the mailing list so everyone can see.

First you can reduce these lines:

        objList := $(srcList:%.cpp=%.o)
        objList := $(addprefix $(objDir)/,$(objList))

to just:

        objList := $(srcList:%.cpp=$(objDir)/%.o)

Ditto for depList.

You still have a bug in your makefile, which is also very common.  I'll
bet it fails the same way on Linux as well, not just Windows.

Here's the rule that's causing your problems:

        $(objDir)/%.d: %.cpp $(objDir) makefile

This lists the directory "Obj" as a prerequisite of all the .d files.
Directories are treated no differently than any other file by make; the
time last modified of the directory is checked against the target.

The problem is that the time last modified on a directory is updated
when (and only when) the directory itself changes: that is, a new file
is added, or a file is removed, or a file is renamed.  That means that
every time you add/remove/rename a file in the Obj directory, the
directory timestamp is updated and any .d file that has already been
created will be considered out of date, and rebuilt.


Using a directory as a normal prerequisite is almost never what you
want.

You have two choices.  I prefer the simple one which is to just force
the directory to be created whenever the makefile is invoked; something
like:

        __dummy := $(shell mkdir -p $(objDir))

The advantage here is this is executed as the makefile is read in, every
time, so you don't have to list this as a prerequisite of any target to
make sure it's created.

The other choice is to use an order-only prerequisite (see the manual).
This would be something like:

        $(objDir)/%.d: %.cpp makefile | $(objDir)

The downside is you have to remember to do that for any rule that writes
to $(objDir).  The advantage is that the directory is not created unless
it's actually needed.




reply via email to

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