Skip to content

Commit

Permalink
CMake: detect support of unicode char types
Browse files Browse the repository at this point in the history
Signed-off-by: Pavel Artsishevsky <polter.rnd@gmail.com>
  • Loading branch information
polter-rnd committed Dec 3, 2024
1 parent 22f9b75 commit 6da328e
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 18 deletions.
2 changes: 2 additions & 0 deletions .iwyu-mappings
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
{ include: [ "<__hash_table>", "private", "<unordered_map>", "public" ] },
{ include: [ "<__hash_table>", "private", "<unordered_set>", "public" ] },
{ include: [ "<__locale>", "private", "<locale>", "public" ] },
# Bug on stdlibc++: std::tm is not from <cwchar>
{ symbol: [ "std::tm", "private", "<ctime>", "public" ] },
# Bug on stdlibc++ w/o fmtlib: std::pair is not from <iterator>
{ symbol: [ "std::pair", "private", "<utility>", "public" ] },
# Bug on libc++ w/o fmtlib: std::reference_wrapper is not from <type_traits>
Expand Down
9 changes: 0 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::format_context>" "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)

Expand Down
28 changes: 28 additions & 0 deletions cmake/Helpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion include/slimlog/pattern-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@

#include <algorithm>
#include <array>
#include <chrono>
#include <climits>
#include <concepts>
#if defined(__cpp_unicode_characters) or defined(__cpp_char8_t)
#include <cuchar> // IWYU pragma: keep
#endif
#include <chrono>
#include <cwchar>
#include <functional>
#include <initializer_list>
Expand Down
36 changes: 35 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}<char${size}_t>, 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<std::format_context, std::chrono::sys_seconds>" "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()

# ---------------------------------------------------------------------------------------
Expand Down
28 changes: 21 additions & 7 deletions src/slimlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,31 +57,45 @@ template class FormatValue<std::size_t, wchar_t>;
template class FormatValue<std::chrono::sys_seconds, wchar_t>;
#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<Logger<std::u8string_view>, SingleThreadedPolicy>;
template class SinkDriver<Logger<std::u8string_view>, MultiThreadedPolicy>;
template class Sink<Logger<std::u8string_view>>;
template class FileSink<Logger<std::u8string_view>>;
template class OStreamSink<Logger<std::u8string_view>>;
template class NullSink<Logger<std::u8string_view>>;
template class RecordStringView<char8_t>;
template class Pattern<char8_t>;
#endif
template class CachedFormatter<std::size_t, char8_t>;
template class CachedFormatter<std::chrono::sys_seconds, char8_t>;
#endif

// char16_t
#if defined(__cpp_unicode_characters)
#ifdef SLIMLOG_CHAR16
template class SinkDriver<Logger<std::u16string_view>, SingleThreadedPolicy>;
template class SinkDriver<Logger<std::u16string_view>, MultiThreadedPolicy>;
template class Sink<Logger<std::u16string_view>>;
template class FileSink<Logger<std::u16string_view>>;
template class OStreamSink<Logger<std::u16string_view>>;
template class NullSink<Logger<std::u16string_view>>;
template class RecordStringView<char16_t>;
template class Pattern<char16_t>;
template class CachedFormatter<std::size_t, char16_t>;
template class CachedFormatter<std::chrono::sys_seconds, char16_t>;
#endif

// char32_t
#ifdef SLIMLOG_CHAR32
template class SinkDriver<Logger<std::u32string_view>, SingleThreadedPolicy>;
template class SinkDriver<Logger<std::u32string_view>, MultiThreadedPolicy>;
template class Sink<Logger<std::u32string_view>>;
template class FileSink<Logger<std::u32string_view>>;
template class OStreamSink<Logger<std::u32string_view>>;
template class NullSink<Logger<std::u32string_view>>;
template class RecordStringView<char32_t>;
template class Pattern<char32_t>;
#endif*/
template class CachedFormatter<std::size_t, char32_t>;
template class CachedFormatter<std::chrono::sys_seconds, char32_t>;
#endif
} // namespace SlimLog

0 comments on commit 6da328e

Please sign in to comment.