diff --git a/.github/workflows/template-janitor.yml b/.github/workflows/template-janitor.yml index c48265a6..61c9102d 100644 --- a/.github/workflows/template-janitor.yml +++ b/.github/workflows/template-janitor.yml @@ -77,7 +77,7 @@ jobs: - name: Insert new org and project run: | # rename the CMake project to match the github project - sed -i "s/myproject/${{ env.NEW_SAFE_PROJECT }}/gi" CMakeLists.txt configured_files/config.hpp.in src/main.cpp + sed -i "s/myproject/${{ env.NEW_SAFE_PROJECT }}/gi" CMakeLists.txt configured_files/config.hpp.in src/main.cpp test/CMakeLists.txt fuzz_test/CMakeLists.txt # Update URL placeholders for project sed -i "s|%%myurl%%|${{ fromJson(steps.get_repo_meta.outputs.data).html_url }}|gi" CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bb3bee9..f887d73d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.16...3.23) # Not ideal to use this global variable, but necessary to make sure # that tooling and projects use the same version @@ -20,11 +20,10 @@ set(ENABLE_DEVELOPER_MODE # Change this to false if you want to disable warnings_as_errors in developer mode set(OPT_WARNINGS_AS_ERRORS_DEVELOPER_DEFAULT TRUE) -# Add project_options v0.17.0 +# Add project_options v0.20.0 # https://github.com/cpp-best-practices/project_options include(FetchContent) -FetchContent_Declare(_project_options - URL https://github.com/cpp-best-practices/project_options/archive/refs/tags/v0.17.0.zip) +FetchContent_Declare(_project_options URL https://github.com/aminya/project_options/archive/refs/tags/v0.20.0.zip) FetchContent_MakeAvailable(_project_options) include(${_project_options_SOURCE_DIR}/Index.cmake) @@ -40,6 +39,18 @@ project( HOMEPAGE_URL "%%myurl%%" LANGUAGES CXX C) +# This variable is set by project() in CMake 3.21+ +string( + COMPARE EQUAL + "${CMAKE_SOURCE_DIR}" + "${PROJECT_SOURCE_DIR}" + PROJECT_IS_TOP_LEVEL) +if(PROJECT_IS_TOP_LEVEL) + # Consider the CTest module, which creates targets and options! + # Only needed if you want to enable submissions to a CDash server. + include(CTest) +endif() + set(GIT_SHA "Unknown" CACHE STRING "SHA this build was generated from") @@ -92,6 +103,7 @@ dynamic_project_options( PCH_HEADERS # This is a list of headers to pre-compile, here are some common ones + ENABLE_CONAN # CONAN_OPTIONS # Extra options to pass to conan # MSVC_WARNINGS # Override the defaults for the MSVC warnings # CLANG_WARNINGS # Override the defaults for the CLANG warnings @@ -100,6 +112,9 @@ dynamic_project_options( ) target_compile_features(project_options INTERFACE cxx_std_${CMAKE_CXX_STANDARD}) +# TODO: The INTERFACE library NAMESPACE ALIAS are missing! CK +add_library(myproject::project_options INTERFACE IMPORTED) +add_library(myproject::project_warnings INTERFACE IMPORTED) # configure files based on CMake configuration options add_subdirectory(configured_files) @@ -108,33 +123,42 @@ add_subdirectory(configured_files) add_subdirectory(src) # Adding the tests: -option(ENABLE_TESTING "Enable the tests" ON) +option(ENABLE_TESTING "Enable the tests" ${PROJECT_IS_TOP_LEVEL}) if(ENABLE_TESTING) enable_testing() - message("Building Tests. Be sure to check out test/constexpr_tests for constexpr -testing") + message(AUTHOR_WARNING "Building Tests. Be sure to check out test/constexpr_tests.cpp for constexpr testing") add_subdirectory(test) endif() option(ENABLE_FUZZING "Enable the fuzz tests" OFF) if(ENABLE_FUZZING) - message("Building Fuzz Tests, using fuzzing sanitizer https://www.llvm.org/docs/LibFuzzer.html") + message(AUTHOR_WARNING "Building Fuzz Tests, using fuzzing sanitizer https://www.llvm.org/docs/LibFuzzer.html") add_subdirectory(fuzz_test) endif() # If MSVC is being used, and ASAN is enabled, we need to set the debugger environment # so that it behaves well with MSVC's debugger, and we can run the target from visual studio if(MSVC) - get_all_targets(all_targets) + get_all_installable_targets(all_targets) + message("all_targets=${all_targets}") set_target_properties(${all_targets} PROPERTIES VS_DEBUGGER_ENVIRONMENT "PATH=$(VC_ExecutablePath_x64);%PATH%") endif() # set the startup project for the "play" button in MSVC set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT intro) +if(CMAKE_SKIP_INSTALL_RULES) + return() +elseif(NOT PROJECT_IS_TOP_LEVEL) + return() +endif() + # Add other targets that you want installed here, be default we just package the one executable # we know we want to ship -package_project(TARGETS intro) +package_project(TARGETS intro project_options project_warnings + # FIXME: this does not work! CK + # PRIVATE_DEPENDENCIES_CONFIGURED project_options project_warnings +) # Experience shows that explicit package naming can help make it easier to sort # out potential ABI related issues before they start, while helping you diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 23208c22..2feabaae 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,16 +1,12 @@ -find_package(fmt CONFIG) -find_package(spdlog CONFIG) -find_package(docopt CONFIG) +find_package(fmt CONFIG REQUIRED) +find_package(spdlog CONFIG REQUIRED) +find_package(docopt CONFIG REQUIRED) # Generic test that uses conan libs add_executable(intro main.cpp) target_link_libraries( intro - PRIVATE project_options - project_warnings - docopt::docopt - fmt::fmt - spdlog::spdlog) + PUBLIC project_options project_warnings + PRIVATE docopt::docopt fmt::fmt spdlog::spdlog) target_include_directories(intro PRIVATE "${CMAKE_BINARY_DIR}/configured_files/include") - diff --git a/src/main.cpp b/src/main.cpp index de9b1564..065668df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,6 +27,7 @@ static constexpr auto USAGE = --drifting Drifting mine. )"; +// NOLINTNEXTLINE(bugprone-exception-escape) int main(int argc, const char **argv) { try { @@ -45,6 +46,6 @@ int main(int argc, const char **argv) fmt::print("Hello, from {}\n", "{fmt}"); } catch (const std::exception &e) { - fmt::print("Unhandled exception in main: {}", e.what()); + spdlog::error("Unhandled exception in main: {}", e.what()); } } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c6a32356..a5e24bc6 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,11 +1,29 @@ -find_package(Catch2 REQUIRED) +cmake_minimum_required(VERSION 3.15...3.23) + +project(CmakeConfigPackageTests LANGUAGES CXX) + +# ---- Test as standalone project the exported config package ---- + +if(PROJECT_IS_TOP_LEVEL OR TEST_INSTALLED_VERSION) + enable_testing() + + find_package(myproject CONFIG REQUIRED) # for intro, project_options, ... + + if(NOT TARGET myproject::project_options) + message(FATAL_ERROR "Requiered config package not found!") + return() # be strictly paranoid for Template Janitor github action! CK + endif() +endif() + +# ---- Dependencies ---- + +find_package(Catch2 CONFIG REQUIRED) -include(CTest) include(Catch) add_library(catch_main OBJECT catch_main.cpp) target_link_libraries(catch_main PUBLIC Catch2::Catch2) -target_link_libraries(catch_main PRIVATE project_options) +target_link_libraries(catch_main PRIVATE myproject::project_options) # Provide a simple smoke test to make sure that the CLI works and can display a --help message add_test(NAME cli.has_help COMMAND intro --help) @@ -17,9 +35,8 @@ add_test(NAME cli.has_help COMMAND intro --help) add_test(NAME cli.version_matches COMMAND intro --version) set_tests_properties(cli.version_matches PROPERTIES PASS_REGULAR_EXPRESSION "${PROJECT_VERSION}") - add_executable(tests tests.cpp) -target_link_libraries(tests PRIVATE project_warnings project_options catch_main) +target_link_libraries(tests PRIVATE myproject::project_warnings myproject::project_options catch_main) # automatically discover tests that are defined in catch based test files you can modify the unittests. Set TEST_PREFIX # to whatever you want, or use different for different binaries @@ -38,7 +55,7 @@ catch_discover_tests( # Add a file containing a set of constexpr tests add_executable(constexpr_tests constexpr_tests.cpp) -target_link_libraries(constexpr_tests PRIVATE project_options project_warnings catch_main) +target_link_libraries(constexpr_tests PRIVATE myproject::project_options myproject::project_warnings catch_main) catch_discover_tests( constexpr_tests @@ -56,7 +73,7 @@ catch_discover_tests( # Disable the constexpr portion of the test, and build again this allows us to have an executable that we can debug when # things go wrong with the constexpr testing add_executable(relaxed_constexpr_tests constexpr_tests.cpp) -target_link_libraries(relaxed_constexpr_tests PRIVATE project_options project_warnings catch_main) +target_link_libraries(relaxed_constexpr_tests PRIVATE myproject::project_options myproject::project_warnings catch_main) target_compile_definitions(relaxed_constexpr_tests PRIVATE -DCATCH_CONFIG_RUNTIME_STATIC_REQUIRE) catch_discover_tests(