diff --git a/CMakeLists.txt b/CMakeLists.txt index d12bd85..0aa365c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.14 FATAL_ERROR) # Note: update this to your new project's name and version project( Greeter - VERSION 1.0 + VERSION 1.1 LANGUAGES CXX ) @@ -18,6 +18,14 @@ if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) ) endif() +# ---- Project settings ---- + +if(NOT DEFINED CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS NO) +endif() + # ---- Add dependencies via CPM ---- # see https://github.com/TheLartians/CPM.cmake for more info @@ -27,7 +35,18 @@ include(cmake/CPM.cmake) CPMAddPackage( NAME PackageProject.cmake GITHUB_REPOSITORY TheLartians/PackageProject.cmake - VERSION 1.4 + VERSION 1.4.1 +) + +# NOTE: If fmt is not imported, this is needed to prevent: CMake Error: install(EXPORT +# "GreeterTargets" ...) includes target "Greeter" which requires target "fmt" that is not in any +# export set. see too https://gitlab.kitware.com/cmake/cmake/-/issues/15415 +set(FMT_VERSION 7.1.3) +CPMAddPackage( + NAME fmt + GIT_TAG ${FMT_VERSION} + GITHUB_REPOSITORY fmtlib/fmt + # XXX OPTION "FMT_INSTALL YES" ) # ---- Add source files ---- @@ -40,17 +59,20 @@ file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/ # ---- 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) +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->") +if(MSVC) + target_compile_options(Greeter PUBLIC /permissive) +endif() -# Link dependencies (if required) target_link_libraries(Greeter PUBLIC cxxopts) +# Link dependencies (if required) +target_link_libraries(Greeter PRIVATE $) +# XXX target_link_libraries(Greeter PUBLIC fmt::fmt) target_include_directories( Greeter PUBLIC $ @@ -72,5 +94,5 @@ packageProject( INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include INCLUDE_DESTINATION include/${PROJECT_NAME}-${PROJECT_VERSION} VERSION_HEADER "${VERSION_HEADER_LOCATION}" - DEPENDENCIES "" + # XXX DEPENDENCIES "fmt ${FMT_VERSION}" ) diff --git a/all/CMakeLists.txt b/all/CMakeLists.txt index e131b89..db5f5fb 100644 --- a/all/CMakeLists.txt +++ b/all/CMakeLists.txt @@ -7,6 +7,9 @@ project(BuildAll LANGUAGES CXX) include(../cmake/tools.cmake) +# needed to generate test target +enable_testing() + 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) 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 302d7f2..dfff2c1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,10 @@ cmake_minimum_required(VERSION 3.14 FATAL_ERROR) -project(GreeterTests LANGUAGES CXX) +project( + GreeterTests + VERSION 1.1 + LANGUAGES CXX +) # ---- Options ---- @@ -22,7 +26,7 @@ CPMAddPackage( ) if(TEST_INSTALLED_VERSION) - find_package(Greeter REQUIRED) + find_package(Greeter ${PROJECT_VERSION} REQUIRED) else() CPMAddPackage(NAME Greeter SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/..) endif() @@ -46,9 +50,9 @@ set_target_properties(GreeterTests PROPERTIES CXX_STANDARD 17) # enable compiler warnings if(NOT TEST_INSTALLED_VERSION) if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") - target_compile_options(Greeter PUBLIC -Wall -pedantic -Wextra -Werror) + target_compile_options(Greeter PRIVATE -Wall -pedantic -Wextra -Werror) elseif(MSVC) - target_compile_options(Greeter PUBLIC /W4 /WX) + target_compile_options(Greeter PRIVATE /W4 /WX) target_compile_definitions(GreeterTests PUBLIC DOCTEST_CONFIG_USE_STD_HEADERS) endif() endif() @@ -65,7 +69,7 @@ doctest_discover_tests(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..345ecf3 100644 --- a/test/source/greeter.cpp +++ b/test/source/greeter.cpp @@ -16,6 +16,11 @@ 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 + static_assert(std::string_view(GREETER_VERSION) == std::string_view("1.1")); + CHECK(std::string(GREETER_VERSION) == std::string("1.1")); +} + +TEST_CASE("Greeter date") { + const greeter::Greeter greeter("Tests"); + CHECK(greeter.getIsoDate() == std::string("03:15:30")); +}