List Info

Thread: Rule-specific variables




Rule-specific variables
user name
2008-04-28 03:55:13
I'm trying to optionally add arguments to a command,
depending on the
target, as shown by my (obviously non-working) example:

%.xdb : %.bdfi
	var=1
	[ $(basename $(F)) = part_of_filename ] && var=2
	command --var=$(var) $(basename $(F)).bdfi

I could make a rule for each possible target, but it seems
it could be
simpler, as there are several possible combinations.

Any ideas?

Please CC me on replies, as I am not subscribed.

Regards

Jeff


_______________________________________________
Help-make mailing list
Help-makegnu.org
http:
//lists.gnu.org/mailman/listinfo/help-make

Re: Rule-specific variables
country flaguser name
United States
2008-04-28 07:37:53
On 2008-04-28 08:55Z, Jeffrey Ratcliffe wrote:
> I'm trying to optionally add arguments to a command,
depending on the
> target, as shown by my (obviously non-working)
example:
> 
> %.xdb : %.bdfi
> 	var=1
> 	[ $(basename $(F)) = part_of_filename ] && var=2
> 	command --var=$(var) $(basename $(F)).bdfi
> 
> I could make a rule for each possible target, but it
seems it could be
> simpler, as there are several possible combinations.

See "Pattern-specific Variable Values" in the
manual, e.g.:

var := 1
part_of_filename.xdb : var := 2

%.xdb : %.bdfi
	command --var=$(var) $(basename $(F)).bdfi


_______________________________________________
Help-make mailing list
Help-makegnu.org
http:
//lists.gnu.org/mailman/listinfo/help-make

Re: Rule-specific variables
country flaguser name
United States
2008-04-28 12:26:47
Jeffrey Ratcliffe wrote:

> I'm trying to optionally add arguments to a command,
depending on the
> target, as shown by my (obviously non-working)
example:
> 
> %.xdb : %.bdfi
>         var=1
>         [ $(basename $(F)) = part_of_filename ]
&& var=2
>         command --var=$(var) $(basename $(F)).bdfi

Everything that is part of the recipe (i.e. starts with a
TAB) is passed 
directly to the shell after undergoing variable expansion,
so any 
variable assignments that occur are in the domain of the
shell and not 
make.  Try the following two commands to understand why this
won't work:

sh -c 'var=1'
sh -c 'echo var is: $var'

This is essentially what you are telling make to invoke with
your 
makefile, and as you can see any assignment to var in the
first command 
is invisible to the second one, because any changes to 'var'
in the 
child process effectively disappear when that child
terminates. 
Therefore if you want to use shell variables you need to
write the 
recipe so that it uses a single shell invocation, e.g.

sh -c 'var=1; echo var is: $var'

You can still write the recipe on multiple lines but you
must use '' at 
the end of each line and separate each command with ';' so
that 
logically it's still one single command.

Moreover, using this technique 'var' is a shell variable not
a 'make' 
variable so you cannot refer to it as $(var).  You need for
the shell to 
see it as $var (or $) so you must write it as $$var (or
$$) in 
the makefile, so that make passes the $ through to the shell
rather than 
trying to expand it as an (empty) make variable.  See
section 5.1.2 
("Using Variables in Recipes") of the manaul.  You
might end up with 
something like:

%.xdb : %.bdfi
	var=1; 
	[ $(basename $(F)) = part_of_filename ] && var=2;

	command --var=$$var $<

There is another way to handle this, however.  You can do
all the logic 
using 'make' functions:

%.xdb : %.bdfi
	command --var=$(if $(findstring part_of_filename,$(basename
$(F))),2,1) $<

This is potentially more efficient since 'make' expands the
$(if ...) 
expression before passing it to the shell, avoiding the need
for the 
shell to have to fork/exec the 'test' binary to evaluate the
expression 
(although most common Bourne shell implementations do have a
'test' 
builtin to avoid this cost.)  But even still it will likely
be faster to 
use $(if ...) since make has an optimization where it can
skip the shell 
and invoke the command directly if the command is simple,
e.g. if after 
expansion it contains no shell metacharacters or shell
constructs like 
redirection or quoting or &&.

The flip side of the coin is that using functions like $(if
...) is GNU 
make specific and so your makefile will not be usable with
other 'make' 
implementations, whereas doing it in the shell does not
depend on any 
'make' features.  However, since you are already using
$(basename ...) 
you most likely don't care about portability since that's
specific to 
GNU make too, AFAIK.

Brian


_______________________________________________
Help-make mailing list
Help-makegnu.org
http:
//lists.gnu.org/mailman/listinfo/help-make

Re: Rule-specific variables
user name
2008-04-29 03:36:24
2008/4/28 Greg Chicares <gchicaressbcglobal.net>:
>  var := 1
>  part_of_filename.xdb : var := 2
>
>  %.xdb : %.bdfi
>         command --var=$(var) $(basename $(F)).bdfi

Excellent. Thank you very much

Jeff


_______________________________________________
Help-make mailing list
Help-makegnu.org
http:
//lists.gnu.org/mailman/listinfo/help-make

[1-4]

about | contact  Other archives ( Real Estate discussion Medical topics )