automake
[Top][All Lists]
Advanced

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

Re: How can I pass $@ to Makefile?


From: Eric Blake
Subject: Re: How can I pass $@ to Makefile?
Date: Thu, 28 May 2015 15:01:53 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0

On 05/28/2015 02:41 PM, Arthur Schwarz wrote:
> 
> So let's try this with your make rule.  The lines starting with a
> "+" character are the actual commands being executed by the shell:
> 
>   % make SHELL='sh -x' test3.abc
>   echo '#!/bin/bash'                                  > test3.abc
>   + echo '#!/bin/bash'
>   echo "echo test3.abc $# ' [' $@ ']'>> test3.log" >> test3.abc

This is what make passed to the shell...

>   + echo 'echo test3.abc 0 '\'' ['\''  '\'']'\''>> test3.log'

...and this is what the shell executed, after doing shell expansions.

>   echo "echo I am a test script        >> test3.log" >> test3.abc
>   + echo 'echo I am a test script        >> test3.log'
> 
> (to get snarky) I saw the problem before. The issue is that the $#/$@
> expands inside make (when test.abc: is executed and not in the shell script.
> I can do this if I put the script into the appropriate directory and take
> creation out of Makefile.am. I know this. I just wish there was another way.

No, $# did NOT expand inside make, but inside the shell that make was
running when asked to execute the commands that will create test3.abc.
You were not using correct shell quoting.  It sounds like you want to
defer expansion of $@ not only in make, but also in the shell that make
runs.  Let's look more closely at your attempt:

echo "echo test3.abc $# ' [' $@ ']'>> test3.log" >> test3.abc

says to do shell interpolation of $# and $@ inside the double quotes,
then append the resulting string to test3.abc.  After executing that
statement in shell, the last line in test3.abc will be:

echo test3.abc 0 ' ['  ']'>> test3.log

Whereas if you had used different quoting, as in:

echo 'echo test3.abc $# " [" $@ "]">> test3.log' >> test3.abc

so that you were telling the shell to NOT interpret $, then the last
line in test3.abc will be:

echo test3.abc $# " [" $@ "]">> test3.log

Of course, that is still underquoted, if you intend to avoid
globbing/splitting on the results of $@ when executing the file
test3.abc.  You want the $@ to be inside double quotes.  Ultimately, it
sounds like you are not quite sure of how many layers of processing text
will go through.  So let's work backwards:

First, figure out what you want in the file test3.abc.  Probably
something like this (and note that things are a lot easier by avoiding '
in this script):

#!/bin/bash
echo test3.abc "$# [ $@ ]">> test3.log
echo I am a test script   >> test3.log

Next, figure out how to generate test3.abc using shell scripting (note
that I'm using '' quoting here to suppress all expansions in the text
being put in the generated file, which is why I avoided ' in the script
I am generating):

echo '#!/bin/bash' > test3.abc
echo 'echo test3.abc "$# [ $@ ]">> test3.log' >> test3.abc
echo 'echo I am a test script   >> test3.log' >> test3.abc

Finally, write that shell script inside a make rule (make passes
everything to shell except for $, which is escaped by adding another $):

test3.abc:
        echo '#!/bin/bash' > test3.abc
        echo 'echo test3.abc "$$# [ $$@ ]">> test3.log' >> test3.abc
        echo 'echo I am a test script   >> test3.log' >> test3.abc

Before you can write effective makefile rules for invoking complicated
shell scripting, you first need to know the difference between '' and ""
in shell quoting rules, and practice writing shell scripts that generate
shell scripts to get a feel for using nested layers of quoting when
generating files.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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