util: Out-of-the-box support for Android logging
Refs: #4970
Change-Id: I01cbb59faf505046c792393eb2e8df347212abcb
diff --git a/.waf-tools/cross.py b/.waf-tools/cross.py
new file mode 100644
index 0000000..17b8c8f
--- /dev/null
+++ b/.waf-tools/cross.py
@@ -0,0 +1,25 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+from waflib import Utils
+
+def options(opt):
+ opt.add_option('--build', default=Utils.unversioned_sys_platform(),
+ help='Build platform that is doing the actual compilation (e.g., darwin)')
+ opt.add_option('--host', default=Utils.unversioned_sys_platform(),
+ help='Host platform on which the compiled binary will run (e.g., android)')
+ # opt.add_option('--target', default=Utils.unversioned_sys_platform(),
+ # help='Target platform on which the compiled binary's output will run')
+
+def configure(conf):
+ conf.env.BUILD = conf.options.build
+ conf.env.HOST = conf.options.host
+ # conf.env.TARGET = conf.options.target
+
+ conf.start_msg('Build platform')
+ conf.end_msg(conf.env.BUILD)
+
+ conf.start_msg('Host platform')
+ conf.end_msg(conf.env.HOST)
+
+ # conf.start_msg('Target platform')
+ # conf.end_msg(conf.env.TARGET)
diff --git a/ndn-cxx/util/impl/logger-android.cpp b/ndn-cxx/util/impl/logger-android.cpp
new file mode 100644
index 0000000..bcfeef5
--- /dev/null
+++ b/ndn-cxx/util/impl/logger-android.cpp
@@ -0,0 +1,77 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2021 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "ndn-cxx/util/impl/logger-android.hpp"
+
+#include <boost/log/sinks.hpp>
+
+#include <android/log.h>
+
+namespace ndn {
+namespace util {
+namespace detail {
+
+class AndroidSinkBackend : public boost::log::sinks::basic_sink_backend<boost::log::sinks::concurrent_feeding>
+{
+public:
+ static int
+ convertToAndroidSeverity(LogLevel level)
+ {
+ switch (level) {
+ case LogLevel::FATAL:
+ return ANDROID_LOG_FATAL;
+ case LogLevel::ERROR:
+ return ANDROID_LOG_ERROR;
+ case LogLevel::WARN:
+ return ANDROID_LOG_WARN;
+ case LogLevel::INFO:
+ return ANDROID_LOG_INFO;
+ case LogLevel::DEBUG:
+ return ANDROID_LOG_DEBUG;
+ case LogLevel::TRACE:
+ return ANDROID_LOG_VERBOSE;
+ case LogLevel::NONE: // not a real log level, but just for translation
+ return ANDROID_LOG_SILENT;
+ case LogLevel::ALL:
+ return ANDROID_LOG_VERBOSE; // this is "ALL" for Android
+ }
+ }
+
+ void
+ consume(const boost::log::record_view& rec)
+ {
+ auto severity = convertToAndroidSeverity(rec[log::severity].get());
+ auto module = rec[log::module].get();
+ auto msg = rec[boost::log::expressions::smessage].get();
+
+ __android_log_write(severity, module.data(), msg.data());
+ }
+};
+
+boost::shared_ptr<boost::log::sinks::sink>
+makeAndroidLogger()
+{
+ return boost::make_shared<boost::log::sinks::synchronous_sink<AndroidSinkBackend>>();
+}
+
+} // namespace detail
+} // namespace util
+} // namespace ndn
diff --git a/ndn-cxx/util/impl/logger-android.hpp b/ndn-cxx/util/impl/logger-android.hpp
new file mode 100644
index 0000000..e31402d
--- /dev/null
+++ b/ndn-cxx/util/impl/logger-android.hpp
@@ -0,0 +1,42 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2021 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_CXX_UTIL_IMPL_LOGGER_ANDROID_HPP
+#define NDN_CXX_UTIL_IMPL_LOGGER_ANDROID_HPP
+
+#include "ndn-cxx/util/logger.hpp"
+
+#ifndef __ANDROID__
+#error "This file should not be compiled ..."
+#endif
+
+namespace ndn {
+namespace util {
+namespace detail {
+
+boost::shared_ptr<boost::log::sinks::sink>
+makeAndroidLogger();
+
+} // namespace detail
+} // namespace util
+} // namespace ndn
+
+#endif // NDN_CXX_UTIL_IMPL_LOGGER_ANDROID_HPP
diff --git a/ndn-cxx/util/logging.cpp b/ndn-cxx/util/logging.cpp
index 4db9f28..77654fb 100644
--- a/ndn-cxx/util/logging.cpp
+++ b/ndn-cxx/util/logging.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -23,6 +23,10 @@
#include "ndn-cxx/util/logger.hpp"
#include "ndn-cxx/util/time.hpp"
+#ifdef __ANDROID__
+#include "ndn-cxx/util/impl/logger-android.hpp"
+#endif
+
#include <boost/log/attributes/function.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/expressions/attr.hpp>
@@ -90,14 +94,19 @@
Logging::Logging()
{
+ // cannot call the static setDestination, as the singleton object is not yet constructed
+#ifndef __ANDROID__
bool wantAutoFlush = true;
const char* environ = std::getenv("NDN_LOG_NOFLUSH");
if (environ != nullptr) {
wantAutoFlush = false;
}
- // cannot call the static setDestination that uses the singleton Logging object that is not yet constructed
- auto destination = makeDefaultStreamDestination(shared_ptr<std::ostream>(&std::clog, [] (auto) {}), wantAutoFlush);
+ auto destination = makeDefaultStreamDestination(shared_ptr<std::ostream>(&std::clog, [] (auto) {}),
+ wantAutoFlush);
+#else
+ auto destination = detail::makeAndroidLogger();
+#endif // __ANDROID__
this->setDestinationImpl(std::move(destination));
environ = std::getenv("NDN_LOG");
@@ -105,7 +114,8 @@
this->setLevelImpl(environ);
}
- boost::log::core::get()->add_global_attribute("Timestamp", boost::log::attributes::make_function(&log::makeTimestamp));
+ boost::log::core::get()->add_global_attribute("Timestamp",
+ boost::log::attributes::make_function(&log::makeTimestamp));
}
void
diff --git a/ndn-cxx/util/logging.hpp b/ndn-cxx/util/logging.hpp
index 71e170e..0019569 100644
--- a/ndn-cxx/util/logging.hpp
+++ b/ndn-cxx/util/logging.hpp
@@ -103,7 +103,7 @@
*
*/
static void
- setDestination(std::ostream& os, bool wantAutoFlush = true);
+ setDestination(std::ostream& os, bool wantAutoFlush);
/** \brief Flush log backend.
*
diff --git a/tests/unit/util/logging.t.cpp b/tests/unit/util/logging.t.cpp
index 24ae88b..7daa1cd 100644
--- a/tests/unit/util/logging.t.cpp
+++ b/tests/unit/util/logging.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2021 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -178,7 +178,7 @@
{
m_systemClock->setNow(LOG_SYSTIME);
Logging::get().resetLevels();
- Logging::setDestination(os);
+ Logging::setDestination(os, true);
}
~LoggingFixture()
@@ -689,7 +689,7 @@
));
os2.reset();
- Logging::setDestination(os);
+ Logging::setDestination(os, true);
BOOST_CHECK(os2weak.expired());
}
diff --git a/wscript b/wscript
index fc739f8..cad98bc 100644
--- a/wscript
+++ b/wscript
@@ -11,7 +11,7 @@
def options(opt):
opt.load(['compiler_cxx', 'gnu_dirs', 'c_osx'])
- opt.load(['default-compiler-flags', 'compiler-features',
+ opt.load(['cross', 'default-compiler-flags', 'compiler-features',
'coverage', 'pch', 'sanitizers', 'osx-frameworks',
'boost', 'openssl', 'sqlite3',
'doxygen', 'sphinx_build'],
@@ -71,7 +71,7 @@
if not conf.options.enable_shared and not conf.options.enable_static:
conf.fatal('Either static library or shared library must be enabled')
- conf.load(['compiler_cxx', 'gnu_dirs', 'c_osx',
+ conf.load(['cross', 'compiler_cxx', 'gnu_dirs', 'c_osx',
'default-compiler-flags', 'compiler-features',
'pch', 'osx-frameworks', 'boost', 'openssl', 'sqlite3',
'doxygen', 'sphinx_build'])
@@ -190,9 +190,10 @@
libndn_cxx = dict(
target='ndn-cxx',
source=bld.path.ant_glob('ndn-cxx/**/*.cpp',
- excl=['ndn-cxx/**/*-osx.cpp',
- 'ndn-cxx/**/*netlink*.cpp',
- 'ndn-cxx/**/*-sqlite3.cpp']),
+ excl=['ndn-cxx/**/*-android.cpp',
+ 'ndn-cxx/**/*-osx.cpp',
+ 'ndn-cxx/**/*-sqlite3.cpp',
+ 'ndn-cxx/**/*netlink*.cpp']),
features='pch',
headers='ndn-cxx/impl/common-pch.hpp',
use='ndn-cxx-mm-objects version BOOST OPENSSL SQLITE3 ATOMIC RT PTHREAD',
@@ -200,16 +201,19 @@
export_includes='.',
install_path='${LIBDIR}')
+ if bld.env.HOST == 'android':
+ libndn_cxx['source'] += bld.path.ant_glob('ndn-cxx/**/*-android.cpp')
+
if bld.env.HAVE_OSX_FRAMEWORKS:
libndn_cxx['source'] += bld.path.ant_glob('ndn-cxx/**/*-osx.cpp')
libndn_cxx['use'] += ' OSX_COREFOUNDATION OSX_SECURITY OSX_SYSTEMCONFIGURATION OSX_FOUNDATION OSX_COREWLAN'
- if bld.env.HAVE_NETLINK:
- libndn_cxx['source'] += bld.path.ant_glob('ndn-cxx/**/*netlink*.cpp')
-
# In case we want to make it optional later
libndn_cxx['source'] += bld.path.ant_glob('ndn-cxx/**/*-sqlite3.cpp')
+ if bld.env.HAVE_NETLINK:
+ libndn_cxx['source'] += bld.path.ant_glob('ndn-cxx/**/*netlink*.cpp')
+
if bld.env.enable_shared:
bld.shlib(name='ndn-cxx',
vnum=VERSION_BASE,
@@ -274,20 +278,24 @@
bld.recurse('examples')
headers = bld.path.ant_glob('ndn-cxx/**/*.hpp',
- excl=['ndn-cxx/**/*-osx.hpp',
- 'ndn-cxx/**/*netlink*.hpp',
+ excl=['ndn-cxx/**/*-android.hpp',
+ 'ndn-cxx/**/*-osx.hpp',
'ndn-cxx/**/*-sqlite3.hpp',
+ 'ndn-cxx/**/*netlink*.hpp',
'ndn-cxx/**/impl/**/*'])
+ if bld.env.HOST == 'android':
+ headers += bld.path.ant_glob('ndn-cxx/**/*-android.hpp', excl='ndn-cxx/**/impl/**/*')
+
if bld.env.HAVE_OSX_FRAMEWORKS:
headers += bld.path.ant_glob('ndn-cxx/**/*-osx.hpp', excl='ndn-cxx/**/impl/**/*')
- if bld.env.HAVE_NETLINK:
- headers += bld.path.ant_glob('ndn-cxx/**/*netlink*.hpp', excl='ndn-cxx/**/impl/**/*')
-
# In case we want to make it optional later
headers += bld.path.ant_glob('ndn-cxx/**/*-sqlite3.hpp', excl='ndn-cxx/**/impl/**/*')
+ if bld.env.HAVE_NETLINK:
+ headers += bld.path.ant_glob('ndn-cxx/**/*netlink*.hpp', excl='ndn-cxx/**/impl/**/*')
+
bld.install_files(bld.env.INCLUDEDIR, headers, relative_trick=True)
# Install generated headers