[Scons-users] Controlling display of a builder

Carnë Draug carandraug+dev at gmail.com
Sat Oct 17 17:29:22 EDT 2015


On 17 October 2015 at 20:57, Bill Deegan <bill at baddogconsulting.com> wrote:
>
> On Sat, Oct 17, 2015 at 11:55 AM, Carnë Draug <carandraug+dev at gmail.com>
> wrote:
>>
>> Hi
>>
>> I have been using the possibility to pass extra arguments to Command
>> to have them used in a builder.  I am doing something like the following:
>>
>>     scons_subprocess_call = (lambda target, source, env
>>                                     : subprocess.call(env['ARGS'],
>> source[0]))
>>
>>     data = env.Command(
>>       source = "foo.pl",
>>       target = "bar.log",
>>       action = scons_subprocess_call,
>>       ARGS   = ['homo sapiens', 'Reference GRCh'])
>>
>> The problem with this is that the output of SCons won't display anything
>> useful:
>>
>>     $ scons
>>     [...]
>>     scons: Building targets ...
>>     <lambda>(["bar.log"], ["foo.pl"])
>>     [...]
>>
>> The main reason I am doing this is to avoid the shell since some of the
>> arguments have whitespace, single and double quotes, and even wildcards.
>> This makes generation of a command problematic.  I have tried to write my
>> own builder but the problem remains.  I create a Builder either by
>> setting a `action`, and continue with the problem of not having the actual
>> call made displayed, or by setting a `generator`, and face the problem of
>> escaping any weird stuff in the arguments.
>>
>>
>> Short of having the builder print() something, is there any way to create
>> a Builder that does not boil down to create a command line for the shell,
>> while still controlling what SCons displays?
>>
>> (I am aware that this means that what gets displayed will not match
>> a command line.  However, it would still be more informative)
>>
>> Thank you,
>> Carnë
>
> Carnë,
>
> No need to do all that coding.  SCons will expand and escape arguments for
> you..
>
>
> env=Environment()
>
>
> if False:
>     scons_subprocess_call = (lambda target, source, env
>                              : subprocess.call(env['ARGS'], source[0]))
>     data = env.Command(
>         source = "foo.pl",
>         target = "bar.log",
>         action = scons_subprocess_call,
>         ARGS   = ['homo sapiens', 'Reference GRCh'])
> else:
>     data = env.Command(
>         source = "./foo.pl",
>         target = "bar.log",
>         action = "${SOURCE.abspath} $ARGS  > $TARGET",
>         ARGS   = ['homo sapiens', 'Reference GRCh'])
>
>
>
> Produces:
> python ~/devel/scons/hg/scons/bootstrap.py
> /usr/bin/python
> /Users/bdbaddog/devel/scons/hg/scons/bootstrap/src/script/scons.py
> scons: Reading SConscript files ...
> scons: done reading SConscript files.
> scons: Building targets ...
> /Users/bdbaddog/devel/scons/bugs/10_17_2015/foo.pl "homo sapiens" "Reference
> GRCh" > bar.log
> scons: done building targets.
>

This is pretty cool.  I didn't know that.  However, it still does not work
for my case because it's not escaping wildcards (my ARGS are simple regular
expression for gene symbols such as 'HIST1*').  Is this a bug and should
I report it?

Here's a full example.  The one liner perl prints back all of the script
arguments.  Note how "bar*" and "foo*" get expanded to the list of files,
and how the script never receives the "bar*" and "foo*".

    $ mkdir scons-playground
    $ cd scons-playground/
    $ cat > foo.pl
    print "$_\n" for @ARGV;
    $ cat > SConstruct
    env = Environment()
    env.Command(
      source="foo.pl",
      target="foo.log",
      action="perl $SOURCE $ARGS > $TARGET",
      ARGS = ["bar*", "foo*"])
    $ touch foobar bar bar1 bar2 bar3
    $ scons
    scons: Reading SConscript files ...
    scons: done reading SConscript files.
    scons: Building targets ...
    perl foo.pl bar* foo* > foo.log
    scons: done building targets.
    $ cat foo.log
    bar
    bar1
    bar2
    bar3
    foo.pl
    foobar


Carnë


More information about the Scons-users mailing list