mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
SERVER-33911 Implement collapsed library builds under a new link model
This commit is contained in:
parent
7ff6991020
commit
47ab234e91
39
SConstruct
39
SConstruct
@ -469,7 +469,7 @@ add_option('variables-files',
|
||||
help="Specify variables files to load",
|
||||
)
|
||||
|
||||
link_model_choices = ['auto', 'object', 'static', 'dynamic', 'dynamic-strict']
|
||||
link_model_choices = ['auto', 'object', 'static', 'dynamic', 'dynamic-strict', 'dynamic-sdk']
|
||||
add_option('link-model',
|
||||
choices=link_model_choices,
|
||||
default='auto',
|
||||
@ -609,7 +609,6 @@ def variable_tools_converter(val):
|
||||
"gziptool",
|
||||
'idl_tool',
|
||||
"jsheader",
|
||||
"mergelib",
|
||||
"mongo_benchmark",
|
||||
"mongo_integrationtest",
|
||||
"mongo_unittest",
|
||||
@ -1282,8 +1281,8 @@ if link_model == "auto":
|
||||
|
||||
# Windows can't currently support anything other than 'object' or 'static', until
|
||||
# we have both hygienic builds and have annotated functions for export.
|
||||
if env.TargetOSIs('windows') and link_model not in ['object', 'static']:
|
||||
env.FatalError("Windows builds must use the 'object' or 'static' link models");
|
||||
if env.TargetOSIs('windows') and link_model not in ['object', 'static', 'dynamic-sdk']:
|
||||
env.FatalError("Windows builds must use the 'object', 'dynamic-sdk', or 'static' link models")
|
||||
|
||||
# The 'object' mode for libdeps is enabled by setting _LIBDEPS to $_LIBDEPS_OBJS. The other two
|
||||
# modes operate in library mode, enabled by setting _LIBDEPS to $_LIBDEPS_LIBS.
|
||||
@ -1292,11 +1291,24 @@ env['_LIBDEPS'] = '$_LIBDEPS_OBJS' if link_model == "object" else '$_LIBDEPS_LIB
|
||||
env['BUILDERS']['ProgramObject'] = env['BUILDERS']['StaticObject']
|
||||
env['BUILDERS']['LibraryObject'] = env['BUILDERS']['StaticObject']
|
||||
|
||||
env['SHARPREFIX'] = '$LIBPREFIX'
|
||||
env['SHARSUFFIX'] = '${SHLIBSUFFIX}${LIBSUFFIX}'
|
||||
env['BUILDERS']['SharedArchive'] = SCons.Builder.Builder(
|
||||
action=env['BUILDERS']['StaticLibrary'].action,
|
||||
emitter='$SHAREMITTER',
|
||||
prefix='$SHARPREFIX',
|
||||
suffix='$SHARSUFFIX',
|
||||
src_suffix=env['BUILDERS']['SharedLibrary'].src_suffix,
|
||||
)
|
||||
|
||||
if link_model.startswith("dynamic"):
|
||||
|
||||
# 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']
|
||||
def library(env, target, source, *args, **kwargs):
|
||||
sharedLibrary = env.SharedLibrary(target, source, *args, **kwargs)
|
||||
sharedArchive = env.SharedArchive(target, source=sharedLibrary[0].sources, *args, **kwargs)
|
||||
return (sharedLibrary, sharedArchive)
|
||||
|
||||
env['BUILDERS']['Library'] = library
|
||||
env['BUILDERS']['LibraryObject'] = env['BUILDERS']['SharedObject']
|
||||
|
||||
# TODO: Ideally, the conditions below should be based on a
|
||||
@ -1365,6 +1377,19 @@ if link_model.startswith("dynamic"):
|
||||
return ["-Wl,-undefined,dynamic_lookup"]
|
||||
return []
|
||||
env['LIBDEPS_TAG_EXPANSIONS'].append(libdeps_tags_expand_incomplete)
|
||||
elif env.TargetOSIs('windows'):
|
||||
if link_model == "dynamic-strict":
|
||||
# Windows is strict by default
|
||||
pass
|
||||
else:
|
||||
def libdeps_tags_expand_incomplete(source, target, env, for_signature):
|
||||
# On windows, since it is strict by default, we need to add a flag
|
||||
# when libraries are tagged incomplete.
|
||||
if ('illegal_cyclic_or_unresolved_dependencies_whitelisted'
|
||||
in target[0].get_env().get("LIBDEPS_TAGS", [])):
|
||||
return ["/FORCE:UNRESOLVED"]
|
||||
return []
|
||||
env['LIBDEPS_TAG_EXPANSIONS'].append(libdeps_tags_expand_incomplete)
|
||||
else:
|
||||
env.AppendUnique(LINKFLAGS=["-Wl,--no-as-needed"])
|
||||
|
||||
|
@ -1516,7 +1516,7 @@ functions:
|
||||
|
||||
${activate_virtualenv}
|
||||
set +o errexit
|
||||
${compile_env|} $python ./buildscripts/scons.py ${compile_flags|} ${task_compile_flags|} ${scons_cache_args|} $extra_args ${targets} ${additional_targets|} MONGO_VERSION=${version}
|
||||
${compile_env|} $python ./buildscripts/scons.py ${compile_flags|} ${task_compile_flags|} ${task_compile_flags_extra|} ${scons_cache_args|} $extra_args ${targets} ${additional_targets|} MONGO_VERSION=${version}
|
||||
exit_status=$?
|
||||
# If compile fails we do not run any tests
|
||||
if [ $exit_status -ne 0 ]; then
|
||||
@ -3578,7 +3578,6 @@ tasks:
|
||||
task_compile_flags: &embedded_sdk_compile_flags >-
|
||||
--install-mode=hygienic
|
||||
--js-engine=none
|
||||
--link-model=dynamic
|
||||
--prefix='$BUILD_ROOT/mongo-embedded-sdk-$MONGO_VERSION'
|
||||
--dbg=off
|
||||
--opt=size
|
||||
@ -3588,6 +3587,8 @@ tasks:
|
||||
--wiredtiger=off
|
||||
--allocator=system
|
||||
CPPPATH='$BUILD_ROOT/mongo-embedded-sdk-$MONGO_VERSION/include/libbson-1.0 $BUILD_ROOT/mongo-embedded-sdk-$MONGO_VERSION/include/libmongoc-1.0'
|
||||
task_compile_flags_extra: >-
|
||||
--link-model=dynamic-sdk
|
||||
|
||||
- name: embedded_sdk_s3_put
|
||||
commands:
|
||||
@ -3620,6 +3621,8 @@ tasks:
|
||||
vars:
|
||||
targets: install-embedded-test
|
||||
task_compile_flags: *embedded_sdk_compile_flags
|
||||
task_compile_flags_extra: >-
|
||||
--link-model=dynamic
|
||||
|
||||
- name: embedded_sdk_tests_s3_put
|
||||
commands:
|
||||
@ -10428,13 +10431,11 @@ buildvariants:
|
||||
-j$(grep -c ^processor /proc/cpuinfo)
|
||||
--variables-files=etc/scons/mongodbtoolchain_gcc.vars
|
||||
LIBPATH="\$BUILD_ROOT/mongo-embedded-sdk-\$MONGO_VERSION/lib"
|
||||
--lto
|
||||
cdriver_cmake_flags: >-
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DCMAKE_C_COMPILER=/opt/mongodbtoolchain/v2/bin/gcc
|
||||
-DCMAKE_CXX_COMPILER=/opt/mongodbtoolchain/v2/bin/g++
|
||||
-DCMAKE_C_FLAGS="-flto"
|
||||
-DCMAKE_SHARED_LINKER_FLAGS="-flto"
|
||||
-DCMAKE_INSTALL_RPATH=\$ORIGIN/../lib
|
||||
disable_unit_tests: true
|
||||
enable_embedded_tests: native
|
||||
@ -10458,6 +10459,7 @@ buildvariants:
|
||||
LIBS=clang_rt.builtins-arm-android
|
||||
LIBPATH="$(dirname $($(dirname $(pwd))/android_toolchain-arm-21/bin/clang -print-file-name=libclang_rt.builtins-arm-android.a)) \$BUILD_ROOT/mongo-embedded-sdk-\$MONGO_VERSION/lib"
|
||||
--lto
|
||||
AR=$(dirname $(pwd))/android_toolchain-arm-21/bin/llvm-ar
|
||||
cdriver_cmake_flags: >-
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DANDROID_NATIVE_API_LEVEL=21
|
||||
@ -10498,6 +10500,7 @@ buildvariants:
|
||||
--cxx-std=17
|
||||
LIBPATH="\$BUILD_ROOT/mongo-embedded-sdk-\$MONGO_VERSION/lib"
|
||||
--lto
|
||||
AR=$(dirname $(pwd))/android_toolchain-arm64-21/bin/llvm-ar
|
||||
cdriver_cmake_flags: >-
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DANDROID_NATIVE_API_LEVEL=21
|
||||
@ -10538,6 +10541,7 @@ buildvariants:
|
||||
--cxx-std=17
|
||||
LIBPATH="\$BUILD_ROOT/mongo-embedded-sdk-\$MONGO_VERSION/lib"
|
||||
--lto
|
||||
AR=$(dirname $(pwd))/android_toolchain-x86_64-21/bin/llvm-ar
|
||||
cdriver_cmake_flags: >-
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DANDROID_NATIVE_API_LEVEL=21
|
||||
|
@ -63,14 +63,25 @@ missing_syslibdep = 'MISSING_LIBDEP_'
|
||||
class dependency(object):
|
||||
Public, Private, Interface = range(3)
|
||||
|
||||
def __init__(self, value, dynamic, deptype):
|
||||
def __init__(self, value, deptype):
|
||||
self.target_node = value
|
||||
# In static mode, all dependencies are public
|
||||
self.dependency_type = deptype if dynamic else dependency.Public
|
||||
self.dependency_type = deptype
|
||||
|
||||
def __str__(self):
|
||||
return str(self.target_node)
|
||||
|
||||
dependency_visibility_ignored = {
|
||||
dependency.Public : dependency.Public,
|
||||
dependency.Private : dependency.Public,
|
||||
dependency.Interface : dependency.Public,
|
||||
}
|
||||
|
||||
dependency_visibility_honored = {
|
||||
dependency.Public : dependency.Public,
|
||||
dependency.Private : dependency.Private,
|
||||
dependency.Interface : dependency.Interface,
|
||||
}
|
||||
|
||||
class DependencyCycleError(SCons.Errors.UserError):
|
||||
"""Exception representing a cycle discovered in library dependencies."""
|
||||
|
||||
@ -223,128 +234,78 @@ def __append_direct_libdeps(node, prereq_nodes):
|
||||
node.attributes.libdeps_direct = []
|
||||
node.attributes.libdeps_direct.extend(prereq_nodes)
|
||||
|
||||
def libdeps_emitter(target, source, env):
|
||||
"""SCons emitter that takes values from the LIBDEPS environment variable and
|
||||
converts them to File node objects, binding correct path information into
|
||||
those File objects.
|
||||
def make_libdeps_emitter(dependency_builder, dependency_map=dependency_visibility_ignored):
|
||||
|
||||
Emitters run on a particular "target" node during the initial execution of
|
||||
the SConscript file, rather than during the later build phase. When they
|
||||
run, the "env" environment's working directory information is what you
|
||||
expect it to be -- that is, the working directory is considered to be the
|
||||
one that contains the SConscript file. This allows specification of
|
||||
relative paths to LIBDEPS elements.
|
||||
def libdeps_emitter(target, source, env):
|
||||
"""SCons emitter that takes values from the LIBDEPS environment variable and
|
||||
converts them to File node objects, binding correct path information into
|
||||
those File objects.
|
||||
|
||||
This emitter also adds LIBSUFFIX and LIBPREFIX appropriately.
|
||||
Emitters run on a particular "target" node during the initial execution of
|
||||
the SConscript file, rather than during the later build phase. When they
|
||||
run, the "env" environment's working directory information is what you
|
||||
expect it to be -- that is, the working directory is considered to be the
|
||||
one that contains the SConscript file. This allows specification of
|
||||
relative paths to LIBDEPS elements.
|
||||
|
||||
NOTE: For purposes of LIBDEPS_DEPENDENTS propagation, only the first member
|
||||
of the "target" list is made a prerequisite of the elements of LIBDEPS_DEPENDENTS.
|
||||
"""
|
||||
This emitter also adds LIBSUFFIX and LIBPREFIX appropriately.
|
||||
|
||||
lib_builder = env['BUILDERS']['StaticLibrary']
|
||||
lib_node_factory = lib_builder.target_factory or env.File
|
||||
NOTE: For purposes of LIBDEPS_DEPENDENTS propagation, only the first member
|
||||
of the "target" list is made a prerequisite of the elements of LIBDEPS_DEPENDENTS.
|
||||
"""
|
||||
|
||||
prog_builder = env['BUILDERS']['Program']
|
||||
prog_node_factory = prog_builder.target_factory or env.File
|
||||
lib_builder = env['BUILDERS'][dependency_builder]
|
||||
lib_node_factory = lib_builder.target_factory or env.File
|
||||
|
||||
prereqs = [dependency(l, False, dependency.Public) for l in env.get(libdeps_env_var, []) if l]
|
||||
prereqs.extend(dependency(l, False, dependency.Interface) for l in env.get(libdeps_env_var + '_INTERFACE', []) if l)
|
||||
prereqs.extend(dependency(l, False, dependency.Private) for l in env.get(libdeps_env_var + '_PRIVATE', []) if l)
|
||||
prog_builder = env['BUILDERS']['Program']
|
||||
prog_node_factory = prog_builder.target_factory or env.File
|
||||
|
||||
for prereq in prereqs:
|
||||
prereqWithIxes = SCons.Util.adjustixes(
|
||||
prereq.target_node, lib_builder.get_prefix(env), lib_builder.get_suffix(env))
|
||||
prereq.target_node = lib_node_factory(prereqWithIxes)
|
||||
prereqs = [dependency(l, dependency_map[dependency.Public]) for l in env.get(libdeps_env_var, []) if l]
|
||||
prereqs.extend(dependency(l, dependency_map[dependency.Interface]) for l in env.get(libdeps_env_var + '_INTERFACE', []) if l)
|
||||
prereqs.extend(dependency(l, dependency_map[dependency.Private]) for l in env.get(libdeps_env_var + '_PRIVATE', []) if l)
|
||||
|
||||
for t in target:
|
||||
# target[0] must be a Node and not a string, or else libdeps will fail to
|
||||
# work properly.
|
||||
__append_direct_libdeps(t, prereqs)
|
||||
for prereq in prereqs:
|
||||
prereqWithIxes = SCons.Util.adjustixes(
|
||||
prereq.target_node, lib_builder.get_prefix(env), lib_builder.get_suffix(env))
|
||||
prereq.target_node = lib_node_factory(prereqWithIxes)
|
||||
|
||||
for dependent in env.get('LIBDEPS_DEPENDENTS', []):
|
||||
if dependent is None:
|
||||
continue
|
||||
for t in target:
|
||||
# target[0] must be a Node and not a string, or else libdeps will fail to
|
||||
# work properly.
|
||||
__append_direct_libdeps(t, prereqs)
|
||||
|
||||
# Ignore any tuple'd in visibility override.
|
||||
if isinstance(dependent, tuple):
|
||||
dependent = dependent[0]
|
||||
for dependent in env.get('LIBDEPS_DEPENDENTS', []):
|
||||
if dependent is None:
|
||||
continue
|
||||
|
||||
dependentWithIxes = SCons.Util.adjustixes(
|
||||
dependent, lib_builder.get_prefix(env), lib_builder.get_suffix(env))
|
||||
dependentNode = lib_node_factory(dependentWithIxes)
|
||||
__append_direct_libdeps(dependentNode, [dependency(target[0], False, dependency.Public)])
|
||||
visibility = dependency.Private
|
||||
if isinstance(dependent, tuple):
|
||||
visibility = dependent[1]
|
||||
dependent = dependent[0]
|
||||
|
||||
for dependent in env.get('PROGDEPS_DEPENDENTS', []):
|
||||
if dependent is None:
|
||||
continue
|
||||
dependentWithIxes = SCons.Util.adjustixes(
|
||||
dependent, prog_builder.get_prefix(env), prog_builder.get_suffix(env))
|
||||
dependentNode = prog_node_factory(dependentWithIxes)
|
||||
__append_direct_libdeps(dependentNode, [dependency(target[0], False, dependency.Public)])
|
||||
dependentWithIxes = SCons.Util.adjustixes(
|
||||
dependent, lib_builder.get_prefix(env), lib_builder.get_suffix(env))
|
||||
dependentNode = lib_node_factory(dependentWithIxes)
|
||||
__append_direct_libdeps(dependentNode, [dependency(target[0], dependency_map[visibility])])
|
||||
|
||||
return target, source
|
||||
for dependent in env.get('PROGDEPS_DEPENDENTS', []):
|
||||
if dependent is None:
|
||||
continue
|
||||
|
||||
def shlibdeps_emitter(target, source, env):
|
||||
"""SCons emitter that takes values from the LIBDEPS environment variable and
|
||||
converts them to File node objects, binding correct path information into
|
||||
those File objects.
|
||||
visibility = dependency.Public
|
||||
if isinstance(dependent, tuple):
|
||||
# TODO: Error here? Non-public PROGDEPS_DEPENDENTS probably are meaningless
|
||||
visibility = dependent[1]
|
||||
dependent = dependent[0]
|
||||
|
||||
Emitters run on a particular "target" node during the initial execution of
|
||||
the SConscript file, rather than during the later build phase. When they
|
||||
run, the "env" environment's working directory information is what you
|
||||
expect it to be -- that is, the working directory is considered to be the
|
||||
one that contains the SConscript file. This allows specification of
|
||||
relative paths to LIBDEPS elements.
|
||||
dependentWithIxes = SCons.Util.adjustixes(
|
||||
dependent, prog_builder.get_prefix(env), prog_builder.get_suffix(env))
|
||||
dependentNode = prog_node_factory(dependentWithIxes)
|
||||
__append_direct_libdeps(dependentNode, [dependency(target[0], dependency_map[visibility])])
|
||||
|
||||
This emitter also adds LIBSUFFIX and LIBPREFIX appropriately.
|
||||
return target, source
|
||||
|
||||
NOTE: For purposes of LIBDEPS_DEPENDENTS propagation, only the first member
|
||||
of the "target" list is made a prerequisite of the elements of LIBDEPS_DEPENDENTS.
|
||||
"""
|
||||
|
||||
lib_builder = env['BUILDERS']['SharedLibrary']
|
||||
lib_node_factory = lib_builder.target_factory or env.File
|
||||
|
||||
prog_builder = env['BUILDERS']['Program']
|
||||
prog_node_factory = prog_builder.target_factory or env.File
|
||||
|
||||
prereqs = [dependency(l, True, dependency.Public) for l in env.get(libdeps_env_var, []) if l]
|
||||
prereqs.extend(dependency(l, True, dependency.Interface) for l in env.get(libdeps_env_var + '_INTERFACE', []) if l)
|
||||
prereqs.extend(dependency(l, True, dependency.Private) for l in env.get(libdeps_env_var + '_PRIVATE', []) if l)
|
||||
|
||||
for prereq in prereqs:
|
||||
prereqWithIxes = SCons.Util.adjustixes(
|
||||
prereq.target_node, lib_builder.get_prefix(env), lib_builder.get_suffix(env))
|
||||
prereq.target_node = lib_node_factory(prereqWithIxes)
|
||||
|
||||
for t in target:
|
||||
# target[0] must be a Node and not a string, or else libdeps will fail to
|
||||
# work properly.
|
||||
__append_direct_libdeps(t, prereqs)
|
||||
|
||||
for dependent in env.get('LIBDEPS_DEPENDENTS', []):
|
||||
if dependent is None:
|
||||
continue
|
||||
|
||||
visibility = dependency.Private
|
||||
if isinstance(dependent, tuple):
|
||||
visibility = dependent[1]
|
||||
dependent = dependent[0]
|
||||
|
||||
dependentWithIxes = SCons.Util.adjustixes(
|
||||
dependent, lib_builder.get_prefix(env), lib_builder.get_suffix(env))
|
||||
dependentNode = lib_node_factory(dependentWithIxes)
|
||||
__append_direct_libdeps(dependentNode, [dependency(target[0], True, visibility)])
|
||||
|
||||
for dependent in env.get('PROGDEPS_DEPENDENTS', []):
|
||||
if dependent is None:
|
||||
continue
|
||||
dependentWithIxes = SCons.Util.adjustixes(
|
||||
dependent, prog_builder.get_prefix(env), prog_builder.get_suffix(env))
|
||||
dependentNode = prog_node_factory(dependentWithIxes)
|
||||
__append_direct_libdeps(dependentNode, [dependency(target[0], True, dependency.Public)])
|
||||
|
||||
return target, source
|
||||
return libdeps_emitter
|
||||
|
||||
def expand_libdeps_tags(source, target, env, for_signature):
|
||||
results = []
|
||||
@ -368,38 +329,53 @@ def setup_environment(env, emitting_shared=False):
|
||||
env[libdeps_env_var] = SCons.Util.CLVar()
|
||||
env[syslibdeps_env_var] = SCons.Util.CLVar()
|
||||
|
||||
env.Append(LIBEMITTER=libdeps_emitter)
|
||||
if emitting_shared:
|
||||
env['_LIBDEPS_LIBS'] = '$_LIBDEPS_GET_LIBS'
|
||||
env.Append(
|
||||
PROGEMITTER=shlibdeps_emitter,
|
||||
SHLIBEMITTER=shlibdeps_emitter)
|
||||
else:
|
||||
# We need a way for environments to alter just which libdeps
|
||||
# emitter they want, without altering the overall program or
|
||||
# library emitter which may have important effects. The
|
||||
# subsitution rules for emitters are a little strange, so build
|
||||
# ourselves a little trampoline to use below so we don't have to
|
||||
# deal with it.
|
||||
def make_indirect_emitter(variable):
|
||||
def indirect_emitter(target, source, env):
|
||||
return env[variable](target, source, env)
|
||||
return indirect_emitter
|
||||
|
||||
def expand_libdeps_with_extraction_flags(source, target, env, for_signature):
|
||||
result = []
|
||||
libs = get_libdeps(source, target, env, for_signature)
|
||||
for lib in libs:
|
||||
if 'init-no-global-side-effects' in env.Entry(lib).get_env().get('LIBDEPS_TAGS', []):
|
||||
result.append(str(lib))
|
||||
else:
|
||||
result.extend(env.subst('$LINK_WHOLE_ARCHIVE_LIB_START'
|
||||
'$TARGET'
|
||||
'$LINK_WHOLE_ARCHIVE_LIB_END', target=lib).split())
|
||||
return result
|
||||
env.Append(
|
||||
LIBDEPS_LIBEMITTER=make_libdeps_emitter('StaticLibrary'),
|
||||
LIBEMITTER=make_indirect_emitter('LIBDEPS_LIBEMITTER'),
|
||||
|
||||
env['_LIBDEPS_LIBS_WITH_TAGS'] = expand_libdeps_with_extraction_flags
|
||||
LIBDEPS_SHAREMITTER=make_libdeps_emitter('SharedArchive'),
|
||||
SHAREMITTER=make_indirect_emitter('LIBDEPS_SHAREMITTER'),
|
||||
|
||||
LIBDEPS_SHLIBEMITTER=make_libdeps_emitter('SharedLibrary', dependency_visibility_honored),
|
||||
SHLIBEMITTER=make_indirect_emitter('LIBDEPS_SHLIBEMITTER'),
|
||||
|
||||
LIBDEPS_PROGEMITTER=make_libdeps_emitter('SharedLibrary' if emitting_shared else 'StaticLibrary'),
|
||||
PROGEMITTER=make_indirect_emitter('LIBDEPS_PROGEMITTER'),
|
||||
)
|
||||
|
||||
def expand_libdeps_with_extraction_flags(source, target, env, for_signature):
|
||||
result = []
|
||||
libs = get_libdeps(source, target, env, for_signature)
|
||||
for lib in libs:
|
||||
if 'init-no-global-side-effects' in env.Entry(lib).get_env().get('LIBDEPS_TAGS', []):
|
||||
result.append(str(lib))
|
||||
else:
|
||||
result.extend(env.subst('$LINK_WHOLE_ARCHIVE_LIB_START'
|
||||
'$TARGET'
|
||||
'$LINK_WHOLE_ARCHIVE_LIB_END', target=lib).split())
|
||||
return result
|
||||
|
||||
env['_LIBDEPS_LIBS_WITH_TAGS'] = expand_libdeps_with_extraction_flags
|
||||
|
||||
env['_LIBDEPS_LIBS'] = ('$LINK_WHOLE_ARCHIVE_START '
|
||||
'$LINK_LIBGROUP_START '
|
||||
'$_LIBDEPS_LIBS_WITH_TAGS '
|
||||
'$LINK_LIBGROUP_END '
|
||||
'$LINK_WHOLE_ARCHIVE_END')
|
||||
|
||||
env['_LIBDEPS_LIBS'] = ('$LINK_WHOLE_ARCHIVE_START '
|
||||
'$LINK_LIBGROUP_START '
|
||||
'$_LIBDEPS_LIBS_WITH_TAGS '
|
||||
'$LINK_LIBGROUP_END '
|
||||
'$LINK_WHOLE_ARCHIVE_END')
|
||||
env.Append(
|
||||
PROGEMITTER=libdeps_emitter,
|
||||
SHLIBEMITTER=libdeps_emitter)
|
||||
env.Prepend(_LIBFLAGS='$_LIBDEPS_TAGS $_LIBDEPS $_SYSLIBDEPS ')
|
||||
for builder_name in ('Program', 'SharedLibrary', 'LoadableModule'):
|
||||
for builder_name in ('Program', 'SharedLibrary', 'LoadableModule', 'SharedArchive'):
|
||||
try:
|
||||
update_scanner(env['BUILDERS'][builder_name])
|
||||
except KeyError:
|
||||
|
@ -11,6 +11,8 @@ def generate(env):
|
||||
env.subst('$PROGSUFFIX') : 'bin',
|
||||
'.dylib' : 'lib',
|
||||
'.so' : 'lib',
|
||||
'.dll' : 'bin',
|
||||
'.lib' : 'lib',
|
||||
}
|
||||
|
||||
def auto_install(env, target, source, **kwargs):
|
||||
|
@ -1,32 +0,0 @@
|
||||
"""Builder for static libraries composed of the contents of other static libraries.
|
||||
|
||||
The following rule creates a library "mylib" whose contents are the contents of
|
||||
"firstlib", "secondlib", and all LIBDEPS dependencies of "firstlib" and
|
||||
"secondlib". This creates self-contained static and shared libraries that can
|
||||
be distributed to customers.
|
||||
|
||||
MergeLibrary('mylib', ['firstlib', 'secondlib'])
|
||||
|
||||
"""
|
||||
|
||||
import libdeps
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
|
||||
def merge_library_method(env, target, source, LIBDEPS=None, **kwargs):
|
||||
return env._MergeLibrary(target, [], LIBDEPS=source, **kwargs)
|
||||
|
||||
def exists( env ):
|
||||
return True
|
||||
|
||||
def generate( env ):
|
||||
merge_library = Builder(
|
||||
action='$ARCOM $_LIBDEPS_OBJS',
|
||||
src_prefix='$LIBPREFIX',
|
||||
src_suffix='$LIBSUFFIX',
|
||||
prefix='$LIBPREFIX',
|
||||
suffix='$LIBSUFFIX',
|
||||
emitter=libdeps.libdeps_emitter )
|
||||
libdeps.update_scanner( merge_library )
|
||||
env['BUILDERS']['_MergeLibrary'] = merge_library
|
||||
env.AddMethod( merge_library_method, 'MergeLibrary' )
|
@ -37,13 +37,13 @@ def exists(env):
|
||||
if pipe.wait() != 0:
|
||||
return False
|
||||
|
||||
isgnu = False
|
||||
found = False
|
||||
for line in pipe.stdout:
|
||||
if isgnu:
|
||||
if found:
|
||||
continue # consume all data
|
||||
isgnu = re.search(r'^GNU ar', line)
|
||||
found = re.search(r'^GNU ar|^LLVM', line)
|
||||
|
||||
return bool(isgnu)
|
||||
return bool(found)
|
||||
|
||||
def _add_emitter(builder):
|
||||
base_emitter = builder.emitter
|
||||
@ -84,9 +84,8 @@ def generate(env):
|
||||
env['RANLIBCOM'] = noop_action
|
||||
env['RANLIBCOMSTR'] = 'Skipping ranlib for thin archive $TARGET'
|
||||
|
||||
builder = env['BUILDERS']['StaticLibrary']
|
||||
_add_emitter(builder)
|
||||
for builder in ['StaticLibrary', 'SharedArchive']:
|
||||
_add_emitter(env['BUILDERS'][builder])
|
||||
|
||||
_add_scanner(env['BUILDERS']['SharedLibrary'])
|
||||
_add_scanner(env['BUILDERS']['LoadableModule'])
|
||||
_add_scanner(env['BUILDERS']['Program'])
|
||||
for builder in ['SharedLibrary', 'LoadableModule', 'Program']:
|
||||
_add_scanner(env['BUILDERS'][builder])
|
||||
|
@ -1,5 +1,7 @@
|
||||
# -*- mode: python; -*-
|
||||
|
||||
import libdeps
|
||||
|
||||
Import("env")
|
||||
Import("get_option")
|
||||
|
||||
@ -70,14 +72,25 @@ env.Library(
|
||||
],
|
||||
)
|
||||
|
||||
def mongo_export_file_generator(target, source, env, for_signature):
|
||||
if env.ToolchainIs('msvc'):
|
||||
script = env.File(env.subst("${TARGET.base}.def", target=target))
|
||||
return script.get_csig() if for_signature else "/DEF:" + str(script)
|
||||
elif env.TargetOSIs('darwin'):
|
||||
script = env.File(env.subst("${TARGET.base}.exported_symbols_list", target=target))
|
||||
return script.get_csig() if for_signature else "-Wl,-exported_symbols_list," + str(script)
|
||||
elif env.TargetOSIs('posix'):
|
||||
script = env.File(env.subst("${TARGET.base}.version_script", target=target))
|
||||
return script.get_csig() if for_signature else "-Wl,--version-script," + str(script)
|
||||
else:
|
||||
pass
|
||||
env['MONGO_EXPORT_FILE_SHLINKFLAGS'] = mongo_export_file_generator
|
||||
|
||||
capiEnv = env.Clone()
|
||||
capiEnv.AppendUnique(
|
||||
CPPDEFINES=[
|
||||
'MONGO_EMBEDDED_CAPI_COMPILING',
|
||||
],
|
||||
SHCCFLAGS=[
|
||||
'-fvisibility=hidden' if env.TargetOSIs('posix') else [],
|
||||
],
|
||||
)
|
||||
|
||||
if get_option('link-model') == 'static':
|
||||
@ -86,6 +99,15 @@ if get_option('link-model') == 'static':
|
||||
'MONGO_EMBEDDED_CAPI_STATIC',
|
||||
],
|
||||
)
|
||||
elif get_option('link-model') == 'dynamic-sdk':
|
||||
capiEnv['LIBDEPS_SHLIBEMITTER'] = libdeps.make_libdeps_emitter(
|
||||
'SharedArchive',
|
||||
libdeps.dependency_visibility_honored
|
||||
)
|
||||
|
||||
capiEnv.AppendUnique(
|
||||
SHLINKFLAGS=['$MONGO_EXPORT_FILE_SHLINKFLAGS']
|
||||
)
|
||||
|
||||
capiEnv.Library(
|
||||
target='mongo_embedded_capi',
|
||||
@ -112,55 +134,56 @@ if get_option('install-mode') == 'hygienic':
|
||||
],
|
||||
)
|
||||
|
||||
capiTest = yamlEnv.Program(
|
||||
target='mongo_embedded_capi_test',
|
||||
source=[
|
||||
'capi_test.cpp',
|
||||
],
|
||||
LIBDEPS=[
|
||||
'$BUILD_DIR/mongo/base',
|
||||
'$BUILD_DIR/mongo/db/commands/test_commands_enabled',
|
||||
'$BUILD_DIR/mongo/db/server_options_core',
|
||||
'$BUILD_DIR/mongo/rpc/protocol',
|
||||
'$BUILD_DIR/mongo/unittest/unittest',
|
||||
'$BUILD_DIR/mongo/util/net/network',
|
||||
'$BUILD_DIR/mongo/util/options_parser/options_parser',
|
||||
'mongo_embedded_capi',
|
||||
],
|
||||
INSTALL_ALIAS=[
|
||||
'embedded-test',
|
||||
],
|
||||
)
|
||||
if get_option('link-model') != 'dynamic-sdk':
|
||||
capiTest = yamlEnv.Program(
|
||||
target='mongo_embedded_capi_test',
|
||||
source=[
|
||||
'capi_test.cpp',
|
||||
],
|
||||
LIBDEPS=[
|
||||
'$BUILD_DIR/mongo/base',
|
||||
'$BUILD_DIR/mongo/db/commands/test_commands_enabled',
|
||||
'$BUILD_DIR/mongo/db/server_options_core',
|
||||
'$BUILD_DIR/mongo/rpc/protocol',
|
||||
'$BUILD_DIR/mongo/unittest/unittest',
|
||||
'$BUILD_DIR/mongo/util/net/network',
|
||||
'$BUILD_DIR/mongo/util/options_parser/options_parser',
|
||||
'mongo_embedded_capi',
|
||||
],
|
||||
INSTALL_ALIAS=[
|
||||
'embedded-test',
|
||||
],
|
||||
)
|
||||
|
||||
env.RegisterUnitTest(capiTest[0])
|
||||
env.RegisterUnitTest(capiTest[0])
|
||||
|
||||
mongoed = yamlEnv.Program(
|
||||
target='mongoed',
|
||||
source=[
|
||||
'mongoed_main.cpp',
|
||||
],
|
||||
LIBDEPS=[
|
||||
'$BUILD_DIR/mongo/db/commands/shell_protocol',
|
||||
'$BUILD_DIR/mongo/db/mongod_options',
|
||||
'$BUILD_DIR/mongo/db/server_options',
|
||||
'$BUILD_DIR/mongo/db/repl/repl_set_status_commands',
|
||||
'$BUILD_DIR/mongo/transport/service_entry_point',
|
||||
'$BUILD_DIR/mongo/transport/transport_layer_manager',
|
||||
'$BUILD_DIR/mongo/util/signal_handlers',
|
||||
'embedded',
|
||||
'embedded_integration_helpers',
|
||||
],
|
||||
INSTALL_ALIAS=[
|
||||
'embedded-test',
|
||||
],
|
||||
)
|
||||
mongoed = yamlEnv.Program(
|
||||
target='mongoed',
|
||||
source=[
|
||||
'mongoed_main.cpp',
|
||||
],
|
||||
LIBDEPS=[
|
||||
'$BUILD_DIR/mongo/db/commands/shell_protocol',
|
||||
'$BUILD_DIR/mongo/db/mongod_options',
|
||||
'$BUILD_DIR/mongo/db/server_options',
|
||||
'$BUILD_DIR/mongo/db/repl/repl_set_status_commands',
|
||||
'$BUILD_DIR/mongo/transport/service_entry_point',
|
||||
'$BUILD_DIR/mongo/transport/transport_layer_manager',
|
||||
'$BUILD_DIR/mongo/util/signal_handlers',
|
||||
'embedded',
|
||||
'embedded_integration_helpers',
|
||||
],
|
||||
INSTALL_ALIAS=[
|
||||
'embedded-test',
|
||||
],
|
||||
)
|
||||
|
||||
env.Alias('all', mongoed) # This ensures it compiles and links, but doesn't copy it anywhere.
|
||||
env.Alias('all', mongoed) # This ensures it compiles and links, but doesn't copy it anywhere.
|
||||
|
||||
hygienic = get_option('install-mode') == 'hygienic'
|
||||
hygienic = get_option('install-mode') == 'hygienic'
|
||||
|
||||
if not hygienic:
|
||||
env.Install('#/', mongoed)
|
||||
if not hygienic:
|
||||
env.Install('#/', mongoed)
|
||||
|
||||
if not env['MONGO_HAVE_LIBMONGOC']:
|
||||
Return()
|
||||
@ -170,9 +193,6 @@ mongocClientEnv.AppendUnique(
|
||||
CPPDEFINES=[
|
||||
'MONGO_EMBEDDED_MONGOC_CLIENT_COMPILING',
|
||||
],
|
||||
SHCCFLAGS=[
|
||||
'-fvisibility=hidden' if env.TargetOSIs('posix') else [],
|
||||
],
|
||||
)
|
||||
|
||||
if get_option('link-model') == 'static':
|
||||
@ -182,6 +202,10 @@ if get_option('link-model') == 'static':
|
||||
],
|
||||
)
|
||||
|
||||
mongocClientEnv.AppendUnique(
|
||||
SHLINKFLAGS=['$MONGO_EXPORT_FILE_SHLINKFLAGS']
|
||||
)
|
||||
|
||||
mongocClientEnv.Library(
|
||||
target='mongo_embedded_mongoc_client',
|
||||
source=[
|
||||
@ -210,22 +234,23 @@ if get_option('install-mode') == 'hygienic':
|
||||
],
|
||||
)
|
||||
|
||||
clientTest = yamlEnv.Program(
|
||||
target='mongo_embedded_mongoc_client_test',
|
||||
source=[
|
||||
'mongo_embedded_mongoc_client_test.cpp',
|
||||
'functions_for_test.cpp',
|
||||
],
|
||||
LIBDEPS=[
|
||||
'$BUILD_DIR/mongo/base',
|
||||
'$BUILD_DIR/mongo/db/server_options_core',
|
||||
'$BUILD_DIR/mongo/unittest/unittest',
|
||||
'$BUILD_DIR/mongo/util/options_parser/options_parser',
|
||||
'mongo_embedded_mongoc_client',
|
||||
],
|
||||
INSTALL_ALIAS=[
|
||||
'embedded-test',
|
||||
],
|
||||
)
|
||||
if get_option('link-model') != 'dynamic-sdk':
|
||||
clientTest = yamlEnv.Program(
|
||||
target='mongo_embedded_mongoc_client_test',
|
||||
source=[
|
||||
'mongo_embedded_mongoc_client_test.cpp',
|
||||
'functions_for_test.cpp',
|
||||
],
|
||||
LIBDEPS=[
|
||||
'$BUILD_DIR/mongo/base',
|
||||
'$BUILD_DIR/mongo/db/server_options_core',
|
||||
'$BUILD_DIR/mongo/unittest/unittest',
|
||||
'$BUILD_DIR/mongo/util/options_parser/options_parser',
|
||||
'mongo_embedded_mongoc_client',
|
||||
],
|
||||
INSTALL_ALIAS=[
|
||||
'embedded-test',
|
||||
],
|
||||
)
|
||||
|
||||
env.RegisterUnitTest(clientTest[0]);
|
||||
env.RegisterUnitTest(clientTest[0]);
|
||||
|
@ -0,0 +1 @@
|
||||
_mongo_embedded_v1_*
|
4
src/mongo/embedded/libmongo_embedded_capi.version_script
Normal file
4
src/mongo/embedded/libmongo_embedded_capi.version_script
Normal file
@ -0,0 +1,4 @@
|
||||
MONGO_EMBEDDED_CAPI_ABI_1.0 {
|
||||
global: mongo_embedded_v1_*;
|
||||
local: *;
|
||||
};
|
@ -0,0 +1 @@
|
||||
_mongo_embedded_v1_mongoc_*
|
@ -0,0 +1,4 @@
|
||||
MONGO_EMBEDDED_MONGOC_CLIENT_ABI_1.0 {
|
||||
global: mongo_embedded_v1_mongoc_client_*;
|
||||
local: *;
|
||||
};
|
14
src/mongo/embedded/mongo_embedded_capi.def
Normal file
14
src/mongo/embedded/mongo_embedded_capi.def
Normal file
@ -0,0 +1,14 @@
|
||||
LIBRARY MONGO_EMBEDDED_CAPI
|
||||
EXPORTS
|
||||
mongo_embedded_v1_status_create
|
||||
mongo_embedded_v1_status_destroy
|
||||
mongo_embedded_v1_status_get_error
|
||||
mongo_embedded_v1_status_get_explanation
|
||||
mongo_embedded_v1_status_get_code
|
||||
mongo_embedded_v1_lib_init
|
||||
mongo_embedded_v1_lib_fini
|
||||
mongo_embedded_v1_instance_create
|
||||
mongo_embedded_v1_instance_destroy
|
||||
mongo_embedded_v1_client_create
|
||||
mongo_embedded_v1_client_destroy
|
||||
mongo_embedded_v1_client_invoke
|
3
src/mongo/embedded/mongo_embedded_mongoc_client.def
Normal file
3
src/mongo/embedded/mongo_embedded_mongoc_client.def
Normal file
@ -0,0 +1,3 @@
|
||||
LIBRARY MONGO_EMBEDDED_MONGOC_CLIENT
|
||||
EXPORTS
|
||||
mongo_embedded_v1_mongoc_client_create
|
Loading…
Reference in New Issue
Block a user