diff options
author | Andrew Morrow <acm@mongodb.com> | 2017-05-25 09:37:12 -0400 |
---|---|---|
committer | Andrew Morrow <acm@mongodb.com> | 2017-05-25 12:12:50 -0400 |
commit | 41046adf0e53a35f7c2301f12d577476086c6c6d (patch) | |
tree | edac398b71baf90aa3428b87b9c54fc4cd584f60 | |
parent | d969e03747dc4587b5e0a2453014dd6be7e65f24 (diff) | |
download | mongo-41046adf0e53a35f7c2301f12d577476086c6c6d.tar.gz |
SERVER-27380 Revert "Revert "SERVER-27380 Re-enable the thin archive tool""
This reverts commit b4e14a64d7f51846e7c7ed94047ac545e26dce25.
-rw-r--r-- | SConstruct | 26 | ||||
-rw-r--r-- | site_scons/site_tools/abilink.py | 84 | ||||
-rw-r--r-- | site_scons/site_tools/thin_archive.py | 50 |
3 files changed, 93 insertions, 67 deletions
diff --git a/SConstruct b/SConstruct index 6222566afe7..61763fcc870 100644 --- a/SConstruct +++ b/SConstruct @@ -1189,13 +1189,6 @@ env['BUILDERS']['LibraryObject'] = env['BUILDERS']['StaticObject'] if link_model.startswith("dynamic"): - # Add in the abi linking tool if the user requested and it is - # supported on this platform. - if env.get('ABIDW'): - abilink = Tool('abilink') - if abilink.exists(env): - abilink(env) - # Redirect the 'Library' target, which we always use instead of 'StaticLibrary' for things # that can be built in either mode, to point to SharedLibrary. env['BUILDERS']['Library'] = env['BUILDERS']['SharedLibrary'] @@ -1359,6 +1352,25 @@ if env['_LIBDEPS'] == '$_LIBDEPS_OBJS': libdeps.setup_environment(env, emitting_shared=(link_model.startswith("dynamic"))) +# Both the abidw tool and the thin archive tool must be loaded after +# libdeps, so that the scanners they inject can see the library +# dependencies added by libdeps. +if link_model.startswith("dynamic"): + # Add in the abi linking tool if the user requested and it is + # supported on this platform. + if env.get('ABIDW'): + abilink = Tool('abilink') + if abilink.exists(env): + abilink(env) + +if env['_LIBDEPS'] == '$_LIBDEPS_LIBS': + # The following platforms probably aren't using the binutils + # toolchain, or may be using it for the archiver but not the + # linker, and binutils currently is the olny thing that supports + # thin archives. Don't even try on those platforms. + if not env.TargetOSIs('solaris', 'darwin', 'windows'): + env.Tool('thin_archive') + if env.TargetOSIs('linux', 'freebsd', 'openbsd'): env['LINK_LIBGROUP_START'] = '-Wl,--start-group' env['LINK_LIBGROUP_END'] = '-Wl,--end-group' diff --git a/site_scons/site_tools/abilink.py b/site_scons/site_tools/abilink.py index 6ca2c7dc6b8..4e4fdcd6310 100644 --- a/site_scons/site_tools/abilink.py +++ b/site_scons/site_tools/abilink.py @@ -15,6 +15,11 @@ import SCons import subprocess +# TODO: Make a SUFF variable for the suffix to write to +# TODO: Prevent using abilink when -gsplit-dwarf is in play, since it doesn't work +# TODO: Make a variable for the md5sum utility (allow any hasher) +# TODO: Add an ABILINKCOM variable to the Action, so it can be silenced. + def _detect(env): try: abidw = env['ABIDW'] @@ -26,53 +31,52 @@ def _detect(env): return env.WhereIs('abidw') -def generate(env): - - class AbilinkNode(SCons.Node.FS.File): - def __init__(self, name, directory, fs): - SCons.Node.FS.File.__init__(self, name, directory, fs) - - def get_contents(self): - if not self.rexists(): - return '' - - fname = self.rfile().abspath - contents = None - - try: - # TODO: If there were python bindings for libabigail, we - # could avoid the shell out (and probably be faster, as we - # could get exactly the information we want). - contents = subprocess.check_output([env.subst('$ABIDW'), fname]) - except subprocess.CalledProcessError, e: - # ABIDW sometimes fails. In that case, log an error - # and fall back to the normal contents - print "WARNING: ABIDW failed for target %s, please file a bug report" % fname - try: - contents = open(fname, "rb").read() - except EnvironmentError, e: - if not e.filename: - e.filename = fname - raise +def _add_emitter(builder): + base_emitter = builder.emitter - return contents + def new_emitter(target, source, env): + new_targets = [] + for t in target: + abidw = str(t) + ".abidw" + abidw = (t.builder.target_factory or env.File)(abidw) + new_targets.append(abidw) + setattr(t.attributes, "abidw", abidw) + targets = target + new_targets + return (targets, source) - def get_content_hash(self): - return SCons.Util.MD5signature(self.get_contents()) + new_emitter = SCons.Builder.ListEmitter([base_emitter, new_emitter]) + builder.emitter = new_emitter - env['ABIDW'] = _detect(env) +def _add_scanner(builder): + old_scanner = builder.target_scanner + path_function = old_scanner.path_function - def ShlibNode(env, name, directory = None, create = 1): - return env.fs._lookup(env.subst(name), directory, AbilinkNode, create) + def new_scanner(node, env, path): + old_results = old_scanner(node, env, path) + new_results = [] + for base in old_results: + abidw = getattr(env.Entry(base).attributes, "abidw", None) + new_results.append(abidw if abidw else base) + return new_results - env.AddMethod(ShlibNode, 'ShlibNode') + builder.target_scanner = SCons.Scanner.Scanner(function=new_scanner, path_function=path_function) - def shlib_target_factory(arg): - return env.ShlibNode(arg) - - env['BUILDERS']['SharedLibrary'].target_factory = shlib_target_factory - env['BUILDERS']['LoadableModule'].target_factory = shlib_target_factory +def _add_action(builder): + actions = builder.action + builder.action = actions + SCons.Action.Action("$ABIDW $TARGET | md5sum > ${TARGET}.abidw") def exists(env): result = _detect(env) != None return result + +def generate(env): + + if not exists(env): + return + + builder = env['BUILDERS']['SharedLibrary'] + _add_emitter(builder) + _add_action(builder) + _add_scanner(builder) + _add_scanner(env['BUILDERS']['Program']) + _add_scanner(env['BUILDERS']['LoadableModule']) diff --git a/site_scons/site_tools/thin_archive.py b/site_scons/site_tools/thin_archive.py index b4bc5f97d6f..511c0ef6e54 100644 --- a/site_scons/site_tools/thin_archive.py +++ b/site_scons/site_tools/thin_archive.py @@ -45,32 +45,35 @@ def exists(env): return bool(isgnu) +def _add_emitter(builder): + base_emitter = builder.emitter -def generate(env): - if not exists(env): - return - - class ThinArchiveNode(SCons.Node.FS.File): - def __init__(self, name, directory, fs): - SCons.Node.FS.File.__init__(self, name, directory, fs) - - def get_contents(self): - child_sigs = sorted([child.get_csig() for child in self.children()]) - return ''.join(child_sigs) - - def get_content_hash(self): - return SCons.Util.MD5signature(self.get_contents()) + def new_emitter(target, source, env): + for t in target: + setattr(t.attributes, "thin_archive", True) + return (target, source) + new_emitter = SCons.Builder.ListEmitter([base_emitter, new_emitter]) + builder.emitter = new_emitter - def _ThinArchiveNode(env, name, directory = None, create = 1): - return env.fs._lookup(env.subst(name), directory, ThinArchiveNode, create) +def _add_scanner(builder): + old_scanner = builder.target_scanner + path_function = old_scanner.path_function - env.AddMethod(_ThinArchiveNode, 'ThinArchiveNode') + def new_scanner(node, env, path): + old_results = old_scanner(node, env, path) + new_results = [] + for base in old_results: + new_results.append(base) + if getattr(env.Entry(base).attributes, "thin_archive", None): + new_results.extend(base.children()) + return new_results - def archive_target_factory(arg): - return env.ThinArchiveNode(arg) + builder.target_scanner = SCons.Scanner.Scanner(function=new_scanner, path_function=path_function) - env['BUILDERS']['StaticLibrary'].target_factory = archive_target_factory +def generate(env): + if not exists(env): + return env['ARFLAGS'] = SCons.Util.CLVar([arflag if arflag != "rc" else "rcsTD" for arflag in env['ARFLAGS']]) @@ -80,3 +83,10 @@ def generate(env): # Disable running ranlib, since we added 's' above env['RANLIBCOM'] = noop_action env['RANLIBCOMSTR'] = 'Skipping ranlib for thin archive $TARGET' + + builder = env['BUILDERS']['StaticLibrary'] + _add_emitter(builder) + + _add_scanner(env['BUILDERS']['SharedLibrary']) + _add_scanner(env['BUILDERS']['LoadableModule']) + _add_scanner(env['BUILDERS']['Program']) |