build: align minimum build dependencies with ndn-cxx

* Recommend boost >= 1.65.1 and gcc >= 7.4.0
 * Require clang >= 4.0, or Xcode >= 9.0 on macOS
 * Silence an ABI-related diagnostic message from gcc on armv7
 * Fix redundant-tags warning with gcc 10
 * Add CentOS-specific instructions to docs/INSTALL.rst
 * Add Xcode 11.5 to Travis CI

Refs: #5087, #5106
Change-Id: I70746729a132ecb07d4788934385bb403039dba9
This commit is contained in:
Davide Pesavento committed 2020-05-15 14:25:26 -04:00
1 parent 4995bf960d
commit 1752159ae0
15 files changed
+142 -461

No files matched your search

+5 -15
View File
@@ -10,21 +10,6 @@ fi
ndnsec-keygen "/tmp/jenkins/$NODE_NAME" | ndnsec-install-cert -
BOOST_VERSION=$(python3 -c "import sys; sys.path.append('build/c4che'); import _cache; print(_cache.BOOST_VERSION_NUMBER);")
ut_log_args() {
if (( BOOST_VERSION >= 106200 )); then
echo --logger=HRF,test_suite,stdout:XML,all,build/xunit-${1:-report}.xml
else
if [[ -n $XUNIT ]]; then
echo --log_level=all $( (( BOOST_VERSION >= 106000 )) && echo -- ) \
--log_format2=XML --log_sink2=build/xunit-${1:-report}.xml
else
echo --log_level=test_suite
fi
fi
}
# https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
ASAN_OPTIONS="color=always"
ASAN_OPTIONS+=":check_initialization_order=1"
@@ -39,6 +24,11 @@ export ASAN_OPTIONS
export BOOST_TEST_BUILD_INFO=1
export BOOST_TEST_COLOR_OUTPUT=1
export BOOST_TEST_DETECT_MEMORY_LEAK=0
ut_log_args() {
echo --logger=HRF,test_suite,stdout:XML,all,build/xunit-log${1:+-$1}.xml
}
# First run all tests as unprivileged user
./build/unit-tests-core $(ut_log_args core)
+9
View File
@@ -18,7 +18,10 @@ env:
jobs:
include:
# Linux
- env: COMPILER=g++-5
- env: COMPILER=g++-6
- env: COMPILER=g++-8
- env: COMPILER=clang++-4.0
- env: COMPILER=clang++-5.0
- env: COMPILER=clang++-7
- env: COMPILER=clang++-8
@@ -38,8 +41,14 @@ jobs:
- os: osx
osx_image: xcode11.3
env: # default compiler
- os: osx
osx_image: xcode11.5
env: # default compiler
allow_failures:
- env: COMPILER=g++-5
- env: COMPILER=g++-6
- env: COMPILER=clang++-4.0
- env: COMPILER=clang++-11
fast_finish: true
-30
View File
@@ -1,30 +0,0 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
"""
Copyright (c) 2014-2016, Regents of the University of California,
Arizona Board of Regents,
Colorado State University,
University Pierre & Marie Curie, Sorbonne University,
Washington University in St. Louis,
Beijing Institute of Technology,
The University of Memphis.
This file is part of NFD (Named Data Networking Forwarding Daemon).
See AUTHORS.md for complete list of NFD authors and contributors.
NFD 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.
NFD 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 GNU General Public License along with
NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
"""
from waflib.Configure import conf
def configure(conf):
pass
+34 -23
View File
@@ -1,10 +1,11 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
import platform
from waflib import Configure, Logs, Utils
def options(opt):
opt.add_option('--debug', '--with-debug', action='store_true', default=False,
help='Compile in debugging mode with minimal optimizations (-O0 or -Og)')
help='Compile in debugging mode with minimal optimizations (-Og)')
def configure(conf):
conf.start_msg('Checking C++ compiler version')
@@ -17,15 +18,21 @@ def configure(conf):
if cxx == 'gcc':
if ccver < (5, 3, 0):
errmsg = ('The version of gcc you are using is too old.\n'
'The minimum supported gcc version is 5.3.0.')
'The minimum supported gcc version is 7.4.0.')
elif ccver < (7, 4, 0):
warnmsg = ('Using a version of gcc older than 7.4.0 is not '
'officially supported and may result in build failures.')
conf.flags = GccFlags()
elif cxx == 'clang':
if ccver < (3, 6, 0):
if Utils.unversioned_sys_platform() == 'darwin' and ccver < (9, 0, 0):
errmsg = ('The version of Xcode you are using is too old.\n'
'The minimum supported Xcode version is 9.0.')
elif ccver < (4, 0, 0):
errmsg = ('The version of clang you are using is too old.\n'
'The minimum supported clang version is 3.6.0.')
'The minimum supported clang version is 4.0.')
conf.flags = ClangFlags()
else:
warnmsg = 'Note: %s compiler is unsupported' % cxx
warnmsg = '%s compiler is unsupported' % cxx
conf.flags = CompilerFlags()
if errmsg:
@@ -33,7 +40,7 @@ def configure(conf):
conf.fatal(errmsg)
elif warnmsg:
conf.end_msg(ccverstr, color='YELLOW')
Logs.warn(warnmsg)
Logs.warn('WARNING: ' + warnmsg)
else:
conf.end_msg(ccverstr)
@@ -137,13 +144,14 @@ class GccBasicFlags(CompilerFlags):
def getDebugFlags(self, conf):
flags = super(GccBasicFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-O0',
'-Og', # gcc >= 4.8, clang >= 4.0
flags['CXXFLAGS'] += ['-Og',
'-g3',
'-pedantic',
'-Wall',
'-Wextra',
'-Werror',
'-Wcatch-value=2',
'-Wextra-semi',
'-Wnon-virtual-dtor',
'-Wno-error=deprecated-declarations', # Bug #3795
'-Wno-error=maybe-uninitialized', # Bug #1615
@@ -159,6 +167,8 @@ class GccBasicFlags(CompilerFlags):
'-pedantic',
'-Wall',
'-Wextra',
'-Wcatch-value=2',
'-Wextra-semi',
'-Wnon-virtual-dtor',
'-Wno-unused-parameter',
]
@@ -168,49 +178,50 @@ class GccBasicFlags(CompilerFlags):
class GccFlags(GccBasicFlags):
def getDebugFlags(self, conf):
flags = super(GccFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-fdiagnostics-color']
flags['CXXFLAGS'] += ['-fdiagnostics-color',
'-Wredundant-tags',
]
if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
return flags
def getOptimizedFlags(self, conf):
flags = super(GccFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fdiagnostics-color']
flags['CXXFLAGS'] += ['-fdiagnostics-color',
'-Wredundant-tags',
]
if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
return flags
class ClangFlags(GccBasicFlags):
def getGeneralFlags(self, conf):
flags = super(ClangFlags, self).getGeneralFlags(conf)
if Utils.unversioned_sys_platform() == 'darwin' and self.getCompilerVersion(conf) >= (9, 0, 0):
if Utils.unversioned_sys_platform() == 'darwin':
# Bug #4296
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
['-isystem', '/opt/local/include']] # for MacPorts
if Utils.unversioned_sys_platform() == 'freebsd':
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']] # Bug #4790
elif Utils.unversioned_sys_platform() == 'freebsd':
# Bug #4790
flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']]
return flags
def getDebugFlags(self, conf):
flags = super(ClangFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wextra-semi',
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
version = self.getCompilerVersion(conf)
if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
if version < (6, 0, 0):
if self.getCompilerVersion(conf) < (6, 0, 0):
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
return flags
def getOptimizedFlags(self, conf):
flags = super(ClangFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
'-Wextra-semi',
'-Wundefined-func-template',
'-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
version = self.getCompilerVersion(conf)
if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (8, 1, 0)):
flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
if version < (6, 0, 0):
if self.getCompilerVersion(conf) < (6, 0, 0):
flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
return flags
+5 -6
View File
@@ -1,7 +1,7 @@
# Notes for NFD developers
If you are new to the NDN software community, please read the
[Contributor's Guide](https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md).
[Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md).
## Code style
@@ -61,12 +61,12 @@ The simplest way to run the tests is to launch the compiled binary without any p
# Run NFD RIB management tests
./build/unit-tests-rib
[Boost.Test framework](https://www.boost.org/doc/libs/1_58_0/libs/test/doc/html/index.html)
The [Boost.Test framework](https://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/index.html)
is very flexible and allows a number of run-time customization of what tests should be run.
For example, it is possible to choose to run only a specific test suite, only a specific
test case within a suite, or specific test cases within specific test suites:
# Run only TCP Face test suite of NFD daemon tests (see tests/daemon/face/tcp.cpp)
# Run only the TCP Face test suite of NFD daemon tests
./build/unit-tests-daemon -t FaceTcp
# Run only test case EndToEnd4 from the same test suite
@@ -93,6 +93,5 @@ or `-p` to show a progress bar:
./build/unit-tests-core -p
There are many more command line options available, information about which can be obtained
either from the command line using `--help` switch, or online on
[Boost.Test library](https://www.boost.org/doc/libs/1_58_0/libs/test/doc/html/index.html)
website.
either from the command line using the `--help` switch, or online on the
[Boost.Test website](https://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/index.html).
+6 -5
View File
@@ -44,11 +44,12 @@ it already contains significant contributions from people outside the project te
since broader community support is key for NDN to succeed as a new Internet architecture.
If you are new to the NDN software community, please read [`README-dev.md`](README-dev.md)
and the [Contributor's Guide](CONTRIBUTING.md) to get started.
and the [Contributor's Guide](https://github.com/named-data/.github/blob/master/CONTRIBUTING.md)
to get started.
## License
NFD is an open and free software package licensed under the GPL version 3 and is the
centerpiece of our committement to making NDN's core technology open and free to all
Internet users and developers. For more information about the licensing details and
limitations, refer to [`COPYING.md`](COPYING.md).
NFD is a free and open-source software package licensed under the GPL version 3 and
is the centerpiece of our committement to making NDN's core technology free and open
to all Internet users and developers. For more information about licensing, refer to
[`COPYING.md`](COPYING.md).
+2 -2
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2020, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -74,8 +74,8 @@
#include <boost/asio.hpp>
#include <boost/assert.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
#include <boost/property_tree/ptree.hpp>
namespace nfd {
+13 -17
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2020, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -63,25 +63,23 @@ PrivilegeHelper::initialize(const std::string& userName, const std::string& grou
groupSize = FALLBACK_GROUP_BUFFER_SIZE;
std::vector<char> groupBuffer(static_cast<size_t>(groupSize));
struct group group;
struct group* groupResult = nullptr;
group gr;
group* grResult = nullptr;
int errorCode = getgrnam_r(groupName.data(), &group,
groupBuffer.data(), groupBuffer.size(), &groupResult);
int errorCode = getgrnam_r(groupName.data(), &gr, groupBuffer.data(), groupBuffer.size(), &grResult);
while (errorCode == ERANGE) {
if (groupBuffer.size() * 2 > MAX_GROUP_BUFFER_SIZE)
throw Error("Cannot allocate large enough buffer for struct group");
groupBuffer.resize(groupBuffer.size() * 2);
errorCode = getgrnam_r(groupName.data(), &group,
groupBuffer.data(), groupBuffer.size(), &groupResult);
errorCode = getgrnam_r(groupName.data(), &gr, groupBuffer.data(), groupBuffer.size(), &grResult);
}
if (errorCode != 0 || !groupResult)
if (errorCode != 0 || !grResult)
throw Error("Failed to get gid for \"" + groupName + "\"");
s_normalGid = group.gr_gid;
s_normalGid = gr.gr_gid;
}
if (!userName.empty()) {
@@ -91,25 +89,23 @@ PrivilegeHelper::initialize(const std::string& userName, const std::string& grou
passwdSize = FALLBACK_PASSWD_BUFFER_SIZE;
std::vector<char> passwdBuffer(static_cast<size_t>(passwdSize));
struct passwd passwd;
struct passwd* passwdResult = nullptr;
passwd pw;
passwd* pwResult = nullptr;
int errorCode = getpwnam_r(userName.data(), &passwd,
passwdBuffer.data(), passwdBuffer.size(), &passwdResult);
int errorCode = getpwnam_r(userName.data(), &pw, passwdBuffer.data(), passwdBuffer.size(), &pwResult);
while (errorCode == ERANGE) {
if (passwdBuffer.size() * 2 > MAX_PASSWD_BUFFER_SIZE)
throw Error("Cannot allocate large enough buffer for struct passwd");
passwdBuffer.resize(passwdBuffer.size() * 2);
errorCode = getpwnam_r(userName.data(), &passwd,
passwdBuffer.data(), passwdBuffer.size(), &passwdResult);
errorCode = getpwnam_r(userName.data(), &pw, passwdBuffer.data(), passwdBuffer.size(), &pwResult);
}
if (errorCode != 0 || !passwdResult)
if (errorCode != 0 || !pwResult)
throw Error("Failed to get uid for \"" + userName + "\"");
s_normalUid = passwd.pw_uid;
s_normalUid = pw.pw_uid;
}
#else
if (!userName.empty() || !groupName.empty()) {
+32 -26
View File
@@ -1,4 +1,4 @@
Getting Started with NFD
Getting started with NFD
========================
Supported platforms
@@ -7,19 +7,20 @@ Supported platforms
NFD is built against a continuous integration system and has been tested on the
following platforms:
- Ubuntu 16.04 (amd64)
- Ubuntu 18.04 (amd64, armhf, i386)
- Ubuntu 19.10 (amd64)
- Ubuntu 20.04 (amd64)
- macOS 10.13
- macOS 10.14
- macOS 10.15
- CentOS 8
NFD is known to work on the following platforms, although they are not officially
supported:
- Debian >= 9
- Debian 10 (Buster)
- Fedora >= 29
- Gentoo Linux
- Raspbian >= 2017-08-16
- Raspbian >= 2019-06-20 (Buster)
.. _Install NFD on Ubuntu Linux using the NDN PPA repository:
@@ -98,14 +99,19 @@ On Linux, NFD needs the following dependencies to enable optional features:
- On Ubuntu::
sudo apt install libpcap-dev libsystemd-dev
sudo apt install libpcap-dev libsystemd-dev
- On CentOS and Fedora::
sudo dnf config-manager --enable PowerTools # on CentOS only
sudo dnf install libpcap-devel systemd-devel
Build
~~~~~
The following commands can be used to build and install NFD from source::
./waf configure
./waf configure # on CentOS, add --without-pch
./waf
sudo ./waf install
@@ -128,12 +134,12 @@ Refer to ``./waf --help`` for more options that can be used during the ``configu
Debug symbols
~~~~~~~~~~~~~
The default compiler flags enable debug symbols to be included in binaries. This should
provide more meaningful debugging information if NFD or other tools happen to crash.
The default compiler flags include debug symbols in binaries. This should provide
more meaningful debugging information if NFD or other tools happen to crash.
If this is undesirable, the default flags can be overridden to disable debug symbols.
The following example shows how to completely disable debug symbols and configure NFD
to be installed into ``/usr`` with configuration in the ``/etc`` directory.
If this is not desired, the default flags can be overridden to disable debug symbols.
The following example shows how to completely disable debug symbols and configure
NFD to be installed into ``/usr`` with configuration in the ``/etc`` directory.
::
@@ -155,7 +161,7 @@ with clang on Linux, use the following::
Building the documentation
~~~~~~~~~~~~~~~~~~~~~~~~~~
NFD tutorials and API documentation can be built using the following commands::
Tutorials and API documentation can be built using the following commands::
# Full set of documentation (tutorials + API) in build/docs
./waf docs
@@ -166,13 +172,14 @@ NFD tutorials and API documentation can be built using the following commands::
# Only API docs in build/docs/doxygen
./waf doxygen
If ``sphinx-build`` is detected during ``./waf configure``, manpages are automatically
built and installed during the normal build process (i.e., during ``./waf`` and ``./waf
install``). By default, manpages are installed into ``${PREFIX}/share/man`` (the default
value for ``PREFIX`` is ``/usr/local``). This location can be changed during the ``./waf
configure`` stage using the ``--prefix``, ``--datarootdir``, or ``--mandir`` options.
If ``sphinx-build`` is detected during ``./waf configure``, manpages will automatically
be built and installed during the normal build process (i.e., during ``./waf`` and
``./waf install``). By default, manpages will be installed into ``${PREFIX}/share/man``
(the default value for ``PREFIX`` is ``/usr/local``). This location can be changed
during the ``./waf configure`` stage using the ``--prefix``, ``--datarootdir``, or
``--mandir`` options.
For more details, please refer to ``./waf --help``.
For further details, please refer to ``./waf --help``.
Initial configuration
---------------------
@@ -261,14 +268,13 @@ of NDN using the following applications and libraries.
Sample applications:
+ `Simple examples using the ndn-cxx library <https://named-data.net/doc/ndn-cxx/current/examples.html>`_
+ `Simple examples using the ndn-cxx library <https://named-data.net/doc/ndn-cxx/current/examples.html>`__
+ `Introductory examples of NDN-CCL
<https://redmine.named-data.net/projects/application-development-documentation-guides/wiki/Step-By-Step_-_Common_Client_Libraries>`_
<https://redmine.named-data.net/projects/application-development-documentation-guides/wiki/Step-By-Step_-_Common_Client_Libraries>`__
Real applications and libraries:
+ `ndn-tools - Essential NDN command-line tools <https://github.com/named-data/ndn-tools>`_
+ `ndn-traffic-generator - Traffic generator for NDN <https://github.com/named-data/ndn-traffic-generator>`_
+ `repo-ng - Next generation NDN repository <https://github.com/named-data/repo-ng>`_
+ `ChronoSync - Sync library for multi-user real-time applications <https://github.com/named-data/ChronoSync>`_
+ `PSync - Partial and full synchronization library <https://github.com/named-data/PSync>`_
+ `ndn-tools - Essential NDN command-line tools <https://github.com/named-data/ndn-tools>`__
+ `ndn-traffic-generator - Traffic generator for NDN <https://github.com/named-data/ndn-traffic-generator>`__
+ `ChronoSync - Sync library for multi-user real-time applications <https://github.com/named-data/ChronoSync>`__
+ `PSync - Partial and full synchronization library <https://github.com/named-data/PSync>`__
+10 -11
View File
@@ -40,24 +40,23 @@ NFD Documentation
**Additional documentation**
* `NFD Developer's Guide <https://named-data.net/wp-content/uploads/2016/10/ndn-0021-7-nfd-developer-guide.pdf>`_
* `NFD Developer's Guide <https://named-data.net/publications/techreports/ndn-0021-10-nfd-developer-guide/>`__
A comprehensive guide to the design and implementation of NFD. The developer's guide also contains
suggestions and hints for anyone wanting to modify or extend NFD.
* `NDN Software Contributor's Guide
<https://github.com/named-data/NFD/blob/master/CONTRIBUTING.md>`__
* `NDN Software Contributor's Guide <https://github.com/named-data/.github/blob/master/CONTRIBUTING.md>`__
(guide for newcomers to the NDN community of software)
* `NFD Wiki <https://redmine.named-data.net/projects/nfd/wiki>`_
* `NFD Wiki <https://redmine.named-data.net/projects/nfd/wiki>`__
+ `NFD Management protocol <https://redmine.named-data.net/projects/nfd/wiki/Management>`_
+ `NFD Configuration file format <https://redmine.named-data.net/projects/nfd/wiki/ConfigFileFormat>`_
+ `NFD Management protocol <https://redmine.named-data.net/projects/nfd/wiki/Management>`__
+ `NFD Configuration file format <https://redmine.named-data.net/projects/nfd/wiki/ConfigFileFormat>`__
The NFD Wiki contains detailed protocol specifications and
information for building on unsupported platforms.
* `API Documentation (doxygen) <doxygen/annotated.html>`_
* `API Documentation (doxygen) <doxygen/annotated.html>`__
* :doc:`RELEASE_NOTES`
@@ -66,7 +65,7 @@ NFD Documentation
License
-------
NFD is an open and free software package licensed under GPL 3.0 license and is the
centerpiece of our committement to making NDN's core technology open and free to all
Internet users and developers. For more information about the licensing details and
limitation, refer to `COPYING.md <https://github.com/named-data/NFD/blob/master/COPYING.md>`_.
NFD is a free and open-source software package licensed under the GPL version 3 and
is the centerpiece of our committement to making NDN's core technology free and open
to all Internet users and developers. For more information about licensing, refer to
`COPYING.md <https://github.com/named-data/NFD/blob/master/COPYING.md>`__.
+1 -1
View File
@@ -38,7 +38,7 @@
<h3>{{ _('Table Of Contents') }}</h3>
{{ toctree(includehidden=True) }}
<h3>{{ _('Additional documenation') }}</h3>
<h3>{{ _('Additional documentation') }}</h3>
<ul>
<li class="toctree-l1"><a class="reference external" href="https://redmine.named-data.net/projects/nfd/wiki">NFD Wiki</a></li>
<li class="toctree-l1"><a class="reference internal" href="doxygen/annotated.html">API documentation (doxygen)</a></li>
-214
View File
@@ -1,214 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2015 Regents of the University of California.
*
* Based on work by Martin Ba (http://stackoverflow.com/a/26718189)
*
* This file is distributed under the Boost Software License, Version 1.0.
* (See http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
#define NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
#include <boost/version.hpp>
#if BOOST_VERSION >= 105900
#include <boost/test/unit_test_parameters.hpp>
#else
#include <boost/test/detail/unit_test_parameters.hpp>
#endif // BOOST_VERSION >= 105900
#include <boost/test/unit_test_log_formatter.hpp>
#include <boost/test/output/compiler_log_formatter.hpp>
#include <boost/test/output/xml_log_formatter.hpp>
namespace boost {
namespace unit_test {
namespace output {
/**
* @brief Log formatter for Boost.Test that outputs the logging to multiple formatters
*
* The log formatter is designed to output to one or multiple formatters at the same time. For
* example, one HRF formatter can output to the standard output, while XML formatter output to
* the file.
*
* Usage:
*
* // Call in init_unit_test_suite: (this will override the --log_format parameter)
* auto formatter = new boost::unit_test::output::multi_log_formatter; // same as already configured logger
*
* // Prepare and add additional logger(s)
* formatter.add(std::make_shared<boost::unit_test::output::xml_log_formatter>(),
* std::make_shared<std::ofstream>("out.xml"));
*
* boost::unit_test::unit_test_log.set_formatter(formatter);
*
* @note Calling `boost::unit_test::unit_test_log.set_stream(...)` will change the stream for
* the original logger.
*/
class multi_log_formatter : public unit_test_log_formatter
{
public:
/**
* @brief Create instance of the logger, based on the configured logger instance
*/
multi_log_formatter()
{
auto format =
#if BOOST_VERSION > 105900
runtime_config::get<output_format>(runtime_config::LOG_FORMAT);
#else
runtime_config::log_format();
#endif // BOOST_VERSION > 105900
switch (format) {
default:
#if BOOST_VERSION >= 105900
case OF_CLF:
#else
case CLF:
#endif // BOOST_VERSION >= 105900
m_loggers.push_back({std::make_shared<compiler_log_formatter>(), nullptr});
break;
#if BOOST_VERSION >= 105900
case OF_XML:
#else
case XML:
#endif // BOOST_VERSION >= 105900
m_loggers.push_back({std::make_shared<xml_log_formatter>(), nullptr});
break;
}
}
void
add(std::shared_ptr<unit_test_log_formatter> formatter, std::shared_ptr<std::ostream> os)
{
m_loggers.push_back({formatter, os});
}
// Formatter interface
void
log_start(std::ostream& os, counter_t test_cases_amount)
{
for (auto& l : m_loggers)
l.logger->log_start(l.os == nullptr ? os : *l.os, test_cases_amount);
}
void
log_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_finish(l.os == nullptr ? os : *l.os);
}
void
log_build_info(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_build_info(l.os == nullptr ? os : *l.os);
}
void
test_unit_start(std::ostream& os, const test_unit& tu)
{
for (auto& l : m_loggers)
l.logger->test_unit_start(l.os == nullptr ? os : *l.os, tu);
}
void
test_unit_finish(std::ostream& os, const test_unit& tu, unsigned long elapsed)
{
for (auto& l : m_loggers)
l.logger->test_unit_finish(l.os == nullptr ? os : *l.os, tu, elapsed);
}
void
test_unit_skipped(std::ostream& os, const test_unit& tu)
{
for (auto& l : m_loggers)
l.logger->test_unit_skipped(l.os == nullptr ? os : *l.os, tu);
}
#if BOOST_VERSION >= 105900
void
log_exception_start(std::ostream& os, const log_checkpoint_data& lcd, const execution_exception& ex)
{
for (auto& l : m_loggers)
l.logger->log_exception_start(l.os == nullptr ? os : *l.os, lcd, ex);
}
void
log_exception_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_exception_finish(l.os == nullptr ? os : *l.os);
}
#else
void
log_exception(std::ostream& os, const log_checkpoint_data& lcd, const execution_exception& ex)
{
for (auto& l : m_loggers)
l.logger->log_exception(l.os == nullptr ? os : *l.os, lcd, ex);
}
#endif // BOOST_VERSION >= 105900
void
log_entry_start(std::ostream& os, const log_entry_data& entry_data, log_entry_types let)
{
for (auto& l : m_loggers)
l.logger->log_entry_start(l.os == nullptr ? os : *l.os, entry_data, let);
}
void
log_entry_value(std::ostream& os, const_string value)
{
for (auto& l : m_loggers)
l.logger->log_entry_value(l.os == nullptr ? os : *l.os, value);
}
void
log_entry_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->log_entry_finish(l.os == nullptr ? os : *l.os);
}
#if BOOST_VERSION >= 105900
void
entry_context_start(std::ostream& os, log_level level)
{
for (auto& l : m_loggers)
l.logger->entry_context_start(l.os == nullptr ? os : *l.os, level);
}
void
log_entry_context(std::ostream& os, const_string value)
{
for (auto& l : m_loggers)
l.logger->log_entry_context(l.os == nullptr ? os : *l.os, value);
}
void
entry_context_finish(std::ostream& os)
{
for (auto& l : m_loggers)
l.logger->entry_context_finish(l.os == nullptr ? os : *l.os);
}
#endif // BOOST_VERSION >= 105900
private:
struct LoggerInfo
{
std::shared_ptr<unit_test_log_formatter> logger;
std::shared_ptr<std::ostream> os;
};
std::vector<LoggerInfo> m_loggers;
};
} // namespace output
} // namespace unit_test
} // namespace boost
#endif // NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
+1 -88
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Copyright (c) 2014-2020, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -24,91 +24,4 @@
*/
// BOOST_TEST_MODULE is defined in tests/wscript
#include <boost/version.hpp>
#if BOOST_VERSION >= 106200
// Boost.Test v3.3 (Boost 1.62) natively supports multi-logger output
#include "boost-test.hpp"
#else
#define BOOST_TEST_ALTERNATIVE_INIT_API
#define BOOST_TEST_NO_MAIN
#include "boost-test.hpp"
#include "boost-multi-log-formatter.hpp"
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>
#include <fstream>
#include <iostream>
static bool
init_tests()
{
init_unit_test();
namespace po = boost::program_options;
namespace ut = boost::unit_test;
po::options_description extraOptions;
std::string logger;
std::string outputFile = "-";
extraOptions.add_options()
("log_format2", po::value<std::string>(&logger), "Type of second log formatter: HRF or XML")
("log_sink2", po::value<std::string>(&outputFile)->default_value(outputFile), "Second log sink, - for stdout")
;
po::variables_map vm;
try {
po::store(po::command_line_parser(ut::framework::master_test_suite().argc,
ut::framework::master_test_suite().argv)
.options(extraOptions)
.run(),
vm);
po::notify(vm);
}
catch (const std::exception& e) {
std::cerr << "ERROR: " << e.what() << "\n"
<< extraOptions << std::endl;
return false;
}
if (vm.count("log_format2") == 0) {
// second logger is not configured
return true;
}
std::shared_ptr<ut::unit_test_log_formatter> formatter;
if (logger == "XML") {
formatter = std::make_shared<ut::output::xml_log_formatter>();
}
else if (logger == "HRF") {
formatter = std::make_shared<ut::output::compiler_log_formatter>();
}
else {
std::cerr << "ERROR: only HRF or XML log formatter can be specified" << std::endl;
return false;
}
std::shared_ptr<std::ostream> output;
if (outputFile == "-") {
output = std::shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
}
else {
output = std::make_shared<std::ofstream>(outputFile.c_str());
}
auto multiFormatter = new ut::output::multi_log_formatter;
multiFormatter->add(formatter, output);
ut::unit_test_log.set_formatter(multiFormatter);
return true;
}
int
main(int argc, char* argv[])
{
return ::boost::unit_test::unit_test_main(&init_tests, argc, argv);
}
#endif // BOOST_VERSION >= 106200
+3 -6
View File
@@ -1,6 +1,6 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
"""
Copyright (c) 2014-2019, Regents of the University of California,
Copyright (c) 2014-2020, Regents of the University of California,
Arizona Board of Regents,
Colorado State University,
University Pierre & Marie Curie, Sorbonne University,
@@ -39,15 +39,12 @@ def build(bld):
headers='../core/common.hpp boost-test.hpp',
defines=[config_path])
for module, name in {'core': 'Core Tests',
'daemon': 'Daemon Tests',
'rib': 'RIB Tests',
'tools': 'Tools Tests'}.items():
for module in ['core', 'daemon', 'rib', 'tools']:
# main() for the module
bld.objects(target='unit-tests-%s-main' % module,
source='main.cpp',
use='BOOST',
defines=['BOOST_TEST_MODULE=%s' % name])
defines=['BOOST_TEST_MODULE=NFD %s' % module.capitalize()])
subdir = 'daemon/rib' if module == 'rib' else module
node = bld.path.find_dir(subdir)
+21 -17
View File
@@ -1,6 +1,6 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
"""
Copyright (c) 2014-2019, Regents of the University of California,
Copyright (c) 2014-2020, Regents of the University of California,
Arizona Board of Regents,
Colorado State University,
University Pierre & Marie Curie, Sorbonne University,
@@ -34,27 +34,27 @@ GIT_TAG_PREFIX = 'NFD-'
def options(opt):
opt.load(['compiler_cxx', 'gnu_dirs'])
opt.load(['default-compiler-flags', 'compiler-features',
opt.load(['default-compiler-flags',
'coverage', 'pch', 'sanitizers', 'boost',
'dependency-checker', 'unix-socket', 'websocket',
'doxygen', 'sphinx_build'],
tooldir=['.waf-tools'])
nfdopt = opt.add_option_group('NFD Options')
optgrp = opt.add_option_group('NFD Options')
opt.addUnixOptions(nfdopt)
opt.addDependencyOptions(nfdopt, 'libresolv')
opt.addDependencyOptions(nfdopt, 'librt')
opt.addDependencyOptions(nfdopt, 'libpcap')
nfdopt.add_option('--without-libpcap', action='store_true', default=False,
opt.addUnixOptions(optgrp)
opt.addDependencyOptions(optgrp, 'libresolv')
opt.addDependencyOptions(optgrp, 'librt')
opt.addDependencyOptions(optgrp, 'libpcap')
optgrp.add_option('--without-libpcap', action='store_true', default=False,
help='Disable libpcap (Ethernet face support will be disabled)')
nfdopt.add_option('--without-systemd', action='store_true', default=False,
optgrp.add_option('--without-systemd', action='store_true', default=False,
help='Disable systemd integration')
opt.addWebsocketOptions(nfdopt)
opt.addWebsocketOptions(optgrp)
nfdopt.add_option('--with-tests', action='store_true', default=False,
optgrp.add_option('--with-tests', action='store_true', default=False,
help='Build unit tests')
nfdopt.add_option('--with-other-tests', action='store_true', default=False,
optgrp.add_option('--with-other-tests', action='store_true', default=False,
help='Build other tests')
PRIVILEGE_CHECK_CODE = '''
@@ -84,8 +84,8 @@ int main()
def configure(conf):
conf.load(['compiler_cxx', 'gnu_dirs',
'default-compiler-flags', 'compiler-features',
'pch', 'boost', 'dependency-checker', 'websocket',
'default-compiler-flags', 'boost',
'pch', 'dependency-checker', 'websocket',
'doxygen', 'sphinx_build'])
conf.env.WITH_TESTS = conf.options.with_tests
@@ -114,9 +114,13 @@ def configure(conf):
conf.check_boost(lib=boost_libs, mt=True)
if conf.env.BOOST_VERSION_NUMBER < 105800:
conf.fatal('Minimum required Boost version is 1.58.0\n'
'Please upgrade your distribution or manually install a newer version of Boost'
' (https://redmine.named-data.net/projects/nfd/wiki/Boost_FAQ)')
conf.fatal('The minimum supported version of Boost is 1.65.1.\n'
'Please upgrade your distribution or manually install a newer version of Boost.\n'
'For more information, see https://redmine.named-data.net/projects/nfd/wiki/Boost')
elif conf.env.BOOST_VERSION_NUMBER < 106501:
Logs.warn('WARNING: Using a version of Boost older than 1.65.1 is not officially supported and may not work.\n'
'If you encounter any problems, please upgrade your distribution or manually install a newer version of Boost.\n'
'For more information, see https://redmine.named-data.net/projects/nfd/wiki/Boost')
conf.load('unix-socket')