diff --git a/CMakeLists.txt b/CMakeLists.txt index 4efa094..81e35e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14 FATAL_ERROR) +cmake_minimum_required(VERSION 3.14...3.19 FATAL_ERROR) # ---- Project ---- @@ -18,6 +18,12 @@ if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) ) endif() +# ---- Project settings ---- + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS NO) + # ---- Add dependencies via CPM ---- # see https://github.com/TheLartians/CPM.cmake for more info @@ -27,30 +33,41 @@ include(cmake/CPM.cmake) CPMAddPackage( NAME PackageProject.cmake GITHUB_REPOSITORY TheLartians/PackageProject.cmake - VERSION 1.3 + VERSION 1.4 ) +find_package(fmt) +if(NOT TARGET fmt::fmt) + # FIXME this add a target without namespace! CK + CPMAddPackage( + NAME fmt + GIT_TAG 7.1.3 + GITHUB_REPOSITORY fmtlib/fmt + ) +endif() + # ---- Add source files ---- # Note: globbing sources is considered bad practice as CMake's generators may not detect new files # automatically. Keep that in mind when changing files, or explicitly mention them here. -file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h") -file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp") +file(GLOB_RECURSE headers CONFIGURE_DEPENDS "include/*.h") +file(GLOB_RECURSE sources CONFIGURE_DEPENDS "source/*.cpp") # ---- Create library ---- # Note: for header-only libraries change all PUBLIC flags to INTERFACE and create an interface -# target: add_library(Greeter INTERFACE) set_target_properties(Greeter PROPERTIES -# INTERFACE_COMPILE_FEATURES cxx_std_17) +# target: +add_library(Greeter) +add_library(${PROJECT_NAME}::Greeter ALIAS Greeter) +target_compile_features(Greeter PUBLIC cxx_std_17) -add_library(Greeter ${headers} ${sources}) - -set_target_properties(Greeter PROPERTIES CXX_STANDARD 17) +target_sources(Greeter PRIVATE ${headers} ${sources}) # being a cross-platform target, we enforce standards conformance on MSVC target_compile_options(Greeter PUBLIC "$<$:/permissive->") -# Link dependencies (if required) target_link_libraries(Greeter PUBLIC cxxopts) +# Link dependencies (if required) +target_link_libraries(Greeter PRIVATE fmt::fmt) target_include_directories( Greeter PUBLIC $ @@ -71,5 +88,8 @@ packageProject( INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include INCLUDE_DESTINATION include/${PROJECT_NAME}-${PROJECT_VERSION} VERSION_HEADER "${VERSION_HEADER_LOCATION}" - DEPENDENCIES "" + # semicolon separated list of the project's dependencies + DEPENDENCIES fmt + # install your library with a namespace! (do NOT add extra '::') + NAMESPACE ${PROJECT_NAME} ) diff --git a/all/CMakeLists.txt b/all/CMakeLists.txt index e131b89..bf9e3f7 100644 --- a/all/CMakeLists.txt +++ b/all/CMakeLists.txt @@ -1,12 +1,15 @@ # this script adds all subprojects to a single build to allow IDEs understand the full project # structure. -cmake_minimum_required(VERSION 3.14 FATAL_ERROR) +cmake_minimum_required(VERSION 3.14...3.19 FATAL_ERROR) project(BuildAll LANGUAGES CXX) include(../cmake/tools.cmake) -add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../standalone ${CMAKE_BINARY_DIR}/standalone) -add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../test ${CMAKE_BINARY_DIR}/test) -add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../documentation ${CMAKE_BINARY_DIR}/documentation) +# needed to generate test target +enable_testing() + +add_subdirectory(../standalone standalone) +add_subdirectory(../test test) +add_subdirectory(../documentation documentation) diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake index bffba54..35edbeb 100644 --- a/cmake/CPM.cmake +++ b/cmake/CPM.cmake @@ -1,4 +1,4 @@ -set(CPM_DOWNLOAD_VERSION 0.27.2) +set(CPM_DOWNLOAD_VERSION 0.28.2) if(CPM_SOURCE_CACHE) set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") diff --git a/cmake/tools.cmake b/cmake/tools.cmake index 4029e37..836ecd4 100644 --- a/cmake/tools.cmake +++ b/cmake/tools.cmake @@ -8,6 +8,8 @@ endif() include(${CMAKE_CURRENT_LIST_DIR}/CPM.cmake) +set(USE_STATIC_ANALYZER "" CACHE STRING "clang-tidy;cppcheck;iwyu") + # enables sanitizers support using the the `USE_SANITIZER` flag available values are: Address, # Memory, MemoryWithOrigins, Undefined, Thread, Leak, 'Address;Undefined' if(USE_SANITIZER OR USE_STATIC_ANALYZER) @@ -65,10 +67,11 @@ if(USE_SANITIZER OR USE_STATIC_ANALYZER) endif() # enables CCACHE support through the USE_CCACHE flag possible values are: YES, NO or equivalent +option(USE_CCACHE "enable ccache usages" ON) if(USE_CCACHE) CPMAddPackage( NAME Ccache.cmake GITHUB_REPOSITORY TheLartians/Ccache.cmake - VERSION 1.2.1 + VERSION 1.2.2 ) endif() diff --git a/documentation/CMakeLists.txt b/documentation/CMakeLists.txt index e48fd95..8373176 100644 --- a/documentation/CMakeLists.txt +++ b/documentation/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14 FATAL_ERROR) +cmake_minimum_required(VERSION 3.14...3.19 FATAL_ERROR) project(GreeterDocs) @@ -11,7 +11,7 @@ CPMAddPackage(NAME Greeter SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/..) CPMAddPackage( NAME MCSS DOWNLOAD_ONLY YES - # patched version until https://github.com/mosra/m.css/pull/171 is resolved + # TODO: patched version until https://github.com/mosra/m.css/pull/171 is resolved GITHUB_REPOSITORY TheLartians/m.css GIT_TAG 1bf162b96d5bfefc9967a80cef138f1270ffa415 ) @@ -22,16 +22,16 @@ CPMAddPackage( set(DOXYGEN_PROJECT_NAME Greeter) set(DOXYGEN_PROJECT_VERSION ${Greeter_VERSION}) set(DOXYGEN_PROJECT_ROOT "${CMAKE_CURRENT_LIST_DIR}/..") -set(DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doxygen") +set(DOXYGEN_OUTPUT_DIRECTORY doxygen) -configure_file(${CMAKE_CURRENT_LIST_DIR}/Doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) +configure_file(${CMAKE_CURRENT_LIST_DIR}/Doxyfile Doxyfile) -configure_file(${CMAKE_CURRENT_LIST_DIR}/conf.py ${CMAKE_CURRENT_BINARY_DIR}/conf.py) +configure_file(${CMAKE_CURRENT_LIST_DIR}/conf.py conf.py) add_custom_target( GenerateDocs ${CMAKE_COMMAND} -E make_directory "${DOXYGEN_OUTPUT_DIRECTORY}" - COMMAND "${MCSS_SOURCE_DIR}/documentation/doxygen.py" "${CMAKE_CURRENT_BINARY_DIR}/conf.py" + COMMAND "${MCSS_SOURCE_DIR}/documentation/doxygen.py" conf.py COMMAND echo "Docs written to: ${DOXYGEN_OUTPUT_DIRECTORY}" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" ) diff --git a/include/greeter/greeter.h b/include/greeter/greeter.h index 77dfe3b..9d367d7 100644 --- a/include/greeter/greeter.h +++ b/include/greeter/greeter.h @@ -26,6 +26,9 @@ namespace greeter { * @return a string containing the greeting */ std::string greet(LanguageCode lang = LanguageCode::EN) const; + + /// @brief Return an iso date string + std::string getIsoDate() const; }; } // namespace greeter diff --git a/source/greeter.cpp b/source/greeter.cpp index b1c54a7..1a5bfb8 100644 --- a/source/greeter.cpp +++ b/source/greeter.cpp @@ -1,8 +1,9 @@ +#include #include using namespace greeter; -Greeter::Greeter(std::string _name) : name(_name) {} +Greeter::Greeter(std::string _name) : name(std::move(_name)) {} std::string Greeter::greet(LanguageCode lang) const { switch (lang) { @@ -17,3 +18,8 @@ std::string Greeter::greet(LanguageCode lang) const { return "Bonjour " + name + "!"; } } + +std::string Greeter::getIsoDate() const { + using namespace std::literals::chrono_literals; + return fmt::format("{:%H:%M:%S}", 3h + 15min + 30s); +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d62ce82..d269262 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14 FATAL_ERROR) +cmake_minimum_required(VERSION 3.14...3.19 FATAL_ERROR) project(GreeterTests LANGUAGES CXX) @@ -15,11 +15,15 @@ include(../cmake/tools.cmake) include(../cmake/CPM.cmake) -CPMAddPackage( - NAME doctest - GITHUB_REPOSITORY onqtam/doctest - GIT_TAG 2.3.7 -) +find_package(doctest) +if(NOT TARGET doctest::doctest) + # FIXME this add a target without namespace! CK + CPMAddPackage( + NAME doctest + GITHUB_REPOSITORY onqtam/doctest + GIT_TAG 2.3.7 + ) +endif() if(TEST_INSTALLED_VERSION) find_package(Greeter REQUIRED) @@ -37,9 +41,9 @@ CPMAddPackage( # ---- Create binary ---- -file(GLOB sources CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp) +file(GLOB sources CONFIGURE_DEPENDS source/*.cpp) add_executable(GreeterTests ${sources}) -target_link_libraries(GreeterTests doctest Greeter) +target_link_libraries(GreeterTests doctest::doctest Greeter::Greeter) set_target_properties(GreeterTests PROPERTIES CXX_STANDARD 17) @@ -57,15 +61,16 @@ endif() enable_testing() -# Note: doctest and similar testing frameworks can automatically configure CMake tests For other -# testing frameworks add the tests target instead: ADD_TEST(GreeterTests GreeterTests) +# Note: doctest and similar testing frameworks can automatically configure CMake tests. +# include(${doctest_SOURCE_DIR}/scripts/cmake/doctest.cmake) +# doctest_discover_tests(GreeterTests) -include(${doctest_SOURCE_DIR}/scripts/cmake/doctest.cmake) -doctest_discover_tests(GreeterTests) +# For other testing frameworks add the tests target instead: +ADD_TEST(GreeterTests GreeterTests) # ---- code coverage ---- -if(ENABLE_TEST_COVERAGE) +if(ENABLE_TEST_COVERAGE AND NOT TEST_INSTALLED_VERSION) target_compile_options(Greeter PUBLIC -O0 -g -fprofile-arcs -ftest-coverage) target_link_options(Greeter PUBLIC -fprofile-arcs -ftest-coverage) endif() diff --git a/test/source/greeter.cpp b/test/source/greeter.cpp index 3d507e0..6dd4a90 100644 --- a/test/source/greeter.cpp +++ b/test/source/greeter.cpp @@ -18,4 +18,9 @@ TEST_CASE("Greeter") { TEST_CASE("Greeter version") { static_assert(std::string_view(GREETER_VERSION) == std::string_view("1.0")); CHECK(std::string(GREETER_VERSION) == std::string("1.0")); -} \ No newline at end of file +} + +TEST_CASE("Greeter date") { + const greeter::Greeter greeter("Tests"); + CHECK(greeter.getIsoDate() == std::string("03:15:30")); +}