summaryrefslogtreecommitdiff
path: root/site_scons/site_tools/ninja.py
diff options
context:
space:
mode:
authorMathew Robinson <mathew.robinson@mongodb.com>2019-12-20 14:17:36 +0000
committerevergreen <evergreen@mongodb.com>2019-12-20 14:17:36 +0000
commitb1c0455f828940f58dd37ab74879b2cd2557bcfb (patch)
tree2fa19b7b0ec322183df30f31c6cfd949ead68358 /site_scons/site_tools/ninja.py
parente57b8036c94546a6494e81d46f552f1c23841eda (diff)
downloadmongo-b1c0455f828940f58dd37ab74879b2cd2557bcfb.tar.gz
SERVER-45165 Support env['ENV'] in Ninja generator
Diffstat (limited to 'site_scons/site_tools/ninja.py')
-rw-r--r--site_scons/site_tools/ninja.py64
1 files changed, 55 insertions, 9 deletions
diff --git a/site_scons/site_tools/ninja.py b/site_scons/site_tools/ninja.py
index feee4f25182..8823121de90 100644
--- a/site_scons/site_tools/ninja.py
+++ b/site_scons/site_tools/ninja.py
@@ -23,7 +23,8 @@ from threading import Lock
from glob import glob
import SCons
-from SCons.Action import _string_from_cmd_list
+from SCons.Action import _string_from_cmd_list, get_default_ENV
+from SCons.Util import is_String, is_List
from SCons.Script import COMMAND_LINE_TARGETS
NINJA_SYNTAX = "NINJA_SYNTAX"
@@ -279,17 +280,25 @@ class SConsToNinjaTranslator:
if results[0]["rule"] == "CMD":
cmdline = ""
for cmd in results:
- if not cmd["variables"]["cmd"]:
- continue
- if cmdline:
- cmdline += " && "
+ # Occasionally a command line will expand to a
+ # whitespace only string (i.e. ' '). Which is not a
+ # valid command but does not trigger the empty command
+ # condition if not cmdstr. So here we strip preceding
+ # and proceeding whitespace to make strings like the
+ # above become empty strings and so will be skipped.
+ cmdstr = cmd["variables"]["cmd"].strip()
+ if not cmdstr:
+ continue
# Skip duplicate commands
- if cmd["variables"]["cmd"] in cmdline:
+ if cmdstr in cmdline:
continue
- cmdline += cmd["variables"]["cmd"]
+ if cmdline:
+ cmdline += " && "
+
+ cmdline += cmdstr
# Remove all preceding and proceeding whitespace
cmdline = cmdline.strip()
@@ -601,8 +610,16 @@ class NinjaState:
# DAG walk so we can't rely on action_to_ninja_build to
# generate this rule even though SCons should know we're
# dependent on SCons files.
+ #
+ # TODO: We're working on getting an API into SCons that will
+ # allow us to query the actual SConscripts used. Right now
+ # this glob method has deficiencies like skipping
+ # jstests/SConscript and being specific to the MongoDB
+ # repository layout.
ninja.build(
- ninja_file, rule="REGENERATE", implicit=glob("**/SCons*", recursive=True),
+ ninja_file,
+ rule="REGENERATE",
+ implicit=[self.env.File("#SConstruct").get_abspath()] + glob("src/**/SConscript", recursive=True),
)
ninja.build(
@@ -763,11 +780,40 @@ def get_command(env, node, action): # pylint: disable=too-many-branches
# safe to make.
outputs = outputs[0:1]
+ command_env = getattr(node.attributes, "NINJA_ENV_ENV", "")
+ if not command_env:
+ ENV = get_default_ENV(sub_env)
+
+ # This is taken wholesale from SCons/Action.py
+ #
+ # Ensure that the ENV values are all strings:
+ for key, value in ENV.items():
+ if not is_String(value):
+ if is_List(value):
+ # If the value is a list, then we assume it is a
+ # path list, because that's a pretty common list-like
+ # value to stick in an environment variable:
+ value = flatten_sequence(value)
+ value = os.pathsep.join(map(str, value))
+ else:
+ # If it isn't a string or a list, then we just coerce
+ # it to a string, which is the proper way to handle
+ # Dir and File instances and will produce something
+ # reasonable for just about everything else:
+ value = str(value)
+
+ if env["PLATFORM"] == "win32":
+ command_env += "set '{}={}' && ".format(key, value)
+ else:
+ command_env += "{}={}; ".format(key, value)
+
+ setattr(node.attributes, "NINJA_ENV_ENV", command_env)
+
return {
"outputs": outputs,
"implicit": implicit,
"rule": rule,
- "variables": {"cmd": cmd},
+ "variables": {"cmd": command_env + cmd},
}