如何限制SCons命令构建器仅在依赖项变化时运行?

4 投票
2 回答
5750 浏览
提问于 2025-04-15 11:25

我在使用scons中的命令构建器,目的是指定一个特定的脚本需要被调用,以生成一个特定的文件。

我希望只有在这个脚本自从上次生成文件以来被修改过的情况下,才运行这个脚本。可是,命令构建器的默认行为似乎是每次都运行这个脚本。我该怎么改变这个行为呢?

这是我现在的SConstruct文件:

speed = Command('speed_analysis.tex','','python code/speed.py')
report = PDF(target = 'report.pdf', source = 'report.tex')
Depends(report, speed)

2 个回答

1

也许你的例子不太完整,但你是不是应该这样做:

env = Environment()
env.Command(....

我觉得你需要把你的依赖项作为第二个参数传给命令:

Command('speed_analysis.tex','code/speed.py','python code/speed.py')
11

首先,看起来 code/speed.py 对输出文件名没有控制……在scons中,硬编码的输出文件名通常被认为是不好的做法(可以参考yacc工具)。这样写会更好:

speed = Command('speed_analysis.tex', [], 'python code/speed.py -o $TARGET')

现在,PDF目标会从 report.tex 生成一个 report.pdf。我猜 report.texspeed_analysis.tex 之间有一个隐含的依赖关系(可能是通过Tex的包含或类似的方式)。

这个:

Depends(report, speed)

如果缺少这个依赖关系,表达它是正确的。不过我很惊讶PDF构建器的扫描器没有发现这个隐含的依赖关系……

你应该使用以下命令来验证依赖树:

scons --tree=all

它应该看起来像这样:

+ report.pdf
  + report.tex
  + speed_analysis.tex
    + code/speed.py
    + /usr/bin/python
  + /usr/bin/pdflatex

现在,关于你的问题,为什么脚本(speed.py)总是运行,这是因为它没有输入。scons没有东西可以检查。这个脚本文件必须读取一些东西作为输入,即使只是读取它自己。你需要告诉scons所有直接和隐含的依赖关系,这样它才能避免后续的重复运行:

Command('speed_analysis.tex', 'code/speed.py', 'python $SOURCE -o $TARGET')

撰写回答