Skip to content

Commit

Permalink
SERVER-9564 When libabigail utils are present, minimize relinking
Browse files Browse the repository at this point in the history
  • Loading branch information
acmorrow committed Jul 25, 2015
1 parent 7d9c2e6 commit e9fc3c3
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 2 deletions.
10 changes: 10 additions & 0 deletions SConstruct
Expand Up @@ -564,6 +564,9 @@ env_vars = Variables(
args=ARGUMENTS
)

env_vars.Add('ABIDW',
help="Configures the path to the 'abidw' (a libabigail) utility")

env_vars.Add('ARFLAGS',
help='Sets flags for the archiver',
converter=variable_shlex_converter)
Expand Down Expand Up @@ -1028,6 +1031,13 @@ env['_LIBDEPS'] = '$_LIBDEPS_OBJS' if link_model == "object" else '$_LIBDEPS_LIB

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']
Expand Down
8 changes: 6 additions & 2 deletions site_scons/libdeps.py
Expand Up @@ -235,7 +235,9 @@ def libdeps_emitter(target, source, env):
file_name = '${LIBPREFIX}' + file_name
if not file_name.endswith(lib_suffix):
file_name += '${LIBSUFFIX}'
libdep_files.append(env.File(os.path.join(dir_name, file_name)))

node_factory = env['BUILDERS']['StaticLibrary'].target_factory or env.File
libdep_files.append(node_factory(os.path.join(dir_name, file_name)))

for t in target:
# target[0] must be a Node and not a string, or else libdeps will fail to
Expand Down Expand Up @@ -276,7 +278,9 @@ def shlibdeps_emitter(target, source, env):
file_name = '${SHLIBPREFIX}' + file_name
if not file_name.endswith(lib_suffix):
file_name += '${SHLIBSUFFIX}'
libdep_files.append(env.File(os.path.join(dir_name, file_name)))

node_factory = env['BUILDERS']['SharedLibrary'].target_factory or env.File
libdep_files.append(node_factory(os.path.join(dir_name, file_name)))

for t in target:
# target[0] must be a Node and not a string, or else libdeps will fail to
Expand Down
66 changes: 66 additions & 0 deletions site_scons/site_tools/abilink.py
@@ -0,0 +1,66 @@
# Copyright (C) 2015 MongoDB Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License, version 3,
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import SCons
import subprocess

def _detect(env):
try:
abidw = env['ABIDW']
if not abidw:
return None
except KeyError:
pass

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
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 EnvironmentError, e:
if not e.filename:
e.filename = fname
raise
return contents

def get_content_hash(self):
return SCons.Util.MD5signature(self.get_contents())

env['ABIDW'] = _detect(env)

def ShlibNode(env, name, directory = None, create = 1):
return env.fs._lookup(env.subst(name), directory, AbilinkNode, create)

env.AddMethod(ShlibNode, 'ShlibNode')

def shlib_target_factory(arg):
return env.ShlibNode(arg)

env['BUILDERS']['SharedLibrary'].target_factory = shlib_target_factory

def exists(env):
result = _detect(env) != None
return result

0 comments on commit e9fc3c3

Please sign in to comment.