Add caching to MSCommon.script_env

#105 Merged at c6befd6
  1. Sye van der Veen

To ensure portability, I'm setting up a build system for nohtyP that builds against multiple compilers, compiler versions, and architectures. The auto-detection capabilities of SCons are impressive, but Microsoft's slow vcvars*.bat scripts are causing problems. I'm currently building against four versions of MSVS, and almost all of the 14-second build time is spent in SCons.Tool.MSCommon.script_env.

I create a separate environment for each valid combination of compiler (4), architecture (x86, amd64), and configuration (debug, release). With a simple change to script_env to cache the output of vcvars*.bat, I can cut this build time in half. The cache recognizes that the output changes depending on the argument given (different architectures result in different environment variables).

The cache is similar to those applied to cached_get_installed_vcs, get_installed_visual_studios, etc, which are also intended to speed up auto-detection of multiple versions.

Comments (4)

  1. anatoly techtonik

    The idea is good, but I am not familiar with multi-environment specifics enough to understand this one completely.

    What are the cases when script_env() is called more than once during one SCons run with the same arguments? Small example of SConstruct file will help.

    The key is (script, args) - if I understand correctly the script is full path to .bat file, right? This path will be different for every MS VS version, so cache won't hit. It seems that .bat filename also depends on architecture, so the cache won't hit for that either. And in the end the debug/release build type depends on the args and won't hit too.

  2. Sye van der Veen author

    Any time someone sets up a new Environment for the MSVS toolchain, they incur a multi-second penalty while vcvars*.bat is called. The batch file is called to get the values for INCLUDE, LIB, LIBPATH, and PATH, and the output never changes (for the given architecture) after the toolchain has been installed on the system.

    This change won't benefit builds where MSVS is initialized in a single Environment, but if "tools=['msvs']" is being used often, this could improve their performance.

  3. anatoly techtonik

    So even if I create multiple environments in a single file? Like this:

    env1 = Environment(tools = 'msvs')
    env2 = Environment(tools = 'msvs')

    Is that's the case, I wish this explanation is embedded into