Skip to content

Commit 211ff9e

Browse files
committed
Improve the quality of the CMake build scripts
This commit does a couple changes: * Actually adheres to the declared CMake 3.8 requirement * HOMEPAGE_URL in project() was added in 3.12 * install(TARGETS) requires the DESTINATION argument * Tests' CML uses CONFIGURE_DEPENDS from CMake 3.12 * Removes unnecessary things * Looking for RPM and DEB packagers is pointless * Misc arguments to CMake commands * Improves correctness * Includes CPack and CTest modules only if top level * Assigns install rules to a project specific component to not clobber the global, `Unspecified` one * Adds a warning guard for projects that vendor ctre * CMAKE_INSTALL_PREFIX should be set at configure time if the person building wants .pc files, so attempt to detect that error * Enables the install rules to be opt-out using the CMake built-in variable * Emulates ARCH_INDEPENDENT for the version config * Installs headers to their own directory (fixes #207) * Use CTest for testing * Small optimization * LANGUAGES can be set to NONE, because this is a header only library
1 parent 2d31ccc commit 211ff9e

File tree

3 files changed

+147
-92
lines changed

3 files changed

+147
-92
lines changed

CMakeLists.txt

+110-88
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,127 @@
1-
cmake_minimum_required(VERSION 3.8.0)
2-
# When updating to a newer version of CMake, see if we can use the following
3-
project(ctre
4-
HOMEPAGE_URL "https://compile-time.re"
5-
VERSION 3.0
6-
LANGUAGES CXX)
1+
cmake_minimum_required(VERSION 3.8)
2+
3+
project(ctre VERSION 3.0 LANGUAGES NONE)
4+
5+
# ---- project() variable shims ----
6+
7+
# Added in CMake 3.9
78
set(PROJECT_DESCRIPTION "Fast compile-time regular expressions with support for matching/searching/capturing during compile-time or runtime.")
89

9-
include(CMakePackageConfigHelpers)
10-
include(CMakeDependentOption)
11-
include(GNUInstallDirs)
12-
include(CTest)
13-
14-
find_program(CTRE_DPKG_BUILDPACKAGE_FOUND dpkg-buildpackage)
15-
find_program(CTRE_RPMBUILD_FOUND rpmbuild)
16-
17-
cmake_dependent_option(CTRE_BUILD_TESTS "Build ctre Tests" ON
18-
"BUILD_TESTING;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
19-
cmake_dependent_option(CTRE_BUILD_PACKAGE "Build ctre Packages" ON
20-
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
21-
cmake_dependent_option(CTRE_BUILD_PACKAGE_DEB
22-
"Create DEB Package (${PROJECT_NAME})" ON
23-
"CTRE_BUILD_PACKAGE;CTRE_DPKG_BUILDPACKAGE_FOUND" OFF)
24-
cmake_dependent_option(CTRE_BUILD_PACKAGE_RPM
25-
"Create RPM Package (${PROJECT_NAME})" ON
26-
"CTRE_BUILD_PACKAGE;CTRE_RPMBUILD_FOUND" OFF)
27-
28-
add_library(${PROJECT_NAME} INTERFACE)
29-
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
30-
31-
target_include_directories(${PROJECT_NAME} INTERFACE
32-
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
33-
$<INSTALL_INTERFACE:include>)
34-
target_compile_features(ctre INTERFACE cxx_std_17)
35-
36-
install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-targets)
37-
38-
if (NOT EXISTS "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake.in")
39-
file(WRITE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake.in [[
40-
@PACKAGE_INIT@
41-
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake")
42-
]])
10+
# Added in CMake 3.12
11+
set(PROJECT_HOMEPAGE_URL "https://compile-time.re")
12+
13+
# Added in CMake 3.21
14+
set(PROJECT_IS_TOP_LEVEL NO)
15+
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
16+
set(PROJECT_IS_TOP_LEVEL YES)
4317
endif()
4418

45-
configure_package_config_file(
46-
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake.in"
47-
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
48-
INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}"
49-
NO_SET_AND_CHECK_MACRO
50-
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
51-
52-
write_basic_package_version_file(ctre-config-version.cmake
53-
VERSION ${PROJECT_VERSION}
54-
COMPATIBILITY SameMajorVersion)
55-
56-
install(EXPORT ${PROJECT_NAME}-targets
57-
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME}"
58-
NAMESPACE ${PROJECT_NAME}::)
59-
install(
60-
FILES
61-
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
62-
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
63-
DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/${PROJECT_NAME})
64-
install(DIRECTORY include/ DESTINATION include
65-
FILES_MATCHING PATTERN *.hpp)
19+
# ---- Warning guard for vendoring projects ----
6620

