bug-make
[Top][All Lists]
Advanced

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

Re: Explicit, implicit rule chain doesn't work in created dirs


From: Paul D. Smith
Subject: Re: Explicit, implicit rule chain doesn't work in created dirs
Date: Tue, 27 Aug 2002 17:15:35 -0400

%% <address@hidden> writes:

  b> dir:
  b>    mkdir -p dir/subdir

This rule is incorrectly written.  You have informed make that you will
be creating a target "dir", but you really created a target
"dir/subdir".  As a result, make doesn't know anything about
"dir/subdir", it only knows about "dir".

  b> if dir/subdir doesn't exist, "make all" fails:
  b>  *** No rule to make target `dir/subdir/file.a', needed by `all'.

This is because of GNU make's internal directory cache.  The first time
make accesses a directory, it creates a cache of the data it finds
there.

In this case, it looks at dir when it first sees that it needs to build
dir/subdir/file.b, and it doesn't exist.  Further, there are no rules
defined in the makefile to build dir/subdir.  So, make gives up.

  b> if the rule for file.b is a pattern rule: everything is fine in
  b> either case.

I guess in this situation, because the rule is implicit rather than
explicit the directory is not cached immediately and by the time make
gets there, it's already been created.


The directory cache can cause problems if your makefiles are not fully
fleshed out (that is, as in the example above, if there are rules that
create files "behind make's back" so it doesn't know about them).
However, it provides a significant speed increase so turning it off
poses a problem.

Luckily for you, what you are trying to do is a very bad idea anyway :).
By that I mean, you should never create directories by defining them as
targets and listing them as prerequisites.  It's just not what you want
to do, period.

Here are two good reasons:

 1) First, unless you are careful to define the directory as a
    prerequisite to _every_ target, someone will get a failure if they
    run "make foo.o" and foo.o doesn't depend on the directory.

 2) Second, if you do #1, then all your code will be rebuilding at odd
    times for no discernable reason.

    Remember that the modification time of a directory changes whenever
    a file is added or removed in that directory.  So, whenever you add
    a file to the directory "dir" above its modification time will be
    reset; that means that any files that depend on "dir" will be
    rebuilt--just because you added (or removed) a file in "dir".

    This is almost never what you want.

The answer is very simple: always create directories first, before make
starts trying to build targets.

You can do this with simply expanded variables (which are expanded by
make as the makefile is read in, before any targets are evaluated), and
the $(shell ...) function:

  _foo := $(shell [ -d dir/subdir ] || mkdir -p dir/subdir)

Done.

-- 
-------------------------------------------------------------------------------
 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]