diff options
-rw-r--r-- | SConstruct | 6 | ||||
-rw-r--r-- | site_scons/site_tools/ccache.py | 11 | ||||
-rw-r--r-- | site_scons/site_tools/icecream.py | 44 |
3 files changed, 50 insertions, 11 deletions
diff --git a/SConstruct b/SConstruct index ac484763558..6460874c488 100644 --- a/SConstruct +++ b/SConstruct @@ -3828,9 +3828,10 @@ def doConfigure(myenv): env = doConfigure( env ) env["NINJA_SYNTAX"] = "#site_scons/third_party/ninja_syntax.py" + # Now that we are done with configure checks, enable ccache and -# icecream, if available. Per the rules declared in the icecream tool, -# load the ccache tool first. +# icecream if requested. If *both* icecream and ccache are requested, +# ccache must be loaded first. env.Tool('ccache') if env.ToolchainIs("clang"): @@ -3840,6 +3841,7 @@ elif env.ToolchainIs("gcc"): env.Tool('icecream') + # Defaults for SCons provided flags. SetOption only sets the option to our value # if the user did not provide it. So for any flag here if it's explicitly passed # the values below set with SetOption will be overwritten. diff --git a/site_scons/site_tools/ccache.py b/site_scons/site_tools/ccache.py index 13a49463c46..76fef32d9b7 100644 --- a/site_scons/site_tools/ccache.py +++ b/site_scons/site_tools/ccache.py @@ -103,6 +103,17 @@ def generate(env): # but it doesn't work or is out of date. env["CCACHE_VERSION"] = _ccache_version_found + # Set up a performant ccache configuration. Here, we don't use a second preprocessor and + # pass preprocessor arguments that deterministically expand source files so a stable + # hash can be calculated on them. This both reduces the amount of work ccache needs to + # do and increases the likelihood of a cache hit. + env["ENV"]["CCACHE_NOCPP2"] = 1 + if env.ToolchainIs("clang"): + env.AppendUnique(CCFLAGS=["-frewrite-includes"]) + elif env.ToolchainIs("gcc"): + env.AppendUnique(CCFLAGS=["-fdirectives-only"]) + + # Make a generator to expand to CCACHE in the case where we are # not a conftest. We don't want to use ccache for configure tests # because we don't want to use icecream for configure tests, but diff --git a/site_scons/site_tools/icecream.py b/site_scons/site_tools/icecream.py index e4ff9fd23da..53cc5eb8ec4 100644 --- a/site_scons/site_tools/icecream.py +++ b/site_scons/site_tools/icecream.py @@ -21,7 +21,7 @@ import subprocess from pkg_resources import parse_version _icecream_version_min = parse_version("1.1rc2") -_ccache_nocpp2_version = parse_version("3.4.1") +_icecream_version_gcc_remote_cpp = parse_version("1.2") # I'd prefer to use value here, but amazingly, its __str__ returns the @@ -230,14 +230,37 @@ def generate(env): if env.ToolchainIs("clang"): env["ENV"]["ICECC_CLANG_REMOTE_CPP"] = 1 - - if ccache_enabled and env["CCACHE_VERSION"] >= _ccache_nocpp2_version: - env.AppendUnique(CCFLAGS=["-frewrite-includes"]) - env["ENV"]["CCACHE_NOCPP2"] = 1 - else: - env.AppendUnique(CCFLAGS=["-fdirectives-only"]) - if ccache_enabled: - env["ENV"]["CCACHE_NOCPP2"] = 1 + elif env.ToolchainIs("gcc"): + if env["ICECREAM_VERSION"] >= _icecream_version_gcc_remote_cpp: + if ccache_enabled: + # Newer versions of Icecream will drop -fdirectives-only from + # preprocessor and compiler flags if it does not find a remote + # build host to build on. ccache, on the other hand, will not + # pass the flag to the compiler if CCACHE_NOCPP2=1, but it will + # pass it to the preprocessor. The combination of setting + # CCACHE_NOCPP2=1 and passing the flag can lead to build + # failures. + + # See: https://jira.mongodb.org/browse/SERVER-48443 + + # We have an open issue with Icecream and ccache to resolve the + # cause of these build failures. Once the bug is resolved and + # the fix is deployed, we can remove this entire conditional + # branch and make it like the one for clang. + # TODO: https://github.com/icecc/icecream/issues/550 + env["ENV"].pop("CCACHE_NOCPP2", None) + env["ENV"]["CCACHE_CPP2"] = 1 + try: + env["CCFLAGS"].remove("-fdirectives-only") + except ValueError: + pass + else: + # If we can, we should make Icecream do its own preprocessing + # to reduce concurrency on the local host. We should not do + # this when ccache is in use because ccache will execute + # Icecream to do its own preprocessing and then execute + # Icecream as the compiler on the preprocessed source. + env["ENV"]["ICECC_REMOTE_CPP"] = 1 if "ICECC_SCHEDULER" in env: env["ENV"]["USE_SCHEDULER"] = env["ICECC_SCHEDULER"] @@ -310,6 +333,9 @@ def generate(env): def exists(env): + # Assume the tool has run if we already know the version. + if "ICECREAM_VERSION" in env: + return True icecc = env.get("ICECC", False) if not icecc: |