summaryrefslogtreecommitdiff
path: root/SConstruct
diff options
context:
space:
mode:
authorAndrew Morrow <acm@mongodb.com>2015-08-12 14:20:44 -0400
committerAndrew Morrow <acm@mongodb.com>2015-08-24 09:36:31 -0400
commit01fff117c028cb820755ba8a7a392ba4c51a0ecc (patch)
treeba614e67fb64ad51afe5426ea5b91d28bb003218 /SConstruct
parentdd15f9c211f5bc40b6fa8a7cd44350d3aeb87d89 (diff)
downloadmongo-01fff117c028cb820755ba8a7a392ba4c51a0ecc.tar.gz
SERVER-9666 Tag cyclic or incomplete libraries, add more missing edges
Diffstat (limited to 'SConstruct')
-rw-r--r--SConstruct78
1 files changed, 65 insertions, 13 deletions
diff --git a/SConstruct b/SConstruct
index 1ccc0506d6c..171bdf27212 100644
--- a/SConstruct
+++ b/SConstruct
@@ -812,6 +812,7 @@ envDict = dict(BUILD_ROOT=buildDir,
CONFIGURELOG=sconsDataDir.File('config.log'),
INSTALL_DIR=installDir,
CONFIG_HEADER_DEFINES={},
+ LIBDEPS_TAG_EXPANSIONS=[],
)
env = Environment(variables=env_vars, **envDict)
@@ -1054,26 +1055,77 @@ if link_model.startswith("dynamic"):
# Do the same for SharedObject
env['BUILDERS']['Object'] = env['BUILDERS']['SharedObject']
- # TODO: Ideally, the conditions below should be based on a detection of what linker we are
- # using, not the local OS, but I doubt very much that we will see the mach-o linker on
- # anything other than Darwin, or a BFD/sun-esque linker elsewhere.
+ # TODO: Ideally, the conditions below should be based on a
+ # detection of what linker we are using, not the local OS, but I
+ # doubt very much that we will see the mach-o linker on anything
+ # other than Darwin, or a BFD/sun-esque linker elsewhere.
- # On Darwin, we need to tell the linker that undefined symbols are resolved via dynamic
- # lookup; otherwise we get build failures. On other unixes, we need to suppress as-needed
- # behavior so that initializers are ensured present, even if there is no visible edge to
- # the library in the symbol graph.
+ # On Darwin, we need to tell the linker that undefined symbols are
+ # resolved via dynamic lookup; otherwise we get build failures. On
+ # other unixes, we need to suppress as-needed behavior so that
+ # initializers are ensured present, even if there is no visible
+ # edge to the library in the symbol graph.
#
- # NOTE: The darwin linker flag is only needed because the library graph is not a DAG. Once
- # the graph is a DAG, we will require all edges to be expressed, and we should drop the
- # flag. When that happens, we should also add -z,defs flag on ELF platforms to ensure that
- # missing symbols due to unnamed dependency edges result in link errors.
+ # NOTE: The darwin linker flag is only needed because the library
+ # graph is not a DAG. Once the graph is a DAG, we will require all
+ # edges to be expressed, and we should drop the flag. When that
+ # happens, we should also add -z,defs flag on ELF platforms to
+ # ensure that missing symbols due to unnamed dependency edges
+ # result in link errors.
+ #
+ # NOTE: The 'incomplete' tag can be applied to a library to
+ # indicate that it does not (or cannot) completely express all of
+ # its required link dependencies. This can occur for three
+ # reasons:
+ #
+ # - No unique provider for the symbol: Some symbols do not have a
+ # unique dependency that provides a definition, in which case it
+ # is impossible for the library to express a dependency edge to
+ # resolve the symbol
+ #
+ # - The library is part of a cycle: If library A depends on B,
+ # which depends on C, which depends on A, then it is impossible
+ # to express all three edges in SCons, since otherwise there is
+ # no way to sequence building the libraries. The cyclic
+ # libraries actually work at runtime, because some parent object
+ # links all of them.
+ #
+ # - The symbol is provided by an executable into which the library
+ # will be linked. The mongo::inShutdown symbol is a good
+ # example.
+ #
+ # All of these are defects in the linking model. In an effort to
+ # eliminate these issues, we have begun tagging those libraries
+ # that are affected, and requiring that all non-tagged libraries
+ # correctly express all dependencies. As we repair each defective
+ # library, we can remove the tag. When all the tags are removed
+ # the graph will be acyclic.
+
if env.TargetOSIs('osx'):
- if link_model != "dynamic-strict":
- env.AppendUnique(SHLINKFLAGS=["-Wl,-undefined,dynamic_lookup"])
+ if link_model == "dynamic-strict":
+ # Darwin is strict by default
+ pass
+ else:
+ def libdeps_tags_expand_incomplete(source, target, env, for_signature):
+ # On darwin, since it is strict by default, we need to add a flag
+ # when libraries are tagged incomplete.
+ if 'incomplete' in target[0].get_env().get("LIBDEPS_TAGS", []):
+ return ["-Wl,-undefined,dynamic_lookup"]
+ return []
+ env['LIBDEPS_TAG_EXPANSIONS'].append(libdeps_tags_expand_incomplete)
else:
env.AppendUnique(SHLINKFLAGS=["-Wl,--no-as-needed"])
if link_model == "dynamic-strict":
env.AppendUnique(SHLINKFLAGS=["-Wl,-z,defs"])
+ else:
+ # On BFD/gold linker environments, which are not strict by
+ # default, we need to add a flag when libraries are not
+ # tagged incomplete.
+ def libdeps_tags_expand_incomplete(source, target, env, for_signature):
+ if 'incomplete' not in target[0].get_env().get("LIBDEPS_TAGS", []):
+ return ["-Wl,-z,defs"]
+ return []
+ env['LIBDEPS_TAG_EXPANSIONS'].append(libdeps_tags_expand_incomplete)
if optBuild:
env.SetConfigHeaderDefine("MONGO_CONFIG_OPTIMIZED_BUILD")