help-make
[Top][All Lists]
Advanced

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

Re: is this a feature or a bug?


From: Paul Smith
Subject: Re: is this a feature or a bug?
Date: Tue, 23 Nov 2010 15:47:16 -0500

On Tue, 2010-11-23 at 11:40 -0800, James Sarrett wrote:
> I was trying to write a very simple Makefile this morning, and was 
> stymied!  What I thought I meant was this:
> 
> xrcs := *.xrc
> py_xrcs := $(xrcs:.xrc=_xrc.py)
> 
> %_xrc.py: %.xrc
>      pywxrc -pv $<
> 
> all: $(py_xrcs)
> 
> I have 2 .xrc files which need to be turned into _xrc.py files via 
> pywxrc.  I'm using GNU make 3.81 on Ubuntu 10.10 (maverick meerkat).  
> What appears to actually happen is that the variable py_xrcs ends up 
> with only the first filename returned by *.xrc translated to 
> file1_xrc.py.  I have found the workaround to be defining xrcs like
> this:
> 
> xrcs := $(wildcard *.xrc)
> 
> This seems like it should not be required.  Is this a bug in patsubst?

There's no bug here.

First, the GNU make manual has this to say about wildcards (from the
section "Using Wildcards in File Names"):

           Wildcard expansion is performed by `make' automatically in
        targets and in prerequisites.  In commands the shell is
        responsible for wildcard expansion.  In other contexts, wildcard
        expansion happens only if you request it explicitly with the
        `wildcard' function.

So, we can see that wildcard expansion does NOT happen automatically in
variable assignments (which should be obvious: how does make know that
the value you're trying to assign is supposed to be a filename wildcard?
It might be something completely different).

Knowing that, look at your makefile:

> xrcs := *.xrc

Here the variable "xrcs" has the literal string "*.xrc"

> py_xrcs := $(xrcs:.xrc=_xrc.py)

Here the variable "py_xrcs" has the literal string "*_xrc.py" (we're
using simple expansion)

> %_xrc.py: %.xrc
>      pywxrc -pv $<
> 
> all: $(py_xrcs)

This is expanded to:

all: *_xrc.py

Here, finally, we have a target or prerequisite with a wildcard in it so
here make does the expansion... maybe you can see the problem now... it
will only match _xrc.py files _that already exist_!!

This is obviously not what you want.

Your change (to use $(wildcard ...) explicitly) is the proper one: you
need to expand to the full list of source files, THEN convert that to
the list of targets you want to build.


Since I went to the trouble of typing out the above I'll get on my
soapbox here: I do not like to use $(wildcard) to find things to build.
It causes problems and leads to incorrect builds if there are temporary
files left in directories etc.

In my experience it's much better to have an explicit list of files to
build, in a variable in the makefile.  I can't think of a project where
so many files were being constantly added that updating the makefile was
an onerous task, and having an explicit list is much cleaner.

FWIW.

Cheers!




reply via email to

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