Merge pull request #277 from hghwng/master

Fix compilation on Android.
This commit is contained in:
Gabi Melman 2016-09-14 17:55:43 +03:00 committed by GitHub
commit 87d79eb95d
9 changed files with 65 additions and 41 deletions

3
.gitignore vendored
View File

@ -1,4 +1,4 @@
# Auto generated files
# Auto generated files
*.slo
*.lo
*.o
@ -46,6 +46,7 @@ example/*
!example/example.vcxproj
!example/CMakeLists.txt
!example/multisink.cpp
!example/jni
# generated files
generated

View File

@ -13,6 +13,7 @@
void async_example();
void syslog_example();
void android_example();
void user_defined_example();
void err_handler_example();
@ -48,7 +49,6 @@ int main(int, char*[])
auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic.txt");
my_logger->info("Some log message");
// Create a file rotating logger with 5mb size max and 3 rotated files
auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/mylogfile", 1048576 * 5, 3);
for (int i = 0; i < 10; ++i)
@ -76,6 +76,9 @@ int main(int, char*[])
// syslog example. linux/osx only
syslog_example();
// android example. compile with NDK
android_example();
// Log user-defined types example
user_defined_example();
@ -119,6 +122,16 @@ void syslog_example()
#endif
}
// Android example
void android_example()
{
#if defined(__ANDROID__)
std::string tag = "spdlog-android";
auto android_logger = spd::android_logger("android", tag);
android_logger->critical("Use \"adb shell logcat\" to view this message.");
#endif
}
// user defined types logging by implementing operator<<
struct my_type
{
@ -148,4 +161,3 @@ void err_handler_example()
});
spd::get("console")->info("some invalid message to trigger an error {}{}{}{}", 3);
}

15
example/jni/Android.mk Normal file
View File

@ -0,0 +1,15 @@
# Setup a project
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := example
LOCAL_SRC_FILES := example.cpp
LOCAL_CPPFLAGS += -Wall -Wshadow -Wextra -pedantic -std=c++11 -fPIE -pie
LOCAL_LDFLAGS += -fPIE -pie
# Add exception support and set path for spdlog's headers
LOCAL_CPPFLAGS += -fexceptions -I../include
# Use android's log library
LOCAL_LDFLAGS += -llog
include $(BUILD_EXECUTABLE)

View File

@ -0,0 +1,2 @@
# Exceptions are used in spdlog. Link to an exception-ready C++ runtime.
APP_STL = gnustl_static

1
example/jni/example.cpp Symbolic link
View File

@ -0,0 +1 @@
../example.cpp

View File

@ -342,7 +342,9 @@ inline std::string errno_str(int err_num)
else
return "Unkown error";
#elif defined(__FreeBSD__) || defined(__APPLE__) || ((_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE) // posix version
#elif defined(__FreeBSD__) || defined(__APPLE__) || defined(ANDROID) || \
((_POSIX_C_SOURCE >= 200112L) && ! _GNU_SOURCE) // posix version
if (strerror_r(err_num, buf, buf_size) == 0)
return std::string(buf);
else
@ -356,5 +358,3 @@ inline std::string errno_str(int err_num)
} //os
} //details
} //spdlog

View File

@ -14,6 +14,7 @@
#include <spdlog/sinks/stdout_sinks.h>
#include <spdlog/sinks/syslog_sink.h>
#include <spdlog/sinks/ansicolor_sink.h>
#include <spdlog/sinks/android_sink.h>
#include <chrono>
#include <functional>
@ -104,6 +105,13 @@ inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string&
}
#endif
#if defined(__ANDROID__)
inline std::shared_ptr<spdlog::logger> spdlog::android_logger(const std::string& logger_name, const std::string& tag)
{
return create<spdlog::sinks::android_sink>(logger_name, tag);
}
#endif
// Create and register a logger a single sink
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const spdlog::sink_ptr& sink)
{

View File

@ -7,51 +7,42 @@
#if defined(__ANDROID__)
#include <spdlog/sinks/base_sink.h>
#include <spdlog/details/null_mutex.h>
#include <android/log.h>
#include <spdlog/sinks/sink.h>
#include <mutex>
#include <string>
#include <android/log.h>
namespace spdlog
{
namespace sinks
{
/*
* Android sink (logging using __android_log_write)
* __android_log_write is thread-safe. No lock is needed.
*/
template<class Mutex>
class base_android_sink : public base_sink < Mutex >
class android_sink : public sink
{
public:
explicit base_android_sink(std::string tag="spdlog"): _tag(tag)
explicit android_sink(const std::string& tag = "spdlog"): _tag(tag) {}
void log(const details::log_msg& msg) override
{
const android_LogPriority priority = convert_to_android(msg.level);
// See system/core/liblog/logger_write.c for explanation of return value
const int ret = __android_log_write(
priority, _tag.c_str(), msg.formatted.c_str()
);
if (ret < 0) {
throw spdlog_ex("__android_log_write() failed", ret);
}
}
void flush() override
{
}
protected:
void _sink_it(const details::log_msg& msg) override
{
const android_LogPriority priority = convert_to_android(msg.level);
const int expected_size = msg.formatted.size();
const int size = __android_log_write(
priority, _tag.c_str(), msg.formatted.c_str()
);
if (size > expected_size)
{
// Will write a little bit more than original message
}
else
{
throw spdlog_ex("Send to Android logcat failed");
}
}
private:
static android_LogPriority convert_to_android(spdlog::level::level_enum level)
{
@ -63,29 +54,20 @@ private:
return ANDROID_LOG_DEBUG;
case spdlog::level::info:
return ANDROID_LOG_INFO;
case spdlog::level::notice:
return ANDROID_LOG_INFO;
case spdlog::level::warn:
return ANDROID_LOG_WARN;
case spdlog::level::err:
return ANDROID_LOG_ERROR;
case spdlog::level::critical:
return ANDROID_LOG_FATAL;
case spdlog::level::alert:
return ANDROID_LOG_FATAL;
case spdlog::level::emerg:
return ANDROID_LOG_FATAL;
default:
throw spdlog_ex("Incorrect level value");
return ANDROID_LOG_DEFAULT;
}
}
std::string _tag;
};
typedef base_android_sink<std::mutex> android_sink_mt;
typedef base_android_sink<details::null_mutex> android_sink_st;
}
}

View File

@ -101,6 +101,9 @@ std::shared_ptr<logger> stderr_logger_st(const std::string& logger_name, bool co
std::shared_ptr<logger> syslog_logger(const std::string& logger_name, const std::string& ident = "", int syslog_option = 0);
#endif
#if defined(__ANDROID__)
std::shared_ptr<logger> android_logger(const std::string& logger_name, const std::string& tag = "spdlog");
#endif
// Create and register a logger a single sink
std::shared_ptr<logger> create(const std::string& logger_name, const sink_ptr& sink);