summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morrow <acm@10gen.com>2013-05-21 21:07:48 -0400
committerAndrew Morrow <acm@10gen.com>2013-06-03 20:21:13 -0400
commitda8c0fa929eeb03dbe3fb0533874de31da0bc8c8 (patch)
treec303beed34a3e80e0e77092cd4eaab7b105836c0
parent9b148b0419d79f7173d0e972e8427fea67f77616 (diff)
downloadmongo-da8c0fa929eeb03dbe3fb0533874de31da0bc8c8.tar.gz
SERVER-6514 Re-add support for building the C++ driver shared library
-rw-r--r--.gitignore1
-rw-r--r--SConscript.smoke26
-rw-r--r--SConstruct13
-rwxr-xr-xbuildscripts/smoke.py6
-rwxr-xr-xdistsrc/client/SConstruct36
-rw-r--r--src/SConscript.client176
-rw-r--r--src/mongo/SConscript17
-rw-r--r--src/mongo/client/examples/httpClientTest.cpp9
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 ) {