Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I constrain the SCons Command builder to run only if its dependencies have changed?

Tags:

python

scons

I am using the Command builder in scons to specify that a particular script needs to be invoked to produce a particular file.

I would like to only run the script if it has been modified since the file was previously generated. The default behaviour of the Command builder seems to be to always run the script. How can I change this?

This is my current SConstruct:

speed = Command('speed_analysis.tex','','python code/speed.py')
report = PDF(target = 'report.pdf', source = 'report.tex')
Depends(report, speed)
like image 864
saffsd Avatar asked Dec 18 '22 08:12

saffsd


2 Answers

First, it looks like code/speed.py has no control on the output filename... Hardcoded output filenames are usually considered bad practice in scons (see yacc tool). It would read better like this:

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

Now, the PDF target produces a report.pdf from report.tex. I'm guessing there's an implicit dependency from report.tex to speed_analysis.tex (through Tex include or something like that).

This:

Depends(report, speed)

Is correct to express that dependency if it's missing. Though I'm surprised the scanner for the PDF builder did not see that implicit dependency...

You should verify the dep tree using:

scons --tree=all

It should look something like this:

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

Now, to answer your question about the script (speed.py) always running, that's because it has no input. There's nothing for scons to check against. That script file must be reading something as an input, if only the py file itself. You need to tell scons about all direct and implicit dependencies for it to short-circuit subsequent runs:

Command('speed_analysis.tex', 'code/speed.py', 'python $SOURCE -o $TARGET')
like image 109
BenG Avatar answered Feb 08 '23 22:02

BenG


Maybe your example is incomplete, but aren't you supposed to do:

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

I think you need to specify your dependencies as the second argument to Command:

Command('speed_analysis.tex','code/speed.py','python code/speed.py')
like image 32
Ross Rogers Avatar answered Feb 08 '23 22:02

Ross Rogers