diff --git a/core/modules/SConscript b/core/modules/SConscript index 404e961616..3414ce2c9d 100644 --- a/core/modules/SConscript +++ b/core/modules/SConscript @@ -70,7 +70,7 @@ import state Import('env') -def standardModule(env, exclude=None, module=None, test_libs=None, unit_tests=None): +def standardModule(env, exclude=None, module=None, test_libs=None, unit_tests=None, bin_cc_files=None): """ Implementation of SConscript logic for "standard" module. @@ -95,6 +95,14 @@ def standardModule(env, exclude=None, module=None, test_libs=None, unit_tests=No then use this parameter to pass list (or space-separated string) of application names. Can be empty string or list to not run any unit tests. + @param bin_cc_files: a dictionary defining which binary products (not + the unit tests) should be built out of C/C++ files. Each key + of the dictionary is the name of a C/C++ file (with function + 'main'). This file will be excluded from the unit tests and + from a list of *.cc files which are complied into a shared + library of the module. And the corresponding value of + the dictionary is a list of libraries which are required to + build the binary. """ build_data = DefaultEnvironment()['build_data'] @@ -104,13 +112,23 @@ def standardModule(env, exclude=None, module=None, test_libs=None, unit_tests=No module = os.path.basename(os.getcwd()) state.log.debug('standardModule: module = %s path = %s' % (module, path)) + # using two optional lists provided by the nmodule to build names of + # *.cc files to be excluded from being used to build module's + # library or unit tests + exclude_cc_files = [] + if exclude is not None: + if isinstance(exclude, str): exclude_cc_files += [exclude,] + else: exclude_cc_files += exclude + if bin_cc_files is not None: exclude_cc_files += bin_cc_files.keys() + # find all *.cc files and split then in two groups: files for libraries # and files for test apps - cc_files = set(env.Glob(os.path.join(path, "*.cc"), source=True, strings=True, exclude=exclude)) + cc_files = set(env.Glob(os.path.join(path, "*.cc"), source=True, strings=True, exclude=exclude_cc_files)) cc_tests = set(fname for fname in cc_files if os.path.basename(fname).startswith("test")) # In Python3 order of set iteration is undefined, do manual sorting cc_objects = sorted(cc_files - cc_tests) cc_tests = sorted(cc_tests) + state.log.debug('standardModule: exclude_cc_files = ' + str(exclude_cc_files)) state.log.debug('standardModule: cc_objects = ' + str(cc_objects)) state.log.debug('standardModule: cc_tests = ' + str(cc_tests)) @@ -163,6 +181,12 @@ def standardModule(env, exclude=None, module=None, test_libs=None, unit_tests=No py_installed = env.Install("$prefix/bin", py_scripts) build_data['install'] += py_installed + # inject binary targets built of the optionally provided C/C++ files + if bin_cc_files is not None: + for f,dependencies in bin_cc_files.items(): + p = env.Program(f, LIBS=dependencies, LIBPATH=['$build_dir'] + env['LIBPATH']) + build_data['build_targets'] += p + build_data['install'] += env.Install("$prefix/bin", p) # ================== SConscript logic start here ==================== @@ -274,6 +298,7 @@ build_data['shlibs'] = shlibs.copy() build_data['tests'] = [] build_data['unit_tests'] = [] build_data['module_lib'] = defaultdict(lambda: None) +build_data['build_targets'] = [] # store in env so that modules can use it defEnv = DefaultEnvironment() @@ -297,7 +322,6 @@ for mod in all_modules: standardModule(env, module=mod) # define targets for shared libs -build_targets = [] for shlib, shopt in shlibs.items(): state.log.debug('defining target for ' + shlib) @@ -319,7 +343,7 @@ for shlib, shopt in shlibs.items(): pfx = shopt.get('SHLIBPREFIX', env['SHLIBPREFIX']) out = env.SharedLibrary(shlib, objects, LIBS=Split(shopt['libs']), SHLIBPREFIX=pfx, LIBPATH=libPath) - build_targets += out + build_data['build_targets'] += out # install target instDir = shopt.get('instDir', 'lib') @@ -341,11 +365,11 @@ if utests: # special builder that checks that unit tests were successful utests = env.UnitTestCheck('unit-test-check-tag', utests) -build_targets += build_data['tests'] +build_data['build_targets'] += build_data['tests'] # define/extend all aliases -state.log.debug("build targets: %s" % map(str, build_targets)) -env.Alias("build", build_targets) +state.log.debug("build targets: %s" % map(str, build_data['build_targets'])) +env.Alias("build", build_data['build_targets']) state.log.debug("install targets: %s" % map(str, build_data['install'])) env.Alias("install-notest", build_data['install']) if utests: diff --git a/core/modules/tests/SConscript b/core/modules/tests/SConscript index 5f3ff81826..66fe89e4cb 100644 --- a/core/modules/tests/SConscript +++ b/core/modules/tests/SConscript @@ -2,4 +2,23 @@ Import('env') Import('standardModule') -standardModule(env, unit_tests="") +import os.path + +# Harvest special binary products - files starting with the package's name +# followed by underscore: +# +# tests_.cc +# +# Then make a Scons target for each of those to be returned by the calling +# SConscript. Also add the source file into a list of sources to be excluded +# from the shared library product. + +bin_cc_files = {} +path = "." +for f in env.Glob(os.path.join(path, "qserv-*.cc"), source=True, strings=True): + bin_cc_files[f] = ["qserv_common","util","protobuf","log","log4cxx"] + +# Initiate the standard sequence of actions for this module by excluding +# the above discovered binary sources + +standardModule(env, bin_cc_files=bin_cc_files, unit_tests="") diff --git a/core/modules/tests/qserv-protobuf-assert-version.cc b/core/modules/tests/qserv-protobuf-assert-version.cc new file mode 100644 index 0000000000..d82270ccb9 --- /dev/null +++ b/core/modules/tests/qserv-protobuf-assert-version.cc @@ -0,0 +1,49 @@ +/* + * LSST Data Management System + * Copyright 2009-2018 AURA/LSST. + * + * This product includes software developed by the + * LSST Project (http://www.lsst.org/). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the LSST License Statement and + * the GNU General Public License along with this program. If not, + * see . + */ + +// System headers + +// Third-party headers + +// LSST headers +#include "lsst/log/Log.h" + +// Qserv headers +#include "proto/worker.pb.h" + +namespace { +LOG_LOGGER _log = LOG_GET("lsst.qserv.tests.tests_protobuf_version"); +} + +int main (int arc, char const* argv[]) { + + LOGS(_log, LOG_LVL_INFO, "testing a version of the Protobuf library"); + + // Verify that the version of the library that we linked against is + // compatible with the version of the headers we compiled against. + + GOOGLE_PROTOBUF_VERIFY_VERSION; + + LOGS(_log, LOG_LVL_INFO, "success"); + + return 0; +}