[Scons-dev] Excessive exec calls at startup
Johan Holmberg
johan556 at gmail.com
Sun Nov 22 18:15:47 EST 2015
Hi!
While building a project with SCons with 144 different Environment()
objects (one for each of my libraries), I observed that a lot of external
processes were created even before SCons did build anything. I use MacOS,
so I turned to DTrace to snoop on new processes created:
$ sudo newproc.d > newproc.log
Then I ran "scons non_existing_file" in another terminal, to see what SCons
did at startup. According to "newproc.d" there are 3486 exec calls (new
processes). By looking in detail in the log from "newproc.d", I see that
"gcc --version" is called 290 times, and "g++ --version" another 290 times
(each *two* times per Environment). And each of these 580 processes seem to
use 6 exec calls internally, like:
gcc --version
/Applications/Xcode.app/Contents/Developer/usr/bin/gcc --version
sh -c /usr/bin/xcode-select -print-path 2> /dev/null
/usr/bin/xcode-select -print-path
/usr/bin/xcrun clang --version
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
--version
I modified the code in "src/engine/SCons/Tool/gcc.py" to cache calls to
"detect_version" where the same gcc/g++ is asked about its version several
times. With this change the number of exec calls went from 3486 to 18. And
the startup time went down from 18 seconds to 8 seconds. (MacOS Yosemite on
an iMac from 2011).
I'm not very familiar with the SCons source code, so my patch is probably
not entirely correct. But I hope something similar could be added to SCons
to avoid wasting time at startup.
Regards,
/Johan Holmberg
--- a/src/engine/SCons/Tool/gcc.py Fri Nov 20 13:54:09 2015 -0800
+++ b/src/engine/SCons/Tool/gcc.py Sat Nov 14 17:09:59 2015 +0100
@@ -63,11 +63,22 @@
# is executable, and is a GNU compiler (or accepts '--version' at
least)
return detect_version(env, env.Detect(env.get('CC', compilers)))
+_detected_version_cache = dict()
+
def detect_version(env, cc):
"""Return the version of the GNU compiler, or None if it is not a GNU
compiler."""
cc = env.subst(cc)
if not cc:
return None
+ cc_path = env.WhereIs(cc)
+ try:
+ return _detected_version_cache[cc_path]
+ except KeyError:
+ version = _detect_version_1(env, cc)
+ _detected_version_cache[cc_path] = version
+ return version
+
+def _detect_version_1(env, cc):
version = None
#pipe = SCons.Action._subproc(env, SCons.Util.CLVar(cc) +
['-dumpversion'],
pipe = SCons.Action._subproc(env, SCons.Util.CLVar(cc) + ['--version'],
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist2.pair.net/pipermail/scons-dev/attachments/20151123/f5788158/attachment.html>
More information about the Scons-dev
mailing list