67-
if(CTRE_BUILD_TESTS)
68-
add_subdirectory(tests)
21+
set(warning_guard "")
22+
if(NOT PROJECT_IS_TOP_LEVEL)
23+
option(ctre_INCLUDES_WITH_SYSTEM
24+
"Use SYSTEM modifier for ctre's includes, disabling warnings" ON)
25+
mark_as_advanced(ctre_INCLUDES_WITH_SYSTEM)
26+
if(ctre_INCLUDES_WITH_SYSTEM)
27+
set(warning_guard SYSTEM)
28+
endif()
6929
endif()
7030

71-
if (NOT CTRE_BUILD_PACKAGE)
72-
return()
73-
endif()
31+
# ---- Declare library ----
7432

75-
list(APPEND source-generators TBZ2 TGZ TXZ ZIP)
33+
add_library(ctre_ctre INTERFACE)
34+
add_library(ctre::ctre ALIAS ctre_ctre)
7635

77-
if (CTRE_BUILD_PACKAGE_DEB)
78-
list(APPEND binary-generators "DEB")
79-
endif()
36+
set_property(TARGET ctre_ctre PROPERTY EXPORT_NAME ctre)
8037

81-
if (CTRE_BUILD_PACKAGE_RPM)
82-
list(APPEND binary-generators "RPM")
83-
endif()
38+
target_include_directories(ctre_ctre ${warning_guard} INTERFACE
39+
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>")
40+
target_compile_features(ctre_ctre INTERFACE cxx_std_17)
41+
42+
# ---- Install rules ----
43+
44+
if(NOT CMAKE_SKIP_INSTALL_RULES)
45+
# For hygienic reasons, install headers to their own directory (issue #207)
46+
if(PROJECT_IS_TOP_LEVEL)
47+
set(CMAKE_INSTALL_INCLUDEDIR include/ctre CACHE PATH "")
48+
endif()
8449

85-
set(CPACK_SOURCE_GENERATOR ${source-generators})
86-
set(CPACK_GENERATOR ${binary-generators})
50+
# The project is configured without a language, so this needs to be set
51+
set(CMAKE_INSTALL_LIBDIR lib CACHE PATH "")
8752

88-
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}")
89-
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}")
53+
include(CMakePackageConfigHelpers)
54+
include(GNUInstallDirs)
9055

91-
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Hanicka Dusíková")
92-
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${PROJECT_DESCRIPTION}")
93-
set(CPACK_DEBIAN_PACKAGE_NAME "lib${PROJECT_NAME}-dev")
56+
# For header-only libraries, everything goes in the -dev package
57+
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME ctre_Development)
9458

95-
set(CPACK_RPM_PACKAGE_NAME "lib${PROJECT_NAME}-devel")
59+
install(DIRECTORY include/
60+
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
61+
FILES_MATCHING PATTERN *.hpp)
9662

