-
Notifications
You must be signed in to change notification settings - Fork 16
extedended main SConscript to support building executables of C++ cod… #375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
86d2b63
e15005e
cd5b0db
ba1bfb2
6860c84
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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_targets=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_targets: a dictionary defining whgich binary products (not | ||
| the unit tests should be built out of C/C++ files. Each key | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Opening parenthesis on previous line is not closed, I guess it should go after "tests".
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
| 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: | ||
| exclude_cc_files = exclude | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. My Python is rusty :-) |
||
| if bin_cc_targets is not None: | ||
| for f in bin_cc_targets: exclude_cc_files.append(f) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed |
||
|
|
||
| # 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,18 @@ 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_targets is not None: | ||
| for f,dependencies in bin_cc_targets.items(): | ||
| source = os.path.basename(str(f)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you need basename for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. No need. I will eliminate it. |
||
| target = source[:-3] | ||
| p = env.Program( | ||
| target=target, | ||
| source=[source], | ||
| LIBS=dependencies, | ||
| LIBPATH=['$build_dir'] + env['LIBPATH']) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks a bit complicated, I'd think this should work:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will give it a try, and if it works then I'll make mods to the code. |
||
| build_data['build_targets'] += p | ||
| build_data['install'] += env.Install("$prefix/bin", p) | ||
|
|
||
| # ================== SConscript logic start here ==================== | ||
|
|
||
|
|
@@ -274,6 +304,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 +328,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 +349,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 +371,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: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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_targets = {} | ||
| path = "." | ||
| for f in env.Glob(os.path.join(path, "tests_*.cc"), source=True, strings=True): | ||
| bin_cc_targets[f] = ["qserv_common","util","protobuf","log","log4cxx"] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't overdo it. Normally all "test*.cc" files are (unit) tests and we don't want their binaries installed so don't try to make all test_*.cc into true binaries. I'd probably give it different name, not starting with "test". I believe you can also write:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps we should come up with some naming convention for the binaries. Something like: qserv--.cc. For instance my only app module tests should be renamed from "tests_protobuf_version.cc" into "qserv-tests-protobuf.cc". And I agree about avoiding using "test*" in apps names". I just wanted to see if my implementation of standardModule would work. And thanks for the advice to replace a list of dependencies with a string. I'll give it a try. |
||
|
|
||
| # Initiate the standard sequence of actions for this module by excluding | ||
| # the above discovered binary sources | ||
|
|
||
| standardModule(env, bin_cc_targets=bin_cc_targets, unit_tests="") | ||
| 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; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whgich -> which
Not shure
targetshas a meaning here. The key in dict is a name of the source, not target?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll come up with a better name