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
diff --git a/.jenkins.d/20-tests.sh b/.jenkins.d/20-tests.sh
index eda93c7..512842b 100755
--- a/.jenkins.d/20-tests.sh
+++ b/.jenkins.d/20-tests.sh
@@ -10,21 +10,6 @@
 
 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 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)
diff --git a/.travis.yml b/.travis.yml
index 16eb7b6..7927f10 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,7 +18,10 @@
 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 @@
     - 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
diff --git a/.waf-tools/compiler-features.py b/.waf-tools/compiler-features.py
deleted file mode 100644
index 27aa34b..0000000
--- a/.waf-tools/compiler-features.py
+++ /dev/null
@@ -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
diff --git a/.waf-tools/default-compiler-flags.py b/.waf-tools/default-compiler-flags.py
index 9e045c3..f3be6e7 100644
--- a/.waf-tools/default-compiler-flags.py
+++ b/.waf-tools/default-compiler-flags.py
@@ -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 @@
     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 @@
         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 @@
 
     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 @@
                               '-pedantic',
                               '-Wall',
                               '-Wextra',
+                              '-Wcatch-value=2',
+                              '-Wextra-semi',
                               '-Wnon-virtual-dtor',
                               '-Wno-unused-parameter',
                               ]
@@ -168,49 +178,50 @@
 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
diff --git a/README-dev.md b/README-dev.md
index 18f5af8..84d5c58 100644
--- a/README-dev.md
+++ b/README-dev.md
@@ -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 @@
     # 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 @@
     ./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).
diff --git a/README.md b/README.md
index e603989..0a4a74a 100644
--- a/README.md
+++ b/README.md
@@ -44,11 +44,12 @@
 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).
diff --git a/core/common.hpp b/core/common.hpp
index 4280dc7..28db409 100644
--- a/core/common.hpp
+++ b/core/common.hpp
@@ -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 {
diff --git a/daemon/common/privilege-helper.cpp b/daemon/common/privilege-helper.cpp
index 7cdfcd0..293eb6f 100644
--- a/daemon/common/privilege-helper.cpp
+++ b/daemon/common/privilege-helper.cpp
@@ -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 @@
       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 @@
       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()) {
diff --git a/docs/INSTALL.rst b/docs/INSTALL.rst
index 4ee93c6..18b4e26 100644
--- a/docs/INSTALL.rst
+++ b/docs/INSTALL.rst
@@ -1,4 +1,4 @@
-Getting Started with NFD
+Getting started with NFD
 ========================
 
 Supported platforms
@@ -7,19 +7,20 @@
 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 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 @@
 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 @@
 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 @@
     # 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 @@
 
 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>`__
diff --git a/docs/index.rst b/docs/index.rst
index 0c5094e..2b6b093 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -40,24 +40,23 @@
 
 **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 @@
 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>`__.
diff --git a/docs/named_data_theme/layout.html b/docs/named_data_theme/layout.html
index 937f8e2..c9fb5c1 100644
--- a/docs/named_data_theme/layout.html
+++ b/docs/named_data_theme/layout.html
@@ -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>
diff --git a/tests/boost-multi-log-formatter.hpp b/tests/boost-multi-log-formatter.hpp
deleted file mode 100644
index ae37416..0000000
--- a/tests/boost-multi-log-formatter.hpp
+++ /dev/null
@@ -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
diff --git a/tests/main.cpp b/tests/main.cpp
index dcb5520..240d8e1 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -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
diff --git a/tests/wscript b/tests/wscript
index ef00870..a5b9a8a 100644
--- a/tests/wscript
+++ b/tests/wscript
@@ -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 @@
             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)
diff --git a/wscript b/wscript
index a7e4906..003fc6c 100644
--- a/wscript
+++ b/wscript
@@ -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 @@
 
 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 @@
 
 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 @@
 
     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')