make ".if exists" problem/question

Harti Brandt hartmut.brandt at dlr.de
Mon Sep 5 09:03:18 PDT 2005


On Thu, 25 Aug 2005, Emanuel Strobl wrote:

ES>Am Donnerstag, 25. August 2005 20:10 CEST schrieb David Kirchner:
ES>> On 8/25/05, Emanuel Strobl <Emanuel.strobl at gmx.net> wrote:
ES>> > Dear make gurus (bsd make, not gmake),
ES>> >
ES>> > it seems that make checks .if directives only at statrup. How can I
ES>> > trigger a "reread"?
ES>> > I have the problem that in one target I create a filetree, another
ES>> > target checks if it exists, if not it creates itself again. Now it
ES>> > works perfectly when I call the two targets both externally
ES>> > (installcfworld installcfconfig) but when the internal higher
ES>> > "install" gets to the installcfconfig target it fails!
ES>> > I'm really desperate, I need to check this. Is this a nasty bug?
ES>>
ES>> This Makefile shows the problem:
ES>>
ES>> all:
ES>> .if ! exists(./foobar)
ES>>         @echo foobar does not exist
ES>> .endif
ES>>         touch foobar
ES>> .if ! exists(./foobar)
ES>>         @echo foobar does not exist
ES>> .endif
ES>>
ES>> If you run make in this directory, and foobar does not already exist
ES>> beforehand:
ES>>
ES>> $ make
ES>> foobar does not exist
ES>> touch foobar
ES>> foobar does not exist
ES>>
ES>> Looking at the make source, it appears that it maintains a cache for
ES>> file lookups, and I don't see a way to have it flush the hash via some
ES>> makefile command. I dunno if it is a bug but the man page does not
ES>> mention a cache.
ES>>
ES>> I wonder if you'll have to start a separate make process for each
ES>> stage of that target's handling.
ES>
ES>Thanks for your suggestion, you described exactly what I mean. So if 
ES>there's no way to flush the cache, it's IMHO a wrong behaviour and should 
ES>be considered as bug.
ES>I'm not too experienced in make, so I don't know if I want to call sub 
ES>makes...
ES>Do you have an idea whom to contact regarding the "bug"?

You should think of .if and .for as "preprocessor directives". They are 
processed when make reads the makefile and builds the dependency graph. If 
you need something more dynamic you must use either a shell line:

foo:
	if [ -f baz ] ; then ...

or go with sub-makes. 

Generally you don't want to use .if to check for a file that your makefile 
creates. In this case you just should use make itself. Given that the tree 
you need to have is named 'tree' do something like:

installcfworld: tree
	...

installcfconfig: tree
	...

tree:
	mkdir tree
	...

harti


More information about the freebsd-current mailing list