build: require boost >= 1.71.0

Refs: #5276
Change-Id: I0f179707020fc6e0908af8aeb1d535ca3cd81410
diff --git a/README-dev.md b/README-dev.md
index 07d3baf..2183b31 100644
--- a/README-dev.md
+++ b/README-dev.md
@@ -57,7 +57,7 @@
 
     ./build/unit-tests
 
-The [Boost.Test framework](https://www.boost.org/doc/libs/1_65_1/libs/test/doc/html/index.html)
+The [Boost.Test framework](https://www.boost.org/doc/libs/1_71_0/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:
@@ -90,7 +90,7 @@
 
 There are many more command line options available, information about which can be obtained
 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).
+[Boost.Test website](https://www.boost.org/doc/libs/1_71_0/libs/test/doc/html/boost_test/runtime_config.html).
 
 **Warning:** If you have customized parameters for NDN platform using `client.conf` in
 `/etc/ndn` or `/usr/local/etc/ndn` (or other `@SYSCONFDIR@/etc` if it was configured to custom
diff --git a/docs/INSTALL.rst b/docs/INSTALL.rst
index b919d15..798ac40 100644
--- a/docs/INSTALL.rst
+++ b/docs/INSTALL.rst
@@ -34,7 +34,7 @@
 - Xcode >= 12.4 or corresponding version of Command Line Tools (if you are on macOS)
 - Python >= 3.8
 - pkg-config
-- Boost >= 1.65.1
+- Boost >= 1.71.0
 - OpenSSL >= 1.1.1
 - SQLite 3.x
 
diff --git a/ndn-cxx/detail/asio-fwd.hpp b/ndn-cxx/detail/asio-fwd.hpp
index a0648a1..a33b122 100644
--- a/ndn-cxx/detail/asio-fwd.hpp
+++ b/ndn-cxx/detail/asio-fwd.hpp
@@ -26,12 +26,8 @@
 
 namespace boost::asio {
 
-#if BOOST_VERSION >= 106600
 class io_context;
 using io_service = io_context;
-#else
-class io_service;
-#endif // BOOST_VERSION >= 106600
 
 } // namespace boost::asio
 
diff --git a/ndn-cxx/encoding/block-helpers.cpp b/ndn-cxx/encoding/block-helpers.cpp
index bf53c86..c9c9233 100644
--- a/ndn-cxx/encoding/block-helpers.cpp
+++ b/ndn-cxx/encoding/block-helpers.cpp
@@ -25,8 +25,6 @@
 
 namespace ndn::encoding {
 
-namespace endian = boost::endian;
-
 // ---- empty ----
 
 template<Tag TAG>
@@ -105,7 +103,7 @@
 {
   uint64_t temp = 0;
   std::memcpy(&temp, &value, 8);
-  endian::native_to_big_inplace(temp);
+  boost::endian::native_to_big_inplace(temp);
   return prependBinaryBlock(encoder, type, {reinterpret_cast<const uint8_t*>(&temp), 8});
 }
 
@@ -133,17 +131,7 @@
   if (block.value_size() != 8) {
     NDN_THROW(tlv::Error("Invalid length for double (must be 8)"));
   }
-
-#if BOOST_VERSION >= 107100
-  return endian::endian_load<double, 8, endian::order::big>(block.value());
-#else
-  uint64_t temp = 0;
-  std::memcpy(&temp, block.value(), 8);
-  endian::big_to_native_inplace(temp);
-  double d = 0;
-  std::memcpy(&d, &temp, 8);
-  return d;
-#endif
+  return boost::endian::endian_load<double, 8, boost::endian::order::big>(block.value());
 }
 
 // ---- binary ----
diff --git a/ndn-cxx/net/dns.cpp b/ndn-cxx/net/dns.cpp
index 5303e93..70d0d8a 100644
--- a/ndn-cxx/net/dns.cpp
+++ b/ndn-cxx/net/dns.cpp
@@ -24,9 +24,7 @@
 
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/ip/udp.hpp>
-#if BOOST_VERSION >= 106600
 #include <boost/asio/post.hpp>
-#endif
 
 namespace ndn::dns {
 
@@ -78,11 +76,7 @@
     m_resolveTimeout.cancel();
 
     // ensure the Resolver isn't destructed while callbacks are still pending, see #2653
-#if BOOST_VERSION >= 106600
     boost::asio::post(m_resolver.get_executor(), [self] {});
-#else
-    m_resolver.get_io_service().post([self] {});
-#endif
 
     if (error) {
       if (error == boost::asio::error::operation_aborted)
@@ -110,11 +104,7 @@
     m_resolver.cancel();
 
     // ensure the Resolver isn't destructed while callbacks are still pending, see #2653
-#if BOOST_VERSION >= 106600
     boost::asio::post(m_resolver.get_executor(), [self] {});
-#else
-    m_resolver.get_io_service().post([self] {});
-#endif
 
     if (m_onError)
       m_onError("Hostname resolution timed out");
diff --git a/ndn-cxx/net/impl/netlink-socket.cpp b/ndn-cxx/net/impl/netlink-socket.cpp
index 706cc6d..0c26637 100644
--- a/ndn-cxx/net/impl/netlink-socket.cpp
+++ b/ndn-cxx/net/impl/netlink-socket.cpp
@@ -141,10 +141,10 @@
     NDN_THROW_ERRNO(Error("Cannot obtain netlink socket address"));
   }
   if (len != sizeof(addr)) {
-    NDN_THROW(Error("Wrong address length (" + to_string(len) + ")"));
+    NDN_THROW(Error("Wrong address length (" + std::to_string(len) + ")"));
   }
   if (addr.nl_family != AF_NETLINK) {
-    NDN_THROW(Error("Wrong address family (" + to_string(addr.nl_family) + ")"));
+    NDN_THROW(Error("Wrong address family (" + std::to_string(addr.nl_family) + ")"));
   }
   m_pid = addr.nl_pid;
   NDN_LOG_TRACE("our pid is " << m_pid);
@@ -179,7 +179,7 @@
   boost::system::error_code ec;
   m_sock->set_option(NetlinkSocketOption<NETLINK_ADD_MEMBERSHIP>(group), ec);
   if (ec) {
-    NDN_THROW(Error("Cannot join netlink group " + to_string(group) + ": " + ec.message()));
+    NDN_THROW(Error("Cannot join netlink group " + std::to_string(group) + ": " + ec.message()));
   }
 }
 
@@ -206,14 +206,14 @@
 std::string
 NetlinkSocket::nlmsgTypeToString(uint16_t type) const
 {
-#define NLMSG_STRINGIFY(x) case NLMSG_##x: return to_string(type) + "<" #x ">"
+#define NLMSG_STRINGIFY(x) case NLMSG_##x: return std::to_string(type) + "<" #x ">"
   switch (type) {
     NLMSG_STRINGIFY(NOOP);
     NLMSG_STRINGIFY(ERROR);
     NLMSG_STRINGIFY(DONE);
     NLMSG_STRINGIFY(OVERRUN);
     default:
-      return to_string(type);
+      return std::to_string(type);
   }
 #undef NLMSG_STRINGIFY
 }
@@ -221,29 +221,23 @@
 void
 NetlinkSocket::asyncWait()
 {
-  // capture a copy of 'm_sock' to prevent its deallocation while the handler is still pending
-  auto handler = [this, sock = m_sock] (const boost::system::error_code& ec) {
-    if (!sock->is_open() || ec == boost::asio::error::operation_aborted) {
-      // socket was closed, ignore the error
-      NDN_LOG_DEBUG("netlink socket closed or operation aborted");
-    }
-    else if (ec) {
-      NDN_LOG_ERROR("read failed: " << ec.message());
-      NDN_THROW(Error("Netlink socket read error (" + ec.message() + ")"));
-    }
-    else {
-      receiveAndValidate();
-      if (!m_pendingRequests.empty())
-        asyncWait();
-    }
-  };
-
-#if BOOST_VERSION >= 106600
-  m_sock->async_wait(boost::asio::socket_base::wait_read, std::move(handler));
-#else
-  m_sock->async_receive(boost::asio::null_buffers(),
-                        [h = std::move(handler)] (const boost::system::error_code& ec, size_t) { h(ec); });
-#endif
+  m_sock->async_wait(boost::asio::socket_base::wait_read,
+    // capture a copy of 'm_sock' to prevent its deallocation while the handler is still pending
+    [this, sock = m_sock] (const auto& ec) {
+      if (!sock->is_open() || ec == boost::asio::error::operation_aborted) {
+        // socket was closed, ignore the error
+        NDN_LOG_DEBUG("netlink socket closed or operation aborted");
+      }
+      else if (ec) {
+        NDN_LOG_ERROR("read failed: " << ec.message());
+        NDN_THROW(Error("Netlink socket read error (" + ec.message() + ")"));
+      }
+      else {
+        receiveAndValidate();
+        if (!m_pendingRequests.empty())
+          asyncWait();
+      }
+  });
 }
 
 void
@@ -383,7 +377,7 @@
   };
   m_sock->async_send(bufs,
     // capture 'hdr' to prevent its premature deallocation
-    [this, hdr] (const boost::system::error_code& ec, size_t) {
+    [this, hdr] (const auto& ec, size_t) {
       if (!ec) {
         NDN_LOG_TRACE("sent dump request type=" << nlmsgTypeToString(hdr->nlh.nlmsg_type)
                       << " seq=" << hdr->nlh.nlmsg_seq);
@@ -398,7 +392,7 @@
 std::string
 RtnlSocket::nlmsgTypeToString(uint16_t type) const
 {
-#define RTM_STRINGIFY(x) case RTM_##x: return to_string(type) + "<" #x ">"
+#define RTM_STRINGIFY(x) case RTM_##x: return std::to_string(type) + "<" #x ">"
   switch (type) {
     RTM_STRINGIFY(NEWLINK);
     RTM_STRINGIFY(DELLINK);
@@ -491,7 +485,7 @@
   };
   m_sock->async_send(bufs,
     // capture 'hdr' to prevent its premature deallocation
-    [this, hdr] (const boost::system::error_code& ec, size_t) {
+    [this, hdr] (const auto& ec, size_t) {
       if (!ec) {
         NDN_LOG_TRACE("sent genl request type=" << nlmsgTypeToString(hdr->nlh.nlmsg_type) <<
                       " cmd=" << static_cast<unsigned>(hdr->genlh.cmd) <<
@@ -598,7 +592,7 @@
   if (type >= GENL_MIN_ID) {
     for (const auto& p : m_cachedFamilyIds) {
       if (p.second == type) {
-        return to_string(type) + "<" + p.first + ">";
+        return std::to_string(type) + "<" + p.first + ">";
       }
     }
   }
diff --git a/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp b/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp
index 8d0de0c..2ca01e4 100644
--- a/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp
+++ b/ndn-cxx/transport/detail/stream-transport-with-resolver-impl.hpp
@@ -53,13 +53,7 @@
       self->connectTimeoutHandler(ec);
     });
 
-    auto resolver = make_shared<typename Protocol::resolver>(this->m_socket
-#if BOOST_VERSION >= 107000
-                                                             .get_executor()
-#else
-                                                             .get_io_service()
-#endif
-                                                             );
+    auto resolver = make_shared<typename Protocol::resolver>(this->m_socket.get_executor());
     resolver->async_resolve(query, [self = this->shared_from_base(), resolver] (auto&&... args) {
       self->resolveHandler(std::forward<decltype(args)>(args)..., resolver);
     });
diff --git a/ndn-cxx/util/time.hpp b/ndn-cxx/util/time.hpp
index 5fb3138..60971cd 100644
--- a/ndn-cxx/util/time.hpp
+++ b/ndn-cxx/util/time.hpp
@@ -336,7 +336,7 @@
  * \param format desired output format (default: `%Y-%m-%d %H:%M:%S`)
  * \param locale desired locale (default: "C" locale)
  *
- * \sa https://www.boost.org/doc/libs/1_65_1/doc/html/date_time/date_time_io.html#date_time.format_flags
+ * \sa https://www.boost.org/doc/libs/1_71_0/doc/html/date_time/date_time_io.html#date_time.format_flags
  *     describes possible formatting flags
  **/
 std::string
@@ -354,7 +354,7 @@
  * \param format input output format (default: `%Y-%m-%d %H:%M:%S`)
  * \param locale input locale (default: "C" locale)
  *
- * \sa https://www.boost.org/doc/libs/1_65_1/doc/html/date_time/date_time_io.html#date_time.format_flags
+ * \sa https://www.boost.org/doc/libs/1_71_0/doc/html/date_time/date_time_io.html#date_time.format_flags
  *     describes possible formatting flags
  */
 system_clock::time_point
diff --git a/tests/unit/io-fixture.hpp b/tests/unit/io-fixture.hpp
index 4934954..191b889 100644
--- a/tests/unit/io-fixture.hpp
+++ b/tests/unit/io-fixture.hpp
@@ -35,11 +35,7 @@
   afterTick() final
   {
     if (m_io.stopped()) {
-#if BOOST_VERSION >= 106600
       m_io.restart();
-#else
-      m_io.reset();
-#endif
     }
     m_io.poll();
   }
diff --git a/tests/unit/net/face-uri.t.cpp b/tests/unit/net/face-uri.t.cpp
index 050b1cc..78e712a 100644
--- a/tests/unit/net/face-uri.t.cpp
+++ b/tests/unit/net/face-uri.t.cpp
@@ -52,11 +52,7 @@
       if (netmon.getCapabilities() & net::NetworkMonitor::CAP_ENUM) {
         netmon.onEnumerationCompleted.connect([this] { m_io.stop(); });
         m_io.run();
-#if BOOST_VERSION >= 106600
         m_io.restart();
-#else
-        m_io.reset();
-#endif
       }
       return netmon.listNetworkInterfaces();
     }();
@@ -90,11 +86,7 @@
 
       m_io.run();
       BOOST_CHECK_EQUAL(didInvokeCb, true);
-#if BOOST_VERSION >= 106600
       m_io.restart();
-#else
-      m_io.reset();
-#endif
     }
   }
 
diff --git a/tests/unit/wscript b/tests/unit/wscript
index 3fcf675..6b4e2b8 100644
--- a/tests/unit/wscript
+++ b/tests/unit/wscript
@@ -1,14 +1,15 @@
 # -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
-top = '../../'
+top = '../..'
 
 def build(bld):
     tmpdir = 'UNIT_TESTS_TMPDIR="%s"' % bld.bldnode.make_node('tmp-files')
 
     # unit test objects
-    srcFiles = bld.path.ant_glob('**/*.cpp', excl=['main.cpp',
-                                                   '**/*-osx.t.cpp',
-                                                   '**/*-sqlite3.t.cpp'])
+    srcFiles = bld.path.ant_glob('**/*.cpp',
+                                 excl=['main.cpp',
+                                       '**/*-osx.t.cpp',
+                                       '**/*-sqlite3.t.cpp'])
 
     if bld.env['HAVE_OSX_FRAMEWORKS']:
         srcFiles += bld.path.ant_glob('**/*-osx.t.cpp')
@@ -16,16 +17,18 @@
     # In case we want to make it optional later
     srcFiles += bld.path.ant_glob('**/*-sqlite3.t.cpp')
 
-    bld.objects(target='unit-tests-objects',
-                source=srcFiles,
-                features='pch',
-                headers='unit-tests-pch.hpp',
-                use='tests-common',
-                defines=[tmpdir])
+    bld.objects(
+        target='unit-tests-objects',
+        source=srcFiles,
+        features='pch',
+        headers='unit-tests-pch.hpp',
+        use='tests-common',
+        defines=[tmpdir])
 
     # unit test binary
-    bld.program(target=top + 'unit-tests',
-                name='unit-tests',
-                source=['main.cpp'],
-                use='unit-tests-objects',
-                install_path=None)
+    bld.program(
+        target=f'{top}/unit-tests',
+        name='unit-tests',
+        source=['main.cpp'],
+        use='unit-tests-objects',
+        install_path=None)
diff --git a/tests/wscript b/tests/wscript
index 2d83303..7ab65d1 100644
--- a/tests/wscript
+++ b/tests/wscript
@@ -1,14 +1,15 @@
 # -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
-top = '../'
+top = '..'
 
 def build(bld):
     # common objects that can be shared among all tests
-    bld.objects(target='tests-common',
-                source=bld.path.ant_glob('*.cpp'),
-                features='pch',
-                headers='tests-pch.hpp',
-                use='BOOST_TESTS ndn-cxx')
+    bld.objects(
+        target='tests-common',
+        source=bld.path.ant_glob('*.cpp'),
+        features='pch',
+        headers='tests-pch.hpp',
+        use='BOOST_TESTS ndn-cxx')
 
     bld.recurse('benchmarks')
     bld.recurse('integration')
diff --git a/tools/ndnsec/cert-dump.cpp b/tools/ndnsec/cert-dump.cpp
index 8237f5d..0baf8df 100644
--- a/tools/ndnsec/cert-dump.cpp
+++ b/tools/ndnsec/cert-dump.cpp
@@ -23,9 +23,6 @@
 #include "util.hpp"
 
 #include <boost/asio/ip/tcp.hpp>
-#if BOOST_VERSION < 106700
-#include <boost/date_time/posix_time/posix_time_duration.hpp>
-#endif // BOOST_VERSION < 106700
 
 namespace ndn::ndnsec {
 
@@ -121,11 +118,7 @@
 
   if (isRepoOut) {
     boost::asio::ip::tcp::iostream requestStream;
-#if BOOST_VERSION >= 106700
     requestStream.expires_after(std::chrono::seconds(10));
-#else
-    requestStream.expires_from_now(boost::posix_time::seconds(10));
-#endif // BOOST_VERSION >= 106700
     requestStream.connect(repoHost, repoPort);
     if (!requestStream) {
       std::cerr << "ERROR: Failed to connect to repo instance" << std::endl;
diff --git a/tools/ndnsec/wscript b/tools/ndnsec/wscript
index 4ff1c5c..1b1f40b 100644
--- a/tools/ndnsec/wscript
+++ b/tools/ndnsec/wscript
@@ -1,18 +1,18 @@
 # -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
-top = '../../'
+top = '../..'
 
 def build(bld):
-    bld.objects(target='tool-ndnsec-objects',
+    bld.objects(target='tools-ndnsec-objects',
                 source=bld.path.ant_glob('*.cpp', excl=['main.cpp']),
                 features='pch',
                 headers='ndnsec-pch.hpp',
                 use='BOOST_TOOLS ndn-cxx')
 
-    bld.program(name='tool-ndnsec',
-                target=top + 'bin/ndnsec',
+    bld.program(name='ndnsec',
+                target=f'{top}/bin/ndnsec',
                 source=['main.cpp'],
-                use='tool-ndnsec-objects')
+                use='tools-ndnsec-objects')
 
     # create convenience symlinks
     for cmd in ('list', 'get-default', 'set-default', 'delete',
diff --git a/tools/wscript b/tools/wscript
index 4f1d11a..93cabd7 100644
--- a/tools/wscript
+++ b/tools/wscript
@@ -1,7 +1,5 @@
 # -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
-from waflib import Utils
-
 top = '..'
 
 def build(bld):
@@ -10,7 +8,7 @@
     # and is built as build/bin/foo. These tools cannot be unit-tested.
     for tool in bld.path.ant_glob('*.cpp'):
         name = tool.change_ext('').path_from(bld.path.get_bld())
-        bld.program(name=f'tool-{name}',
+        bld.program(name=name,
                     target=f'{top}/bin/{name}',
                     source=[tool],
                     use='ndn-cxx')
@@ -18,7 +16,7 @@
     # Sub-directory tools:
     # tools/foo/**/*.cpp are compiled and linked into build/bin/foo.
     # tools/foo/main.cpp must exist and must contain the main() function.
-    # All other objects are collected into 'tool-foo-objects' and can be unit-tested.
+    # All other objects are collected into 'tools-foo-objects' and can be unit-tested.
     for subdir in bld.path.ant_glob('*', dir=True, src=False):
         name = subdir.path_from(bld.path)
         subWscript = subdir.find_node('wscript')
@@ -35,11 +33,11 @@
         srcFiles = subdir.ant_glob('**/*.cpp', excl=['main.cpp'])
         srcObjects = ''
         if srcFiles:
-            srcObjects = f'tool-{name}-objects'
+            srcObjects = f'tools-{name}-objects'
             bld.objects(target=srcObjects,
                         source=srcFiles,
                         use='ndn-cxx')
-        bld.program(name=f'tool-{name}',
+        bld.program(name=name,
                     target=f'{top}/bin/{name}',
                     source=[mainFile],
-                    use='ndn-cxx ' + srcObjects)
+                    use=f'ndn-cxx {srcObjects}')
diff --git a/wscript b/wscript
index 0c185a2..5eb2681 100644
--- a/wscript
+++ b/wscript
@@ -1,7 +1,8 @@
 # -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
+import os
+import subprocess
 from waflib import Context, Logs, Utils
-import os, subprocess
 
 VERSION = '0.8.1'
 APPNAME = 'ndn-cxx'
@@ -74,9 +75,9 @@
                'osx-frameworks', 'boost', 'openssl', 'sqlite3',
                'doxygen', 'sphinx_build'])
 
+    conf.env.WITH_EXAMPLES = conf.options.with_examples
     conf.env.WITH_TESTS = conf.options.with_tests
     conf.env.WITH_TOOLS = conf.options.with_tools
-    conf.env.WITH_EXAMPLES = conf.options.with_examples
 
     conf.find_program('dot', mandatory=False)
 
@@ -103,7 +104,18 @@
     conf.check_sqlite3()
     conf.check_openssl(lib='crypto', atleast_version='1.1.1')
 
-    boost_libs = ['system', 'chrono', 'date_time', 'filesystem', 'thread', 'log']
+    conf.check_boost()
+    if conf.env.BOOST_VERSION_NUMBER < 107100:
+        conf.fatal('The minimum supported version of Boost is 1.71.0.\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')
+
+    # Boost.Log requires Boost.Thread
+    boost_libs = ['chrono', 'filesystem', 'log', 'thread']
+
+    # Boost.Date_Time is header-only since 1.73
+    if conf.env.BOOST_VERSION_NUMBER < 107300:
+        boost_libs.append('date_time')
 
     stacktrace_backend = conf.options.with_stacktrace
     if stacktrace_backend is None:
@@ -121,16 +133,6 @@
         boost_libs.append(f'stacktrace_{stacktrace_backend}')
 
     conf.check_boost(lib=boost_libs, mt=True)
-    if conf.env.BOOST_VERSION_NUMBER < 106501:
-        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')
-
-    # Workaround for bug 4860
-    if conf.env.BOOST_VERSION_NUMBER < 106900 and conf.env.CXX_NAME == 'clang':
-        conf.env.append_unique('DEFINES_BOOST', ['BOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW'])
-
-    conf.env.append_unique('DEFINES_BOOST', ['BOOST_FILESYSTEM_NO_DEPRECATED'])
 
     if conf.env.WITH_TESTS:
         conf.check_boost(lib='unit_test_framework', mt=True, uselib_store='BOOST_TESTS')
@@ -138,6 +140,8 @@
     if conf.env.WITH_TOOLS:
         conf.check_boost(lib='program_options', mt=True, uselib_store='BOOST_TOOLS')
 
+    conf.env.append_unique('DEFINES_BOOST', ['BOOST_FILESYSTEM_NO_DEPRECATED'])
+
     conf.check_compiler_flags()
 
     # Loading "late" to prevent tests from being compiled with profiling flags
@@ -168,7 +172,7 @@
         name='version.hpp',
         source='ndn-cxx/version.hpp.in',
         target='ndn-cxx/version.hpp',
-        install_path=None,
+        install_path='${INCLUDEDIR}/ndn-cxx',
         VERSION_STRING=VERSION_BASE,
         VERSION_BUILD=VERSION,
         VERSION=int(VERSION_SPLIT[0]) * 1000000 +
@@ -214,56 +218,16 @@
         libndn_cxx['source'] += bld.path.ant_glob('ndn-cxx/**/*netlink*.cpp')
 
     if bld.env.enable_shared:
-        bld.shlib(name='ndn-cxx',
-                  vnum=VERSION_BASE,
-                  cnum=VERSION_BASE,
-                  **libndn_cxx)
+        bld.shlib(
+            name='ndn-cxx',
+            vnum=VERSION_BASE,
+            cnum=VERSION_BASE,
+            **libndn_cxx)
 
     if bld.env.enable_static:
-        bld.stlib(name='ndn-cxx-static' if bld.env.enable_shared else 'ndn-cxx',
-                  **libndn_cxx)
-
-    # Prepare flags that should go to pkgconfig file
-    pkgconfig_libs = []
-    pkgconfig_ldflags = []
-    pkgconfig_linkflags = []
-    pkgconfig_includes = []
-    pkgconfig_cxxflags = []
-    pkgconfig_defines = []
-    for lib in Utils.to_list(libndn_cxx['use']):
-        if bld.env[f'LIB_{lib}']:
-            pkgconfig_libs += Utils.to_list(bld.env[f'LIB_{lib}'])
-        if bld.env[f'LIBPATH_{lib}']:
-            pkgconfig_ldflags += Utils.to_list(bld.env[f'LIBPATH_{lib}'])
-        if bld.env[f'INCLUDES_{lib}']:
-            pkgconfig_includes += Utils.to_list(bld.env[f'INCLUDES_{lib}'])
-        if bld.env[f'LINKFLAGS_{lib}']:
-            pkgconfig_linkflags += Utils.to_list(bld.env[f'LINKFLAGS_{lib}'])
-        if bld.env[f'CXXFLAGS_{lib}']:
-            pkgconfig_cxxflags += Utils.to_list(bld.env[f'CXXFLAGS_{lib}'])
-        if bld.env[f'DEFINES_{lib}']:
-            pkgconfig_defines += Utils.to_list(bld.env[f'DEFINES_{lib}'])
-
-    EXTRA_FRAMEWORKS = ''
-    if bld.env.HAVE_OSX_FRAMEWORKS:
-        EXTRA_FRAMEWORKS = '-framework CoreFoundation -framework Security -framework SystemConfiguration -framework Foundation -framework CoreWLAN'
-
-    def uniq(alist):
-        return list(dict.fromkeys(alist))
-
-    bld(features='subst',
-        source='libndn-cxx.pc.in',
-        target='libndn-cxx.pc',
-        install_path='${LIBDIR}/pkgconfig',
-        VERSION=VERSION_BASE,
-        # This probably not the right thing to do, but to simplify life of apps
-        # that use the library
-        EXTRA_LIBS=' '.join([f'-l{i}' for i in uniq(pkgconfig_libs)]),
-        EXTRA_LDFLAGS=' '.join([f'-L{i}' for i in uniq(pkgconfig_ldflags)]),
-        EXTRA_LINKFLAGS=' '.join(uniq(pkgconfig_linkflags)),
-        EXTRA_INCLUDES=' '.join([f'-I{i}' for i in uniq(pkgconfig_includes)]),
-        EXTRA_CXXFLAGS=' '.join(uniq(pkgconfig_cxxflags) + [f'-D{i}' for i in uniq(pkgconfig_defines)]),
-        EXTRA_FRAMEWORKS=EXTRA_FRAMEWORKS)
+        bld.stlib(
+            name='ndn-cxx-static' if bld.env.enable_shared else 'ndn-cxx',
+            **libndn_cxx)
 
     if bld.env.WITH_TESTS:
         bld.recurse('tests')
@@ -274,6 +238,7 @@
     if bld.env.WITH_EXAMPLES:
         bld.recurse('examples')
 
+    # Install header files
     headers = bld.path.ant_glob('ndn-cxx/**/*.hpp',
                                 excl=['ndn-cxx/**/*-android.hpp',
                                       'ndn-cxx/**/*-osx.hpp',
@@ -294,12 +259,49 @@
         headers += bld.path.ant_glob('ndn-cxx/**/*netlink*.hpp', excl='ndn-cxx/**/impl/**/*')
 
     bld.install_files('${INCLUDEDIR}', headers, relative_trick=True)
+    bld.install_files('${INCLUDEDIR}/ndn-cxx/detail', 'ndn-cxx/detail/config.hpp')
 
-    # Install generated headers
-    for filename in ('ndn-cxx/detail/config.hpp', 'ndn-cxx/version.hpp'):
-        bld.install_files('${INCLUDEDIR}/%s' % os.path.dirname(filename),
-                          bld.path.find_resource(filename))
+    # Prepare flags that should go into pkgconfig file
+    pkgconfig_libs = []
+    pkgconfig_ldflags = []
+    pkgconfig_linkflags = []
+    pkgconfig_includes = []
+    pkgconfig_cxxflags = []
+    pkgconfig_defines = []
+    for lib in Utils.to_list(libndn_cxx['use']):
+        if bld.env[f'LIB_{lib}']:
+            pkgconfig_libs += Utils.to_list(bld.env[f'LIB_{lib}'])
+        if bld.env[f'LIBPATH_{lib}']:
+            pkgconfig_ldflags += Utils.to_list(bld.env[f'LIBPATH_{lib}'])
+        if bld.env[f'LINKFLAGS_{lib}']:
+            pkgconfig_linkflags += Utils.to_list(bld.env[f'LINKFLAGS_{lib}'])
+        if bld.env[f'INCLUDES_{lib}']:
+            pkgconfig_includes += Utils.to_list(bld.env[f'INCLUDES_{lib}'])
+        if bld.env[f'CXXFLAGS_{lib}']:
+            pkgconfig_cxxflags += Utils.to_list(bld.env[f'CXXFLAGS_{lib}'])
+        if bld.env[f'DEFINES_{lib}']:
+            pkgconfig_defines += Utils.to_list(bld.env[f'DEFINES_{lib}'])
 
+    EXTRA_FRAMEWORKS = '-framework CoreFoundation -framework Security -framework SystemConfiguration -framework Foundation -framework CoreWLAN'
+
+    def uniq(alist):
+        return list(dict.fromkeys(alist))
+
+    bld(features='subst',
+        source='libndn-cxx.pc.in',
+        target='libndn-cxx.pc',
+        install_path='${LIBDIR}/pkgconfig',
+        VERSION=VERSION_BASE,
+        # This probably not the right thing to do, but to simplify life of apps
+        # that use the library
+        EXTRA_LIBS=' '.join([f'-l{i}' for i in uniq(pkgconfig_libs)]),
+        EXTRA_LDFLAGS=' '.join([f'-L{i}' for i in uniq(pkgconfig_ldflags)]),
+        EXTRA_LINKFLAGS=' '.join(uniq(pkgconfig_linkflags)),
+        EXTRA_INCLUDES=' '.join([f'-I{i}' for i in uniq(pkgconfig_includes)]),
+        EXTRA_CXXFLAGS=' '.join(uniq(pkgconfig_cxxflags) + [f'-D{i}' for i in uniq(pkgconfig_defines)]),
+        EXTRA_FRAMEWORKS=EXTRA_FRAMEWORKS if bld.env.HAVE_OSX_FRAMEWORKS else '')
+
+    # Install sample config
     bld.install_files('${SYSCONFDIR}/ndn', 'client.conf.sample')
 
     if bld.env.SPHINX_BUILD: