Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 31 additions & 7 deletions core/modules/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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']
Expand All @@ -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))

Expand Down Expand Up @@ -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 ====================

Expand Down Expand Up @@ -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()
Expand All @@ -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)
Expand All @@ -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')
Expand All @@ -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:
Expand Down
21 changes: 20 additions & 1 deletion core/modules/tests/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -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_<something>.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="")
49 changes: 49 additions & 0 deletions core/modules/tests/qserv-protobuf-assert-version.cc
Original file line number Diff line number Diff line change
@@ -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 <http://www.lsstcorp.org/LegalNotices/>.
*/

// 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;
}