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

时间:2012-07-19 15:41:44

标签: scons

默认情况下,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之间切换时,SCons仍然希望重建所有内容。

3 个答案:

答案 0 :(得分:3)

问题在于,scons会对动作进行一些最小的解析,以确定您正在调用的内容,以便

   python $SOURCE > $TARGET

自动为python添加依赖项。它还包括动作的md5中的动作TEXT。因此,如果您将其更改为

   anotherprog -cmd python $SOURCE > $TARGET

它会检测到3个变化:

  1. 删除了对python的依赖
  2. 添加了对anotherprog的依赖
  3. 更改了命令行
  4. 这是半合理的,因为如果你改变另一个程序,你应该可以说有一个重建。

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

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

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

    不会导致重建。

    所以我猜你是否有

      $( python $) $SOURCE > $TARGET
    

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

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

答案 1 :(得分: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已经过时。

答案 2 :(得分:0)

我不确定这是否会有所帮助,但最好按照以下方式更改操作字符串:

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

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

可能无法像您在上面的评论中所建议的那样关闭行为,但您应该尝试使用Ignore()和{{3}进行微调,而不必制作自己的构建器。 } 功能。绝对最糟糕的情况是通过调用在内部执行qrsh和python的shell脚本来有效地使动作字符串不变。