[Scons-users] SCons builder to call scripts with other files as arguments
Carnë Draug
carandraug+dev at gmail.com
Sun Jan 24 17:33:22 EST 2016
On 24 January 2016 at 21:24, Bill Deegan <bill at baddogconsulting.com> wrote:
> On Sun, Jan 24, 2016 at 2:15 PM, Carnë Draug <carandraug+dev at gmail.com>
> wrote:
>>
>> I have many cases where I use scripts and data files in SCons. At the
>> moment I'm writing something like this:
>>
>> foo_script = 'scripts/mk_foo.py'
>> foo = env.Command(source = 'data/foo.json',
>> target = 'results/foo.tex',
>> action = 'python %s $SOURCE > $TARGET')
>> env.Depends(foo, foo_script)
>>
>> This is already not ideal because I have to keep repeating 'foo_script'.
>> However, my problem is another which I think also solves it.
>>
>> I have changed the structure of my project and started to make use of
>> SConscript in subdirectory. When using a SConscript, SCons builders
>> are smart enough to fix the path for the declared nodes ("source" and
>> "target") but obviously not for the actual path of the script.
>>
>> Short of exporting one more variable from SConstruct and join the paths
>> myself, how can I do this with SCons?
>>
>> Carnë
>
> Add a builder for mk_foo.py, in the emitter add the dependency on the
> script.
> (see: https://bitbucket.org/scons/scons/wiki/ToolsForFools)
> and/or add a psuedo builder.
> (see: http://scons.org/doc/production/HTML/scons-user/ch20.html)
A builder for each of the many scripts seem excessive. So I made it
work with a pseudo builder.
I first found out that this works:
foo = env.Command(source = ['scripts/mk_foo.py',
'data/foo.json'],
target = 'results/foo.tex',
action = 'python $SOURCES > $TARGET')
which was pretty nice. All the paths are expanded nicely even within
a SConscript.
However, I didn't like the idea of mixing both script and input
arguments in SOURCES. I also wanted more flexibility for python.
So I wrote a general builder to call on python scripts:
vars = Variables()
vars.Add('PYTHON', default='python', help='The python interpreter')
vars.Update(env)
def python_output(env, script, source, target, args=[]):
script = env.File(script)
c = env.Command(target, source, SCRIPT=script, ARGS=args,
action='$PYTHON $SCRIPT $SOURCE $ARGS > $TARGET')
env.Depends(c, script)
return c
env.AddMethod(python_output, "PythonOutput")
foo = env.PythonOutput(script = 'scripts/mk_foo.py',
source = 'data/foo.json',
target = 'results/foo.tex')
The trick required was on using File(). It works different outside of
a builder which took me forever to realize.
Carnë
More information about the Scons-users
mailing list