|
2 | 2 | # Distributed under the MIT software license, see the accompanying |
3 | 3 | # file COPYING or http://www.opensource.org/licenses/mit-license.php. |
4 | 4 |
|
| 5 | +# Top-level wrapper for standalone builds (`cmake -S .`). Adds the example |
| 6 | +# subdirectory, which is the only thing not relevant to subtree consumers |
| 7 | +# (which configure `lib/` directly via `add_subdirectory()`). |
| 8 | +# |
| 9 | +# The actual library, generator, headers, tests and pkg-config template live |
| 10 | +# under `lib/` so that `git subtree split --prefix=lib` produces a `lib` |
| 11 | +# branch suitable for use as a slim git subtree by downstream projects. |
| 12 | + |
5 | 13 | cmake_minimum_required(VERSION 3.12) |
6 | 14 |
|
7 | 15 | project("Libmultiprocess" CXX) |
8 | | -if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) |
9 | | - set(CMAKE_CXX_STANDARD 20) |
10 | | - set(CMAKE_CXX_STANDARD_REQUIRED YES) |
11 | | -endif() |
| 16 | +set(CMAKE_CXX_STANDARD 20) |
| 17 | +set(CMAKE_CXX_STANDARD_REQUIRED YES) |
12 | 18 |
|
13 | | -include("cmake/compat_find.cmake") |
| 19 | +# Tell lib/CMakeLists.txt that this is a standalone build, even though it is |
| 20 | +# being processed via add_subdirectory() rather than as the top-level source. |
| 21 | +set(MP_STANDALONE TRUE) |
| 22 | +include(CTest) |
14 | 23 |
|
| 24 | +# Threads::Threads and Cap'n Proto targets are needed by the example/ |
| 25 | +# subdirectory. find_package() creates IMPORTED targets in the calling |
| 26 | +# directory's scope, so do it here as well as in lib/CMakeLists.txt. |
15 | 27 | find_package(Threads REQUIRED) |
16 | 28 | find_package(CapnProto 0.7 QUIET NO_MODULE) |
17 | | - if(NOT CapnProto_FOUND) |
18 | | - message(FATAL_ERROR |
19 | | - "Cap'n Proto is required but was not found.\n" |
20 | | - "To resolve, choose one of the following:\n" |
21 | | - " - Install Cap'n Proto (version 1.0+ recommended)\n" |
22 | | - " - For Bitcoin Core compilation build with -DENABLE_IPC=OFF to disable multiprocess support\n" |
23 | | - ) |
24 | | - endif() |
25 | | - |
26 | | -# Cap'n Proto compatibility checks |
27 | | -set(CAPNPROTO_ISSUES "") |
28 | | -set(CAPNPROTO_CVE_AFFECTED FALSE) |
29 | | -set(CAPNPROTO_CLANG_INCOMPATIBLE FALSE) |
30 | | - |
31 | | -# Check for list-of-pointers memory access bug from Nov 2022 |
32 | | -# https://nvd.nist.gov/vuln/detail/CVE-2022-46149 |
33 | | -# https://github.com/advisories/GHSA-qqff-4vw4-f6hx |
34 | | -# https://github.com/capnproto/capnproto/security/advisories/GHSA-qqff-4vw4-f6hx |
35 | | -# https://github.com/capnproto/capnproto/blob/master/security-advisories/2022-11-30-0-pointer-list-bounds.md |
36 | | -# https://capnproto.org/news/2022-11-30-CVE-2022-46149-security-advisory.html |
37 | | -# https://dwrensha.github.io/capnproto-rust/2022/11/30/out_of_bounds_memory_access_bug.html |
38 | | -if(CapnProto_VERSION STREQUAL "0.7.0" |
39 | | - OR CapnProto_VERSION STREQUAL "0.8.0" |
40 | | - OR CapnProto_VERSION STREQUAL "0.9.0" |
41 | | - OR CapnProto_VERSION STREQUAL "0.9.1" |
42 | | - OR CapnProto_VERSION STREQUAL "0.10.0" |
43 | | - OR CapnProto_VERSION STREQUAL "0.10.1" |
44 | | - OR CapnProto_VERSION STREQUAL "0.10.2") |
45 | | - set(CAPNPROTO_CVE_AFFECTED TRUE) |
46 | | - string(APPEND CAPNPROTO_ISSUES "- CVE-2022-46149 security vulnerability (details: https://github.com/advisories/GHSA-qqff-4vw4-f6hx)\n") |
47 | | -endif() |
48 | | - |
49 | | -# Check for Cap'n Proto / Clang / C++20 incompatibility |
50 | | -# Cap'n Proto 0.9.x and 0.10.x are incompatible with Clang 16+ when using C++20 |
51 | | -# due to P2468R2 implementation. This was fixed in Cap'n Proto 1.0+. |
52 | | -# See: https://github.com/bitcoin-core/libmultiprocess/issues/199 |
53 | | -if((CapnProto_VERSION VERSION_GREATER_EQUAL "0.9.0") AND |
54 | | - (CapnProto_VERSION VERSION_LESS "1.0.0") AND |
55 | | - (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND |
56 | | - (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "16") AND |
57 | | - (CMAKE_CXX_STANDARD EQUAL 20)) |
58 | | - set(CAPNPROTO_CLANG_INCOMPATIBLE TRUE) |
59 | | - string(APPEND CAPNPROTO_ISSUES "- Incompatible with Clang ${CMAKE_CXX_COMPILER_VERSION} when using C++20\n") |
60 | | -endif() |
61 | | - |
62 | | -if(CAPNPROTO_CVE_AFFECTED OR CAPNPROTO_CLANG_INCOMPATIBLE) |
63 | | - set(RESOLUTION_OPTIONS "") |
64 | | - |
65 | | - # Fixes both issues |
66 | | - string(APPEND RESOLUTION_OPTIONS " - Upgrade to Cap'n Proto version 1.0 or newer (recommended)\n") |
67 | | - |
68 | | - if(CAPNPROTO_CVE_AFFECTED AND NOT CAPNPROTO_CLANG_INCOMPATIBLE) |
69 | | - string(APPEND RESOLUTION_OPTIONS " - Upgrade to a patched minor version (0.7.1, 0.8.1, 0.9.2, 0.10.3, or later)\n") |
70 | | - elseif(CAPNPROTO_CLANG_INCOMPATIBLE AND NOT CAPNPROTO_CVE_AFFECTED) |
71 | | - string(APPEND RESOLUTION_OPTIONS " - Use GCC instead of Clang\n") |
72 | | - endif() |
73 | | - |
74 | | - string(APPEND RESOLUTION_OPTIONS " - For Bitcoin Core compilation build with -DENABLE_IPC=OFF to disable multiprocess support\n") |
75 | | - |
76 | | - message(FATAL_ERROR |
77 | | - "The version of Cap'n Proto detected: ${CapnProto_VERSION} has known compatibility issues:\n" |
78 | | - "${CAPNPROTO_ISSUES}" |
79 | | - "To resolve, choose one of the following:\n" |
80 | | - "${RESOLUTION_OPTIONS}" |
81 | | - ) |
82 | | -endif() |
83 | | - |
84 | | -set(MPGEN_EXECUTABLE "" CACHE FILEPATH "If specified, should be full path to an external mpgen binary to use rather than the one built internally.") |
85 | | - |
86 | | -option(MP_ENABLE_CLANG_TIDY "Run clang-tidy with the compiler." OFF) |
87 | | -if(MP_ENABLE_CLANG_TIDY) |
88 | | - find_program(CLANG_TIDY_EXECUTABLE NAMES clang-tidy) |
89 | | - if(NOT CLANG_TIDY_EXECUTABLE) |
90 | | - message(FATAL_ERROR "MP_ENABLE_CLANG_TIDY is ON but clang-tidy is not found.") |
91 | | - endif() |
92 | | - set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXECUTABLE}") |
93 | | - |
94 | | - # Workaround for nix from https://gitlab.kitware.com/cmake/cmake/-/issues/20912#note_793338 |
95 | | - # Nix injects header paths via $NIX_CFLAGS_COMPILE; CMake tags these as |
96 | | - # CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES and omits them from the compile |
97 | | - # database, so clang-tidy, which ignores $NIX_CFLAGS_COMPILE, can't find capnp |
98 | | - # headers. Setting them as standard passes them to clang-tidy. |
99 | | - set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) |
100 | | -endif() |
101 | | - |
102 | | -option(MP_ENABLE_IWYU "Run include-what-you-use with the compiler." OFF) |
103 | | -if(MP_ENABLE_IWYU) |
104 | | - find_program(IWYU_EXECUTABLE NAMES include-what-you-use iwyu) |
105 | | - if(NOT IWYU_EXECUTABLE) |
106 | | - message(FATAL_ERROR "MP_ENABLE_IWYU is ON but include-what-you-use was not found.") |
107 | | - endif() |
108 | | - set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${IWYU_EXECUTABLE};-Xiwyu;--error") |
109 | | - if(DEFINED ENV{IWYU_MAPPING_FILE}) |
110 | | - list(APPEND CMAKE_CXX_INCLUDE_WHAT_YOU_USE "-Xiwyu" "--mapping_file=$ENV{IWYU_MAPPING_FILE}") |
111 | | - endif() |
112 | | -endif() |
113 | | - |
114 | | -include("cmake/compat_config.cmake") |
115 | | -include("cmake/pthread_checks.cmake") |
116 | | -include(GNUInstallDirs) |
117 | | - |
118 | | -# Set MP_INCLUDE_DIR as a global property so target_capnp_sources function can |
119 | | -# use it, and its callers don't need to specify the include directory manually |
120 | | -# to avoid "error: Import failed: /mp/proxy.capnp" failures from capnproto. |
121 | | -set_property(GLOBAL PROPERTY MP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") |
122 | | - |
123 | | -# Set a convenience variable for subdirectories. |
124 | | -if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) |
125 | | - set(MP_STANDALONE TRUE) |
126 | | - include(CTest) |
127 | | -else() |
128 | | - set(MP_STANDALONE FALSE) |
129 | | -endif() |
130 | | - |
131 | | -# Prevent include directories from parent project from leaking into this one. |
132 | | -set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES "") |
133 | | - |
134 | | -# Generated C++ preprocessor defines |
135 | | -configure_file(include/mp/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/mp/config.h") |
136 | | - |
137 | | -# Generated C++ Capn'Proto schema files |
138 | | -capnp_generate_cpp(MP_PROXY_SRCS MP_PROXY_HDRS include/mp/proxy.capnp) |
139 | | -set_source_files_properties("${MP_PROXY_SRCS}" PROPERTIES SKIP_LINTING TRUE) # Ignored before cmake 3.27 |
140 | | - |
141 | | -# util library |
142 | | -add_library(mputil OBJECT src/mp/util.cpp) |
143 | | -target_include_directories(mputil PRIVATE |
144 | | - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> |
145 | | - $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>) |
146 | | -target_link_libraries(mputil PUBLIC CapnProto::kj) |
147 | | - |
148 | | -# libmultiprocess.a runtime library |
149 | | -set(MP_PUBLIC_HEADERS |
150 | | - ${MP_PROXY_HDRS} |
151 | | - include/mp/proxy-io.h |
152 | | - include/mp/proxy-types.h |
153 | | - include/mp/proxy.h |
154 | | - include/mp/type-char.h |
155 | | - include/mp/type-chrono.h |
156 | | - include/mp/type-context.h |
157 | | - include/mp/type-data.h |
158 | | - include/mp/type-decay.h |
159 | | - include/mp/type-exception.h |
160 | | - include/mp/type-function.h |
161 | | - include/mp/type-interface.h |
162 | | - include/mp/type-map.h |
163 | | - include/mp/type-message.h |
164 | | - include/mp/type-number.h |
165 | | - include/mp/type-optional.h |
166 | | - include/mp/type-pair.h |
167 | | - include/mp/type-pointer.h |
168 | | - include/mp/type-set.h |
169 | | - include/mp/type-string.h |
170 | | - include/mp/type-struct.h |
171 | | - include/mp/type-threadmap.h |
172 | | - include/mp/type-tuple.h |
173 | | - include/mp/type-vector.h |
174 | | - include/mp/type-void.h |
175 | | - include/mp/util.h) |
176 | | -add_library(multiprocess STATIC |
177 | | - ${MP_PROXY_SRCS} |
178 | | - ${MP_PUBLIC_HEADERS} |
179 | | - src/mp/proxy.cpp |
180 | | - $<TARGET_OBJECTS:mputil>) |
181 | | -add_library(Libmultiprocess::multiprocess ALIAS multiprocess) |
182 | | -target_include_directories(multiprocess PUBLIC |
183 | | - $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> |
184 | | - $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> |
185 | | - $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) |
186 | | -target_link_libraries(multiprocess PUBLIC CapnProto::capnp) |
187 | | -target_link_libraries(multiprocess PUBLIC CapnProto::capnp-rpc) |
188 | | -target_link_libraries(multiprocess PUBLIC CapnProto::kj) |
189 | | -target_link_libraries(multiprocess PUBLIC CapnProto::kj-async) |
190 | | -set_target_properties(multiprocess PROPERTIES |
191 | | - PUBLIC_HEADER "${MP_PUBLIC_HEADERS}") |
192 | | -install(TARGETS multiprocess EXPORT LibTargets |
193 | | - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib |
194 | | - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mp COMPONENT lib) |
195 | | - |
196 | | -# mpgen code generator |
197 | | -add_executable(mpgen src/mp/gen.cpp $<TARGET_OBJECTS:mputil>) |
198 | | -add_executable(Libmultiprocess::mpgen ALIAS mpgen) |
199 | | -target_include_directories(mpgen PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>) |
200 | | -target_include_directories(mpgen PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) |
201 | | -target_link_libraries(mpgen PRIVATE CapnProto::capnp) |
202 | | -target_link_libraries(mpgen PRIVATE CapnProto::capnp-rpc) |
203 | | -target_link_libraries(mpgen PRIVATE CapnProto::capnpc) |
204 | | -target_link_libraries(mpgen PRIVATE CapnProto::kj) |
205 | | -target_link_libraries(mpgen PRIVATE Threads::Threads) |
206 | | -set_target_properties(mpgen PROPERTIES |
207 | | - INSTALL_RPATH_USE_LINK_PATH TRUE) |
208 | | -set_target_properties(mpgen PROPERTIES |
209 | | - PUBLIC_HEADER include/mp/proxy.capnp) |
210 | | -install(TARGETS mpgen EXPORT BinTargets |
211 | | - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin |
212 | | - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mp COMPONENT bin) |
213 | | - |
214 | | -# makefile include to invoke mpgen code generator, for downstream Make projects |
215 | | -install(FILES "include/mpgen.mk" |
216 | | - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT bin) |
217 | | - |
218 | | -# pkg-config module to build against libmultiprocess library, for downstream autoconf projects |
219 | | -configure_file(pkgconfig/libmultiprocess.pc.in "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/libmultiprocess.pc" @ONLY) |
220 | | -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/libmultiprocess.pc" |
221 | | - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT lib) |
222 | | - |
223 | | -# cmake include to invoke mpgen code generator, for downstream CMake projects |
224 | | -install( |
225 | | - FILES |
226 | | - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/TargetCapnpSources.cmake |
227 | | - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess COMPONENT bin) |
228 | | - |
229 | | -# CMake target import files, for downstream CMake projects |
230 | | -install(EXPORT BinTargets |
231 | | - NAMESPACE Libmultiprocess:: |
232 | | - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess COMPONENT bin) |
233 | | -install(EXPORT LibTargets |
234 | | - NAMESPACE Libmultiprocess:: |
235 | | - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess COMPONENT lib) |
236 | | - |
237 | | -# CMake find_package config file, for downstream CMake projects |
238 | | -include(CMakePackageConfigHelpers) |
239 | | -configure_package_config_file( |
240 | | - ${PROJECT_SOURCE_DIR}/cmake/Config.cmake.in |
241 | | - LibmultiprocessConfig.cmake |
242 | | - INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess |
243 | | - NO_SET_AND_CHECK_MACRO) |
244 | | -install( |
245 | | - FILES |
246 | | - ${CMAKE_CURRENT_BINARY_DIR}/LibmultiprocessConfig.cmake |
247 | | - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Libmultiprocess |
248 | | - COMPONENT common) |
249 | | - |
250 | | -# Makefile targets to support "make install-bin" "make install-lib" |
251 | | -add_custom_target(install-bin |
252 | | - COMMAND ${CMAKE_COMMAND} -DCOMPONENT=bin -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake |
253 | | - COMMAND ${CMAKE_COMMAND} -DCOMPONENT=common -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake |
254 | | - VERBATIM) |
255 | | -add_dependencies(install-bin mpgen) |
256 | | -add_custom_target(install-lib |
257 | | - COMMAND ${CMAKE_COMMAND} -DCOMPONENT=lib -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake |
258 | | - COMMAND ${CMAKE_COMMAND} -DCOMPONENT=common -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake |
259 | | - VERBATIM) |
260 | | -add_dependencies(install-lib multiprocess) |
261 | 29 |
|
262 | | -# Example and test subdirectories |
| 30 | +add_subdirectory(lib) |
263 | 31 | add_subdirectory(example EXCLUDE_FROM_ALL) |
264 | | -add_subdirectory(test EXCLUDE_FROM_ALL) |
0 commit comments