Skip to content

Commit

Permalink
upgrade to project_options v0.20.0
Browse files Browse the repository at this point in the history
modernize the cmake build concept too:
 * Import your installed targets with an test to be sure it is usable.
 * Add support for PROJECT_IS_TOP_LEVEL cmake variable
 * Enable conan again as default
  • Loading branch information
ClausKlein committed Apr 3, 2022
1 parent f37c1ab commit e51378d
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 28 deletions.
44 changes: 34 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)

Expand All @@ -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")
Expand Down Expand Up @@ -92,6 +103,7 @@ dynamic_project_options(
PCH_HEADERS
<vector>
<string> # 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
Expand All @@ -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)
Expand All @@ -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
Expand Down
14 changes: 5 additions & 9 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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")

3 changes: 2 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ static constexpr auto USAGE =
--drifting Drifting mine.
)";

// NOLINTNEXTLINE(bugprone-exception-escape)
int main(int argc, const char **argv)
{
try {
Expand All @@ -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());
}
}
28 changes: 20 additions & 8 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
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, ...
endif()

# ---- Dependencies ----

find_package(Catch2 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)
add_test(NAME cli.has_help COMMAND myproject::intro --help)

# Provide a test to verify that the version being reported from the application
# matches the version given to CMake. This will be important once you package
# your program. Real world shows that this is the kind of simple mistake that is easy
# to make, but also easy to test for.
add_test(NAME cli.version_matches COMMAND intro --version)
add_test(NAME cli.version_matches COMMAND myproject::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
Expand All @@ -38,7 +50,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
Expand All @@ -56,7 +68,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(
Expand Down

0 comments on commit e51378d

Please sign in to comment.