# -*- mode: python -*- import json Import("env use_system_version_of_library usemozjs get_option") Import("use_libunwind") Import("use_system_libunwind") Import("use_vendored_libunwind") Import("wiredtiger") snappySuffix = '-1.1.7' zlibSuffix = '-1.2.11' zstdSuffix = '-1.4.4' pcreSuffix = "-8.42" mozjsSuffix = '-60' icuSuffix = '-57.1' timelibSuffix = '-2021.06' tomcryptSuffix = '-1.18.2' variantSuffix = '-1.4.0' thirdPartyEnvironmentModifications = { 'fmt' : { 'CPPPATH' : ['#src/third_party/fmt/dist/include'], }, 's2' : { 'CPPPATH' : ['#src/third_party/s2'], }, 'safeint' : { 'CPPPATH' : ['#src/third_party/SafeInt'], # SAFEINT_USE_INTRINSICS=0 for overflow-safe constexpr multiply. See comment in SafeInt.hpp. 'CPPDEFINES' : [('SAFEINT_USE_INTRINSICS', 0)], }, 'timelib' : { 'CPPPATH' : ['#/src/third_party/timelib' + timelibSuffix], }, 'unwind' : { }, 'variant' : { 'CPPPATH' : ['#src/third_party/variant' + variantSuffix + '/include'], }, } def injectMozJS(thisEnv): thisEnv.InjectThirdParty(libraries=['mozjs']) if thisEnv.TargetOSIs('windows'): thisEnv.Append( CPPDEFINES=[ '_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING', ] ) else: thisEnv.Append( CXXFLAGS=[ '-Wno-non-virtual-dtor', '-Wno-invalid-offsetof', ], ) thisEnv.Prepend(CPPDEFINES=[ 'JS_USE_CUSTOM_ALLOCATOR', 'STATIC_JS_API=1', ]) if get_option('spider-monkey-dbg') == "on": thisEnv.Prepend(CPPDEFINES=[ 'DEBUG', 'JS_DEBUG', ]) env.AddMethod(injectMozJS, 'InjectMozJS') if not use_system_version_of_library('tcmalloc'): # GPerftools does this slightly differently than the others. thirdPartyEnvironmentModifications['gperftools'] = {} if not use_system_version_of_library('pcre'): thirdPartyEnvironmentModifications['pcre'] = { 'CPPPATH' : ['#/src/third_party/pcre' + pcreSuffix], } if not use_system_version_of_library('boost'): # On at least Apple clang, proto throws this error. # # See https://github.com/boostorg/proto/issues/30. # # We use a generator so we can filter out conf tests, where applying this # flag could change their meaning. def NoErrorForUnknownWarningOptionGenerator(target, source, env, for_signature): if 'conftest' in str(target[0]): return str() return '-Wno-error=unknown-warning-option' thirdPartyEnvironmentModifications['boost'] = { 'CPPPATH' : ['#/src/third_party/boost'], # We could narror further to just clang on Darwin, but there is # little harm in applying for all clang. 'NOERROR_FOR_UNKNOWN_WARNING_OPTION_GEN' : NoErrorForUnknownWarningOptionGenerator, 'CCFLAGS' : ['$NOERROR_FOR_UNKNOWN_WARNING_OPTION_GEN'] if env.ToolchainIs('clang') else [] } if not use_system_version_of_library('abseil-cpp'): thirdPartyEnvironmentModifications['abseil-cpp'] = { 'CPPPATH' : ['#/src/third_party/abseil-cpp-master/abseil-cpp'], } if not use_system_version_of_library('snappy'): thirdPartyEnvironmentModifications['snappy'] = { 'CPPPATH' : ['#/src/third_party/snappy' + snappySuffix], } # Valgrind is a header only include as valgrind.h includes everything we need if not use_system_version_of_library('valgrind'): thirdPartyEnvironmentModifications['valgrind'] = { 'CPPPATH' : ['#/src/third_party/valgrind/include'], } if not use_system_version_of_library('zlib'): thirdPartyEnvironmentModifications['zlib'] = { 'CPPPATH' : ['#/src/third_party/zlib' + zlibSuffix], } if not use_system_version_of_library('zstd'): thirdPartyEnvironmentModifications['zstd'] = { 'CPPPATH' : ['#/src/third_party/zstandard' + zstdSuffix + '/zstd/lib'], } if not use_system_version_of_library('google-benchmark'): thirdPartyEnvironmentModifications['benchmark'] = { 'CPPPATH' : ['#/src/third_party/benchmark/dist/include'], } # TODO: figure out if we want to offer system versions of mozjs. Mozilla # hasn't offered a source tarball since 24, but in theory they could. # #if not use_system_version_of_library('mozjs'): if True: thirdPartyEnvironmentModifications['mozjs'] = { 'CPPPATH' : [ '#/src/third_party/mozjs' + mozjsSuffix + '/include', '#/src/third_party/mozjs' + mozjsSuffix + '/mongo_sources', '#/src/third_party/mozjs' + mozjsSuffix + '/platform/' + env["TARGET_ARCH"] + "/" + env["TARGET_OS"] + "/include", ], 'FORCEINCLUDES' : [ 'js-config.h', 'js/RequiredDefines.h', ], } if "tom" in env["MONGO_CRYPTO"]: thirdPartyEnvironmentModifications['tomcrypt'] = { 'CPPPATH' : ['#/src/third_party/tomcrypt' + tomcryptSuffix + '/src/headers'], } if not use_system_version_of_library('stemmer'): thirdPartyEnvironmentModifications['stemmer'] = { 'CPPPATH' : ['#/src/third_party/libstemmer_c/include'], } # Note that the wiredtiger.h header is generated, so # we want to look for it in the build directory not # the source directory. if wiredtiger and not use_system_version_of_library('wiredtiger'): thirdPartyEnvironmentModifications['wiredtiger'] = { 'CPPPATH' : ['$BUILD_DIR/third_party/wiredtiger'], } if not use_system_version_of_library('yaml'): thirdPartyEnvironmentModifications['yaml'] = { 'CPPPATH' : ['#/src/third_party/yaml-cpp/yaml-cpp/include'], 'CPPDEFINES' : ['_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING'] if env.ToolchainIs('msvc') else [], } if not use_system_version_of_library('asio'): thirdPartyEnvironmentModifications['asio'] = { 'CPPPATH' : ['#/src/third_party/asio-master/asio/include'], } if not use_system_version_of_library('intel_decimal128'): thirdPartyEnvironmentModifications['intel_decimal128'] = { 'CPPPATH' : ['#/src/third_party/IntelRDFPMathLib20U1/LIBRARY'], } if not use_system_version_of_library('icu'): thirdPartyEnvironmentModifications['icu'] = { 'CPPPATH' : ['#/src/third_party/icu4c' + icuSuffix + '/source/common', '#/src/third_party/icu4c' + icuSuffix + '/source/i18n'], } if not use_system_version_of_library('kms-message'): thirdPartyEnvironmentModifications['kms-message'] = { 'CPPPATH' : ['#/src/third_party/kms-message/src'], 'CPPDEFINES' :['KMS_MSG_STATIC'] } if use_system_libunwind: thirdPartyEnvironmentModifications['unwind'] = { 'SYSLIBDEPS_PRIVATE' : [env['LIBDEPS_UNWIND_SYSLIBDEP'], 'lzma'], } elif use_vendored_libunwind: thirdPartyEnvironmentModifications['unwind'] = { 'SYSLIBDEPS_PRIVATE' : ['lzma'], } def injectThirdParty(thisEnv, libraries=[], parts=[]): libraries = thisEnv.Flatten([libraries]) parts = thisEnv.Flatten([parts]) for lib in libraries: mods = thirdPartyEnvironmentModifications.get(lib, None) if mods is None: continue if not parts: thisEnv.PrependUnique(**mods) else: for part in parts: thisEnv.PrependUnique({part : mods[part]}) env.AddMethod(injectThirdParty, 'InjectThirdParty') env = env.Clone() murmurEnv = env.Clone() murmurEnv.InjectThirdParty(libraries=['fmt']) murmurEnv.SConscript('murmurhash3/SConscript', exports={ 'env' : murmurEnv }) s2Env = env.Clone() s2Env.InjectThirdParty(libraries=[ 's2', 'boost', 'abseil-cpp', 'fmt', 'safeint', 'variant', ]) s2Env.InjectMongoIncludePaths() s2Env.SConscript('s2/SConscript', exports={'env' : s2Env}) if use_libunwind: unwindEnv = env.Clone( LIBDEPS_NO_INHERIT=[ '$BUILD_DIR/shim_crt', '$BUILD_DIR/shim_cxx', '$BUILD_DIR/third_party/shim_allocator', ], ) if use_system_libunwind: unwindEnv = unwindEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_UNWIND_SYSLIBDEP'], ]) else: unwindEnv = unwindEnv.Clone() # SCons uses the "$CC" tool for both C and assembler files. Distinguish them for the sake of # later tools like our Ninja SCons module. unwindEnv['ASPP'] = '$CC' unwindEnv['ASPPCOM'] = unwindEnv['ASPPCOM'].replace('$CC ', '$ASPP ') def registerConsumerModifications(env, **kwargs): for k,v in kwargs.items(): thirdPartyEnvironmentModifications['unwind'][k] = v unwindEnv.AddMethod(registerConsumerModifications, 'RegisterConsumerModifications') unwindEnv.SConscript('unwind/SConscript', exports={'env' : unwindEnv}) unwindEnv.Append( LIBDEPS_INTERFACE=[ 'unwind/unwind', ]) unwindEnv.ShimLibrary( name="unwind", ) fmtEnv = env.Clone() if use_system_version_of_library("fmt"): fmtEnv = fmtEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_FMT_SYSLIBDEP'], ]) else: fmtEnv = fmtEnv.Clone() fmtEnv.InjectThirdParty(libraries=['fmt']) fmtEnv.InjectMongoIncludePaths() fmtEnv.SConscript('fmt/SConscript', exports={'env' : fmtEnv}) fmtEnv = fmtEnv.Clone( LIBDEPS_INTERFACE=[ 'fmt/fmt', ]) fmtEnv.ShimLibrary(name="fmt") pcreEnv = env.Clone() if use_system_version_of_library("pcre"): pcreEnv = pcreEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_PCRE_SYSLIBDEP'], env['LIBDEPS_PCRECPP_SYSLIBDEP'], ]) else: pcreEnv = pcreEnv.Clone() pcreEnv.InjectThirdParty(libraries=['pcre']) pcreEnv.SConscript('pcre' + pcreSuffix + '/SConscript', exports={ 'env' : pcreEnv }) pcreEnv = pcreEnv.Clone( LIBDEPS_INTERFACE=[ 'pcre' + pcreSuffix + '/pcrecpp', ]) pcreEnv.ShimLibrary(name="pcrecpp") boostEnv = env.Clone() if use_system_version_of_library("boost"): # On windows, we don't need the syslibdeps because autolib will select the right libraries # for us automatically. if not env.TargetOSIs('windows'): boostEnv = boostEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_BOOST_PROGRAM_OPTIONS_SYSLIBDEP'], env['LIBDEPS_BOOST_FILESYSTEM_SYSLIBDEP'], env['LIBDEPS_BOOST_SYSTEM_SYSLIBDEP'], env['LIBDEPS_BOOST_IOSTREAMS_SYSLIBDEP'], env['LIBDEPS_BOOST_THREAD_SYSLIBDEP'], env['LIBDEPS_BOOST_LOG_SYSLIBDEP'], ]) else: boostDirectory = 'boost' boostEnv = boostEnv.Clone() boostEnv.InjectThirdParty(libraries=['boost']) boostEnv.SConscript(boostDirectory + '/SConscript', exports={ 'env' : boostEnv }) boostEnv = boostEnv.Clone( LIBDEPS_INTERFACE=[ boostDirectory + '/boost_filesystem', boostDirectory + '/boost_iostreams', boostDirectory + '/boost_log', boostDirectory + '/boost_program_options', boostDirectory + '/boost_system', ]) boostEnv.ShimLibrary(name="boost") abseilEnv = env.Clone() if use_system_version_of_library("abseil-cpp"): abseilEnv = abseilEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_ABSL_CONTAINER_SYSLIBDEP'], env['LIBDEPS_ABSL_HASH_SYSLIBDEP'], ]) else: abseilDirectory = 'abseil-cpp-master' abseilEnv = abseilEnv.Clone() abseilEnv.InjectThirdParty(libraries=['abseil-cpp']) abseilEnv.SConscript(abseilDirectory + '/SConscript', exports={ 'env' : abseilEnv }) abseilEnv = abseilEnv.Clone( LIBDEPS_INTERFACE=[ abseilDirectory + '/absl_container', abseilDirectory + '/absl_hash', ]) abseilEnv.ShimLibrary(name="abseil") snappyEnv = env.Clone() if use_system_version_of_library("snappy"): snappyEnv = snappyEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_SNAPPY_SYSLIBDEP'], ]) else: snappyEnv = snappyEnv.Clone() snappyEnv.InjectThirdParty(libraries=['snappy']) snappyEnv.InjectMongoIncludePaths() snappyEnv.SConscript('snappy' + snappySuffix + '/SConscript', exports={ 'env' : snappyEnv }) snappyEnv = snappyEnv.Clone( LIBDEPS_INTERFACE=[ 'snappy' + snappySuffix + '/snappy', ]) snappyEnv.ShimLibrary(name="snappy") zlibEnv = env.Clone() if use_system_version_of_library("zlib"): zlibEnv = zlibEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_ZLIB_SYSLIBDEP'], ]) else: zlibEnv = zlibEnv.Clone() zlibEnv.InjectThirdParty(libraries=['zlib']) zlibEnv.SConscript('zlib' + zlibSuffix + '/SConscript', exports={ 'env' : zlibEnv }) zlibEnv = zlibEnv.Clone( LIBDEPS_INTERFACE=[ 'zlib' + zlibSuffix + '/zlib', ]) zlibEnv.ShimLibrary( name="zlib", ) zstdEnv = env.Clone() if use_system_version_of_library("zstd"): zstdEnv = zstdEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_ZSTD_SYSLIBDEP'], ]) else: zstdEnv = zstdEnv.Clone() zstdEnv.InjectThirdParty(libraries=['zstd']) zstdEnv.SConscript('zstandard' + zstdSuffix + '/SConscript', exports={ 'env' : zstdEnv }) zstdEnv = zstdEnv.Clone( LIBDEPS_INTERFACE=[ 'zstandard' + zstdSuffix + '/zstd', ]) zstdEnv.ShimLibrary( name="zstd", ) benchmarkEnv = env.Clone() if use_system_version_of_library("google-benchmark"): benchmarkEnv = benchmarkEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_BENCHMARK_SYSLIBDEP'], ]) else: benchmarkEnv = benchmarkEnv.Clone() benchmarkEnv.InjectThirdParty(libraries=['benchmark']) benchmarkEnv.SConscript( 'benchmark/SConscript', exports={ 'env' : benchmarkEnv }) benchmarkEnv = benchmarkEnv.Clone( LIBDEPS_INTERFACE=[ 'benchmark/benchmark', ]) benchmarkEnv.ShimLibrary(name="benchmark") if usemozjs: mozjsEnv = env.Clone() mozjsEnv.SConscript('mozjs' + mozjsSuffix + '/SConscript', exports={'env' : mozjsEnv }) mozjsEnv = mozjsEnv.Clone( LIBDEPS_INTERFACE=[ 'mozjs' + mozjsSuffix + '/mozjs', 'shim_zlib', ]) mozjsEnv.ShimLibrary(name="mozjs") if "tom" in env["MONGO_CRYPTO"]: tomcryptEnv = env.Clone() tomcryptEnv.SConscript('tomcrypt' + tomcryptSuffix + '/SConscript', exports={'env' : tomcryptEnv }) tomcryptEnv = tomcryptEnv.Clone( LIBDEPS_INTERFACE=[ 'tomcrypt' + tomcryptSuffix + '/tomcrypt', ]) tomcryptEnv.ShimLibrary( name="tomcrypt", ) gperftoolsEnv = env.Clone( LIBDEPS_NO_INHERIT=[ '$BUILD_DIR/shim_crt', '$BUILD_DIR/shim_cxx', '$BUILD_DIR/third_party/shim_allocator', ], ) if gperftoolsEnv['MONGO_ALLOCATOR'] in ["tcmalloc", "tcmalloc-experimental"]: if use_system_version_of_library("tcmalloc"): gperftoolsEnv = gperftoolsEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_TCMALLOC_SYSLIBDEP'], ]) else: gperftoolsEnv = gperftoolsEnv.Clone() gperftoolsEnv.InjectThirdParty(libraries=['gperftools']) # Allow gperftools to determine its own consumer-side include/ dirs. # Needed because those are in a platform-specific subdirectory. def registerConsumerModifications(env, **kwargs): for k, v in kwargs.items(): thirdPartyEnvironmentModifications['gperftools'][k] = v gperftoolsEnv.AddMethod(registerConsumerModifications, 'RegisterConsumerModifications') gperftoolsEnv.SConscript( 'gperftools' + '/SConscript', exports={'env' : gperftoolsEnv}) gperftoolsEnv = gperftoolsEnv.Clone( LIBDEPS_INTERFACE=[ 'gperftools/tcmalloc_minimal', ]) gperftoolsEnv.ShimLibrary( name="allocator", LIBDEPS_TAGS=[ # TODO: Remove when SERVER-48291 is merged into stable build tools. # An inserted dependency must be linked to every node, including what would # be considered a leaf node to ensure that a system dependency is not linked # in before this one. This tag allows nodes tagged as leaf nodes to still # get the correct allocator. 'lint-leaf-node-allowed-dep', # This tag allows this dependency to be linked to nodes marked as not # allowed to have public dependencies. 'lint-public-dep-allowed' ] ) stemmerEnv = env.Clone() if use_system_version_of_library("stemmer"): stemmerEnv = stemmerEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_STEMMER_SYSLIBDEP'], ]) else: stemmerEnv = stemmerEnv.Clone() stemmerEnv.InjectThirdParty(libraries=['stemmer']) stemmerEnv.SConscript('libstemmer_c/SConscript', exports={ 'env' : stemmerEnv }) stemmerEnv = stemmerEnv.Clone( LIBDEPS_INTERFACE=[ 'libstemmer_c/stemmer', ]) stemmerEnv.ShimLibrary(name="stemmer") yamlEnv = env.Clone() if use_system_version_of_library("yaml"): yamlEnv = yamlEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_YAML_SYSLIBDEP'], ]) else: yamlEnv = yamlEnv.Clone() yamlEnv.InjectThirdParty(libraries=['yaml', 'boost']) yamlEnv.SConscript('yaml-cpp/SConscript', exports={ 'env' : yamlEnv }) yamlEnv = yamlEnv.Clone( LIBDEPS_INTERFACE=[ 'yaml-cpp/yaml', ]) yamlEnv.ShimLibrary(name="yaml") timelibEnv = env.Clone() timelibEnv.InjectThirdParty(libraries=['timelib']) timelibEnv.SConscript('timelib' + timelibSuffix + '/SConscript', exports={ 'env' : timelibEnv }) timelibEnv = timelibEnv.Clone( LIBDEPS_INTERFACE=[ 'timelib' + timelibSuffix + '/timelib', ]) timelibEnv.ShimLibrary( name='timelib', ) wiredtigerEnv = env.Clone() if wiredtiger: if use_system_version_of_library("wiredtiger"): wiredtigerEnv = wiredtigerEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_WIREDTIGER_SYSLIBDEP'], ]) else: wiredtigerEnv = wiredtigerEnv.Clone() wiredtigerEnv.InjectThirdParty(libraries=['wiredtiger']) wiredtigerEnv.SConscript('wiredtiger/SConscript', exports={ 'env' : wiredtigerEnv }) wiredtigerEnv = wiredtigerEnv.Clone( LIBDEPS_INTERFACE=[ 'wiredtiger/wiredtiger', ]) wiredtigerEnv.ShimLibrary(name="wiredtiger") asioEnv = env.Clone() if use_system_version_of_library("asio"): # Normally, we would request LIBDEPS_ASIO_SYSLIBDEP here, but on most systems, the system asio # will be header only so there is no library required. In the rare case where one is, it can be # injected via LIBS= on the command line. asioEnv = asioEnv.Clone() else: asioEnv = asioEnv.Clone() asioEnv.InjectThirdParty(libraries=['asio']) asioEnv.SConscript('asio-master/SConscript', exports={ 'env' : asioEnv }) asioEnv = asioEnv.Clone( LIBDEPS_INTERFACE=[ 'asio-master/asio', ]) asioEnv.ShimLibrary(name="asio") intelDecimal128Env = env.Clone() if use_system_version_of_library("intel_decimal128"): intelDecimal128Env = intelDecimal128Env.Clone( SYSLIBDEPS=[ env['LIBDEPS_INTEL_DECIMAL128_SYSLIBDEP'], ]) else: intelDecimal128Env = intelDecimal128Env.Clone() intelDecimal128Env.InjectThirdParty(libraries=['intel_decimal128']) intelDecimal128Env.SConscript('IntelRDFPMathLib20U1/SConscript', exports={ 'env' : intelDecimal128Env }) intelDecimal128Env = intelDecimal128Env.Clone( LIBDEPS_INTERFACE=[ 'IntelRDFPMathLib20U1/intel_decimal128', ]) intelDecimal128Env.ShimLibrary( name="intel_decimal128", ) icuEnv = env.Clone() if use_system_version_of_library("icu"): icuEnv = icuEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_ICUDATA_SYSLIBDEP'], env['LIBDEPS_ICUI18N_SYSLIBDEP'], env['LIBDEPS_ICUUC_SYSLIBDEP'], ]) else: icuEnv = icuEnv.Clone() icuEnv.InjectThirdParty(libraries=['icu']) icuEnv.SConscript('icu4c' + icuSuffix + '/source/SConscript', exports={ 'env' : icuEnv }) icuEnv = icuEnv.Clone( LIBDEPS_INTERFACE=[ 'icu4c' + icuSuffix + '/source/icu_i18n', ]) icuEnv.ShimLibrary( name="icu", ) kmsEnv = env.Clone() if get_option('ssl') == 'on': if use_system_version_of_library("kms-message"): kmsEnv = kmsEnv.Clone( SYSLIBDEPS=[ env['LIBDEPS_KMS-MESSAGE_SYSLIBDEP'], ]) else: kmsEnv = kmsEnv.Clone() kmsEnv.InjectThirdParty(libraries=['kms-message']) kmsEnv.SConscript('kms-message/SConscript', exports={ 'env' : kmsEnv }) kmsEnv = kmsEnv.Clone( LIBDEPS_INTERFACE=[ 'kms-message/kms-message', ]) kmsEnv.ShimLibrary( name="kms_message", )