help-make
[Top][All Lists]
Advanced

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

Re: Can I generate multiple recipe commands dynamically in makefile


From: Christian Rishøj Jensen
Subject: Re: Can I generate multiple recipe commands dynamically in makefile
Date: Thu, 19 May 2011 16:38:23 +0200

I've often seen this question arise, and I keep wondering why people are 
encouraged to use loop constructs, whether Make-native or shell loops. 

Why not just let Make's dependencies handle it?

E.g.:

================

define show
        echo "[$1]"
endef

filelist = 1.c 2.c 3.c

show-% :
        @$(call show,$*)

all : $(addprefix show-,$(filelist))

================


Or, even just:

================

filelist = 1.c 2.c 3.c

show-% :
        @echo "[$*]"

all : $(addprefix show-,$(filelist))

================


Is the addprefix function non-portable?
Or is there some other argument that I am unaware of?

– Christian


On May 16, 2011, at 3:15 AM, Chen Jun (陈军) wrote:

> 
> Thank you Paul, your first two method is surely workable and I have
> thought about them, but I am also aware of some drawback of them(just I
> think). See my comment below. So I'd like to heard about the ultimate
> $(eval ) method. I've been using GNU make intensively for five years and
> Paul had kindly answer some real-world $(eval ) questions for me, so I'm
> sure I'm quite versed in $(eval ), (ugh, except the very question today).
> 
> On 2011-05-15 23:22, Paul Smith wrote:
>> On Sun, 2011-05-15 at 18:06 +0800, Chen(陈) Jun(军) wrote:
>>> Please check my makefile:
>>> 
>>> ================
>>> define show
>>>    echo "[$1]"
>>> endef
>>> 
>>> filelist = 1.c 2.c 3.c
>>> 
>>> all:
>>>    @$(call show,1.c)
>>>    @$(call show,2.c)
>>>    @$(call show,3.c)
>>> 
>>> # That code below cannot work!
>>> #all2:
>>> #    @$(foreach f,$(filelist),$(call show,$p))
>>> ================
>>> 
>>> I'd like to dynamically generate N shell commands under "all" targets when
>>> filelist has N words. How can I do it? Without the ultimate solution,
>>> everytime I add a word to filelist, I have to manually add one command line
>>> under "all".
>> There are a number of ways to do this, some more portable/easier to
>> understand than others.
>> 
>> The most portable and simplest way is to use shell loops, not make
>> loops, like this:
>> 
>>      all:
>>              @for f in $(filelist); do echo "[$$f]"; done
>> 
> 
> Assume this method1(M1). What if I want to generate dynamic shell
> command with multiple factors, For example, for each word in
> filelist($w), I will call a make function to get a parameter($p) and use
> $p in shell command. $p is easy to get from makefile, but very hard from
> shell script execution. That's the problem.
> 
>> Alternatively you can use make commands to generate a list of shell
>> commands, similar to your attempt above, BUT you have to add a semicolon
>> between them so the shell will interpret them as different commands,
>> like this:
>> 
>>      all:
>>              @$(foreach f,$(filelist),$(call show,$p);)
>> 
>> This is relatively straightforward but relies on GNU make features
>> (foreach, call, etc.)
> Assume this method2(M2). I'm afraid there's a problem here: If filelist
> contains lots of words and each command-let is quite long, then the
> single command(passed to ``sh -c'') can be very long, perhaps >32KB(that
> will exceed Windows CreateProcess limit).
>> The final method is to use $(eval ...); this is GNU make-specific AND
>> complicated to understand.
>> 
> So, I'm looking forward to $(eval ), just call it method3(M3), but
> cannot figure it out myself. I'll be very grateful if you can exhibit
> this great technique.


reply via email to

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