From 5f73a9bbf08751ca04b6486ecae0ccf138d97c78 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 8 Feb 2022 18:39:27 -0800 Subject: [PATCH] scons: Use either the "build" or "gem5.build" as build anchor. If gem5.build already exists within a directory, then that build directory can be used without having to worry about variants. If it doesn't exist and we find a build/${VARIANT} style path, then we use that as the anchor. In either case, the variant name is the final component of the build path. The parse_build_path function had been separating that out, but it was just put back onto the path again anyway by the only caller, and then split out again when that path was consumed. We save a step by not splitting it out in parse_build_path. Change-Id: I8705b3dbb7664748f5525869cb188df70319d403 --- SConstruct | 26 ++++--------------------- site_scons/gem5_scons/__init__.py | 32 +++++++++++++++++-------------- 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/SConstruct b/SConstruct index e7fa4b53b7..69c941a078 100755 --- a/SConstruct +++ b/SConstruct @@ -240,27 +240,9 @@ def makePathListAbsolute(path_list, root=GetLaunchDir()): # doesn't work (obviously!). BUILD_TARGETS[:] = makePathListAbsolute(BUILD_TARGETS) -# Generate a list of the unique build roots and configs that the -# collected targets reference. -variant_paths = set() -build_root = None -for t in BUILD_TARGETS: - this_build_root, variant = parse_build_path(t) - - # Make sure all targets use the same build root. - if not build_root: - build_root = this_build_root - elif this_build_root != build_root: - error("build targets not under same build root\n %s\n %s" % - (build_root, this_build_root)) - - # Collect all the variants into a set. - variant_paths.add(os.path.join('/', build_root, variant)) - -# Make sure build_root exists (might not if this is the first build there) -if not isdir(build_root): - mkdir(build_root) -main['BUILDROOT'] = build_root +# Generate a list of the unique build directories that the collected targets +# reference. +variant_paths = set(map(parse_build_path, BUILD_TARGETS)) ######################################################################## @@ -395,7 +377,7 @@ for variant_path in variant_paths: env = main.Clone() env['BUILDDIR'] = variant_path - gem5_build = os.path.join(build_root, variant_path, 'gem5.build') + gem5_build = os.path.join(variant_path, 'gem5.build') env['GEM5BUILD'] = gem5_build Execute(Mkdir(gem5_build)) diff --git a/site_scons/gem5_scons/__init__.py b/site_scons/gem5_scons/__init__.py index c93a5e29e0..3638d9c561 100644 --- a/site_scons/gem5_scons/__init__.py +++ b/site_scons/gem5_scons/__init__.py @@ -39,6 +39,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os +import os.path import pickle import sys import tempfile @@ -56,7 +57,7 @@ termcap = get_termcap() def strip_build_path(path, env): path = str(path) build_base = "build/" - variant_base = env["BUILDROOT"] + os.path.sep + variant_base = os.path.dirname(env["BUILDDIR"]) + os.path.sep if path.startswith(variant_base): path = path[len(variant_base) :] elif path.startswith(build_base): @@ -117,7 +118,7 @@ class Transform: source = source[0 : self.max_sources] def strip(f): - return strip_build_path(str(f), env) + return strip_build_path(f, env) if len(source) > 0: srcs = list(map(strip, source)) @@ -255,18 +256,21 @@ def error(*args, **kwargs): def parse_build_path(target): path_dirs = target.split("/") - # Pop off the target file. - path_dirs.pop() - - # Search backwards for the "build" directory. Whatever was just before it - # was the name of the variant. - variant_dir = path_dirs.pop() - while path_dirs and path_dirs[-1] != "build": - variant_dir = path_dirs.pop() - if not path_dirs: - error("No non-leaf 'build' dir found on target path.", target) - - return os.path.join("/", *path_dirs), variant_dir + # Search backwards for a directory with a gem5.build sub-directory, or a + # directory who's parent is called "build". gem5.build identifies an + # existing gem5 build directory. A directory called "build" is an anchor + # for a legacy "build/${VARIANT}/${TARGET}" style build path, where the + # variant selects a default config to use. + while path_dirs: + dot_gem5 = os.path.join("/", *path_dirs, "gem5.build") + if ( + os.path.isdir(dot_gem5) + or len(path_dirs) > 1 + and path_dirs[-2] == "build" + ): + return os.path.join("/", *path_dirs) + path_dirs.pop() + error(f"No existing build directory and no variant for {target}") # The MakeAction wrapper, and a SCons tool to set up the *COMSTR variables.