Skip to content

Commit 9589f7c

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 may change at install time, so .pc file is generated at that time to ensure the prefix is always right * 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 9589f7c

File tree

5 files changed

+153
-99
lines changed

5 files changed

+153
-99
lines changed

CMakeLists.txt

+106-88
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,123 @@
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+
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME ctre_Development)
9457

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

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-
)
62+
install(TARGETS ctre_ctre
63+
EXPORT ctre-targets
64+
DESTINATION dummy # required until 3.14
65+
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
66+
67+
# Replace with ARCH_INDEPENDENT once updated to CMake 3.14
68+
set(tmp_CMAKE_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}")
69+
set(CMAKE_SIZEOF_VOID_P "")
70+
71+
write_basic_package_version_file(ctre-config-version.cmake
72+
COMPATIBILITY SameMajorVersion)
73+
74+
set(CMAKE_SIZEOF_VOID_P "${tmp_CMAKE_SIZEOF_VOID_P}")
75+
76+
# Allow package maintainers to freely override the path for the configs
77+
set(ctre_INSTALL_CMAKEDIR "${CMAKE_INSTALL_DATADIR}/cmake/ctre"
78+
CACHE PATH "CMake package config location relative to the install prefix")
79+
mark_as_advanced(ctre_INSTALL_CMAKEDIR)
80+
81+
install(FILES "${PROJECT_BINARY_DIR}/ctre-config-version.cmake"
82+
DESTINATION "${ctre_INSTALL_CMAKEDIR}")
83+
84+
install(EXPORT ctre-targets
85+
FILE ctre-config.cmake
86+
DESTINATION "${ctre_INSTALL_CMAKEDIR}"
87+
NAMESPACE ctre::)
88+
89+
option(ctre_ENABLE_PKGCONFIG "Install a .pc file for the project" ON)
90+
if(ctre_ENABLE_PKGCONFIG)
91+
set(ctre_INSTALL_PKGCONFIG "${CMAKE_INSTALL_DATADIR}/pkgconfig/ctre.pc"
92+
CACHE FILEPATH "pkgconfig file location relative to the install prefix")
93+
mark_as_advanced(ctre_INSTALL_PKGCONFIG)
94+
95+
# Export variables for pkgconfig.cmake to use in the install script
96+
install(CODE "set(pc_path [==[${ctre_INSTALL_PKGCONFIG}]==])")
97+
install(CODE "set(include_dir [==[${CMAKE_INSTALL_INCLUDEDIR}]==])")
98+
foreach(var IN ITEMS NAME DESCRIPTION VERSION)
99+
install(CODE "set(PROJECT_${var} [==[${PROJECT_${var}}]==])")
100+
endforeach()
101+
install(SCRIPT packaging/pkgconfig.cmake)
102+
endif()
103+
104+
if(PROJECT_IS_TOP_LEVEL)
105+
# This variable is normally used by set_property(INSTALL), but there aren't
106+
# any in this project, so it makes this a convenient place to provide some
107+
# defaults
108+
set(CPACK_PROPERTIES_FILE
109+
"${PROJECT_SOURCE_DIR}/packaging/CPackDefaults.cmake")
110+
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}")
111+
set(CPACK_PACKAGE_HOMEPAGE_URL "${PROJECT_HOMEPAGE_URL}")
112+
include(CPack)
113+
endif()
114+
endif()
102115

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

105-
include(CPack)
118+
if(PROJECT_IS_TOP_LEVEL)
119+
include(CTest)
120+
if(BUILD_TESTING)
121+
add_subdirectory(tests)
122+
endif()
123+
endif()

packaging/CPackDefaults.cmake

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# This file is loaded at the end of the generated CPackConfig.cmake
2+
3+
set(CPACK_PACKAGE_FILE_NAME "ctre-${CPACK_PACKAGE_VERSION}")
4+
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}")
5+
6+
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Hanicka Dusíková")
7+
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
8+
set(CPACK_DEBIAN_PACKAGE_NAME libctre-dev)
9+
10+
set(CPACK_RPM_PACKAGE_NAME libctre-devel)
11+
12+
list(APPEND CPACK_SOURCE_IGNORE_FILES
13+
"/\\.git/" /build/ "\\.gitignore" "\\.DS_Store")

packaging/pkgconfig.cmake

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# This script is run at CMake install time
2+
3+
get_filename_component(prefix "${CMAKE_INSTALL_PREFIX}" ABSOLUTE)
4+
file(WRITE "${CMAKE_INSTALL_PREFIX}/${pc_path}" "\
5+
prefix=${prefix}
6+
includedir=\${prefix}/${include_dir}
7+
8+
Name: ${PROJECT_NAME}
9+
Description: ${PROJECT_DESCRIPTION}
10+
Version: ${PROJECT_VERSION}
11+
Cflags: -I\${includedir}
12+
")

packaging/pkgconfig.pc.in

-7
This file was deleted.

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)