Permalink
Browse files

SERVER-7410 Fix SYSLIBDEPS functionality

The previous implementation was not recursively following the LIBDEPS hierarchy, looking for SYSLIBDEPS
to add.  Instead, it was trying to walk a hierachy like LIBDEPS rooted in the SYSLIBDEPS variable.  This
isn't really a meaningful behavior, since SYSLIBDEPS always list system libraries, which are always leaf
nodes in the dependency graph for our build system.
  • Loading branch information...
1 parent f4270ab commit fdebd7bae6ca938a80713694ef2dfe360f3dc27f @andy10gen andy10gen committed with milkie Oct 18, 2012
Showing with 36 additions and 18 deletions.
  1. +36 −18 site_scons/libdeps.py
View
@@ -51,6 +51,9 @@
import SCons.Scanner
import SCons.Util
+libdeps_env_var = 'LIBDEPS'
+syslibdeps_env_var = 'SYSLIBDEPS'
+
def sorted_by_str(iterable):
"""Shorthand for sorting an iterable according to its string representation.
@@ -71,19 +74,19 @@ def __init__(self, first_node ):
def __str__(self):
return " => ".join(str(n) for n in self.cycle_nodes)
-def __get_libdeps(node, env_var):
+def __get_libdeps(node):
"""Given a SCons Node, return its library dependencies.
Computes the dependencies if they're not already cached.
"""
- cached_var_name = env_var + '_cached'
+ cached_var_name = libdeps_env_var + '_cached'
if not hasattr(node.attributes, cached_var_name):
- setattr(node.attributes, cached_var_name, __compute_libdeps(node, env_var))
+ setattr(node.attributes, cached_var_name, __compute_libdeps(node))
return getattr(node.attributes, cached_var_name)
-def __compute_libdeps(node, env_var):
+def __compute_libdeps(node):
"""Recursively identify all library dependencies for a node."""
if getattr(node.attributes, 'libdeps_exploring', False):
@@ -94,11 +97,11 @@ def __compute_libdeps(node, env_var):
node.attributes.libdeps_exploring = True
try:
try:
- for child in env.Flatten(env.get(env_var, [])):
+ for child in env.Flatten(env.get(libdeps_env_var, [])):
if not child:
continue
deps.add(child)
- deps.update(__get_libdeps(child, env_var))
+ deps.update(__get_libdeps(child))
except DependencyCycleError, e:
if len(e.cycle_nodes) == 1 or e.cycle_nodes[0] != e.cycle_nodes[-1]:
@@ -109,6 +112,20 @@ def __compute_libdeps(node, env_var):
return deps
+def __get_syslibdeps(node):
+ """ Given a SCons Node, return its system library dependencies.
+
+ These are the depencencies listed with SYSLIBDEPS, and are linked using -l.
+ """
+ cached_var_name = syslibdeps_env_var + '_cached'
+ if not hasattr(node.attributes, cached_var_name):
+ syslibdeps = []
+ for lib in __get_libdeps(node):
+ for syslib in lib.get_env().get(syslibdeps_env_var, []):
+ syslibdeps.append(syslib)
+ setattr(node.attributes, cached_var_name, sorted(syslibdeps))
+ return getattr(node.attributes, cached_var_name)
+
def update_scanner(builder):
"""Update the scanner for "builder" to also scan library dependencies."""
@@ -118,14 +135,12 @@ def update_scanner(builder):
path_function = old_scanner.path_function
def new_scanner(node, env, path=()):
result = set(old_scanner.function(node, env, path))
- result.update(__get_libdeps(node, 'LIBDEPS'))
- result.update(__get_libdeps(node, 'SYSLIBDEPS'))
+ result.update(__get_libdeps(node))
return sorted_by_str(result)
else:
path_function = None
def new_scanner(node, env, path=()):
- result = set(__get_libdeps(node, 'LIBDEPS'))
- result.update(__get_libdeps(node, 'SYSLIBDEPS'))
+ result = set(__get_libdeps(node))
return sorted_by_str(result)
builder.target_scanner = SCons.Scanner.Scanner(function=new_scanner,
@@ -138,7 +153,7 @@ def get_libdeps(source, target, env, for_signature):
"""
target = env.Flatten([target])
- return sorted_by_str(__get_libdeps(target[0], 'LIBDEPS'))
+ return sorted_by_str(__get_libdeps(target[0]))
def get_libdeps_objs(source, target, env, for_signature):
objs = set()
@@ -151,8 +166,11 @@ def get_libdeps_special_sun(source, target, env, for_signature):
return x + x + x
def get_syslibdeps(source, target, env, for_signature):
- deps = list(__get_libdeps(target[0], 'SYSLIBDEPS'))
- return deps
+ deps = __get_syslibdeps(target[0])
+ lib_link_prefix = env.subst('$LIBLINKPREFIX')
+ lib_link_suffix = env.subst('$LIBLINKSUFFIX')
+ result = ''.join([' %s%s%s' % (lib_link_prefix, d, lib_link_suffix) for d in deps])
+ return result
def libdeps_emitter(target, source, env):
"""SCons emitter that takes values from the LIBDEPS environment variable and
@@ -172,7 +190,7 @@ def libdeps_emitter(target, source, env):
libdep_files = []
lib_suffix = env.subst('$LIBSUFFIX', target=target, source=source)
lib_prefix = env.subst('$LIBPREFIX', target=target, source=source)
- for dep in env.Flatten([env.get('LIBDEPS', [])]):
+ for dep in env.Flatten([env.get(libdeps_env_var, [])]):
full_path = env.subst(str(dep), target=target, source=source)
dir_name = os.path.dirname(full_path)
file_name = os.path.basename(full_path)
@@ -182,7 +200,7 @@ def libdeps_emitter(target, source, env):
file_name += '${LIBSUFFIX}'
libdep_files.append(env.File(os.path.join(dir_name, file_name)))
- env['LIBDEPS'] = libdep_files
+ env[libdeps_env_var] = libdep_files
return target, source
@@ -203,11 +221,11 @@ def setup_environment(env):
env['_LIBDEPS_LIBS'] = get_libdeps
env['_LIBDEPS_OBJS'] = get_libdeps_objs
- env['_SYSLIBDEPS'] = ' ${_stripixes(LIBLINKPREFIX, SYSLIBDEPS, LIBLINKSUFFIX, LIBPREFIXES, LIBSUFFIXES, __env__)} '
+ env['_SYSLIBDEPS'] = get_syslibdeps
env['_SHLIBDEPS'] = '$SHLIBDEP_GROUP_START ${_concat(SHLIBDEPPREFIX, __env__.subst(_LIBDEPS, target=TARGET, source=SOURCE), SHLIBDEPSUFFIX, __env__, target=TARGET, source=SOURCE)} $SHLIBDEP_GROUP_END'
- env['LIBDEPS'] = SCons.Util.CLVar()
- env['SYSLIBDEPS'] = SCons.Util.CLVar()
+ env[libdeps_env_var] = SCons.Util.CLVar()
+ env[syslibdeps_env_var] = SCons.Util.CLVar()
env.Append(LIBEMITTER=libdeps_emitter,
PROGEMITTER=libdeps_emitter,
SHLIBEMITTER=libdeps_emitter)

0 comments on commit fdebd7b

Please sign in to comment.