有没有办法从SCons中的构建器调用的python函数中获取返回值?

时间:2017-03-27 12:12:54

标签: python scons

我正在使用SCons builder to call a python function,通常将目标指定为文件。但是在某些情况下,返回一个对象会很方便,但仍保留依赖关系,例如:将变量传递给另一个构建器。

构建器函数must返回0或None,但是有没有其他方法可以从构建器调用的函数中返回一些变量?

这个功能失调的剧本希望能够解释我想做的事情:

import os
env = Environment(ENV = os.environ)

def give_me_5(foo):
    foo = 5
    return foo # This must be 0 or None...

bar = give_me_5(4)  
print 'How many? ', bar
#How many? 5

builder_bar = env.Command(
        source=None,
        target=None,
        action=give_me_5,
        foo = 4
        ) #Command doesn't return functions variables

print 'How many? ', builder_bar
#How many? []

但我想:How many? 5

3 个答案:

答案 0 :(得分:1)

构建器返回一个Node()数组 值节点是可以作为目标的类型。

那说你的例子不会奏效。

当脚本运行时,它会构建DAG,然后行走DAG并运行操作。

因此,在运行SConscripts之前,操作本身不会运行。

答案 1 :(得分:1)

我可以使用文件在两个foo构建器之间传递Command

import os
import json

JSON_FILE_NAME = 'give_me_5.json'

env = Environment(ENV=os.environ)

def give_me_5(target, source, env):
    d = env.Dictionary()
    print "foo = %s" % d['foo']
    for t in target:
        foo = 5
        with open(str(t), 'w') as json_file:
            json.dump(foo, json_file)
    return None

env.Command(source=None,
            target=JSON_FILE_NAME,
            action=give_me_5,
            foo=4)

def get_foo(target, source, env):
    for s in source:
        with open(str(s), 'r') as json_file:
            foo = json.load(json_file)
        os.unlink(str(s))
    print "How many? ", foo
    return None

env.Command(source=JSON_FILE_NAME,
            target=None,
            action=get_foo)

<强>输出

scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
give_me_5(["give_me_5.json"], [])
foo = 4
get_foo(["give_me_5"], ["give_me_5.json"])
How many?  5
scons: done building targets.

请注意sourcetarget如何用于运行Command个实例。另请注意,'give_me_5.json'调用后get_foo中的os.unlink文件已被删除foo文件。这会导致每次都创建文件。此外,还有一个示例,说明如何从env参数中获取Builder值。

SCons专家可能能够指出在{{1}}个实例之间共享数据的更好方法。我使用JSON来序列化数据,但这限制了可以共享的数据类型。我真的只是提供这个答案作为概念验证,以防你真的陷入困境并立即需要解决方案。

答案 2 :(得分:0)

你可以改变函数外的变量:

bar = [None]

def give_me_5(foo):
    foo = 5
    bar[0] = foo

...

print 'How many? ', bar[0]

更全面:

import os
env = Environment(ENV = os.environ)

builder_bar = [None]

def give_me_5(foo):
    foo = 5
    builder_bar[0] = foo

env.Command(
        source=None,
        target=None,
        action=give_me_5,
        foo = 4
        )

print 'How many? ', builder_bar[0]
# How many?  5