diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 5fd86c7..6f8ef7a 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -40,9 +40,6 @@ jobs: sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 90 sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-13 90 -# sudo python3 -m pip install --upgrade pip -# sudo python3 -m pip install scikit-build -# sudo python3 -m pip install cmake==3.25 requests gitpython gcovr pyyaml - name: run checks run: | #!/bin/bash @@ -51,5 +48,5 @@ jobs: test ${VER_COUNT} -eq 0 && echo "no llvm version detected" && exit 1 export LLVM_ROOT=$(ls -r -d -1 ${LLVM_DIR} | head -1) export PATH=${LLVM_ROOT}/bin:${LLVM_ROOT}/share/clang:${PATH} - cmake . -Bbuild + cmake . -Bbuild -DBUILD_TESTS=ON .github/aux/clang-tidy.sh build diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml index 17fd9c7..f5e068a 100644 --- a/.github/workflows/compilers.yml +++ b/.github/workflows/compilers.yml @@ -50,6 +50,7 @@ jobs: if [ "$RUNNER_OS" = "macOS" ]; then brew install ninja + sudo xcode-select --switch /Library/Developer/CommandLineTools else sudo apt-get update || true sudo apt-get install -y ninja-build gcovr gcc-13 g++-13 clang-18 clang++-18 clang-tidy-18 clang-format-18 @@ -74,7 +75,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # has to be included to access other secrets GITHUB_HUNTER_USERNAME: ${{ secrets.GITHUB_HUNTER_USERNAME }} GITHUB_HUNTER_TOKEN: ${{ secrets.GITHUB_HUNTER_TOKEN }} - run: cmake . -Bbuild + run: cmake . -Bbuild -DBUILD_TESTS=ON - name: build run: cmake --build build -- -j4 diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index fb3664f..e1d5bdb 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -41,10 +41,6 @@ jobs: sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 90 sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-13 90 -# sudo python3 -m pip install --upgrade pip -# sudo python3 -m pip install scikit-build -# sudo python3 -m pip install cmake==3.25 requests gitpython gcovr pyyaml - - name: "cmake" env: CC: clang diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 12d6417..cc9069e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -52,8 +52,6 @@ jobs: set -e sudo apt-get update || true sudo apt-get install -y ninja-build -# sudo python3 -m pip install --upgrade pip -# sudo pip3 install cmake requests gitpython gcovr pyyaml - name: cmake env: @@ -62,7 +60,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # has to be included to access other secrets GITHUB_HUNTER_USERNAME: ${{ secrets.GITHUB_HUNTER_USERNAME }} GITHUB_HUNTER_TOKEN: ${{ secrets.GITHUB_HUNTER_TOKEN }} - run: cmake . -Bbuild -D${{ matrix.options.sanitizer }}=ON + run: cmake . -Bbuild -DBUILD_TESTS=ON -D${{ matrix.options.sanitizer }}=ON - name: build run: cmake --build build -- -j4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 38a9fb7..98f84f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,10 +7,52 @@ cmake_minimum_required(VERSION 3.12) -include("cmake/Hunter/init.cmake") +option(BUILD_TESTS "Build tests" OFF) +option(EXAMPLES "Build examples" ON) +option(CLANG_FORMAT "Enable clang-format target" OFF) +option(CLANG_TIDY "Enable clang-tidy checks during compilation" OFF) +option(COVERAGE "Enable generation of coverage info" OFF) + +# Sanitizers enables only for this project, and will be disabled for dependencies +option(ASAN "Enable address sanitizer" OFF) +option(LSAN "Enable leak sanitizer" OFF) +option(MSAN "Enable memory sanitizer" OFF) +option(TSAN "Enable thread sanitizer" OFF) +option(UBSAN "Enable UB sanitizer" OFF) + +if (COVERAGE) + set(BUILD_TESTS ON) # tests are needed to generate coverage info +endif () + +if (PACKAGE_MANAGER) + if(PACKAGE_MANAGER NOT MATCHES "^(hunter|vcpkg)$") + message(FATAL_ERROR "PACKAGE_MANAGER must be set to 'hunter', 'vcpkg' or isn't set") + endif () +else () + set(PACKAGE_MANAGER "hunter") + if (CMAKE_TOOLCHAIN_FILE) + get_filename_component(ACTUAL_NAME ${CMAKE_TOOLCHAIN_FILE} NAME) + if(ACTUAL_NAME STREQUAL "vcpkg.cmake") + message(STATUS "vcpkg will be used because vcpkg.cmake has found") + set(PACKAGE_MANAGER "vcpkg") + endif () + endif () +endif () +message(STATUS "Selected package manager: ${PACKAGE_MANAGER}") + +if (PACKAGE_MANAGER STREQUAL "hunter") + include("cmake/Hunter/init.cmake") +endif () + +if(BUILD_TESTS) + if (PACKAGE_MANAGER STREQUAL "vcpkg") + list(APPEND VCPKG_MANIFEST_FEATURES soralog-tests) + endif() +endif() cmake_policy(SET CMP0048 NEW) -project(soralog VERSION 0.2.4 LANGUAGES CXX) + +project(soralog VERSION 0.2.5 LANGUAGES CXX) find_program(CCACHE_FOUND ccache) if (CCACHE_FOUND) @@ -22,37 +64,21 @@ include(cmake/functions.cmake) include(cmake/toolchain/compiler.cmake) -if (NOT DEFINED CMAKE_TOOLCHAIN_FILE) +if (NOT DEFINED CMAKE_TOOLCHAIN_FILE OR NOT DEFINED CMAKE_CXX_STANDARD) if (MAX_SUPPORTED_CXX_STANDARD GREATER_EQUAL 20) - set(CMAKE_TOOLCHAIN_FILE - "${CMAKE_SOURCE_DIR}/cmake/toolchain/cxx20.cmake" - CACHE FILEPATH "Default toolchain" - ) + set(CXXSTD 20) else () - set(CMAKE_TOOLCHAIN_FILE - "${CMAKE_SOURCE_DIR}/cmake/toolchain/cxx17.cmake" - CACHE FILEPATH "Default toolchain" - ) + set(CXXSTD 17) + endif () + include("${CMAKE_SOURCE_DIR}/cmake/toolchain/cxx${CXXSTD}.cmake") + print("Using C++${CXXSTD} standard") + if (NOT DEFINED CMAKE_TOOLCHAIN_FILE) + set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/cmake/toolchain/cxx${CXXSTD}.cmake") endif () endif () -print("Toolchain: ${CMAKE_TOOLCHAIN_FILE}") -include(${CMAKE_TOOLCHAIN_FILE}) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -option(TESTING "Build tests" ON) -option(EXAMPLES "Build examples" ON) -option(CLANG_FORMAT "Enable clang-format target" OFF) -option(CLANG_TIDY "Enable clang-tidy checks during compilation" OFF) -option(COVERAGE "Enable generation of coverage info" OFF) - -# Sanitizers enables only for this project, and will be disabled for dependencies -option(ASAN "Enable address sanitizer" OFF) -option(LSAN "Enable leak sanitizer" OFF) -option(MSAN "Enable memory sanitizer" OFF) -option(TSAN "Enable thread sanitizer" OFF) -option(UBSAN "Enable UB sanitizer" OFF) - # the property is out of "if TESTING" scope due to addtest func is out too set_property(GLOBAL PROPERTY TEST_TARGETS) @@ -70,7 +96,7 @@ endif() add_subdirectory(src) -if(TESTING OR COVERAGE) +if (BUILD_TESTS) enable_testing() add_subdirectory(test) endif() diff --git a/cmake/Hunter/init.cmake b/cmake/Hunter/init.cmake index b275bf4..5e667c5 100644 --- a/cmake/Hunter/init.cmake +++ b/cmake/Hunter/init.cmake @@ -34,7 +34,7 @@ set( include(${CMAKE_CURRENT_LIST_DIR}/HunterGate.cmake) HunterGate( - URL https://github.com/qdrvm/hunter/archive/refs/tags/v0.25.3-qdrvm3.zip - SHA1 8989599eaa462f367805e2d36a30150c93b1d660 + URL https://github.com/qdrvm/hunter/archive/refs/tags/v0.25.3-qdrvm26.zip + SHA1 21e8e29f562962e97fc8bcd35a4ad5244794c7fc LOCAL ) diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index c1cbcdc..6dba01c 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -5,16 +5,22 @@ # SPDX-License-Identifier: Apache-2.0 # -if (TESTING OR COVERAGE) - hunter_add_package(GTest) - find_package(GTest CONFIG REQUIRED) -endif() +if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.27") + cmake_policy(SET CMP0144 NEW) +endif () + +function(reg_dependency name) + if (PACKAGE_MANAGER STREQUAL "hunter") + hunter_add_package(${name}) + endif () + find_package(${name} CONFIG REQUIRED) +endfunction() -hunter_add_package(yaml-cpp) -find_package(yaml-cpp CONFIG REQUIRED) -if (NOT TARGET yaml-cpp::yaml-cpp) - add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp) -endif() -hunter_add_package(fmt) -find_package(fmt CONFIG REQUIRED) +reg_dependency(yaml-cpp) + +reg_dependency(fmt) + +if (BUILD_TESTS) + reg_dependency(GTest) +endif() diff --git a/cmake/toolchain/compiler/clang.cmake b/cmake/toolchain/compiler/clang.cmake index aa5be39..fe97f2a 100644 --- a/cmake/toolchain/compiler/clang.cmake +++ b/cmake/toolchain/compiler/clang.cmake @@ -20,6 +20,9 @@ endif() find_program(CMAKE_C_COMPILER clang + clang-20 + clang-19 + clang-18 clang-17 clang-16 clang-15 @@ -29,6 +32,9 @@ find_program(CMAKE_C_COMPILER clang-11) find_program(CMAKE_CXX_COMPILER clang++ + clang++-20 + clang++-19 + clang++-18 clang++-17 clang++-16 clang++-15 diff --git a/cmake/toolchain/compiler/gcc.cmake b/cmake/toolchain/compiler/gcc.cmake index 9d2fc36..ab0a17b 100644 --- a/cmake/toolchain/compiler/gcc.cmake +++ b/cmake/toolchain/compiler/gcc.cmake @@ -13,6 +13,7 @@ endif() find_program(CMAKE_C_COMPILER gcc + gcc-14 gcc-13 gcc-12 gcc-11 @@ -20,6 +21,7 @@ find_program(CMAKE_C_COMPILER gcc-9) find_program(CMAKE_CXX_COMPILER g++ + g++-14 g++-13 g++-12 g++-11 diff --git a/include/soralog/circular_buffer.hpp b/include/soralog/circular_buffer.hpp index 25d8510..76aa463 100644 --- a/include/soralog/circular_buffer.hpp +++ b/include/soralog/circular_buffer.hpp @@ -38,7 +38,7 @@ namespace soralog { } // NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes) - std::atomic_flag busy = ATOMIC_VAR_INIT(false); + std::atomic_flag busy{false}; private: // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) diff --git a/include/soralog/event.hpp b/include/soralog/event.hpp index a673b0d..b7c4c97 100644 --- a/include/soralog/event.hpp +++ b/include/soralog/event.hpp @@ -88,8 +88,9 @@ namespace soralog { } it{message_data_}; try { + using OutputIt = decltype(it); message_size_ = - ::fmt::vformat_to_n( + ::fmt::vformat_to_n( it, max_message_length, ::fmt::detail_exported::compile_string_to_view(format), diff --git a/include/soralog/impl/configurator_from_yaml.hpp b/include/soralog/impl/configurator_from_yaml.hpp index 7ee1e2a..9c25039 100644 --- a/include/soralog/impl/configurator_from_yaml.hpp +++ b/include/soralog/impl/configurator_from_yaml.hpp @@ -20,8 +20,8 @@ namespace soralog { /** * @class ConfiguratorFromYAML - * @brief This configurator for set up Logging System in according with - * config using YAML format. + * @brief This configurator for set up Logging System + * in according to config using YAML format. */ class ConfiguratorFromYAML : public Configurator { public: @@ -53,22 +53,32 @@ namespace soralog { std::string config_content) : previous_(std::move(previous)), config_(std::move(config_content)) {}; + /** + * Uses YAML-node {@param config_yaml_node} as source of config + * Firstly applies provided underlying configurator {@param previous}. + */ + explicit ConfiguratorFromYAML(std::shared_ptr previous, + YAML::Node config_yaml_node) + : previous_(std::move(previous)), + config_(std::move(config_yaml_node)) {}; + ~ConfiguratorFromYAML() override = default; Result applyOn(LoggingSystem &system) const override; private: std::shared_ptr previous_; - std::variant config_; + std::variant config_; /** * Helper-class to parse config and create sinks and groups during that */ class Applicator { public: - Applicator(LoggingSystem &system, - std::variant config, - std::shared_ptr previous = {}) + Applicator( + LoggingSystem &system, + std::variant config, + std::shared_ptr previous = {}) : system_(system), previous_(std::move(previous)), config_(std::move(config)) {} @@ -106,7 +116,7 @@ namespace soralog { // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) LoggingSystem &system_; std::shared_ptr previous_ = nullptr; - std::variant config_; + std::variant config_; bool has_warning_ = false; bool has_error_ = false; std::ostringstream errors_; diff --git a/src/impl/configurator_from_yaml.cpp b/src/impl/configurator_from_yaml.cpp index ce887c9..f8bc052 100644 --- a/src/impl/configurator_from_yaml.cpp +++ b/src/impl/configurator_from_yaml.cpp @@ -65,6 +65,7 @@ namespace soralog { [&](auto &&arg) { using T = std::decay_t; + // Provided path - trying to read and parse like yaml-file if constexpr (std::is_same_v) { try { node = YAML::LoadFile(arg); @@ -75,6 +76,7 @@ namespace soralog { has_error_ = true; } + // Provided string - trying to parse like yaml-content } else if constexpr (std::is_same_v) { try { node = YAML::Load(arg); @@ -83,6 +85,10 @@ namespace soralog { has_error_ = true; } + // Provided yaml-node - using directly + } else if constexpr (std::is_same_v) { + node = arg; + } else { static_assert(always_false_v, "non-exhaustive visitor!"); } diff --git a/src/logging_system.cpp b/src/logging_system.cpp index 7512d96..48a5f58 100644 --- a/src/logging_system.cpp +++ b/src/logging_system.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/src/soralog.cpp b/src/soralog.cpp index 77acc7c..2398763 100644 --- a/src/soralog.cpp +++ b/src/soralog.cpp @@ -10,6 +10,6 @@ namespace soralog { // to suppress warning about no symbols in cpp // NOLINTNEXTLINE(bugprone-reserved-identifier) - const char *const __library_name = "soralog"; + extern const char *const __library_name = "soralog"; } // namespace soralog diff --git a/test/unit/macros_test.cpp b/test/unit/macros_test.cpp index 7a109a2..9585649 100644 --- a/test/unit/macros_test.cpp +++ b/test/unit/macros_test.cpp @@ -20,8 +20,9 @@ class MacrosTest : public ::testing::Test { template void log(Level lvl, const Format &format, Args &&...args) { last_level = lvl; + using OutputIt = decltype(message_buf.begin()); size_t len = - ::fmt::vformat_to_n( + ::fmt::vformat_to_n( message_buf.begin(), message_buf.size(), ::fmt::detail_exported::compile_string_to_view(format), ::fmt::make_format_args(args...)) diff --git a/vcpkg-configuration.json b/vcpkg-configuration.json new file mode 100644 index 0000000..4f69c22 --- /dev/null +++ b/vcpkg-configuration.json @@ -0,0 +1,14 @@ +{ + "default-registry": { + "kind": "git", + "baseline": "fe1cde61e971d53c9687cf9a46308f8f55da19fa", + "repository": "https://github.com/microsoft/vcpkg" + }, + "registries": [ + { + "kind": "artifact", + "location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip", + "name": "microsoft" + } + ] +} diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 0000000..59d7c24 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,16 @@ +{ + "name": "soralog", + "version": "0.2.5", + "dependencies": [ + "fmt", + "yaml-cpp" + ], + "features": { + "soralog-tests": { + "description": "Test of soralog's mechanisms", + "dependencies": [ + "gtest" + ] + } + } +}