From d05c507c047cd934245f5e0c6c604ca93ca51d97 Mon Sep 17 00:00:00 2001 From: Matthias Schoepfer Date: Mon, 7 Oct 2019 18:03:19 +0200 Subject: [PATCH] Uses GenerateExportHeaders from cmake to export only symbols needed externally This should only affect the library part, and to be more specific, the shared library part. Cmake allows to generate a special header file through GenerateExportHeader()[1]. This defines - amongst other - a SPDLOG_EXPORT Symbol, that does the right thing, depending on compiler / OS. On Windows, default is, if I recall correctly, that all symbols are not exported while Linux does it the other way around. So this patch sets default to *not* export symbols except those marked SPDLOG_EXPORT. Behaviour with Windows and Linux should be the same. Also, I removed SPDLOG_BUILD_SHARED in favour of the standard BUILD_SHARED_LIBS, which is a global symbol. This *might* give some issues when used as add_subdirectory(), but I am not sure. Also I made Threads::Threads private, so a depending cmake package does not need to have find_package(Threads) on. Why all that? On x86_64, gcc 8.3.0 .so code size reduction is: 811320 bytes original vs. 532536 now (~65% of the original). And, I *guess*, this will resolve the issue that it is not possible to use shared libs with windows. But I cannot test it, I only have Linux. [1] https://cmake.org/cmake/help/latest/module/GenerateExportHeader.html Signed-off-by: Matthias Schoepfer --- CMakeLists.txt | 40 +++++++++++-------- include/spdlog/async_logger.h | 4 +- include/spdlog/common.h | 36 ++++++++++------- include/spdlog/details/backtracer.h | 10 ++++- include/spdlog/details/console_globals.h | 9 ++++- include/spdlog/details/file_helper.h | 2 +- include/spdlog/details/log_msg.h | 2 +- include/spdlog/details/log_msg_buffer.h | 7 +++- include/spdlog/details/null_mutex.h | 10 ++++- include/spdlog/details/os.h | 22 +++++++++++ include/spdlog/details/pattern_formatter.h | 6 +-- include/spdlog/details/registry.h | 2 +- include/spdlog/details/thread_pool.h | 6 +-- include/spdlog/fmt/bundled/core.h | 20 +++++++--- include/spdlog/formatter.h | 2 +- include/spdlog/logger.h | 3 +- include/spdlog/sinks/android_sink.h | 4 +- include/spdlog/sinks/base_sink.h | 2 +- include/spdlog/sinks/basic_file_sink.h | 4 +- include/spdlog/sinks/daily_file_sink.h | 4 +- include/spdlog/sinks/dist_sink.h | 2 +- include/spdlog/sinks/dup_filter_sink.h | 2 +- include/spdlog/sinks/msvc_sink.h | 2 +- include/spdlog/sinks/null_sink.h | 2 +- include/spdlog/sinks/ostream_sink.h | 2 +- include/spdlog/sinks/rotating_file_sink.h | 4 +- include/spdlog/sinks/sink.h | 2 +- include/spdlog/sinks/stdout_color_sinks.h | 6 +++ include/spdlog/sinks/stdout_sinks.h | 2 +- include/spdlog/sinks/syslog_sink.h | 2 +- include/spdlog/sinks/systemd_sink.h | 2 +- include/spdlog/sinks/wincolor_sink.h | 6 +-- include/spdlog/spdlog.h | 20 ++++++++++ src/color_sinks.cpp | 45 ++++++++++++---------- src/file_sinks.cpp | 13 +++++-- src/spdlog.cpp | 11 ++++-- src/stdout_sinks.cpp | 33 +++++++++------- tests/CMakeLists.txt | 2 +- 38 files changed, 234 insertions(+), 119 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f6b0788..39a7e4df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,11 +41,6 @@ if (NOT DEFINED SPDLOG_MASTER_PROJECT) endif() endif () -# build shared option -if(NOT WIN32) - option(SPDLOG_BUILD_SHARED "Build shared library" OFF) -endif() - # example options option(SPDLOG_BUILD_EXAMPLE "Build example" ${SPDLOG_MASTER_PROJECT}) option(SPDLOG_BUILD_EXAMPLE_HO "Build header only example" OFF) @@ -101,22 +96,25 @@ if(NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO) list(APPEND SPDLOG_SRCS src/fmt.cpp) endif() -if (SPDLOG_BUILD_SHARED) - if(WIN32) - message(FATAL_ERROR "spdlog shared lib is not yet supported under windows") - endif() - add_library(spdlog SHARED ${SPDLOG_SRCS} ${SPDLOG_ALL_HEADERS}) -else() - add_library(spdlog STATIC ${SPDLOG_SRCS} ${SPDLOG_ALL_HEADERS}) +add_library(spdlog ${SPDLOG_SRCS} ${SPDLOG_ALL_HEADERS}) +add_library(spdlog::spdlog ALIAS spdlog) + +if (BUILD_SHARED_LIBS) + generate_export_header(spdlog) + target_compile_definitions(spdlog PRIVATE SPDLOG_USE_EXPORT_HEADER) + set_target_properties(spdlog PROPERTIES CXX_VISIBILITY_PRESET hidden) + set_target_properties(spdlog PROPERTIES VISIBILITY_INLINES_HIDDEN 1) endif() add_library(spdlog::spdlog ALIAS spdlog) target_compile_definitions(spdlog PUBLIC SPDLOG_COMPILED_LIB) target_include_directories(spdlog PUBLIC - "$" - "$") -target_link_libraries(spdlog PUBLIC Threads::Threads) + "$" + "$" + "$") + +target_link_libraries(spdlog PRIVATE Threads::Threads) spdlog_enable_warnings(spdlog) set_target_properties(spdlog PROPERTIES VERSION ${SPDLOG_VERSION} SOVERSION ${SPDLOG_VERSION_MAJOR}) @@ -129,8 +127,10 @@ add_library(spdlog_header_only INTERFACE) add_library(spdlog::spdlog_header_only ALIAS spdlog_header_only) target_include_directories(spdlog_header_only INTERFACE - "$" - "$") + "$" + "$" + "$") + target_link_libraries(spdlog_header_only INTERFACE Threads::Threads) @@ -154,6 +154,10 @@ if(SPDLOG_FMT_EXTERNAL OR SPDLOG_FMT_EXTERNAL_HO) endif() set(PKG_CONFIG_REQUIRES fmt) # add dependency to pkg-config +else() + if (BUILD_SHARED_LIBS) + target_compile_definitions(spdlog PRIVATE FMT_SHARED) + endif() endif() #--------------------------------------------------------------------------------------- @@ -241,6 +245,8 @@ if (SPDLOG_INSTALL) # Include files #--------------------------------------------------------------------------------------- install(DIRECTORY include/ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" PATTERN "fmt/bundled" EXCLUDE) + install(FILES ${PROJECT_BINARY_DIR}/spdlog_export.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + install(TARGETS spdlog spdlog_header_only EXPORT spdlog DESTINATION "${CMAKE_INSTALL_LIBDIR}") if(NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO) diff --git a/include/spdlog/async_logger.h b/include/spdlog/async_logger.h index 829c5acc..417f3ae4 100644 --- a/include/spdlog/async_logger.h +++ b/include/spdlog/async_logger.h @@ -19,7 +19,7 @@ namespace spdlog { // Async overflow policy - block by default. -enum class async_overflow_policy +enum class SPDLOG_EXPORT async_overflow_policy { block, // Block until message can be enqueued overrun_oldest // Discard oldest message in the queue if full when trying to @@ -30,7 +30,7 @@ namespace details { class thread_pool; } -class async_logger final : public std::enable_shared_from_this, public logger +class SPDLOG_EXPORT async_logger final : public std::enable_shared_from_this, public logger { friend class details::thread_pool; diff --git a/include/spdlog/common.h b/include/spdlog/common.h index 830220ef..f4d85ee2 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -5,6 +5,19 @@ #include #include +#ifdef SPDLOG_USE_EXPORT_HEADER +# include "spdlog_export.h" +#else +# define SPDLOG_EXPORT +# if defined(__GNUC__) || defined(__clang__) +# define SPDLOG_DEPRECATED __attribute__((deprecated)) +# elif defined(_MSC_VER) +# define SPDLOG_DEPRECATED __declspec(deprecated) +# else +# define SPDLOG_DEPRECATED +# endif +#endif + #include #include @@ -46,14 +59,6 @@ #define SPDLOG_CONSTEXPR constexpr #endif -#if defined(__GNUC__) || defined(__clang__) -#define SPDLOG_DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define SPDLOG_DEPRECATED __declspec(deprecated) -#else -#define SPDLOG_DEPRECATED -#endif - // disable thread local on msvc 2013 #ifndef SPDLOG_NO_TLS #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__cplusplus_winrt) @@ -138,7 +143,7 @@ using level_t = std::atomic; // Log level enum namespace level { -enum level_enum +enum SPDLOG_EXPORT level_enum { trace = SPDLOG_LEVEL_TRACE, debug = SPDLOG_LEVEL_DEBUG, @@ -164,8 +169,13 @@ enum level_enum } #endif +SPDLOG_EXPORT string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT; + +SPDLOG_EXPORT const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT; + +SPDLOG_EXPORT spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT; using level_hasher = std::hash; @@ -174,7 +184,7 @@ using level_hasher = std::hash; // // Color mode used by sinks with color support. // -enum class color_mode +enum class SPDLOG_EXPORT color_mode { always, automatic, @@ -185,7 +195,7 @@ enum class color_mode // Pattern time - specific time getting to use for pattern_formatter. // local time by default // -enum class pattern_time_type +enum class SPDLOG_EXPORT pattern_time_type { local, // log localtime utc // log utc @@ -194,7 +204,7 @@ enum class pattern_time_type // // Log exception // -class spdlog_ex : public std::exception +class SPDLOG_EXPORT spdlog_ex : public std::exception { public: explicit spdlog_ex(std::string msg); @@ -205,7 +215,7 @@ private: std::string msg_; }; -struct source_loc +struct SPDLOG_EXPORT source_loc { SPDLOG_CONSTEXPR source_loc() = default; SPDLOG_CONSTEXPR source_loc(const char *filename_in, int line_in, const char *funcname_in) diff --git a/include/spdlog/details/backtracer.h b/include/spdlog/details/backtracer.h index 0e779cab..60094f52 100644 --- a/include/spdlog/details/backtracer.h +++ b/include/spdlog/details/backtracer.h @@ -3,6 +3,12 @@ #pragma once +#ifdef SPDLOG_USE_EXPORT_HEADER +#include "spdlog_export.h" +#else +#define SPDLOG_EXPORT +#endif + #include #include @@ -15,7 +21,7 @@ namespace spdlog { namespace details { -class backtracer +class SPDLOG_EXPORT backtracer { mutable std::mutex mutex_; std::atomic enabled_{false}; @@ -42,4 +48,4 @@ public: #ifdef SPDLOG_HEADER_ONLY #include "backtracer-inl.h" -#endif \ No newline at end of file +#endif diff --git a/include/spdlog/details/console_globals.h b/include/spdlog/details/console_globals.h index 665201dd..1b8d4bde 100644 --- a/include/spdlog/details/console_globals.h +++ b/include/spdlog/details/console_globals.h @@ -3,13 +3,18 @@ #pragma once +#ifdef SPDLOG_USE_EXPORT_HEADER +#include "spdlog_export.h" +#else +#define SPDLOG_EXPORT +#endif #include #include namespace spdlog { namespace details { -struct console_mutex +struct SPDLOG_EXPORT console_mutex { using mutex_t = std::mutex; static mutex_t &mutex() @@ -19,7 +24,7 @@ struct console_mutex } }; -struct console_nullmutex +struct SPDLOG_EXPORT console_nullmutex { using mutex_t = null_mutex; static mutex_t &mutex() diff --git a/include/spdlog/details/file_helper.h b/include/spdlog/details/file_helper.h index 3228ce84..3774e63f 100644 --- a/include/spdlog/details/file_helper.h +++ b/include/spdlog/details/file_helper.h @@ -13,7 +13,7 @@ namespace details { // When failing to open a file, retry several times(5) with a delay interval(10 ms). // Throw spdlog_ex exception on errors. -class file_helper +class SPDLOG_EXPORT file_helper { public: explicit file_helper() = default; diff --git a/include/spdlog/details/log_msg.h b/include/spdlog/details/log_msg.h index 9ae473d4..f8528594 100644 --- a/include/spdlog/details/log_msg.h +++ b/include/spdlog/details/log_msg.h @@ -8,7 +8,7 @@ namespace spdlog { namespace details { -struct log_msg +struct SPDLOG_EXPORT log_msg { log_msg() = default; log_msg(source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg); diff --git a/include/spdlog/details/log_msg_buffer.h b/include/spdlog/details/log_msg_buffer.h index c20ae7b0..e4cae9e5 100644 --- a/include/spdlog/details/log_msg_buffer.h +++ b/include/spdlog/details/log_msg_buffer.h @@ -3,6 +3,11 @@ #pragma once +#ifdef SPDLOG_USE_EXPORT_HEADER +#include "spdlog_export.h" +#else +#define SPDLOG_EXPORT +#endif #include namespace spdlog { @@ -11,7 +16,7 @@ namespace details { // Extend log_msg with internal buffer to store its payload. // THis is needed since log_msg holds string_views that points to stack data. -class log_msg_buffer : public log_msg +class SPDLOG_EXPORT log_msg_buffer : public log_msg { memory_buf_t buffer; void update_string_views(); diff --git a/include/spdlog/details/null_mutex.h b/include/spdlog/details/null_mutex.h index 83533d4f..9d0e897e 100644 --- a/include/spdlog/details/null_mutex.h +++ b/include/spdlog/details/null_mutex.h @@ -3,13 +3,19 @@ #pragma once +#ifdef SPDLOG_USE_EXPORT_HEADER +#include "spdlog_export.h" +#else +#define SPDLOG_EXPORT +#endif + #include #include // null, no cost dummy "mutex" and dummy "atomic" int namespace spdlog { namespace details { -struct null_mutex +struct SPDLOG_EXPORT null_mutex { void lock() const {} void unlock() const {} @@ -19,7 +25,7 @@ struct null_mutex } }; -struct null_atomic_int +struct SPDLOG_EXPORT null_atomic_int { int value; null_atomic_int() = default; diff --git a/include/spdlog/details/os.h b/include/spdlog/details/os.h index 0894a6c0..29bb156b 100644 --- a/include/spdlog/details/os.h +++ b/include/spdlog/details/os.h @@ -10,14 +10,19 @@ namespace spdlog { namespace details { namespace os { +SPDLOG_EXPORT spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT; +SPDLOG_EXPORT std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT; +SPDLOG_EXPORT std::tm localtime() SPDLOG_NOEXCEPT; +SPDLOG_EXPORT std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT; +SPDLOG_EXPORT std::tm gmtime() SPDLOG_NOEXCEPT; // eol definition @@ -39,52 +44,67 @@ SPDLOG_CONSTEXPR static const char folder_sep = '/'; #endif #ifdef SPDLOG_PREVENT_CHILD_FD +SPDLOG_EXPORT void prevent_child_fd(FILE *f); #endif // fopen_s on non windows for writing +SPDLOG_EXPORT bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode); // Remove filename. return 0 on success +SPDLOG_EXPORT int remove(const filename_t &filename) SPDLOG_NOEXCEPT; // Remove file if exists. return 0 on success // Note: Non atomic (might return failure to delete if concurrently deleted by other process/thread) +SPDLOG_EXPORT int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT; +SPDLOG_EXPORT int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT; // Return if file exists. +SPDLOG_EXPORT bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT; // Return file size according to open FILE* object +SPDLOG_EXPORT size_t filesize(FILE *f); // Return utc offset in minutes or throw spdlog_ex on failure +SPDLOG_EXPORT int utc_minutes_offset(const std::tm &tm = details::os::localtime()); // Return current thread id as size_t // It exists because the std::this_thread::get_id() is much slower(especially // under VS 2013) +SPDLOG_EXPORT size_t _thread_id() SPDLOG_NOEXCEPT; // Return current thread id as size_t (from thread local storage) +SPDLOG_EXPORT size_t thread_id() SPDLOG_NOEXCEPT; // This is avoid msvc issue in sleep_for that happens if the clock changes. // See https://github.com/gabime/spdlog/issues/609 +SPDLOG_EXPORT void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT; +SPDLOG_EXPORT std::string filename_to_str(const filename_t &filename); +SPDLOG_EXPORT int pid() SPDLOG_NOEXCEPT; // Determine if the terminal supports colors // Source: https://github.com/agauniyal/rang/ +SPDLOG_EXPORT bool is_color_terminal() SPDLOG_NOEXCEPT; // Determine if the terminal attached // Source: https://github.com/agauniyal/rang/ +SPDLOG_EXPORT bool in_terminal(FILE *file) SPDLOG_NOEXCEPT; #if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) @@ -96,10 +116,12 @@ void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target); // "abc/" => "abc" // "abc" => "" // "abc///" => "abc//" +SPDLOG_EXPORT filename_t dir_name(filename_t path); // Create a dir from the given path. // Return true if succeeded or if this dir already exists. +SPDLOG_EXPORT bool create_dir(filename_t path); } // namespace os diff --git a/include/spdlog/details/pattern_formatter.h b/include/spdlog/details/pattern_formatter.h index fa134ada..47cb4104 100644 --- a/include/spdlog/details/pattern_formatter.h +++ b/include/spdlog/details/pattern_formatter.h @@ -19,7 +19,7 @@ namespace spdlog { namespace details { // padding information. -struct padding_info +struct SPDLOG_EXPORT padding_info { enum pad_side { @@ -46,7 +46,7 @@ struct padding_info bool enabled_ = false; }; -class flag_formatter +class SPDLOG_EXPORT flag_formatter { public: explicit flag_formatter(padding_info padinfo) @@ -62,7 +62,7 @@ protected: } // namespace details -class pattern_formatter final : public formatter +class SPDLOG_EXPORT pattern_formatter final : public formatter { public: explicit pattern_formatter( diff --git a/include/spdlog/details/registry.h b/include/spdlog/details/registry.h index 6ac571dc..d2aff92f 100644 --- a/include/spdlog/details/registry.h +++ b/include/spdlog/details/registry.h @@ -24,7 +24,7 @@ namespace details { class thread_pool; class periodic_worker; -class registry +class SPDLOG_EXPORT registry { public: registry(const registry &) = delete; diff --git a/include/spdlog/details/thread_pool.h b/include/spdlog/details/thread_pool.h index 12078044..226f1866 100644 --- a/include/spdlog/details/thread_pool.h +++ b/include/spdlog/details/thread_pool.h @@ -20,7 +20,7 @@ namespace details { using async_logger_ptr = std::shared_ptr; -enum class async_msg_type +enum class SPDLOG_EXPORT async_msg_type { log, flush, @@ -30,7 +30,7 @@ enum class async_msg_type #include // Async msg to move to/from the queue // Movable only. should never be copied -struct async_msg : log_msg_buffer +struct SPDLOG_EXPORT async_msg : log_msg_buffer { async_msg_type msg_type{async_msg_type::log}; async_logger_ptr worker_ptr; @@ -79,7 +79,7 @@ struct async_msg : log_msg_buffer {} }; -class thread_pool +class SPDLOG_EXPORT thread_pool { public: using item_type = async_msg; diff --git a/include/spdlog/fmt/bundled/core.h b/include/spdlog/fmt/bundled/core.h index bcce2f50..4ba539c7 100644 --- a/include/spdlog/fmt/bundled/core.h +++ b/include/spdlog/fmt/bundled/core.h @@ -152,12 +152,20 @@ FMT_INLINE_NAMESPACE v6 { #endif -#if !defined(FMT_HEADER_ONLY) && defined(_WIN32) -# ifdef FMT_EXPORT -# define FMT_API __declspec(dllexport) -# elif defined(FMT_SHARED) -# define FMT_API __declspec(dllimport) -# define FMT_EXTERN_TEMPLATE_API FMT_API +#if !defined(FMT_HEADER_ONLY) +# ifdef SPDLOG_USE_EXPORT_HEADER +# include "spdlog_export.h" +# define FMT_API SPDLOG_EXPORT +# elif defined (_WIN32) +# ifdef FMT_EXPORT +# define FMT_API __declspec(dllexport) +# elif defined(FMT_SHARED) +# define FMT_API __declspec(dllimport) +# define FMT_EXTERN_TEMPLATE_API FMT_API +# else +# define FMT_API +# define FMT_EXTERN_TEMPLATE_API +# endif # endif #endif #ifndef FMT_API diff --git a/include/spdlog/formatter.h b/include/spdlog/formatter.h index 5086fb21..67cbaf84 100644 --- a/include/spdlog/formatter.h +++ b/include/spdlog/formatter.h @@ -8,7 +8,7 @@ namespace spdlog { -class formatter +class SPDLOG_EXPORT formatter { public: virtual ~formatter() = default; diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index 43f39600..5adb2f2b 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -39,7 +39,7 @@ namespace spdlog { -class logger +class SPDLOG_EXPORT logger { public: // Empty logger @@ -365,6 +365,7 @@ protected: void err_handler_(const std::string &msg); }; +SPDLOG_EXPORT void swap(logger &a, logger &b); } // namespace spdlog diff --git a/include/spdlog/sinks/android_sink.h b/include/spdlog/sinks/android_sink.h index bdbe542b..73ea3a20 100644 --- a/include/spdlog/sinks/android_sink.h +++ b/include/spdlog/sinks/android_sink.h @@ -28,7 +28,7 @@ namespace sinks { * Android sink (logging using __android_log_write) */ template -class android_sink final : public base_sink +class SPDLOG_EXPORT android_sink final : public base_sink { public: explicit android_sink(std::string tag = "spdlog", bool use_raw_msg = false) @@ -116,4 +116,4 @@ inline std::shared_ptr android_logger_st(const std::string &logger_name, } // namespace spdlog -#endif // __ANDROID__ \ No newline at end of file +#endif // __ANDROID__ diff --git a/include/spdlog/sinks/base_sink.h b/include/spdlog/sinks/base_sink.h index bc832763..267cac06 100644 --- a/include/spdlog/sinks/base_sink.h +++ b/include/spdlog/sinks/base_sink.h @@ -16,7 +16,7 @@ namespace spdlog { namespace sinks { template -class base_sink : public sink +class SPDLOG_EXPORT base_sink : public sink { public: base_sink(); diff --git a/include/spdlog/sinks/basic_file_sink.h b/include/spdlog/sinks/basic_file_sink.h index 0ab9a4a1..cabc5dd1 100644 --- a/include/spdlog/sinks/basic_file_sink.h +++ b/include/spdlog/sinks/basic_file_sink.h @@ -17,7 +17,7 @@ namespace sinks { * Trivial file sink with single file as target */ template -class basic_file_sink final : public base_sink +class SPDLOG_EXPORT basic_file_sink final : public base_sink { public: explicit basic_file_sink(const filename_t &filename, bool truncate = false); @@ -55,4 +55,4 @@ inline std::shared_ptr basic_logger_st(const std::string &logger_name, c #ifdef SPDLOG_HEADER_ONLY #include "basic_file_sink-inl.h" -#endif \ No newline at end of file +#endif diff --git a/include/spdlog/sinks/daily_file_sink.h b/include/spdlog/sinks/daily_file_sink.h index 40a37a71..a0be246a 100644 --- a/include/spdlog/sinks/daily_file_sink.h +++ b/include/spdlog/sinks/daily_file_sink.h @@ -24,7 +24,7 @@ namespace sinks { /* * Generator of daily log file names in format basename.YYYY-MM-DD.ext */ -struct daily_filename_calculator +struct SPDLOG_EXPORT daily_filename_calculator { // Create filename for the form basename.YYYY-MM-DD static filename_t calc_filename(const filename_t &filename, const tm &now_tm) @@ -42,7 +42,7 @@ struct daily_filename_calculator * If max_files > 0, retain only the last max_files and delete previous. */ template -class daily_file_sink final : public base_sink +class SPDLOG_EXPORT daily_file_sink final : public base_sink { public: // create daily file sink which rotates on given time diff --git a/include/spdlog/sinks/dist_sink.h b/include/spdlog/sinks/dist_sink.h index ae98fee4..7130de17 100644 --- a/include/spdlog/sinks/dist_sink.h +++ b/include/spdlog/sinks/dist_sink.h @@ -20,7 +20,7 @@ namespace spdlog { namespace sinks { template -class dist_sink : public base_sink +class SPDLOG_EXPORT dist_sink : public base_sink { public: dist_sink() = default; diff --git a/include/spdlog/sinks/dup_filter_sink.h b/include/spdlog/sinks/dup_filter_sink.h index 8ee63e40..03197980 100644 --- a/include/spdlog/sinks/dup_filter_sink.h +++ b/include/spdlog/sinks/dup_filter_sink.h @@ -36,7 +36,7 @@ namespace spdlog { namespace sinks { template -class dup_filter_sink : public dist_sink +class SPDLOG_EXPORT dup_filter_sink : public dist_sink { public: template diff --git a/include/spdlog/sinks/msvc_sink.h b/include/spdlog/sinks/msvc_sink.h index 6db10bc9..611ab184 100644 --- a/include/spdlog/sinks/msvc_sink.h +++ b/include/spdlog/sinks/msvc_sink.h @@ -19,7 +19,7 @@ namespace sinks { * MSVC sink (logging using OutputDebugStringA) */ template -class msvc_sink : public base_sink +class SPDLOG_EXPORT msvc_sink : public base_sink { public: explicit msvc_sink() {} diff --git a/include/spdlog/sinks/null_sink.h b/include/spdlog/sinks/null_sink.h index eb832801..2d07bdfe 100644 --- a/include/spdlog/sinks/null_sink.h +++ b/include/spdlog/sinks/null_sink.h @@ -13,7 +13,7 @@ namespace spdlog { namespace sinks { template -class null_sink : public base_sink +class SPDLOG_EXPORT null_sink : public base_sink { protected: void sink_it_(const details::log_msg &) override {} diff --git a/include/spdlog/sinks/ostream_sink.h b/include/spdlog/sinks/ostream_sink.h index 95c1e962..5365a46e 100644 --- a/include/spdlog/sinks/ostream_sink.h +++ b/include/spdlog/sinks/ostream_sink.h @@ -12,7 +12,7 @@ namespace spdlog { namespace sinks { template -class ostream_sink final : public base_sink +class SPDLOG_EXPORT ostream_sink final : public base_sink { public: explicit ostream_sink(std::ostream &os, bool force_flush = false) diff --git a/include/spdlog/sinks/rotating_file_sink.h b/include/spdlog/sinks/rotating_file_sink.h index 5be8583a..0be571f4 100644 --- a/include/spdlog/sinks/rotating_file_sink.h +++ b/include/spdlog/sinks/rotating_file_sink.h @@ -19,7 +19,7 @@ namespace sinks { // Rotating file sink based on size // template -class rotating_file_sink final : public base_sink +class SPDLOG_EXPORT rotating_file_sink final : public base_sink { public: rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false); @@ -75,4 +75,4 @@ inline std::shared_ptr rotating_logger_st( #ifdef SPDLOG_HEADER_ONLY #include "rotating_file_sink-inl.h" -#endif \ No newline at end of file +#endif diff --git a/include/spdlog/sinks/sink.h b/include/spdlog/sinks/sink.h index b2ca4db1..1e59c9c4 100644 --- a/include/spdlog/sinks/sink.h +++ b/include/spdlog/sinks/sink.h @@ -9,7 +9,7 @@ namespace spdlog { namespace sinks { -class sink +class SPDLOG_EXPORT sink { public: virtual ~sink() = default; diff --git a/include/spdlog/sinks/stdout_color_sinks.h b/include/spdlog/sinks/stdout_color_sinks.h index e67aa91b..75ee3584 100644 --- a/include/spdlog/sinks/stdout_color_sinks.h +++ b/include/spdlog/sinks/stdout_color_sinks.h @@ -9,6 +9,12 @@ #include #endif +#ifdef SPDLOG_USE_EXPORT_HEADER +#include "spdlog_export.h" +#else +#define SPDLOG_EXPORT +#endif + #include namespace spdlog { diff --git a/include/spdlog/sinks/stdout_sinks.h b/include/spdlog/sinks/stdout_sinks.h index 1cc47bd0..a74e4326 100644 --- a/include/spdlog/sinks/stdout_sinks.h +++ b/include/spdlog/sinks/stdout_sinks.h @@ -13,7 +13,7 @@ namespace spdlog { namespace sinks { template -class stdout_sink_base : public sink +class SPDLOG_EXPORT stdout_sink_base : public sink { public: using mutex_t = typename ConsoleMutex::mutex_t; diff --git a/include/spdlog/sinks/syslog_sink.h b/include/spdlog/sinks/syslog_sink.h index 2f4e3fde..abb07e2f 100644 --- a/include/spdlog/sinks/syslog_sink.h +++ b/include/spdlog/sinks/syslog_sink.h @@ -16,7 +16,7 @@ namespace sinks { * Sink that write to syslog using the `syscall()` library call. */ template -class syslog_sink : public base_sink +class SPDLOG_EXPORT syslog_sink : public base_sink { public: diff --git a/include/spdlog/sinks/systemd_sink.h b/include/spdlog/sinks/systemd_sink.h index d90edb22..2d8b54af 100644 --- a/include/spdlog/sinks/systemd_sink.h +++ b/include/spdlog/sinks/systemd_sink.h @@ -22,7 +22,7 @@ namespace sinks { * Locking is not needed, as `sd_journal_send()` itself is thread-safe. */ template -class systemd_sink : public base_sink +class SPDLOG_EXPORT systemd_sink : public base_sink { public: // diff --git a/include/spdlog/sinks/wincolor_sink.h b/include/spdlog/sinks/wincolor_sink.h index 743db5c6..c211c193 100644 --- a/include/spdlog/sinks/wincolor_sink.h +++ b/include/spdlog/sinks/wincolor_sink.h @@ -21,7 +21,7 @@ namespace sinks { * colors */ template -class wincolor_sink : public sink +class SPDLOG_EXPORT wincolor_sink : public sink { public: const WORD BOLD = FOREGROUND_INTENSITY; @@ -65,14 +65,14 @@ protected: }; template -class wincolor_stdout_sink : public wincolor_sink +class SPDLOG_EXPORT wincolor_stdout_sink : public wincolor_sink { public: explicit wincolor_stdout_sink(color_mode mode = color_mode::automatic); }; template -class wincolor_stderr_sink : public wincolor_sink +class SPDLOG_EXPORT wincolor_stderr_sink : public wincolor_sink { public: explicit wincolor_stderr_sink(color_mode mode = color_mode::automatic); diff --git a/include/spdlog/spdlog.h b/include/spdlog/spdlog.h index facb0b3f..f61e5b3b 100644 --- a/include/spdlog/spdlog.h +++ b/include/spdlog/spdlog.h @@ -46,60 +46,77 @@ inline std::shared_ptr create(std::string logger_name, SinkArgs // auto console_sink = std::make_shared(); // auto console_logger = std::make_shared("console_logger", console_sink); // spdlog::initialize_logger(console_logger); +SPDLOG_EXPORT void initialize_logger(std::shared_ptr logger); // Return an existing logger or nullptr if a logger with such name doesn't // exist. // example: spdlog::get("my_logger")->info("hello {}", "world"); +SPDLOG_EXPORT std::shared_ptr get(const std::string &name); // Set global formatter. Each sink in each logger will get a clone of this object +SPDLOG_EXPORT void set_formatter(std::unique_ptr formatter); // Set global format string. // example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v"); +SPDLOG_EXPORT void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local); // enable global backtrace support +SPDLOG_EXPORT void enable_backtrace(size_t n_messages); // disable global backtrace support +SPDLOG_EXPORT void disable_backtrace(); // call dump backtrace on default logger +SPDLOG_EXPORT void dump_backtrace(); // Set global logging level +SPDLOG_EXPORT void set_level(level::level_enum log_level); // Set global flush level +SPDLOG_EXPORT void flush_on(level::level_enum log_level); // Start/Restart a periodic flusher thread // Warning: Use only if all your loggers are thread safe! +SPDLOG_EXPORT void flush_every(std::chrono::seconds interval); // Set global error handler +SPDLOG_EXPORT void set_error_handler(void (*handler)(const std::string &msg)); // Register the given logger with the given name +SPDLOG_EXPORT void register_logger(std::shared_ptr logger); // Apply a user defined function on all registered loggers // Example: // spdlog::apply_all([&](std::shared_ptr l) {l->flush();}); +SPDLOG_EXPORT void apply_all(const std::function)> &fun); // Drop the reference to the given logger +SPDLOG_EXPORT void drop(const std::string &name); // Drop all references from the registry +SPDLOG_EXPORT void drop_all(); // stop any running threads started by spdlog and clean registry loggers +SPDLOG_EXPORT void shutdown(); // Automatic registration of loggers when using spdlog::create() or spdlog::create_async +SPDLOG_EXPORT void set_automatic_registration(bool automatic_registration); // API for using default logger (stdout_color_mt), @@ -117,10 +134,13 @@ void set_automatic_registration(bool automatic_registration); // set_default_logger() *should not* be used concurrently with the default API. // e.g do not call set_default_logger() from one thread while calling spdlog::info() from another. +SPDLOG_EXPORT std::shared_ptr default_logger(); +SPDLOG_EXPORT spdlog::logger *default_logger_raw(); +SPDLOG_EXPORT void set_default_logger(std::shared_ptr default_logger); template diff --git a/src/color_sinks.cpp b/src/color_sinks.cpp index 3a335a77..45816762 100644 --- a/src/color_sinks.cpp +++ b/src/color_sinks.cpp @@ -7,6 +7,11 @@ #include +#ifdef SPDLOG_USE_EXPORT_HEADER +#include "spdlog_export.h" +#else +#define SPDLOG_EXPORT +#endif #include "spdlog/details/null_mutex.h" #include "spdlog/async.h" // @@ -14,34 +19,34 @@ // #ifdef _WIN32 #include "spdlog/sinks/wincolor_sink-inl.h" -template class spdlog::sinks::wincolor_sink; -template class spdlog::sinks::wincolor_sink; -template class spdlog::sinks::wincolor_stdout_sink; -template class spdlog::sinks::wincolor_stdout_sink; -template class spdlog::sinks::wincolor_stderr_sink; -template class spdlog::sinks::wincolor_stderr_sink; +template class SPDLOG_EXPORT spdlog::sinks::wincolor_sink; +template class SPDLOG_EXPORT spdlog::sinks::wincolor_sink; +template class SPDLOG_EXPORT spdlog::sinks::wincolor_stdout_sink; +template class SPDLOG_EXPORT spdlog::sinks::wincolor_stdout_sink; +template class SPDLOG_EXPORT spdlog::sinks::wincolor_stderr_sink; +template class SPDLOG_EXPORT spdlog::sinks::wincolor_stderr_sink; #else #include "spdlog/sinks/ansicolor_sink-inl.h" -template class spdlog::sinks::ansicolor_sink; -template class spdlog::sinks::ansicolor_sink; -template class spdlog::sinks::ansicolor_stdout_sink; -template class spdlog::sinks::ansicolor_stdout_sink; -template class spdlog::sinks::ansicolor_stderr_sink; -template class spdlog::sinks::ansicolor_stderr_sink; +template class SPDLOG_EXPORT spdlog::sinks::ansicolor_sink; +template class SPDLOG_EXPORT spdlog::sinks::ansicolor_sink; +template class SPDLOG_EXPORT spdlog::sinks::ansicolor_stdout_sink; +template class SPDLOG_EXPORT spdlog::sinks::ansicolor_stdout_sink; +template class SPDLOG_EXPORT spdlog::sinks::ansicolor_stderr_sink; +template class SPDLOG_EXPORT spdlog::sinks::ansicolor_stderr_sink; #endif // factory methods for color loggers #include "spdlog/sinks/stdout_color_sinks-inl.h" -template std::shared_ptr spdlog::stdout_color_mt( +template SPDLOG_EXPORT std::shared_ptr spdlog::stdout_color_mt( const std::string &logger_name, color_mode mode); -template std::shared_ptr spdlog::stdout_color_st( +template SPDLOG_EXPORT std::shared_ptr spdlog::stdout_color_st( const std::string &logger_name, color_mode mode); -template std::shared_ptr spdlog::stderr_color_mt( +template SPDLOG_EXPORT std::shared_ptr spdlog::stderr_color_mt( const std::string &logger_name, color_mode mode); -template std::shared_ptr spdlog::stderr_color_st( +template SPDLOG_EXPORT std::shared_ptr spdlog::stderr_color_st( const std::string &logger_name, color_mode mode); -template std::shared_ptr spdlog::stdout_color_mt(const std::string &logger_name, color_mode mode); -template std::shared_ptr spdlog::stdout_color_st(const std::string &logger_name, color_mode mode); -template std::shared_ptr spdlog::stderr_color_mt(const std::string &logger_name, color_mode mode); -template std::shared_ptr spdlog::stderr_color_st(const std::string &logger_name, color_mode mode); +template SPDLOG_EXPORT std::shared_ptr spdlog::stdout_color_mt(const std::string &logger_name, color_mode mode); +template SPDLOG_EXPORT std::shared_ptr spdlog::stdout_color_st(const std::string &logger_name, color_mode mode); +template SPDLOG_EXPORT std::shared_ptr spdlog::stderr_color_mt(const std::string &logger_name, color_mode mode); +template SPDLOG_EXPORT std::shared_ptr spdlog::stderr_color_st(const std::string &logger_name, color_mode mode); diff --git a/src/file_sinks.cpp b/src/file_sinks.cpp index bc23f8d5..dd606509 100644 --- a/src/file_sinks.cpp +++ b/src/file_sinks.cpp @@ -6,13 +6,18 @@ #endif #include +#ifdef SPDLOG_USE_EXPORT_HEADER +#include "spdlog_export.h" +#else +#define SPDLOG_EXPORT +#endif #include "spdlog/details/null_mutex.h" #include "spdlog/details/file_helper-inl.h" #include "spdlog/sinks/basic_file_sink-inl.h" -template class spdlog::sinks::basic_file_sink; -template class spdlog::sinks::basic_file_sink; +template class SPDLOG_EXPORT spdlog::sinks::basic_file_sink; +template class SPDLOG_EXPORT spdlog::sinks::basic_file_sink; #include "spdlog/sinks/rotating_file_sink-inl.h" -template class spdlog::sinks::rotating_file_sink; -template class spdlog::sinks::rotating_file_sink; \ No newline at end of file +template class SPDLOG_EXPORT spdlog::sinks::rotating_file_sink; +template class SPDLOG_EXPORT spdlog::sinks::rotating_file_sink; diff --git a/src/spdlog.cpp b/src/spdlog.cpp index ec183c95..57d179c8 100644 --- a/src/spdlog.cpp +++ b/src/spdlog.cpp @@ -5,6 +5,11 @@ #error Please define SPDLOG_COMPILED_LIB to compile this file. #endif +#ifdef SPDLOG_USE_EXPORT_HEADER +#include "spdlog_export.h" +#else +#define SPDLOG_EXPORT +#endif #include "spdlog/spdlog-inl.h" #include "spdlog/common-inl.h" #include "spdlog/details/backtracer-inl.h" @@ -21,6 +26,6 @@ #include // template instantiate logger constructor with sinks init list -template spdlog::logger::logger(std::string name, sinks_init_list::iterator begin, sinks_init_list::iterator end); -template class spdlog::sinks::base_sink; -template class spdlog::sinks::base_sink; \ No newline at end of file +template SPDLOG_EXPORT spdlog::logger::logger(std::string name, sinks_init_list::iterator begin, sinks_init_list::iterator end); +template class SPDLOG_EXPORT spdlog::sinks::base_sink; +template class SPDLOG_EXPORT spdlog::sinks::base_sink; diff --git a/src/stdout_sinks.cpp b/src/stdout_sinks.cpp index 36d6699e..6e42e999 100644 --- a/src/stdout_sinks.cpp +++ b/src/stdout_sinks.cpp @@ -7,23 +7,28 @@ #include +#ifdef SPDLOG_USE_EXPORT_HEADER +#include "spdlog_export.h" +#else +#define SPDLOG_EXPORT +#endif #include "spdlog/details/null_mutex.h" #include "spdlog/async.h" #include "spdlog/sinks/stdout_sinks-inl.h" -template class spdlog::sinks::stdout_sink_base; -template class spdlog::sinks::stdout_sink_base; -template class spdlog::sinks::stdout_sink; -template class spdlog::sinks::stdout_sink; -template class spdlog::sinks::stderr_sink; -template class spdlog::sinks::stderr_sink; +template class SPDLOG_EXPORT spdlog::sinks::stdout_sink_base; +template class SPDLOG_EXPORT spdlog::sinks::stdout_sink_base; +template class SPDLOG_EXPORT spdlog::sinks::stdout_sink; +template class SPDLOG_EXPORT spdlog::sinks::stdout_sink; +template class SPDLOG_EXPORT spdlog::sinks::stderr_sink; +template class SPDLOG_EXPORT spdlog::sinks::stderr_sink; -template std::shared_ptr spdlog::stdout_logger_mt(const std::string &logger_name); -template std::shared_ptr spdlog::stdout_logger_st(const std::string &logger_name); -template std::shared_ptr spdlog::stderr_logger_mt(const std::string &logger_name); -template std::shared_ptr spdlog::stderr_logger_st(const std::string &logger_name); +template SPDLOG_EXPORT std::shared_ptr spdlog::stdout_logger_mt(const std::string &logger_name); +template SPDLOG_EXPORT std::shared_ptr spdlog::stdout_logger_st(const std::string &logger_name); +template SPDLOG_EXPORT std::shared_ptr spdlog::stderr_logger_mt(const std::string &logger_name); +template SPDLOG_EXPORT std::shared_ptr spdlog::stderr_logger_st(const std::string &logger_name); -template std::shared_ptr spdlog::stdout_logger_mt(const std::string &logger_name); -template std::shared_ptr spdlog::stdout_logger_st(const std::string &logger_name); -template std::shared_ptr spdlog::stderr_logger_mt(const std::string &logger_name); -template std::shared_ptr spdlog::stderr_logger_st(const std::string &logger_name); \ No newline at end of file +template SPDLOG_EXPORT std::shared_ptr spdlog::stdout_logger_mt(const std::string &logger_name); +template SPDLOG_EXPORT std::shared_ptr spdlog::stdout_logger_st(const std::string &logger_name); +template SPDLOG_EXPORT std::shared_ptr spdlog::stderr_logger_mt(const std::string &logger_name); +template SPDLOG_EXPORT std::shared_ptr spdlog::stderr_logger_st(const std::string &logger_name); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3184e9b6..d3a7ac22 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -41,7 +41,7 @@ function(spdlog_prepare_test test_target spdlog_lib) spdlog_enable_warnings(${test_target}) target_link_libraries(${test_target} PRIVATE ${spdlog_lib}) if(systemd_FOUND) - target_link_libraries(${test_target} PRIVATE ${systemd_LIBRARIES}) + target_link_libraries(${test_target} PRIVATE ${systemd_LIBRARIES} Threads::Threads) endif() if(SPDLOG_SANITIZE_ADDRESS) spdlog_enable_sanitizer(${test_target})