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.