[Scons-users] Pass custom arguments to a builder

William Deegan bill at baddogconsulting.com
Mon Jan 20 15:00:49 EST 2014


Delbert,


On Jan 20, 2014, at 8:01 AM, Gary Oberbrunner <garyo at oberbrunner.com> wrote:


> On Mon, Jan 20, 2014 at 3:12 AM, delbert dev <delbertum at gmail.com> wrote:

>> def my_action(source, target, env):

>> with zipfile.ZipFile(env['src_file'] , "r") as z:

>> z.extractall(env['out_folder'])

>> print "Extracted : " + env['src_file'] + " to: " + env['out_folder']

>>

>> # First "envocation"

>> my_cmd_builder = Builder(action=my_action, src_file=gtestOutputFile,

>> out_folder=outdir)

>> env.Append( BUILDERS = {'MyCmd' : my_cmd_builder } )

>> extract_gtest_cmd = env.MyCmd(["Extract gtest"], os.popen('which

>> bash').read().strip())

>

> If I understand correctly, the only reason you create two builders is

> to change src_file. You don't need to do that. All builder calls

> allow you to specify "environment overrides" as keyword args, so:

> extract_gtest_cmd = env.MyCmd(["Extract gtest"], os.popen('which

> bash').read().strip(), src_file=gtestOutputFile)

> extract_gmock_cmd = env.MyCmd(["Extract gmock"], os.popen('which

> bash').read().strip(), src_file=gmockOutputFile)

>

> Also, and this is important, action functions like your my_action take

> target, source, env; you have source, target, env.



I'm not sure why you're running which bash, I'm guessing that's just some dummy operation.
Here's one way to make a more real builder for unzipping your files.
I've not tried it locally.


# Define your action and emitters
import os
def my_action(source, target, env):
with zipfile.ZipFile(env['src_file'] , "r") as z:
z.extractall(env['out_folder'])
print "Extracted : " + env['src_file'] + " to: " + env['out_folder']


def my_emitter(target, source, env):
with zip file.ZipFile(source[0],'r') as z:
target.append("%s%s%s"%(env['MYCMD_OUTPUT_DIR'],os.pathsep,z)]
return target,source




# Create your builder
my_cmd_builder = Builder(action=my_action, emitter=my_emitter)

# Add your builder to the Environment()
env.Append( BUILDERS = {'MyCmd' : my_cmd_builder } )



extract_gtest_cmd = env.MyCmd(["Extract gtest"], gTestOutputFile, MYCMD_OUTPUT_DIR=outdir)
extract_gmock_cmd = env.MyCmd(["Extract gmock"], gmockOutputFile, MYCMD_OUTPUT_DIR=outdir)

# Was
# Default(env.Alias('obs', Depends(extract_gtest_cmd,[gmockDownload, gtestDownload, extract_gmock_cmd])))

#Assuming your *Download functions have a target of *OutputFile, then there's no need for the Depends.
# So the following should be sufficient
# also note that the output of all builders is a list of Node objects, as such you can just add them together as below.
my_alias = env.Alias('obs',extract_gtest_cmd+extract_gmock_cmd)

Default(my_alias)

For a reasonable downloading builder you may want to have a custom decider and use the output from:
curl -L --head http://prdownloads.sourceforge.net/scons/scons-2.3.0.tar.gz

To decide if a file you have already downloaded is up to date.

Also, as a general statement, coming from Make to SCons a common mistake is to try and force the order of things, the proper way to use SCons is to set up all your dependencies properly, and then SCons will run them in the right order. If you can't get it to do so then likely you don't have a good understanding of each build steps dependencies and you should take a step back.


Hope that helps!
-Bill








More information about the Scons-users mailing list