3

默认情况下,SCons 似乎会查看用于构建程序的“配方”并从中提取隐式依赖项。例如假设我的 SConstruct 包含:

Command('foo', 'foocreator.py', '/usr/bin/python foocreator.py > foo')

而且我已经构建了“foo”(“foo”是最新的)。现在我更改 SConstruct(或更现实地说,传递不同的选项),以便 'foo' 的命令变为:

Command('foo', 'foocreator.py', '/usr/bin/qrsh -V -cwd /usr/bin/python foocreator.py > foo')

(换句话说,通过 SGE 运行 foocreator.py 脚本)现在 SCons 尝试重建 foo,--debug=explain 告诉我这是因为“对 /usr/bin/qrsh 的新依赖”和“已删除的依赖”在 /usr/bin/python")。

我怎样才能防止从配方中推断出这种依赖关系,最好是全局的?到目前为止,我什至无法找到这种行为的规范。我不想说明“foo”并不真正依赖于 python 或 qrsh 的事实,因为我必须对每个目标以及这些程序的每个可能位置都这样做。必须有一个“正确”的方式。

编辑:我现在也尝试为每个目标显式添加忽略,如:

Ignore('foo', '/usr/bin/python')
Ignore('foo', '/usr/bin/qrsh')

甚至这也行不通!每当我在运行 qrsh 和不运行之间切换时,SCons 仍然希望重建所有内容。

4

3 回答 3

4

问题是 scons 对动作进行一些最小的解析来确定你在调用什么,这样

   python $SOURCE > $TARGET

自动将依赖项添加到 python。它还在动作的 md5 中包含动作 TEXT。所以如果你把它改成

   anotherprog -cmd python $SOURCE > $TARGET

它将检测到 3 个变化:

  1. 删除了对 python 的依赖
  2. 添加了对 anotherprog 的依赖
  3. 改变了命令行

这是半合理的,因为如果您更改另一个程序,您可能应该进行重建。

您可以通过在“$(”和“$)”中包含不重要的位来停止 scons 检测命令行更改,因此更改

   anotherprog $( -date $TIME $) $SOURCE > $TARGET

   anotherprog $( -time $DATE $) $SOURCE > $TARGET

不会导致重建。

所以我猜如果你有

  $( python $) $SOURCE > $TARGET

  $( anotherprog =cmd python $) $SOURCE > $TARGET

它会做你想要的。但我没有尝试过。

于 2012-07-20T07:46:56.587 回答
1

我找到了记录在案的解决方案:有一个构造变量 IMPLICIT_COMMAND_DEPENDENCIES 可以精确控制这种行为。它记录在http://www.scons.org/doc/HTML/scons-man.html上(但我通过搜索 scons 源代码发现了它!)

所以这给出了基于我原来的例子我想要的行为。

env = Environment(IMPLICIT_COMMAND_DEPENDENCIES =0, ... )
Command('foo', 'foocreator.py', '/usr/bin/python foocreator.py > foo')

(或者)

env = Environment(IMPLICIT_COMMAND_DEPENDENCIES =0, ... )
Command('foo', 'foocreator.py', '/usr/bin/python foocreator.py > foo')

我可以在目标 'foo' 的两个定义之间切换,并且 scons 不会认为 foo 已过时。

于 2012-07-23T15:54:54.453 回答
0

我不确定这是否会有所帮助,但最好如下更改您的操作字符串:

actionStr = '/usr/bin/qrsh -V -cwd /usr/bin/python $SOURCE > $TARGET'
Command(target = 'foo', source = 'foocreator.py', action = actionStr)

SCons 可能无法从操作字符串中确定源和目标是什么,并且可能会感到困惑。

可能无法像您在上面的评论中建议的那样关闭行为,但是您应该尝试使用Ignore()Depends()函数对其进行微调,而不是创建自己的构建器。绝对最坏的情况是通过调用在内部执行 qrsh 和 python 的 shell 脚本来有效地使操作字符串保持不变。

于 2012-07-19T16:02:42.460 回答