如何告诉SCons忽略来自命令操作的隐式依赖关系?

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,因为我将不得不为每个目标和每个可能的这些程序位置都这样做。一定有一种“正确”的方法。
编辑:我现在也尝试了为每个目标显式添加Ignores,例如:
Ignore('foo', '/usr/bin/python')
Ignore('foo', '/usr/bin/qrsh')

即使如此也不起作用!每当我在qrsh和非qrsh之间切换时,SCons仍然想要重建所有内容。


SCons是否总是尝试重新构建foo,还是只在更改Command()操作后才这样做?如果仅在更改操作后才这样做,那么对我来说听起来相当合理。 - Brady
@Brady只有在“更改”操作时才会生效。即使环境发生变化,例如使用不同版本的python(或gcc等),它也会执行相同的操作。我同意这种行为在许多情况下都很有用,我只是想知道如何关闭它。 - Joe
3个回答

4
事实上,Scons会对操作进行一些最基本的解析来确定您正在调用什么,因此:

   python $SOURCE > $TARGET

自动添加了对Python的依赖。它还将动作TEXT包含在动作的md5中。因此,如果您更改了它,

   anotherprog -cmd python $SOURCE > $TARGET

它将检测到三个更改:

  1. 去除了对Python的依赖
  2. 增加了对另一个程序的依赖
  3. 更改了命令行

这在某种程度上是合理的,因为如果您更改了另一个程序,您应该重新构建。

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

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

to

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

不会导致重新构建。

因此,我猜如果你有

  $( python $) $SOURCE > $TARGET

为了

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

它应该能做到你想要的,但我没有尝试过。


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已经过时。


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 脚本来有效地使操作字符串保持不变。


我非常确定这与我的示例相当--您只是提供了命名参数而不是位置参数。(并且使用$SOURCE和$TARGET只是方便--在我的真实SConstruct中,名称是通过编程方式构建的,在配方中没有硬编码文件名)。 - Joe
@Joe,我通常默认使用命名参数,并不是建议这样做会有什么区别,显然不会 :) 我回答的重点是在操作中使用SOURCE和TARGET。就像我在答案中提到的那样,我不确定它是否有帮助,但我认为值得一试。我在答案中添加了一个解决方法。它并不能真正关闭行为,但应该可以工作。 - Brady

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接