Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在使用python函数生成器时,Scons会忽略依赖项跟踪环境_Python_Scons - Fatal编程技术网

在使用python函数生成器时,Scons会忽略依赖项跟踪环境

在使用python函数生成器时,Scons会忽略依赖项跟踪环境,python,scons,Python,Scons,在scons 2.5.1中,我遇到了一个与通过环境向基于python的构建器传递参数有关的问题。 调用普通构建器时,如果传入的任何源文件或环境变量发生了更改,则结果似乎被标记为脏。 当使用python函数生成器(这里描述)时,SCON似乎只关心源文件 这里有一个最小的人工例子,说明它失败的地方。这是通过环境传递参数并使用shell将其写入目标文件的两种实现。一个实现只是一个命令字符串,另一个使用python子流程在python函数中调用它。我使用参数来选择要使用的生成器 #SConstruct

在scons 2.5.1中,我遇到了一个与通过环境向基于python的构建器传递参数有关的问题。 调用普通构建器时,如果传入的任何源文件或环境变量发生了更改,则结果似乎被标记为脏。 当使用python函数生成器(这里描述)时,SCON似乎只关心源文件

这里有一个最小的人工例子,说明它失败的地方。这是通过环境传递参数并使用shell将其写入目标文件的两种实现。一个实现只是一个命令字符串,另一个使用python子流程在python函数中调用它。我使用参数来选择要使用的生成器

#SConstruct
import subprocess

def echo_fun(env, source, target):
    subprocess.check_call('echo %s > %s' % (env['MESSAGE'], str(target[0])), shell= True)
    return None

env = Environment(BUILDERS = {'echo' : Builder(action='echo $MESSAGE > $TARGET'),
                              'echo_py': Builder(action=echo_fun),
                              })
build_fn = env.echo_py if ARGUMENTS.get('USE_PYTHON', False) else env.echo
build_fn(['test.file'], [], MESSAGE = ARGUMENTS.get('MSG', 'None'))
以下是使用不同参数运行scons脚本的结果:

PS C:\work\code\sconsissue> scons -Q MSG=Hello
echo Hello > test.file
PS C:\work\code\sconsissue> scons -Q MSG=Hello
scons: `.' is up to date.
PS C:\work\code\sconsissue> scons -Q MSG=HelloAgain
echo HelloAgain > test.file
PS C:\work\code\sconsissue> del .\test.file
PS C:\work\code\sconsissue> scons -Q MSG=Hello -Q USE_PYTHON=True
echo_fun(["test.file"], [])
PS C:\work\code\sconsissue> scons -Q MSG=Hello -Q USE_PYTHON=True
scons: `.' is up to date.
PS C:\work\code\sconsissue> scons -Q MSG=HelloAgain -Q USE_PYTHON=True
scons: `.' is up to date.
在使用普通构建器的情况下,当MSG发生变化时,它会检测到结果是脏的(当MSG保持不变时,它会检测到结果是干净的),但在python命令版本中,它认为即使MSG发生了变化,结果也是最新的

解决方法是将我的构建器脚本放在一个单独的python脚本中,并使用环境依赖项作为命令行参数调用该python脚本,但这似乎很复杂

这是预期的行为还是错误


有没有比我上面描述的更简单的解决方法,可以将生成函数保存在sconstuct文件中?

这是预期的行为,因为scon无法知道函数(编写时)依赖于消息

但是,如果您阅读手册页

您将看到(在“动作对象”下):

变量也可以由varlist=关键字参数指定; 如果两者都存在,则将它们合并。无论何时,这都是必要的 希望在使用特定构造变量时重建目标 变化。字符串操作通常不需要这样做,因为 变量通常是命令行的一部分,但可能需要 如果Python函数操作使用构造变量的值 生成命令行时

因此,如果您重写为:

#SConstruct
import subprocess

def echo_fun(env, source, target):
    subprocess.check_call('echo %s > %s' % (env['MESSAGE'], str(target[0])), shell= True)
    return None

env = Environment(BUILDERS = {'echo' : Builder(action='echo $MESSAGE > $TARGET'),
                              'echo_py': Builder(action=Action(echo_fun, varlist=['MESSAGE'])),
                              })
build_fn = env.echo_py if ARGUMENTS.get('USE_PYTHON', False) else env.echo
build_fn(['test.file'], [], MESSAGE = ARGUMENTS.get('MSG', 'None'))
它应该按照你的意愿来运作

#SConstruct
import subprocess

def echo_fun(env, source, target):
    subprocess.check_call('echo %s > %s' % (env['MESSAGE'], str(target[0])), shell= True)
    return None

env = Environment(BUILDERS = {'echo' : Builder(action='echo $MESSAGE > $TARGET'),
                              'echo_py': Builder(action=Action(echo_fun, varlist=['MESSAGE'])),
                              })
build_fn = env.echo_py if ARGUMENTS.get('USE_PYTHON', False) else env.echo
build_fn(['test.file'], [], MESSAGE = ARGUMENTS.get('MSG', 'None'))