help-make
[Top][All Lists]
Advanced

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

Re: Pattern rules with % matching empty string?


From: Glen Huang
Subject: Re: Pattern rules with % matching empty string?
Date: Sat, 25 Apr 2020 13:53:38 +0800

Thanks for the detailed examples.

Using variables to instantiate all hosts sounds overkill. I just want the 
pattern rule to also apply when the stem would be empty, and all but one host 
has a number suffix in their names.

I end up making all hosts contain the number suffix. Given the solutions 
provided, it feels like the cleanest one. 

> On Apr 25, 2020, at 1:29 PM, Kaz Kylheku (gmake) <address@hidden> wrote:
> 
> On 2020-04-24 21:56, Kaz Kylheku (gmake) wrote:
>> And a fourth option: keep the host names inconsistent
>> (they are probably hard to change) but enumerate them
>> with consistently named stamp files (easy to control).
>> Use computed variable names to associate the two together:
>>  remote-bin-host%: bin
>>     scp $< $(host_$*):$<
>>     touch $@
> 
> 
> With computed variable names, you can fake out a data
> structure in which it looks like keys are matched to records
> that have fields.
> 
> Then you can specify a database of hosts records, such
> that for each one you can give a stamp file name, host
> name and any other property, like using a different SSH
> key or whatever.
> 
> Please study this Makefile:
> 
>  host_1.name := foo
>  host_1.stamp := foo.txt
> 
>  host_2.name := bar
>  host_2.stamp := bar.txt
> 
>  host_list := 1 2
> 
>  define host_bin_template =
>  $$(host_$1.stamp): bin
>       echo scp $$< $$(host_$1.name):$$<
>       touch $$@
>  endef
> 
>  $(foreach n,$(host_list),$(eval $(call host_bin_template,$n)))
> 
> If we run "make foo.txt", this happens:
> 
>  echo scp bin foo:bin
>  scp bin foo:bin
>  touch foo.txt
> 
> Make has deduced through the structure we set up and the generated rules that 
> foo.txt is a stamp file associated with host foo.
> 
> This doesn't use pattern rules at all, but procedural rule expansion. We have 
> a list of hosts 1 2.
> The foreach loop steps over this list, and substitutes it as parameter $1 
> into the host_bin_template, which is evaluated via $(eval ...) as a piece of 
> Makefile syntax. That syntax creates a rule, exactly as if we had typed this 
> in:
> 
>  $(host_1.stamp): bin
>       echo scp $< $(host_1.name):$<
>       touch $@
> 
>  $(host_2.stamp): bin
>       echo scp $< $(host_2.name):$<
>       touch $@
> 
> Of course, these variables expand, and so the effect of the for loop and eval 
> is that this is generated:
> 
>  foo.txt: bin
>       echo scp $< foo:$<
>       touch $@
> 
>  bar.txt: bin
>       echo scp $< bar:$<
>       touch $@
> 
> 
> To add, a third rule, we just create new variables:
> 
>  host_3.name := saturn.localdomain
>  host_3.stamp := saturn.stamp
> 
> Update the list:
> 
>  host_list = 1 2 3
> 
> 
> Done. Now we have a third rule where saturn.stamp is a target,
> and updating it copies the bin file to saturn.localdomain.
> 
> With a little more hacking, we can probably (and ironically)
> re-create the "rdist" utility. :)
> 
> The advantage of pattern rules is that they avoid instantiation bloat.
> A pattern rule can potentially match just, say, one of potentially
> thousands of targets, which is more efficient than generating thousands
> of rules with an eval. And it can match new things in the filesystem
> that don't require any new definitions in the Makefile.
> 
> We lost some of the advantage of the pattern rule when we turned
> to computed variables for assistance; manual definitions had to be made
> to satisfy the computed variable references.
> 
> 




reply via email to

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