[Top][All Lists]

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

Re: how to create a single rule to build a directory as necessary

From: Philip Guenther
Subject: Re: how to create a single rule to build a directory as necessary
Date: Tue, 22 Sep 2009 11:11:29 -0700

On Tue, Sep 22, 2009 at 10:19 AM, Sam Steingold <address@hidden> wrote:
> Paul Smith wrote:
>> On Tue, 2009-09-22 at 11:44 -0400, Sam Steingold wrote:
>>> I, too, am struggling with rebuilding a directory.
>>> it appears that the rule:
>>> gllib: config.status
>>>        mkdir -p gllib; cd gllib; make
>>> is wrong because the script "mkdir ..." is always executed, regardless of
>>> whether config.status has changed or not.
>>> So, what is the right way to handle this?
>> The short answer is that using a directory as a target in make is almost
>> never correct, unless it's a .PHONY target or the equivalent.
> so what is this SUBDIRS automake thingie?

Uh, that would be a question for the automake people/list.  'make'
itself gives no special semantics to the variable SUBDIRS, but many
makefiles use it to specify a list of directories into which they plan
on recursing.  Exactly how they implement that recursion (e.g., using
a shell 'for' loop or as multiple prerequisites on some other target)
is up to whomever (or whatever) generated the makefile.

>> The problem is that the modification time on a directory means something
>> that is not really appropriate for make: the modification time on a
>> directory changes whenever the DIRECTORY ITSELF changes.  When does a
>> directory change?  It changes whenever any element in the directory is
>> renamed or deleted, or a new element is created in the directory.  In
>> short, if you run "ls -a" before and after some command and the output
>> is identical, then the directory was not modified.
> this makes perfect sense.
> thanks.
> how about this addition then:
> gllib: config.status
>        mkdir -p gllib; cd gllib; make
>        touch gllib/.stamp; rm -f gllib/.stamp
> adding and removing the .stamp file will modify the directory, right?

The problem with that is that other operations may change the
timestamp on the directory *without* doing a 'make', in which case a
change to the config.status might not result in make being invoked.
That can be 'solved' by having a persistent timestamp file and doing
comparisons, but it leaves you with a different problem: if something
is changed inside that directory, the toplevel Makefile wouldn't know
about it or see any reason to run 'make' inside it.  That why, as Paul
described in his message, directories are usually marked as .PHONY so
that they're always remade and the "don't do unnecessary work" bit can
be left to the subsidiary makefile.

>> which by the way, is not well-formed; it should be:
>>        mkdir -p $@ && cd $@ && $(MAKE)
> I am afraid I cannot use the "gnuisms" (as they were called by a NetBSD user
> who was bitten by these variables when I used them)

Whoever told you that is sadly mistaken.  The '@' and 'MAKE' variables
are both specified by the POSIX/SUS standard for make and were present
in 4.2 BSD!  It's handy to keep around a link to the standards
specification for quoting at people that are, uh, confused about
history and requirements.  Here's the link for 'make' from the Single
UNIX Standard, Issue 6.

>> Your problem here is more conceptual than anything.  What, in words, are
>> you really trying to get make to do?  How does the upper level makefile
>> know, really, that it does or doesn't need to invoke the sub-make?  It
>> can't know that... unless it invokes the submake to see whether anything
>> needs to be done.
> I need a few files which are created in gllib by make.
> Do I need to explicitly type
> gllib/foo gllib/bar : config.status
>        mkdir -p gllib; cd gllib; make

Better would be this:

# What do we need from inside the gllib subdir?

# those files depend on the .stamp file existing in the subdir and
being up to date
${GLLIB_TARGETS:%=gllib/%}: gllib/.stamp

# the .stamp file records the time we last did a build in that directory
#of the ${GLLIB_TARGETS}
gllib/.stamp: config.status
        mkdir -p gllib
        cd gllib && ${MAKE} ${GLLIB_TARGETS}
        touch $@

>> In a standard recursive make environment, sub-makes are almost always
>> set up as .PHONY, so they're always invoked, to be sure that their
>> content is up to date.  That's why recursive makes are slower,
>> typically, than non-recursive makes.
> so, if I add gllib to .PHONY, the commands will be always executed, even
> with the .stamp trick?

Yes, but that's okay, because the subsidiary makefile is the one that
knows whether 'foo' and 'bar' really need to be rebuilt.

Philip Guenther

reply via email to

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