From 6da328e9afafe847e2858f736f4f05b761d6aa7f Mon Sep 17 00:00:00 2001 From: Pavel Artsishevsky Date: Mon, 2 Dec 2024 13:51:23 +0100 Subject: [PATCH] CMake: detect support of unicode char types Signed-off-by: Pavel Artsishevsky --- .iwyu-mappings | 2 ++ CMakeLists.txt | 9 --------- cmake/Helpers.cmake | 28 +++++++++++++++++++++++++++ include/slimlog/pattern-inl.h | 2 +- src/CMakeLists.txt | 36 ++++++++++++++++++++++++++++++++++- src/slimlog.cpp | 28 ++++++++++++++++++++------- 6 files changed, 87 insertions(+), 18 deletions(-) diff --git a/.iwyu-mappings b/.iwyu-mappings index 4b8ed68..c86867b 100644 --- a/.iwyu-mappings +++ b/.iwyu-mappings @@ -12,6 +12,8 @@ { include: [ "<__hash_table>", "private", "", "public" ] }, { include: [ "<__hash_table>", "private", "", "public" ] }, { include: [ "<__locale>", "private", "", "public" ] }, + # Bug on stdlibc++: std::tm is not from + { symbol: [ "std::tm", "private", "", "public" ] }, # Bug on stdlibc++ w/o fmtlib: std::pair is not from { symbol: [ "std::pair", "private", "", "public" ] }, # Bug on libc++ w/o fmtlib: std::reference_wrapper is not from diff --git a/CMakeLists.txt b/CMakeLists.txt index e461356..1fe2d89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,15 +136,6 @@ find_package_switchable( PURPOSE ${FMT_PURPOSE} ) -# If fmtlib is not available, check for C++20 std::format() -if(NOT ENABLE_FMTLIB AND NOT ENABLE_FMTLIB_HO) - include(CheckCXXSymbolExists) - check_cxx_symbol_exists("std::make_format_args" "format" HAS_CXX20_FORMAT) - if(NOT HAS_CXX20_FORMAT) - message(FATAL_ERROR "C++20 std::format() is not available, please enable fmtlib support") - endif() -endif() - # Include library targets add_subdirectory(src) diff --git a/cmake/Helpers.cmake b/cmake/Helpers.cmake index 0bc6266..453fa8d 100644 --- a/cmake/Helpers.cmake +++ b/cmake/Helpers.cmake @@ -21,6 +21,16 @@ # - `-DENABLE_MYPKG=ON`: marks package as required and fails if it is not found; # - `-DENABLE_MYPKG=OFF`: disables package and does not call find_package(). # +# If package is found, the following variables are propagated to parent scope: +# +# - `\${package}_FOUND`: whether the package was found; +# - `\${package}_VERSION`: full provided version string; +# - `\${package}_VERSION_MAJOR`: major version if provided, else 0; +# - `\${package}_VERSION_MINOR`: minor version if provided, else 0; +# - `\${package}_VERSION_PATCH`: patch version if provided, else 0; +# - `\${package}_VERSION_TWEAK`: tweak version if provided, else 0; +# - `\${package}_VERSION_COUNT`: number of version components, 0 to 4. +# # ~~~{.cmake} # include(Helpers) # find_package_switchable(MyPackage @@ -84,6 +94,24 @@ function(find_package_switchable package) endif() option(${ARG_OPTION} ${ARG_PURPOSE} ${${ARG_OPTION}}) endif() + if(${${package}_FOUND}) + # Expand version variables visibility to parent scope + foreach( + suffix + FOUND + VERSION + VERSION_MAJOR + VERSION_MINOR + VERSION_PATCH + VERSION_TWEAK + VERSION_COUNT + ) + set(${package}_${suffix} + ${${package}_${suffix}} + PARENT_SCOPE + ) + endforeach() + endif() endfunction() # [cmake_documentation] dump_option_variables(filter) diff --git a/include/slimlog/pattern-inl.h b/include/slimlog/pattern-inl.h index ff74dce..3f9d629 100644 --- a/include/slimlog/pattern-inl.h +++ b/include/slimlog/pattern-inl.h @@ -19,12 +19,12 @@ #include #include +#include #include #include #if defined(__cpp_unicode_characters) or defined(__cpp_char8_t) #include // IWYU pragma: keep #endif -#include #include #include #include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 763f89b..33b4e5e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,14 +74,48 @@ if(ENABLE_FMTLIB OR ENABLE_FMTLIB_HO) target_compile_definitions(slimlog-header-only INTERFACE SLIMLOG_FMTLIB) if(ENABLE_FMTLIB) + set(CMAKE_REQUIRED_LIBRARIES fmt::fmt) target_link_libraries(slimlog PUBLIC fmt::fmt) target_link_libraries(slimlog-header-only INTERFACE fmt::fmt) else() + set(CMAKE_REQUIRED_LIBRARIES fmt::fmt-header-only) target_link_libraries(slimlog PUBLIC fmt::fmt-header-only) target_link_libraries(slimlog-header-only INTERFACE fmt::fmt-header-only) endif() - set(PKG_CONFIG_REQUIRES fmt) # add dependency to pkg-config + # Add dependency to pkg-config + set(PKG_CONFIG_REQUIRES fmt) + + # Check which unicode types are supported + include(CheckCXXSymbolExists) + if(${fmt_VERSION} VERSION_GREATER_EQUAL 11.0.0) + set(fmt_format_context "fmt::buffered_context") + else() + set(fmt_format_context "fmt::buffer_context") + endif() + foreach(size 8 16 32) + check_cxx_symbol_exists( + "fmt::make_format_args<${fmt_format_context}, std::chrono::sys_seconds>" + "fmt/format.h;fmt/chrono.h;chrono" FORMATTABLE_CHAR${size} + ) + if(FORMATTABLE_CHAR${size}) + check_cxx_symbol_exists("std::mbrtoc${size}" "cuchar" HAS_MBRTOC${size}) + if(HAS_MBRTOC${size}) + target_compile_definitions(slimlog PUBLIC SLIMLOG_CHAR${size}) + target_compile_definitions(slimlog-header-only INTERFACE SLIMLOG_CHAR${size}) + endif() + endif() + endforeach() +else() + # If fmtlib is not available, check for C++20 std::format() + include(CheckCXXSymbolExists) + check_cxx_symbol_exists( + "std::make_format_args" "format;chrono" + HAS_CXX20_FORMAT + ) + if(NOT HAS_CXX20_FORMAT) + message(FATAL_ERROR "C++20 std::format() is not available, please enable fmtlib support") + endif() endif() # --------------------------------------------------------------------------------------- diff --git a/src/slimlog.cpp b/src/slimlog.cpp index 9ab1809..0c246d8 100644 --- a/src/slimlog.cpp +++ b/src/slimlog.cpp @@ -57,31 +57,45 @@ template class FormatValue; template class FormatValue; #endif -// char8_t (std::mbrtoc8() is supported only for newer versions of glibc++ and libc++) -/*#if defined(__cpp_char8_t) -#if defined(_GLIBCXX_USE_UCHAR_C8RTOMB_MBRTOC8_CXX20) \ - or defined(_LIBCPP_VERSION) and !defined(_LIBCPP_HAS_NO_C8RTOMB_MBRTOC8) +// char8_t +#ifdef SLIMLOG_CHAR8 template class SinkDriver, SingleThreadedPolicy>; template class SinkDriver, MultiThreadedPolicy>; template class Sink>; +template class FileSink>; +template class OStreamSink>; +template class NullSink>; template class RecordStringView; template class Pattern; -#endif +template class CachedFormatter; +template class CachedFormatter; #endif // char16_t -#if defined(__cpp_unicode_characters) +#ifdef SLIMLOG_CHAR16 template class SinkDriver, SingleThreadedPolicy>; template class SinkDriver, MultiThreadedPolicy>; template class Sink>; +template class FileSink>; +template class OStreamSink>; +template class NullSink>; template class RecordStringView; template class Pattern; +template class CachedFormatter; +template class CachedFormatter; +#endif // char32_t +#ifdef SLIMLOG_CHAR32 template class SinkDriver, SingleThreadedPolicy>; template class SinkDriver, MultiThreadedPolicy>; template class Sink>; +template class FileSink>; +template class OStreamSink>; +template class NullSink>; template class RecordStringView; template class Pattern; -#endif*/ +template class CachedFormatter; +template class CachedFormatter; +#endif } // namespace SlimLog