scons: Stop auto including the git tool from the default too override.
authorGabe Black <gabe.black@gmail.com>
Fri, 18 Dec 2020 17:40:09 +0000 (09:40 -0800)
committerGabe Black <gabe.black@gmail.com>
Mon, 21 Dec 2020 21:53:33 +0000 (21:53 +0000)
SCons has a system of "tools", which basically detect versions of build
tools (compilers, linkers, etc) and set up an environment with the
appropriate build variable substitutions for that tool to be used.

For instance, there would be a "tool" for gcc, and it would detect if
gcc is present on the system, and if so would set the "CC" variable to
"gcc". An actually tool as defined by SCons would be a lot more
sophisticated than that and set more variables, but that's the basic
idea.

To help modularize the gem5 SConstruct file, I moved code which would
set up git commit hooks into a "tool" which helped modularize it and
reduce the size of SConstruct.

This isn't quite right since, while the code does detect if git was
used to check out the source (if there is a .git file at the root), it
doesn't really modify the environment at all. It will also be invoked
every time any environment is set up, although right now that will only
be the DefaultEnvironment, what's used when loose functions like
Builder or Command are called with, and the "main" environment which
all the others are Clone-d from.

Normally, when SCons sets up a new environment, either implicitly or
when Environment() is called, it sets up a bunch of built in tools
which are fixed within SCons itself. If you want, you can add a "tools"
argument to Environment (or to the DefaultEnvironment() function) which
will replace that list of tools. That can be used to make an
environment use the new "git" tool, but it isn't automatic.

SCons also lets you override default tools by creating your own with
the same name as the default. To make loading the git tool automatic,
I added an override "default" tool which, in addition to setting some
defaults which should apply to all environments, also pulled in other
tools, at that time "git" and "mercurial" (RIP).

Unfortunately, that meant that today, apparently particularly with
SCons version 4, *any* Environment would pull in "git", and all of
"git"'s dependencies, even if SCons wasn't set up enough for those to
work.

To break that dependency, this change stops the default tool from
automatically loading the git tool, although it does continue to set
other defaults which have very minimal external dependencies. When
creating the "main" Environment in the SConstruct, the "git" tool is
now added in explicitly. Since the list of tools replaces the original
and doesn't extend it, we have to add in "default" explicitly as well.

Really, the "git" tool should be converted from the tool interface into
something more appropriate, like perhaps a small module under
site_scons which site_init.py can import and call. When that happens,
main can be declared like normal again.

While making this change, I also got rid of a few nonstandard additions
to the main environment that were little used and not really necessary.
When reading the SConstruct, it wasn't very obvious where those extra
values were coming from, and they didn't really add any value.

Change-Id: I574db42fc2196bf62fc13d6754357c753ceb9117
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38616
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Yu-hsin Wang <yuhsingw@google.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
SConstruct
site_scons/site_tools/default.py

index 50333440928fbc8ae065b254336fa08a73b87fa0..b5505ff534ae5e2b7d5e7283abc687d74977c764 100755 (executable)
@@ -139,7 +139,7 @@ if GetOption('no_lto') and GetOption('force_lto'):
 #
 ########################################################################
 
-main = Environment()
+main = Environment(tools=['default', 'git'])
 
 from gem5_scons.util import get_termcap
 termcap = get_termcap()
@@ -259,7 +259,7 @@ global_vars.Save(global_vars_file, main)
 
 # Parse EXTRAS variable to build list of all directories where we're
 # look for sources etc.  This list is exported as extras_dir_list.
-base_dir = main.srcdir.abspath
+base_dir = Dir('#src').abspath
 if main['EXTRAS']:
     extras_dir_list = makePathListAbsolute(main['EXTRAS'].split(':'))
 else:
@@ -1027,7 +1027,7 @@ export_vars += ['USE_FENV', 'TARGET_ISA', 'TARGET_GPU_ISA',
 # value of the variable.
 def build_config_file(target, source, env):
     (variable, value) = [s.get_contents().decode('utf-8') for s in source]
-    with open(str(target[0]), 'w') as f:
+    with open(str(target[0].abspath), 'w') as f:
         print('#define', variable, value, file=f)
     return None
 
@@ -1040,7 +1040,7 @@ def config_emitter(target, source, env):
     # extract variable name from Builder arg
     variable = str(target[0])
     # True target is config header file
-    target = joinpath('config', variable.lower() + '.hh')
+    target = Dir('config').File(variable.lower() + '.hh')
     val = env[variable]
     if isinstance(val, bool):
         # Force value to 0/1
@@ -1049,9 +1049,9 @@ def config_emitter(target, source, env):
         val = '"' + val + '"'
 
     # Sources are variable name & value (packaged in SCons Value nodes)
-    return ([target], [Value(variable), Value(val)])
+    return [target], [Value(variable), Value(val)]
 
-config_builder = Builder(emitter = config_emitter, action = config_action)
+config_builder = Builder(emitter=config_emitter, action=config_action)
 
 main.Append(BUILDERS = { 'ConfigFile' : config_builder })
 
@@ -1105,7 +1105,7 @@ if sys.platform != "darwin":
 main.AddMethod(add_local_rpath, 'AddLocalRPATH')
 
 # builds in ext are shared across all configs in the build root.
-ext_dir = abspath(joinpath(str(main.root), 'ext'))
+ext_dir = Dir('#ext').abspath
 ext_build_dirs = []
 for root, dirs, files in os.walk(ext_dir):
     if 'SConscript' in files:
@@ -1193,7 +1193,7 @@ for variant_path in variant_paths:
         # normally determined by name of $VARIANT_DIR, but can be
         # overridden by '--default=' arg on command line.
         default = GetOption('default')
-        opts_dir = joinpath(main.root.abspath, 'build_opts')
+        opts_dir = Dir('#build_opts').abspath
         if default:
             default_vars_files = [joinpath(build_root, 'variables', default),
                                   joinpath(opts_dir, default)]
index 1965a201735ae2d0c0167907942228c0471efdf7..305a2a27f2102c6e3760e68d6c67a1c571bc02c5 100644 (file)
@@ -71,22 +71,14 @@ def common_config(env):
     # https://github.com/SCons/scons/issues/2811
     env['IMPLICIT_COMMAND_DEPENDENCIES'] = 0
     env.Decider('MD5-timestamp')
-    env.root = env.Dir('#')
-    env.srcdir = env.root.Dir('src')
 
     # add useful python code PYTHONPATH so it can be used by subprocesses
     # as well
     env.AppendENVPath('PYTHONPATH', extra_python_paths)
 
-gem5_tool_list = [
-    'git',
-]
-
 def generate(env):
     common_config(env)
     SCons.Tool.default.generate(env)
-    for tool in gem5_tool_list:
-        SCons.Tool.Tool(tool)(env)
 
 def exists(env):
     return 1