From 6bdd897f04f4efdf90d0761c6d31d3f960f4eacf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 28 Apr 2017 04:00:42 -0700 Subject: scons: Put Source objects in groups and partially link them. The groups will be linked together into intermediate partially linked object files. Right now the hierarchy is assumed to be flat, but with some effort it could be extended to allow truly hierarchical linking. Change-Id: I77b77710554e5f05e8b00720a0170afaf4afac2d Reviewed-on: https://gem5-review.googlesource.com/2945 Reviewed-by: Andreas Sandberg Reviewed-by: Jason Lowe-Power Maintainer: Andreas Sandberg --- src/SConscript | 65 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 10 deletions(-) (limited to 'src/SConscript') diff --git a/src/SConscript b/src/SConscript index 645b9251a..99f986a24 100755 --- a/src/SConscript +++ b/src/SConscript @@ -72,6 +72,17 @@ from m5.util import code_formatter, compareVersions # values will be retrieved recursively from parents (children override # parents). # +def guarded_source_iterator(sources, **guards): + '''Iterate over a set of sources, gated by a set of guards.''' + for src in sources: + for flag,value in guards.iteritems(): + # if the flag is found and has a different value, skip + # this file + if src.all_guards.get(flag, False) != value: + break + else: + yield src + class SourceMeta(type): '''Meta class for source files that keeps track of all files of a particular type and has a get function for finding all functions @@ -83,14 +94,8 @@ class SourceMeta(type): def get(cls, **guards): '''Find all files that match the specified guards. If a source file does not specify a flag, the default is False''' - for src in cls.all: - for flag,value in guards.iteritems(): - # if the flag is found and has a different value, skip - # this file - if src.all_guards.get(flag, False) != value: - break - else: - yield src + for s in guarded_source_iterator(cls.all, **guards): + yield s class SourceFile(object): '''Base object that encapsulates the notion of a source file. @@ -161,6 +166,15 @@ class SourceFile(object): class Source(SourceFile): + current_group = None + source_groups = { None : [] } + + @classmethod + def set_group(cls, group): + if not group in Source.source_groups: + Source.source_groups[group] = [] + Source.current_group = group + '''Add a c/c++ source file to the build''' def __init__(self, source, Werror=True, swig=False, **guards): '''specify the source file, and any guards''' @@ -169,6 +183,8 @@ class Source(SourceFile): self.Werror = Werror self.swig = swig + Source.source_groups[Source.current_group].append(self) + class PySource(SourceFile): '''Add a python source file to the named package''' invalid_sym_char = re.compile('[^A-z0-9_]') @@ -1165,8 +1181,37 @@ def makeEnv(env, label, objsfx, strip = False, **kwargs): if GetOption('without_python'): lib_guards['skip_no_python'] = False - static_objs = [ make_obj(s, True) for s in Source.get(**lib_guards) ] - shared_objs = [ make_obj(s, False) for s in Source.get(**lib_guards) ] + static_objs = [] + shared_objs = [] + for s in guarded_source_iterator(Source.source_groups[None], **lib_guards): + static_objs.append(make_obj(s, True)) + shared_objs.append(make_obj(s, False)) + + partial_objs = [] + for group, all_srcs in Source.source_groups.iteritems(): + # If these are the ungrouped source files, skip them. + if not group: + continue + + # Get a list of the source files compatible with the current guards. + srcs = [ s for s in guarded_source_iterator(all_srcs, **lib_guards) ] + # If there aren't any left, skip this group. + if not srcs: + continue + + # Set up the static partially linked objects. + source_objs = [ make_obj(s, True) for s in srcs ] + file_name = new_env.subst("${OBJPREFIX}lib${OBJSUFFIX}.partial") + target = File(joinpath(group, file_name)) + partial = env.PartialStatic(target=target, source=source_objs) + static_objs.append(partial) + + # Set up the shared partially linked objects. + source_objs = [ make_obj(s, False) for s in srcs ] + file_name = new_env.subst("${SHOBJPREFIX}lib${SHOBJSUFFIX}.partial") + target = File(joinpath(group, file_name)) + partial = env.PartialShared(target=target, source=source_objs) + shared_objs.append(partial) static_date = make_obj(date_source, static=True, extra_deps=static_objs) static_objs.append(static_date) -- cgit v1.2.3