help-make
[Top][All Lists]
Advanced

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

Re: HELP! Can I construct individial shell commands using a function


From: Luke Shumaker
Subject: Re: HELP! Can I construct individial shell commands using a function
Date: Sun, 27 Feb 2011 16:55:19 -0500

On Sun, 2011-02-27 at 10:29 +0000, Oleksandr Gavenko wrote:
> On 2011-02-27 5:10, address@hidden wrote:
> > Thank you so much, Luke. You've revealed this great trick just in time,
> > about which GNU make manual does not say. Correct me if it does say.
> >
> > On Sat, 26 Feb 2011 21:23:15 -0500, Luke Shumaker<address@hidden>
> > wrote:
> >> The trick is to get the different commands on different lines.  Try
> >> this:
> >>
> >> define _ExecuteShcmdArray
> >> $(foreach c,$1,@$($c)
> >> )
> >> endef
> This seems VERY tricky!
> 
> I simply wrote your function as recursively expanded variable
> with command invoked in separate shells (e.g. '(echo 1);(echo 2);' ):
> 
> _ExecuteShcmdArray = $(foreach c,$1,($($c));)
> 
> ...
>
> Question to GNU Make GURU: 'foreach' with newline in 'define'
> documented behavior?

I think the newline trick is documented, if indirectly.

In the original the recipe for `all' evaluated to

all:
        cd .. ; pwd;cd .. ; pwd

Which produced the output it did, since the ``cd ..''s stacked.  The
obvious solution is to run them in separate shells.  Now, in a recipe,
each line is ran in a separate shell (unless you set .ONESHELL, a
feature introduced in 3.82).  So, since the desired effect is to run
each command in a separate shell, my first reaction was to put the
commands on different lines:

all:
        cd .. ; pwd
        cd .. ; pwd

The original $(foreach) used `;' as a delimiter between commands, I
simply changed it to a newline.  The only tricky part here is that this
means making `_ExecuteShcmdArray' a multiline variable, which is what
`define' does.   My code is equivalent to:

define newline

endef
_ExecuteShcmdArray = $(foreach c,$1,@$($c)$(newline))

Your (Oleksandr Gavenko's) code works just as well, but differently.
Instead of running the command sets in different shells, they run in the
same shell, but it has the shell run them in different environments.
This may even be more efficient, because spawning a new process is a
relatively slow process, but it is not typically the bottleneck in
Makefiles.

-- 
~ LukeShu
http://lukeshu.ath.cx




reply via email to

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