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