I liked that RPGilespie answered a lot and played with it for our software package with ~ 4500 nodes. I made friends a little and thought I would send it if this helps anyone. The main differences:
1.) I added a command to run at the end of the job to write the total number of node to a file based on this message . This saves time to constantly hit the file system as a function of progress.
2.) Because of 1.) it updates the file every time scons is started (not only when it considers that the number of nodes has exceeded the previous maximum). This is useful if you are working with one part of the tree (i.e., with fewer nodes) and constantly rebuilding that particular part.
3.) I put the carriage back before updating the screen so that he could write it directly from progress_function, and not to set a variable for a later one. This has the added benefit of showing a counter update while it scans the mostly constructed tree at the beginning.
As a side note, I set the refresh interval to only 1 here. The reason is that sometimes I noticed that the number of nodes associated with one build command was less than the interval, causing it not to print a counter for this line. With the above change in how the counter is written, I did not notice a noticeable slowdown due to this. YMMV.
At the end of my SConstruct file, I put the following:
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')
Output Example:
[ 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] ...
For completeness, here are my COMSTR definitions:
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]")