97-
set(PKG_CONFIG_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc")
98-
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/packaging/pkgconfig.pc.in" "${PKG_CONFIG_FILE_NAME}" @ONLY)
99-
install(FILES "${PKG_CONFIG_FILE_NAME}"
100-
DESTINATION "${CMAKE_INSTALL_DATADIR}/pkgconfig"
101-
)
63+
install(TARGETS ctre_ctre
64+
EXPORT ctre-targets
65+
DESTINATION dummy # required until 3.14
66+
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
67+
68+
# Replace with ARCH_INDEPENDENT once updated to CMake 3.14
69+
set(tmp_CMAKE_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}")
70+
set(CMAKE_SIZEOF_VOID_P "")
71+
72+
write_basic_package_version_file(ctre-config-version.cmake
73+
COMPATIBILITY SameMajorVersion)
74+
75+
set(CMAKE_SIZEOF_VOID_P "${tmp_CMAKE_SIZEOF_VOID_P}")
76+
77+
# Allow package maintainers to freely override the path for the configs
78+
set(ctre_INSTALL_CMAKEDIR "${CMAKE_INSTALL_DATADIR}/cmake/ctre"
79+
CACHE PATH "CMake package config location relative to the install prefix")
80+
mark_as_advanced(ctre_INSTALL_CMAKEDIR)
81+
82+
install(FILES "${PROJECT_BINARY_DIR}/ctre-config-version.cmake"
83+
DESTINATION "${ctre_INSTALL_CMAKEDIR}")
84+
85+
install(EXPORT ctre-targets
86+
FILE ctre-config.cmake
87+
DESTINATION "${ctre_INSTALL_CMAKEDIR}"
88+
NAMESPACE ctre::)
89+
90+
option(ctre_ENABLE_PKGCONFIG "Install a .pc file for the project" ON)
91+
if(ctre_ENABLE_PKGCONFIG)
92+
# This can only detect issues on first configure, but it's still better
93+
# than nothing
94+
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
95+
message(AUTHOR_WARNING "The value of CMAKE_INSTALL_PREFIX was not set, "
96+
"but ctre_ENABLE_PKGCONFIG was enabled. This is likely an error.")
97+
endif()
98+
99+
set(ctre_INSTALL_PKGCONFIGDIR "${CMAKE_INSTALL_DATADIR}/pkgconfig"
100+
CACHE FILEPATH "pkgconfig file location relative to the install prefix")
101+
mark_as_advanced(ctre_INSTALL_PKGCONFIG)
102+
103+
configure_file(packaging/pkgconfig.pc.in ctre.pc @ONLY)
104+
install(FILES "${PROJECT_BINARY_DIR}/ctre.pc"
105+
DESTINATION "${ctre_INSTALL_PKGCONFIGDIR}")
106+
endif()
107+
108+
if(PROJECT_IS_TOP_LEVEL)
109+
foreach(cpack_type IN ITEMS Config SourceConfig)
110+
configure_file(packaging/CPackDefaults.cmake.in
111+
"CPack${cpack_type}-ctre.cmake" @ONLY)
112+
endforeach()
113+
114+
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}")
115+
set(CPACK_PACKAGE_HOMEPAGE_URL "${PROJECT_HOMEPAGE_URL}")
116+
include(CPack)
117+
endif()
118+
endif()
102119

103-
list(APPEND CPACK_SOURCE_IGNORE_FILES /.git/ /build/ .gitignore .DS_Store)
120+
# ---- Testing ----
104121

105-
include(CPack)
122+
if(PROJECT_IS_TOP_LEVEL)
123+
include(CTest)
124+
if(BUILD_TESTING)
125+
add_subdirectory(tests)
126+
endif()
127+
endif()

packaging/CPackDefaults.cmake.in

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# This file is configured to the root binary directory and should be included
2+
# with the --config flag of cpack
3+
4+
include(CPack@cpack_type@.cmake)
5+
6+
set(CPACK_PACKAGE_FILE_NAME "ctre-@PROJECT_VERSION@")
7+
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}")
8+
9+
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Hanicka Dusíková")
10+
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "@PROJECT_DESCRIPTION@")
11+
set(CPACK_DEBIAN_PACKAGE_NAME libctre-dev)
12+
13+
set(CPACK_RPM_PACKAGE_NAME libctre-devel)
14+
15+
set(CPACK_IGNORE_FILES "/\\.git/;/build/;\\.gitignore;\\.DS_Store")

tests/CMakeLists.txt

+22-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
1+
cmake_minimum_required(VERSION 3.12)
2+
3+
enable_language(CXX)
4+
5+
# CONFIGURE_DEPENDS was added in 3.12, so tests require at least that version
16
file(GLOB test-sources CONFIGURE_DEPENDS *.cpp)
27

8+
# TODO: remove once nothing depends on this (replaced by CTest tests)
39
add_custom_target(ctre-test)
410

5-
foreach (source IN LISTS test-sources)
11+
# --config needs to be passed to the build command only if the generator is
12+
# multi-config, otherwise there is only one configuration to pick from
13+
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
14+
set(config_args "")
15+
if(is_multi_config)
16+
set(config_args --config $<CONFIG>)
17+
endif()
18+
19+
foreach(source IN LISTS test-sources)
620
get_filename_component(test "${source}" NAME_WE)
7-
add_library(ctre-test-${test} STATIC EXCLUDE_FROM_ALL ${source})
8-
target_link_libraries(ctre-test-${test} PRIVATE ctre)
9-
add_dependencies(ctre-test ctre-test-${test})
21+
add_library("ctre-test-${test}" STATIC EXCLUDE_FROM_ALL "${source}")
22+
target_link_libraries("ctre-test-${test}" PRIVATE ctre::ctre)
23+
add_dependencies(ctre-test "ctre-test-${test}")
24+
# The tests passes only if the above target compiles successfully
25+
add_test(NAME "ctre.${test}" COMMAND
26+
"${CMAKE_COMMAND}" --build "${ctre_BINARY_DIR}" ${config_args} # unquoted
27+
--target "ctre-test-${test}")
1028
endforeach()

0 commit comments

Comments
 (0)