From 213ce2139ece1f2171b460196102497031a4cb88 Mon Sep 17 00:00:00 2001 From: Uilian Ries Date: Sat, 29 Jun 2024 22:25:05 +0200 Subject: [PATCH] build: Honor CMake USE_STD_FORMAT option (#761) * Honor use_std_format option Signed-off-by: Uilian Ries * use format option in contribution guide Signed-off-by: Uilian Ries * Revert CMakePresets Signed-off-by: Uilian Ries * Avoid cmake expression-generator Signed-off-by: Uilian Ries * Add status message when not fiding std format Signed-off-by: Uilian Ries --------- Signed-off-by: Uilian Ries --- CMakeLists.txt | 23 +++++++++++++++-------- CONTRIBUTING.md | 25 +++++++++++++++++++++++++ src/common/FormatHelper.h | 4 ++-- tests/CMakeLists.txt | 4 ++-- 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fb1188e39..cfa468bf1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,16 +4,23 @@ project(faker-cxx LANGUAGES CXX) include(cmake/CompilerWarnings.cmake) option(USE_SYSTEM_DEPENDENCIES "Use fmt and GTest from system" OFF) -option(USE_STD_FORMAT "Use std::format when available" ON) option(BUILD_EXAMPLES "Build examples" OFF) option(BUILD_TESTING "Build tests" ON) -if (USE_STD_FORMAT) +if (MSVC) + set(CMAKE_REQUIRED_FLAGS /std:c++20) +else() set(CMAKE_REQUIRED_FLAGS -std=c++20) - include(CheckCXXSourceCompiles) - check_cxx_source_compiles("#include \nint main(){ auto var = std::format(\"{}\", \"Hello\"); return 0; }" - HAS_STD_FORMAT) -endif () +endif() +include(CheckCXXSourceCompiles) +check_cxx_source_compiles("#include \nint main(){ auto var = std::format(\"{}\", \"Hello\"); return 0; }" + HAS_STD_FORMAT) +if (NOT HAS_STD_FORMAT) + message(STATUS "Compiler has no support for std::format. Need to use fmt library as dependency.") +endif() + +include(CMakeDependentOption) +cmake_dependent_option(USE_STD_FORMAT "Use std::format when available" ON "HAS_STD_FORMAT" OFF) if (BUILD_TESTING) enable_testing() @@ -119,8 +126,8 @@ install(EXPORT ${CMAKE_PROJECT_NAME}-targets FILE ${CMAKE_PROJECT_NAME}-config.cmake DESTINATION lib/cmake/${CMAKE_PROJECT_NAME}) -if (HAS_STD_FORMAT) - target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE HAS_STD_FORMAT) +if (USE_STD_FORMAT) + target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE USE_STD_FORMAT) elseif (USE_SYSTEM_DEPENDENCIES) find_package(fmt CONFIG REQUIRED) target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE fmt::fmt) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b3da9fd94..b91f44250 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -140,6 +140,31 @@ Follow the steps below to build the project: cmake --build --preset unixlike-gcc-debug-static ``` +#### Choosing between STL std::format and fmt library + +The faker-cxx project uses formated string feature, which can be solved by: + +- [fmt](https://github.com/fmtlib/fmt) library +- [std::format](https://en.cppreference.com/w/cpp/utility/format/format) + +The `std::format` requires C++20 standard support from the compiler. The feature is checked via CMake when building the project. +In case available, the option `USE_STD_FORMAT` will be available: + + ```sh + cmake -S . --preset unixlike-gcc-debug-static -DUSE_STD_FORMAT=ON + ``` + +In case `std::format` is not available, faker-cxx will use `fmt` library instead. It can be used as external dependency via +git submodules, or consumed from your system (installed by Conan or system package manager). In order to manage the way to +acquire `fmt`, the CMake option `USE_SYSTEM_DEPENDENCIES` manages if should be used from system, or from git submodule: + + ```sh + cmake -S . --preset unixlike-gcc-debug-static -DUSE_SYSTEM_DEPENDENCIES=OFF // Install from submodule + ``` + +In case passing `USE_STD_FORMAT=ON` and `std::format` is not available, CMake will try to use `fmt` library automatically. +Then, in case not finding `fmt`, it will fail. + ### Testing the Project After building the project, you can run the tests to ensure everything is working correctly. We use CTest for running diff --git a/src/common/FormatHelper.h b/src/common/FormatHelper.h index b49e92aab..941b752ae 100644 --- a/src/common/FormatHelper.h +++ b/src/common/FormatHelper.h @@ -8,7 +8,7 @@ #include "faker-cxx/types/Precision.h" #include "faker-cxx/Export.h" -#if !defined(HAS_STD_FORMAT) +#if !defined(USE_STD_FORMAT) #include #include #else @@ -21,7 +21,7 @@ namespace faker class FormatHelper { public: -#if !defined(HAS_STD_FORMAT) +#if !defined(USE_STD_FORMAT) template static std::string format(fmt::format_string fmt, Args&&... args) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3c9d088c0..5666c0431 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -70,9 +70,9 @@ else () target_link_libraries(${PROJECT_NAME} PRIVATE gtest_main gmock_main faker-cxx) endif () -if (HAS_STD_FORMAT) +if (USE_STD_FORMAT) target_include_directories(${PROJECT_NAME} PRIVATE ${GTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR} ${CMAKE_CURRENT_LIST_DIR}) - target_compile_definitions(${PROJECT_NAME} PRIVATE HAS_STD_FORMAT) + target_compile_definitions(${PROJECT_NAME} PRIVATE USE_STD_FORMAT) else () target_link_libraries(${PROJECT_NAME} PRIVATE $,fmt::fmt,fmt>) target_include_directories(${PROJECT_NAME} PRIVATE ${FMT_INCLUDE_DIR} ${GTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR} ${CMAKE_CURRENT_LIST_DIR})