diff options
author | Andrew Morrow <acm@10gen.com> | 2013-05-21 21:07:48 -0400 |
---|---|---|
committer | Andrew Morrow <acm@10gen.com> | 2013-06-03 20:21:13 -0400 |
commit | da8c0fa929eeb03dbe3fb0533874de31da0bc8c8 (patch) | |
tree | c303beed34a3e80e0e77092cd4eaab7b105836c0 | |
parent | 9b148b0419d79f7173d0e972e8427fea67f77616 (diff) | |
download | mongo-da8c0fa929eeb03dbe3fb0533874de31da0bc8c8.tar.gz |
SERVER-6514 Re-add support for building the C++ driver shared library
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | SConscript.smoke | 26 | ||||
-rw-r--r-- | SConstruct | 13 | ||||
-rwxr-xr-x | buildscripts/smoke.py | 6 | ||||
-rwxr-xr-x | distsrc/client/SConstruct | 36 | ||||
-rw-r--r-- | src/SConscript.client | 176 | ||||
-rw-r--r-- | src/mongo/SConscript | 17 | ||||
-rw-r--r-- | src/mongo/client/examples/httpClientTest.cpp | 9 |
8 files changed, 214 insertions, 70 deletions
diff --git a/.gitignore b/.gitignore index 5231f4f4965..8259ae8ddb0 100644 --- a/.gitignore +++ b/.gitignore @@ -101,6 +101,7 @@ scratch /libmongoclient.* /libmongotestfiles.* /libmongoshellfiles.* +/sharedclient /emr.jar *.class diff --git a/SConscript.smoke b/SConscript.smoke index 3dbef68dee0..8d2eb873bd6 100644 --- a/SConscript.smoke +++ b/SConscript.smoke @@ -68,16 +68,22 @@ def addSmokeSuite( name, suitefile, needMongod=False ): addSmoketest( "smoke", [ add_exe( "test" ), add_exe( "mongod" ), add_exe( "mongo" ) ] ) addSmoketest( "smokePerf", [ add_exe("perftest") ] ) -addSmoketest( "smokeClient", [ - add_exe('firstExample'), - add_exe('rsExample'), - add_exe('secondExample'), - add_exe('whereExample'), - add_exe('authTest'), - add_exe('httpClientTest'), - add_exe('bsondemo'), - add_exe('clientTest'), - ] ) + +smokeClientDeps = [ + add_exe('firstExample'), + add_exe('rsExample'), + add_exe('secondExample'), + add_exe('whereExample'), + add_exe('authTest'), + add_exe('httpClientTest'), + add_exe('clientTest'), +] +if has_option("sharedclient"): + smokeClientDeps += [ "sharedclient/" + name for name in smokeClientDeps ] +smokeClientDeps += [add_exe('bsondemo')] +smokeClientDeps += [add_exe('mongod'), add_exe('mongo')] +smokeClient = addSmoketest( "smokeClient", smokeClientDeps ) + addSmoketest( "mongosTest", [ add_exe( 'mongos' ) ]) addSmokeSuite( "smokeCppUnittests", "$UNITTEST_LIST" ) addSmokeSuite( "smokeModuleTests", "$MODULETEST_LIST" ) diff --git a/SConstruct b/SConstruct index 4d12d5d6737..e52f14a8ba7 100644 --- a/SConstruct +++ b/SConstruct @@ -359,7 +359,10 @@ if has_option('build-fast-and-loose'): if has_option('mute'): env.Append( CCCOMSTR = "Compiling $TARGET" ) env.Append( CXXCOMSTR = env["CCCOMSTR"] ) + env.Append( SHCCCOMSTR = "Compiling $TARGET" ) + env.Append( SHCXXCOMSTR = env["SHCCCOMSTR"] ) env.Append( LINKCOMSTR = "Linking $TARGET" ) + env.Append( SHLINKCOMSTR = env["LINKCOMSTR"] ) env.Append( ARCOMSTR = "Generating library $TARGET" ) if has_option('mongod-concurrency-level'): @@ -737,7 +740,7 @@ if nix: pass if linux and has_option( "sharedclient" ): - env.Append( LINKFLAGS=" -Wl,--as-needed -Wl,-zdefs " ) + env.Append( SHLINKFLAGS=" -Wl,--as-needed -Wl,-zdefs " ) if linux and has_option( "gcov" ): env.Append( CXXFLAGS=" -fprofile-arcs -ftest-coverage " ) @@ -1423,13 +1426,6 @@ if len(COMMAND_LINE_TARGETS) > 0 and 'uninstall' in COMMAND_LINE_TARGETS: BUILD_TARGETS.remove("uninstall") BUILD_TARGETS.append("install") -clientEnv = env.Clone() -clientEnv['CPPDEFINES'].remove('MONGO_EXPOSE_MACROS') - -if not use_system_version_of_library("boost"): - clientEnv.Append(LIBS=['boost_thread', 'boost_filesystem', 'boost_system']) - clientEnv.Prepend(LIBPATH=['$BUILD_DIR/third_party/boost/']) - module_sconscripts = moduleconfig.get_module_sconscripts(mongo_modules) # The following symbols are exported for use in subordinate SConscript files. @@ -1441,7 +1437,6 @@ module_sconscripts = moduleconfig.get_module_sconscripts(mongo_modules) # conditional decision making that hasn't been moved up to this SConstruct file, # and they are exported here, as well. Export("env") -Export("clientEnv") Export("shellEnv") Export("testEnv") Export("has_option use_system_version_of_library") diff --git a/buildscripts/smoke.py b/buildscripts/smoke.py index 9232136f4f1..f0a8f0d431e 100755 --- a/buildscripts/smoke.py +++ b/buildscripts/smoke.py @@ -692,6 +692,12 @@ def expand_suites(suites,expandUseDB=True): paths = ["firstExample", "secondExample", "whereExample", "authTest", "clientTest", "httpClientTest"] if os.sys.platform == "win32": paths = [path + '.exe' for path in paths] + + # Add any files of the same name from the sharedclient directory. + scpaths = ["sharedclient/" + path for path in paths] + scfiles = glob.glob("sharedclient/*") + paths += [scfile for scfile in scfiles if scfile in scpaths] + # hack tests += [(test_path and path or os.path.join(mongo_repo, path), False) for path in paths] elif suite == 'mongosTest': diff --git a/distsrc/client/SConstruct b/distsrc/client/SConstruct index e9fac9305aa..ed95f0a639a 100755 --- a/distsrc/client/SConstruct +++ b/distsrc/client/SConstruct @@ -22,13 +22,27 @@ AddOption("--prefix", help="installation root") +# Stub out has_option so that we can use it in SConscript.client +def has_option(name): + return False + +# Stub out use_system_version_of_library so we can use it in SConscript.client +def use_system_version_of_library(name): + return True + env = Environment(BUILD_DIR='#build', CLIENT_ARCHIVE='${CLIENT_DIST_BASENAME}${DIST_ARCHIVE_SUFFIX}', CLIENT_DIST_BASENAME='mongo-cxx-driver', CLIENT_LICENSE='#LICENSE.txt', CLIENT_SCONSTRUCT='#SConstruct', MSVS_ARCH=None, - PYTHON=sys.executable) + PYTHON=sys.executable, + PYSYSPLATFORM=os.sys.platform) + +if env['PYSYSPLATFORM'] == 'linux3': + env['PYSYSPLATFORM'] = 'linux2' +if 'freebsd' in env['PYSYSPLATFORM']: + env['PYSYSPLATFORM'] = 'freebsd' def addExtraLibs(s): for x in s.split(","): @@ -44,18 +58,20 @@ env.Append(CPPDEFINES=[ "_SCONS", "MONGO_EXPOSE_MACROS" ]) nix = False linux = False -win = False +windows = False +darwin = False if "darwin" == sys.platform: addExtraLibs( "/opt/local/" ) nix = True + darwin = True elif sys.platform in ("linux2", "linux3"): nix = True linux = True elif sys.platform == 'win32': - win = True + windows = True -if win: +if windows: env['DIST_ARCHIVE_SUFFIX'] = '.zip' env.Append(CCFLAGS=['/EHsc', '/O2']) else: @@ -71,7 +87,7 @@ conf = Configure(env) for lib in boostLibs: if not conf.CheckLib(["boost_%s-mt" % lib, "boost_%s" % lib], language="C++"): - if not win: + if not windows: Exit(1) env['MONGO_BUILD_SASL_CLIENT'] = conf.CheckLibWithHeader( @@ -79,10 +95,14 @@ env['MONGO_BUILD_SASL_CLIENT'] = conf.CheckLibWithHeader( conf.Finish() -clientEnv = env.Clone() -clientEnv['CPPDEFINES'].remove('MONGO_EXPOSE_MACROS') +class InstallSetup: + binaries = False + libraries = False + headers = False +installSetup = InstallSetup() -Export("env clientEnv") +Export("env has_option use_system_version_of_library installSetup") +Export("nix linux windows darwin") env.SConscript('src/SConscript.client', variant_dir='$BUILD_DIR', duplicate=False) mongoclient = env.Alias('mongoclient', ['${LIBPREFIX}mongoclient${LIBSUFFIX}']) diff --git a/src/SConscript.client b/src/SConscript.client index 434213701db..df31c976f17 100644 --- a/src/SConscript.client +++ b/src/SConscript.client @@ -2,14 +2,19 @@ # This SConscript describes build and install rules for the Mongo C++ driver and associated exmaple # programs. +Import('env has_option installSetup use_system_version_of_library') -Import('env clientEnv') +Import('nix darwin windows') + +buildShared = False +if has_option("sharedclient"): + buildShared = True env.Command(['mongo/base/error_codes.h', 'mongo/base/error_codes.cpp',], ['mongo/base/generate_error_codes.py', 'mongo/base/error_codes.err'], '$PYTHON $SOURCES $TARGETS') -env.Command(['mongo/db/auth/action_type.h', 'mongo/db/auth/action_type.cpp'], +env.Command(['mongo/db/auth/action_type.h', 'mongo/db/auth/action_type.cpp'], ['mongo/db/auth/generate_action_types.py', 'mongo/db/auth/action_types.txt'], '$PYTHON $SOURCES $TARGETS') @@ -36,7 +41,6 @@ clientSourceBasic = [ 'mongo/client/dbclient.cpp', 'mongo/client/dbclient_rs.cpp', 'mongo/client/dbclientcursor.cpp', - 'mongo/client/distlock.cpp', 'mongo/client/gridfs.cpp', 'mongo/client/model.cpp', 'mongo/client/sasl_client_authenticate.cpp', @@ -60,6 +64,7 @@ clientSourceBasic = [ 'mongo/util/concurrency/mutexdebugger.cpp', 'mongo/util/debug_util.cpp', 'mongo/util/stacktrace.cpp', + 'mongo/util/file.cpp', 'mongo/util/file_allocator.cpp', 'mongo/util/fail_point.cpp', 'mongo/util/fail_point_registry.cpp', @@ -77,6 +82,8 @@ clientSourceBasic = [ 'mongo/util/net/sock.cpp', 'mongo/util/net/ssl_manager.cpp', 'mongo/util/password.cpp', + 'mongo/util/processinfo.cpp', + env.File('mongo/util/processinfo_${PYSYSPLATFORM}.cpp'), 'mongo/util/ramlog.cpp', 'mongo/util/signal_handlers.cpp', 'mongo/util/stringutils.cpp', @@ -94,7 +101,9 @@ clientSourceSasl = ['mongo/client/sasl_client_authenticate_impl.cpp', clientSourceAll = clientSourceBasic + clientSourceSasl -if env['MONGO_BUILD_SASL_CLIENT']: +usingSasl = env['MONGO_BUILD_SASL_CLIENT'] + +if usingSasl: clientSource = clientSourceAll else: clientSource = clientSourceBasic @@ -128,8 +137,8 @@ clientHeaderDirectories = [ "util/", "util/concurrency/", "util/mongoutils/", - "util/net/", - "" + "util/net/", + "" ] clientHeaders = [] @@ -137,16 +146,143 @@ for path in clientHeaderDirectories: clientHeaders.extend(Glob('mongo/%s/*.h' % path)) clientHeaders.extend(Glob('mongo/%s/*.hpp' % path)) -mongoclient_lib = env.Library('mongoclient', clientSource), -mongoclient_install = env.Install('#/', [ - mongoclient_lib, - #env.SharedLibrary('mongoclient', clientSource), - ]) -env.Alias('mongoclient', mongoclient_install) +# This relies on static and shared objects being the same, since we will link these object +# files twice: once into a .a, and another time into a .so +clientObjects = [env.Object(source) for source in clientSource] + +mongoClientLibs = [] +mongoClientLibDeps = [] +mongoClientSysLibDeps = [] + +if usingSasl: + mongoClientSysLibDeps += ["sasl2"] + +if use_system_version_of_library("boost"): + mongoClientLibs.append(['boost_thread-mt']) +else: + mongoClientLibDeps.append(['$BUILD_DIR/third_party/shim_boost']) + +mongoClientInstalls = [] +mongoClientPrefixInstalls = [] + +if windows and buildShared: + print("Building the client driver as a DLL is not supported, see SERVER-5650") + Exit(1) + +staticLibEnv = env.Clone() +staticLibEnv.AppendUnique( + LIBDEPS=mongoClientLibDeps, + SYSLIBDEPS=mongoClientSysLibDeps) + +mongoClientStaticLib = staticLibEnv.StaticLibrary( + 'mongoclient', clientObjects), +mongoClientInstalls.append(staticLibEnv.Install('#/', mongoClientStaticLib)) + +if installSetup.libraries: + mongoClientPrefixInstalls.append(env.Install("$INSTALL_DIR/lib", mongoClientStaticLib)) + +mongoClientSharedLib = None + +if buildShared: + + # TODO: When we are ready to set a SONAME for mongoclient, set SHLIBVERSION=x.y.z in this + # environment to enable SCons versioned shared library support. This support is only stable + # in SCons > 2.3.0, so if you add it here, be sure to add a EnsuredSconsVersion as well. + sharedLibEnv = env.Clone() + sharedLibEnv.AppendUnique( + LIBS=mongoClientLibs + mongoClientSysLibDeps, + # TODO: This currently causes the files for the libdep to get dragged into dependents + # of this shared library, incorrectly. We need to patch up libdeps to treat shared + # libraries as dependency terminals. + LIBDEPS=mongoClientLibDeps) + + mongoClientSharedLib = sharedLibEnv.SharedLibrary('mongoclient', clientObjects) + + mongoClientSharedLibInstall = sharedLibEnv.InstallVersionedLib( + '#/sharedclient', mongoClientSharedLib) + + if darwin: + # Set up the copy of the client library in #/sharedclient so that things that link + # against it record the local directory as the install_name. + sharedLibEnv.AddPostAction( + mongoClientSharedLibInstall, + "install_name_tool -id @executable_path/%s %s" % ( + mongoClientSharedLibInstall[0].name, + mongoClientSharedLibInstall[0] + )) + mongoClientInstalls.append(mongoClientSharedLibInstall) -clientTests = clientEnv.Install('#/', [ - clientEnv.Program(target, - [source, mongoclient_lib]) for (target, source) in exampleSourceMap]) + if installSetup.libraries: + mongoClientSharedLibPrefixInstall = sharedLibEnv.InstallVersionedLib( + '$INSTALL_DIR/lib', mongoClientSharedLib) + if darwin: + sharedLibEnv.AddPostAction( + mongoClientSharedLibPrefixInstall, + "install_name_tool -id %s %s" % ( + mongoClientSharedLibPrefixInstall[0], + mongoClientSharedLibPrefixInstall[0] + )) + mongoClientPrefixInstalls.append(mongoClientSharedLibPrefixInstall) + +env.Alias('mongoclient', mongoClientInstalls) + +if installSetup.headers: + for x in clientHeaderDirectories: + inst = env.Install("$INSTALL_DIR/include/mongo/" + x, + [Glob('mongo/%s*.h' % x), Glob('mongo/%s*.hpp' % x)]) + env.AddPostAction(inst, Chmod('$TARGET', 0644)) + mongoClientPrefixInstalls.append(inst) + +if installSetup.headers or installSetup.libraries: + env.Alias('install-mongoclient', mongoClientPrefixInstalls) + +clientEnv = env.Clone() +clientEnv['CPPDEFINES'].remove('MONGO_EXPOSE_MACROS') + +# Compile the example files to .o so that we can link them twice: once statically, once shared. +exampleObjMap = [(target, clientEnv.Object(source)) for (target, source) in exampleSourceMap] + +# Create an environment for linking the examples to the static library. For out of tree builds, +# we need to use LIBS. For in-tree builds we need LIBDEPS. +staticClientEnv = clientEnv.Clone() +if '_LIBDEPS' in clientEnv: + staticClientEnv.AppendUnique(LIBDEPS=[mongoClientStaticLib]) +else: + staticClientEnv.AppendUnique(LIBS=[mongoClientStaticLib]) + +# Build each statically linked client program +staticClientPrograms = [staticClientEnv.Program(target, obj) for (target, obj) in exampleObjMap] + +# Install them to the root, and append the install targets to the list of client tests +clientTests = staticClientEnv.Install("#/", staticClientPrograms) + +# Do the same for the shared library case, if we are doing that. +if buildShared: + sharedClientEnv = clientEnv.Clone() + + # Deal with the different lookup models between regular UNIX and Darwin. For regular unix, + # we can just link against the shared lib wherever it lives, and set $ORIGIN to pull the + # copy we run against from the current directory (#/sharedclient). This won't work on + # Darwin though, so to work around, we link against the staged copy of the mongoclient + # dylib in #sharedclient, which has @executable path set as its install_name. + if nix: + if darwin: + sharedClientEnv.AppendUnique( + LIBS=['mongoclient'], + LIBPATH=["#/sharedclient"] + ) + else: + sharedClientEnv.AppendUnique( + LIBS=[mongoClientSharedLib], + LINKFLAGS="-Wl,-z,origin", + RPATH=[sharedClientEnv.Literal("\\$$ORIGIN")]) + + sharedClientPrograms = [ + sharedClientEnv.Program("sharedclient/" + target, obj) for (target, obj) in exampleObjMap] + env.Depends(sharedClientPrograms, mongoClientInstalls) + + sharedClientProgramInstalls = sharedClientEnv.Install("#/sharedclient", sharedClientPrograms) + clientTests.append(sharedClientProgramInstalls) clientEnv.Alias('clientTests', clientTests, []) @@ -174,13 +310,3 @@ env.Install( '--transform distsrc/client=$CLIENT_DIST_BASENAME ' '--transform =$CLIENT_DIST_BASENAME/ ' '${TEMPFILE(SOURCES[1:])}')) - -# install -prefix = GetOption("prefix") - -env.Install(prefix + "/lib", '${LIBPREFIX}mongoclient${LIBSUFFIX}') - -for x in clientHeaderDirectories: - inst = env.Install(prefix + "/include/mongo/" + x, - [Glob('mongo/%s*.h' % x), Glob('mongo/%s*.hpp' % x)]) - env.AddPostAction(inst, Chmod('$TARGET', 0644)) diff --git a/src/mongo/SConscript b/src/mongo/SConscript index 50d4abebb8a..9f0597f62ed 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -760,9 +760,6 @@ env.Library("clientandshell", ["client/clientAndShell.cpp"], "gridfs"]) env.Library("allclient", "client/clientOnly.cpp", LIBDEPS=["clientandshell"]) -if has_option( "sharedclient" ): - sharedClientLibName = str( env.SharedLibrary( "mongoclient", [], LIBDEPS=["allclient"] )[0] ) - # dbtests test binary env.StaticLibrary('testframework', ['dbtests/framework.cpp'], LIBDEPS=['unittest/unittest']) @@ -901,20 +898,6 @@ if shellEnv is not None: env.Alias( "core", [ '#/%s' % b for b in [ add_exe( "mongo" ), add_exe( "mongod" ), add_exe( "mongos" ) ] ] ) -#headers -if installSetup.headers: - for id in [ "", "util/", "util/net/", "util/mongoutils/", "util/concurrency/", "db/", - "db/stats/", "db/repl/", "db/ops/", "client/", "bson/", "bson/util/", "s/", - "scripting/", "base/", "platform/" ]: - env.Install( "$INSTALL_DIR/include/" + id, Glob( id + "*.h" ) ) - env.Install( "$INSTALL_DIR/include/" + id, Glob( id + "*.hpp" ) ) - -#lib -if installSetup.libraries: - env.Install('$INSTALL_DIR/$NIX_LIB_DIR', '#${LIBPREFIX}mongoclient${LIBSUFFIX}') - if has_option( "sharedclient" ): - env.Install( "$INSTALL_DIR/$NIX_LIB_DIR", '#${SHLIBPREFIX}mongoclient${SHLIBSUFFIX}') - # Stage the top-level mongodb banners distsrc = env.Dir('#distsrc') env.Append(MODULE_BANNERS = [distsrc.File('README'), diff --git a/src/mongo/client/examples/httpClientTest.cpp b/src/mongo/client/examples/httpClientTest.cpp index d7d0659faa3..e7848cc42bc 100644 --- a/src/mongo/client/examples/httpClientTest.cpp +++ b/src/mongo/client/examples/httpClientTest.cpp @@ -17,6 +17,7 @@ #include <iostream> +#include "mongo/base/init.h" #include "mongo/client/dbclient.h" #include "util/net/httpclient.h" @@ -39,7 +40,13 @@ void play( string url ) { } -int main( int argc, const char **argv ) { +int main( int argc, const char **argv, char **envp) { + +#ifdef MONGO_SSL + cmdLine.sslOnNormalPorts = true; +#endif + + runGlobalInitializersOrDie(argc, argv, envp); int port = 27017; if ( argc != 1 ) { |