summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morrow <acm@mongodb.com>2018-07-01 17:15:13 -0400
committerAndrew Morrow <acm@mongodb.com>2018-09-12 16:10:41 -0400
commit47ab234e910a04cb2bee4114170b042d47586c35 (patch)
treea4f8976a00af0076646daf92b56c36744e87b54d
parent7ff69910209132acaa6abf6237f0f2d36ce518c2 (diff)
downloadmongo-47ab234e910a04cb2bee4114170b042d47586c35.tar.gz
SERVER-33911 Implement collapsed library builds under a new link model
-rw-r--r--SConstruct39
-rw-r--r--etc/evergreen.yml12
-rw-r--r--site_scons/libdeps.py258
-rw-r--r--site_scons/site_tools/auto_install_binaries.py2
-rw-r--r--site_scons/site_tools/mergelib.py32
-rw-r--r--site_scons/site_tools/thin_archive.py17
-rw-r--r--src/mongo/embedded/SConscript161
-rw-r--r--src/mongo/embedded/libmongo_embedded_capi.exported_symbols_list1
-rw-r--r--src/mongo/embedded/libmongo_embedded_capi.version_script4
-rw-r--r--src/mongo/embedded/libmongo_embedded_mongoc_client.exported_symbols_list1
-rw-r--r--src/mongo/embedded/libmongo_embedded_mongoc_client.version_script4
-rw-r--r--src/mongo/embedded/mongo_embedded_capi.def14
-rw-r--r--src/mongo/embedded/mongo_embedded_mongoc_client.def3
13 files changed, 287 insertions, 261 deletions
diff --git a/SConstruct b/SConstruct
index 032aec64024..62df588ff23 100644
--- a/SConstruct
+++ b/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"])
diff --git a/etc/evergreen.yml b/etc/evergreen.yml
index 47779454e3b..93057bdd70c 100644
--- a/etc/evergreen.yml
+++ b/etc/evergreen.yml
@@ -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
diff --git a/site_scons/libdeps.py b/site_scons/libdeps.py
index f002c4f067e..5bc530ba1e7 100644
--- a/site_scons/libdeps.py
+++ b/site_scons/libdeps.py
@@ -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
-
- prog_builder = env['BUILDERS']['Program']
- prog_node_factory = prog_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)
-
- 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
-
- # Ignore any tuple'd in visibility override.
- if isinstance(dependent, tuple):
- 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], False, dependency.Public)])
-
- 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)])
-
- return target, source
-
-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.
-
- 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.
-
- This emitter also adds LIBSUFFIX and LIBPREFIX appropriately.
-
- 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.
- """
+ 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'][dependency_builder]
+ 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
- lib_builder = env['BUILDERS']['SharedLibrary']
- lib_node_factory = lib_builder.target_factory or env.File
+ 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)
- 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, 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 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)
+ visibility = dependency.Private
+ if isinstance(dependent, tuple):
+ visibility = dependent[1]
+ 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], dependency_map[visibility])])
- 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, lib_builder.get_prefix(env), lib_builder.get_suffix(env))
- dependentNode = lib_node_factory(dependentWithIxes)
- __append_direct_libdeps(dependentNode, [dependency(target[0], True, visibility)])
+ visibility = dependency.Public
+ if isinstance(dependent, tuple):
+ # TODO: Error here? Non-public PROGDEPS_DEPENDENTS probably are meaningless
+ 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], True, dependency.Public)])
+ 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])])
- return target, source
+ 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:
-
- 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
+ # 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
+
+ env.Append(
+ LIBDEPS_LIBEMITTER=make_libdeps_emitter('StaticLibrary'),
+ LIBEMITTER=make_indirect_emitter('LIBDEPS_LIBEMITTER'),
+
+ 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:
diff --git a/site_scons/site_tools/auto_install_binaries.py b/site_scons/site_tools/auto_install_binaries.py
index 87821f0341b..9f3de6166df 100644
--- a/site_scons/site_tools/auto_install_binaries.py
+++ b/site_scons/site_tools/auto_install_binaries.py
@@ -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):
diff --git a/site_scons/site_tools/mergelib.py b/site_scons/site_tools/mergelib.py
deleted file mode 100644
index d8fcf3347ba..00000000000
--- a/site_scons/site_tools/mergelib.py
+++ /dev/null
@@ -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' )
diff --git a/site_scons/site_tools/thin_archive.py b/site_scons/site_tools/thin_archive.py
index 511c0ef6e54..15357874438 100644
--- a/site_scons/site_tools/thin_archive.py
+++ b/site_scons/site_tools/thin_archive.py
@@ -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])
diff --git a/src/mongo/embedded/SConscript b/src/mongo/embedded/SConscript
index 883502177af..f5ad103a351 100644
--- a/src/mongo/embedded/SConscript
+++ b/src/mongo/embedded/SConscript
@@ -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]);
diff --git a/src/mongo/embedded/libmongo_embedded_capi.exported_symbols_list b/src/mongo/embedded/libmongo_embedded_capi.exported_symbols_list
new file mode 100644
index 00000000000..b4eff2f5a5e
--- /dev/null
+++ b/src/mongo/embedded/libmongo_embedded_capi.exported_symbols_list
@@ -0,0 +1 @@
+_mongo_embedded_v1_*
diff --git a/src/mongo/embedded/libmongo_embedded_capi.version_script b/src/mongo/embedded/libmongo_embedded_capi.version_script
new file mode 100644
index 00000000000..5c9a6bb5447
--- /dev/null
+++ b/src/mongo/embedded/libmongo_embedded_capi.version_script
@@ -0,0 +1,4 @@
+MONGO_EMBEDDED_CAPI_ABI_1.0 {
+ global: mongo_embedded_v1_*;
+ local: *;
+};
diff --git a/src/mongo/embedded/libmongo_embedded_mongoc_client.exported_symbols_list b/src/mongo/embedded/libmongo_embedded_mongoc_client.exported_symbols_list
new file mode 100644
index 00000000000..4b117b2cf3a
--- /dev/null
+++ b/src/mongo/embedded/libmongo_embedded_mongoc_client.exported_symbols_list
@@ -0,0 +1 @@
+_mongo_embedded_v1_mongoc_*
diff --git a/src/mongo/embedded/libmongo_embedded_mongoc_client.version_script b/src/mongo/embedded/libmongo_embedded_mongoc_client.version_script
new file mode 100644
index 00000000000..9c877162b27
--- /dev/null
+++ b/src/mongo/embedded/libmongo_embedded_mongoc_client.version_script
@@ -0,0 +1,4 @@
+MONGO_EMBEDDED_MONGOC_CLIENT_ABI_1.0 {
+ global: mongo_embedded_v1_mongoc_client_*;
+ local: *;
+};
diff --git a/src/mongo/embedded/mongo_embedded_capi.def b/src/mongo/embedded/mongo_embedded_capi.def
new file mode 100644
index 00000000000..46e19745b3a
--- /dev/null
+++ b/src/mongo/embedded/mongo_embedded_capi.def
@@ -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
diff --git a/src/mongo/embedded/mongo_embedded_mongoc_client.def b/src/mongo/embedded/mongo_embedded_mongoc_client.def
new file mode 100644
index 00000000000..089008391d8
--- /dev/null
+++ b/src/mongo/embedded/mongo_embedded_mongoc_client.def
@@ -0,0 +1,3 @@
+LIBRARY MONGO_EMBEDDED_MONGOC_CLIENT
+EXPORTS
+ mongo_embedded_v1_mongoc_client_create