我非常喜欢 RPGilespie 的回答,并在我们拥有约 4500 个节点的软件包中使用它。不过,我做了一些调整,并认为我会发布它以防万一它对任何人有帮助。主要区别在于:
1.) 我添加了一个在作业结束时运行的命令,以根据这篇文章将总节点数写入文件。这样就不必在进度功能中不断地访问文件系统。
2.) 由于 1.) 每次运行 scons 时它都会更新文件(不仅仅是当它检测到节点数超过之前的最大值时)。如果您正在处理树的单个部分(即较少的节点)并且不断重建该部分,这将很有用。
3.)我让它在屏幕更新之前放回车,这样它就可以直接从progress_function写入它,而不是为以后设置一个变量。这有一个额外的好处,即在开始扫描主要构建的树时显示计数器更新。
作为旁注,我在这里将更新间隔设置为 1。原因是因为我注意到有时与单个构建命令关联的节点数少于导致它不打印该行的计数器的时间间隔。通过上述对计数器文件编写方式的更改,我没有看到任何明显的减速。YMMV。
我将以下内容放在我的 SConstruct 文件的末尾:
screen = open('/dev/tty', 'w')
node_count = 0
node_count_max = 0
node_count_interval = 1
node_count_fname = str(env.Dir('#')) + '/.scons_node_count'
def progress_function(node):
global node_count, node_count_max, node_count_interval, node_count_fname
node_count += node_count_interval
if node_count > node_count_max: node_count_max = 0
if node_count_max>0 :
screen.write('\r[%3d%%] ' % (node_count*100/node_count_max))
screen.flush()
def progress_finish(target, source, env):
global node_count
with open(node_count_fname, 'w') as f: f.write('%d\n' % node_count)
try:
with open(node_count_fname) as f: node_count_max = int(f.readline())
except: pass
Progress(progress_function, interval=node_count_interval)
progress_finish_command = Command('progress_finish', [], progress_finish)
Depends(progress_finish_command, BUILD_TARGETS)
if 'progress_finish' not in BUILD_TARGETS:
BUILD_TARGETS.append('progress_finish')
示例输出是:
[ 0%] Installing [/Users/davidl/HallD/builds/sim-recon/Darwin_macosx10.11-x86_64-llvm8.0.0/bin/MakeEventWriterROOT.pl]
[ 0%] Installing [/Users/davidl/HallD/builds/sim-recon/Darwin_macosx10.11-x86_64-llvm8.0.0/bin/MakeReactionPlugin.pl]
[ 0%] Compiling [programs/Simulation/genr8/genkin.c]
[ 0%] Compiling [programs/Simulation/genr8/genr8.c]
[ 3%] Compiling [programs/Utilities/hddm/hddm-cpp.cpp]
[ 3%] Compiling [programs/Utilities/hddm/XString.cpp]
[ 3%] Compiling [programs/Utilities/hddm/XParsers.cpp]
[ 3%] Compiling [programs/Utilities/hddm/md5.c]
[ 4%] Compiling [external/xstream/src/base64.cpp]
[ 4%] Compiling [external/xstream/src/bz.cpp]
[ 4%] Compiling [external/xstream/src/common.cpp]
[ 4%] Compiling [external/xstream/src/dater.cpp]
[ 4%] Linking [.Darwin_macosx10.11-x86_64-llvm8.0.0/programs/Simulation/genr8/genr8]
[ 4%] Installing [/Users/davidl/HallD/builds/sim-recon/Darwin_macosx10.11-x86_64-llvm8.0.0/bin/genr8]
[ 4%] Compiling [external/xstream/src/debug.cpp]
[ 4%] Compiling [external/xstream/src/digest.cpp]
...
为了完整起见,这是我的 COMSTR 定义:
env.Replace( CCCOMSTR = "Compiling [$SOURCE]",
CXXCOMSTR = "Compiling [$SOURCE]",
FORTRANPPCOMSTR = "Compiling [$SOURCE]",
FORTRANCOMSTR = "Compiling [$SOURCE]",
SHCCCOMSTR = "Compiling [$SOURCE]",
SHCXXCOMSTR = "Compiling [$SOURCE]",
LINKCOMSTR = "Linking [$TARGET]",
SHLINKCOMSTR = "Linking [$TARGET]",
INSTALLSTR = "Installing [$TARGET]",
ARCOMSTR = "Archiving [$TARGET]",
RANLIBCOMSTR = "Ranlib [$TARGET]")