Skip to content

Commit 2428f6c

Browse files
committed
Merge #13: build: Add CMake-based build system (5 of N)
8ee7537 cmake: Add `systemtap-sdt` optional package support (Hennadii Stepanov) 697c397 cmake: Add `libzmq` optional package support (Hennadii Stepanov) b195c9c cmake: Add `libminiupnpc` optional package support (Hennadii Stepanov) 9587ed7 cmake: Add `libnatpmp` optional package support (Hennadii Stepanov) ba50cad [FIXUP] cmake: Fix `check_evhttp_connection_get_peer` macro (Hennadii Stepanov) 9412a2e [FIXUP] cmake: Cleanup `AddBoostIfNeeded` module (Hennadii Stepanov) 15bcb8e cmake: Add `ccache` support (Hennadii Stepanov) 480c8cb cmake: Add `TristateOption` module (Hennadii Stepanov) Pull request description: It was [suggested](#10 (comment)): > It might be helpful to get some more of the depends interactions hooked up as a next step Done in this PR. --- The parent PR: bitcoin#25797. The previous PRs in the staging branch: #5, #6, #7, #10. --- EXAMPLES: 1. Cross-compiling for Windows: ``` make -C depends HOST=x86_64-w64-mingw32 NO_QT=1 NO_WALLET=1 cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=depends/x86_64-w64-mingw32/share/toolchain.cmake cmake --build build ``` 2. Cross-compiling for macOS (`arm64`, `x86_64`): ``` make -C depends HOST=arm64-apple-darwin NO_QT=1 NO_WALLET=1 cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=depends/arm64-apple-darwin/share/toolchain.cmake cmake --build build ``` 3. Building on macOS, arm64: - essential build tools: ``` brew install cmake pkg-config ``` - optional build tools: ``` brew install ccache ``` - essential dependencies: ``` brew install boost libevent ``` - optional dependencies: ``` brew install libnatpmp miniupnpc zeromq ``` - configure and build: ``` cmake -S . -B build cmake --build build ``` 4. Building on Windows: - `ccache` is available [here](https://community.chocolatey.org/packages/ccache) or [here](https://ccache.dev/download.html) (also see a [note](#13 (comment))): ``` choco install ccache --version=4.7.4 ``` - the [`vcpkg`](https://vcpkg.io) package manager is used to provide other dependencies: ``` vcpkg --triplet=x64-windows-static install boost-multi-index boost-signals2 libevent miniupnpc zeromq ``` - configure and build: ``` cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static cmake --build build -- -property:UseMultiToolTask=true -maxCpuCount ``` --- **NOTE** As always, make sure your build tree is clean :) ACKs for top commit: vasild: ACK 8ee7537 theuni: ACK 8ee7537 Tree-SHA512: 36ebc63e73d507d86b154121b9bc5b8216554fd63f31808f257cefff7a1a104ce066f2b2cf9fdfc1828066d33cdc0b9ede4a81d8e6a7932de3adcb1f14674796
2 parents 5b25bcd + 8ee7537 commit 2428f6c

File tree

10 files changed

+311
-13
lines changed

10 files changed

+311
-13
lines changed

CMakeLists.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ option(ASM "Use assembly routines." ON)
4343
cmake_dependent_option(CXX20 "Enable compilation in C++20 mode." OFF "NOT MSVC" ON)
4444
option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON)
4545

46+
# TODO: These tri-state options will be removed and most features
47+
# will become opt-in by default before merging into master.
48+
include(TristateOption)
49+
tristate_option(CCACHE "Use ccache for compiling." "if ccache is found." AUTO)
50+
tristate_option(WITH_NATPMP "Enable NAT-PMP." "if libnatpmp is found." AUTO)
51+
tristate_option(WITH_MINIUPNPC "Enable UPnP." "if libminiupnpc is found." AUTO)
52+
tristate_option(WITH_ZMQ "Enable ZMQ notifications." "if libzmq is found." AUTO)
53+
tristate_option(WITH_USDT
54+
"Enable tracepoints for Userspace, Statically Defined Tracing."
55+
"if sys/sdt.h is found."
56+
AUTO
57+
)
58+
4659
if(CXX20)
4760
set(CMAKE_CXX_STANDARD 20)
4861
else()
@@ -113,6 +126,8 @@ include(cmake/secp256k1.cmake)
113126
include(CheckStdFilesystem)
114127
check_std_filesystem()
115128

129+
include(cmake/optional.cmake)
130+
116131
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14)
117132
include(CheckPIESupported)
118133
check_pie_supported(OUTPUT_VARIABLE check_pie_output LANGUAGES CXX)
@@ -133,6 +148,11 @@ message("Configure summary")
133148
message("=================")
134149
message("Executables:")
135150
message(" bitcoind ............................ ${BUILD_DAEMON}")
151+
message("Optional packages:")
152+
message(" NAT-PMP ............................. ${WITH_NATPMP}")
153+
message(" UPnP ................................ ${WITH_MINIUPNPC}")
154+
message(" ZeroMQ .............................. ${WITH_ZMQ}")
155+
message(" USDT tracing ........................ ${WITH_USDT}")
136156
message("")
137157
if(CMAKE_CROSSCOMPILING)
138158
set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}")
@@ -175,6 +195,7 @@ else()
175195
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
176196
endif()
177197
message("Use assembly routines ................. ${ASM}")
198+
message("Use ccache for compiling .............. ${CCACHE}")
178199
message("\n")
179200
if(configure_warnings)
180201
message(" ******\n")

cmake/bitcoin-config.h.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
/* Copyright year */
3434
#define COPYRIGHT_YEAR @COPYRIGHT_YEAR@
3535

36+
/* Define to 1 to enable tracepoints for Userspace, Statically Defined Tracing
37+
*/
38+
#cmakedefine ENABLE_TRACING 1
39+
3640
/* Define this symbol if you have __builtin_clzl */
3741
#cmakedefine HAVE_BUILTIN_CLZL 1
3842

cmake/module/AddBoostIfNeeded.cmake

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,6 @@ function(add_boost_if_needed)
1717
directory and other added INTERFACE properties.
1818
]=]
1919

20-
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND BREW_COMMAND)
21-
execute_process(
22-
COMMAND ${BREW_COMMAND} --prefix boost
23-
OUTPUT_VARIABLE BOOST_ROOT
24-
ERROR_QUIET
25-
OUTPUT_STRIP_TRAILING_WHITESPACE
26-
)
27-
endif()
28-
2920
set(Boost_NO_BOOST_CMAKE ON)
3021
find_package(Boost 1.64.0 REQUIRED)
3122
set_target_properties(Boost::boost PROPERTIES IMPORTED_GLOBAL TRUE)

cmake/module/AddLibeventIfNeeded.cmake

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
# Distributed under the MIT software license, see the accompanying
33
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
# Check whether evhttp_connection_get_peer expects const char**.
6+
# See https://github.com/libevent/libevent/commit/a18301a2bb160ff7c3ffaf5b7653c39ffe27b385
57
macro(check_evhttp_connection_get_peer target)
6-
# Check whether evhttp_connection_get_peer expects const char**.
7-
# Fail if neither are available.
8+
cmake_push_check_state(RESET)
9+
set(CMAKE_REQUIRED_LIBRARIES ${target})
810
check_cxx_source_compiles("
911
#include <cstdint>
1012
#include <event2/http.h>
@@ -18,6 +20,7 @@ macro(check_evhttp_connection_get_peer target)
1820
}
1921
" HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR
2022
)
23+
cmake_pop_check_state()
2124
target_compile_definitions(${target} INTERFACE
2225
$<$<BOOL:${HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR}>:HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR=1>
2326
)
@@ -38,14 +41,20 @@ function(add_libevent_if_needed)
3841
endif()
3942

4043
include(CrossPkgConfig)
41-
cross_pkg_check_modules(libevent REQUIRED libevent>=${libevent_minimum_version} IMPORTED_TARGET GLOBAL)
44+
cross_pkg_check_modules(libevent
45+
REQUIRED IMPORTED_TARGET GLOBAL
46+
libevent>=${libevent_minimum_version}
47+
)
4248
check_evhttp_connection_get_peer(PkgConfig::libevent)
4349
target_link_libraries(PkgConfig::libevent INTERFACE
4450
$<$<BOOL:${MINGW}>:iphlpapi;ssp;ws2_32>
4551
)
4652
add_library(libevent::libevent ALIAS PkgConfig::libevent)
4753

4854
if(NOT WIN32)
49-
cross_pkg_check_modules(libevent_pthreads REQUIRED libevent_pthreads>=${libevent_minimum_version} IMPORTED_TARGET)
55+
cross_pkg_check_modules(libevent_pthreads
56+
REQUIRED IMPORTED_TARGET GLOBAL
57+
libevent_pthreads>=${libevent_minimum_version}
58+
)
5059
endif()
5160
endfunction()

cmake/module/FindMiniUPnPc.cmake

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright (c) 2023 The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
if(NOT MSVC)
6+
include(CrossPkgConfig)
7+
cross_pkg_check_modules(PC_MiniUPnPc QUIET miniupnpc)
8+
endif()
9+
10+
find_path(MiniUPnPc_INCLUDE_DIR
11+
NAMES miniupnpc/miniupnpc.h
12+
PATHS ${PC_MiniUPnPc_INCLUDE_DIRS}
13+
)
14+
15+
if(MiniUPnPc_INCLUDE_DIR)
16+
file(
17+
STRINGS "${MiniUPnPc_INCLUDE_DIR}/miniupnpc/miniupnpc.h" version_strings
18+
REGEX "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+[0-9]+"
19+
)
20+
string(REGEX REPLACE "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+([0-9]+)" "\\1" MiniUPnPc_API_VERSION "${version_strings}")
21+
22+
# The minimum supported miniUPnPc API version is set to 17. This excludes
23+
# versions with known vulnerabilities.
24+
if(MiniUPnPc_API_VERSION GREATER_EQUAL 17)
25+
set(MiniUPnPc_API_VERSION_OK TRUE)
26+
endif()
27+
endif()
28+
29+
if(MSVC)
30+
cmake_path(GET MiniUPnPc_INCLUDE_DIR PARENT_PATH MiniUPnPc_IMPORTED_PATH)
31+
find_library(MiniUPnPc_LIBRARY_DEBUG
32+
NAMES miniupnpc PATHS ${MiniUPnPc_IMPORTED_PATH}/debug/lib
33+
NO_DEFAULT_PATH
34+
)
35+
find_library(MiniUPnPc_LIBRARY_RELEASE
36+
NAMES miniupnpc PATHS ${MiniUPnPc_IMPORTED_PATH}/lib
37+
NO_DEFAULT_PATH
38+
)
39+
set(MiniUPnPc_required MiniUPnPc_IMPORTED_PATH)
40+
else()
41+
find_library(MiniUPnPc_LIBRARY
42+
NAMES miniupnpc
43+
PATHS ${PC_MiniUPnPc_LIBRARY_DIRS}
44+
)
45+
set(MiniUPnPc_required MiniUPnPc_LIBRARY)
46+
endif()
47+
48+
include(FindPackageHandleStandardArgs)
49+
find_package_handle_standard_args(MiniUPnPc
50+
REQUIRED_VARS ${MiniUPnPc_required} MiniUPnPc_INCLUDE_DIR MiniUPnPc_API_VERSION_OK
51+
)
52+
53+
if(MiniUPnPc_FOUND AND NOT TARGET MiniUPnPc::MiniUPnPc)
54+
add_library(MiniUPnPc::MiniUPnPc UNKNOWN IMPORTED)
55+
set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES
56+
INTERFACE_INCLUDE_DIRECTORIES "${MiniUPnPc_INCLUDE_DIR}"
57+
)
58+
if(MSVC)
59+
if(MiniUPnPc_LIBRARY_DEBUG)
60+
set_property(TARGET MiniUPnPc::MiniUPnPc APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
61+
set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES
62+
IMPORTED_LOCATION_DEBUG "${MiniUPnPc_LIBRARY_DEBUG}"
63+
)
64+
endif()
65+
if(MiniUPnPc_LIBRARY_RELEASE)
66+
set_property(TARGET MiniUPnPc::MiniUPnPc APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
67+
set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES
68+
IMPORTED_LOCATION_RELEASE "${MiniUPnPc_LIBRARY_RELEASE}"
69+
)
70+
endif()
71+
else()
72+
set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES
73+
IMPORTED_LOCATION "${MiniUPnPc_LIBRARY}"
74+
)
75+
endif()
76+
set_property(TARGET MiniUPnPc::MiniUPnPc PROPERTY
77+
INTERFACE_COMPILE_DEFINITIONS USE_UPNP=1 $<$<PLATFORM_ID:Windows>:MINIUPNP_STATICLIB>
78+
)
79+
endif()
80+
81+
mark_as_advanced(
82+
MiniUPnPc_INCLUDE_DIR
83+
MiniUPnPc_LIBRARY
84+
)

cmake/module/FindNATPMP.cmake

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Copyright (c) 2023 The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
find_path(NATPMP_INCLUDE_DIR
6+
NAMES natpmp.h
7+
)
8+
9+
find_library(NATPMP_LIBRARY
10+
NAMES natpmp
11+
)
12+
13+
include(FindPackageHandleStandardArgs)
14+
find_package_handle_standard_args(NATPMP
15+
REQUIRED_VARS NATPMP_LIBRARY NATPMP_INCLUDE_DIR
16+
)
17+
18+
if(NATPMP_FOUND AND NOT TARGET NATPMP::NATPMP)
19+
add_library(NATPMP::NATPMP UNKNOWN IMPORTED)
20+
set_target_properties(NATPMP::NATPMP PROPERTIES
21+
IMPORTED_LOCATION "${NATPMP_LIBRARY}"
22+
INTERFACE_INCLUDE_DIRECTORIES "${NATPMP_INCLUDE_DIR}"
23+
)
24+
set_property(TARGET NATPMP::NATPMP PROPERTY
25+
INTERFACE_COMPILE_DEFINITIONS USE_NATPMP=1 $<$<PLATFORM_ID:Windows>:NATPMP_STATICLIB>
26+
)
27+
endif()
28+
29+
mark_as_advanced(
30+
NATPMP_INCLUDE_DIR
31+
NATPMP_LIBRARY
32+
)

cmake/module/TristateOption.cmake

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright (c) 2023 The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
# A tri-state option with three possible values: AUTO, OFF and ON (case-insensitive).
6+
# TODO: This function will be removed before merging into master.
7+
function(tristate_option variable description_text auto_means_on_condition_text default_value)
8+
set(${variable} ${default_value} CACHE STRING
9+
"${description_text} \"AUTO\" means \"ON\" ${auto_means_on_condition_text}"
10+
)
11+
12+
set(expected_values AUTO OFF ON)
13+
set_property(CACHE ${variable} PROPERTY STRINGS ${expected_values})
14+
15+
string(TOUPPER "${${variable}}" value)
16+
if(NOT value IN_LIST expected_values)
17+
message(FATAL_ERROR "${variable} value is \"${${variable}}\", but must be one of \"AUTO\", \"OFF\" or \"ON\".")
18+
endif()
19+
20+
set(${${variable}} ${value} PARENT_SCOPE)
21+
endfunction()

cmake/optional.cmake

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Copyright (c) 2023 The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
# Optional features and packages.
6+
7+
if(CCACHE)
8+
find_program(CCACHE_EXECUTABLE ccache)
9+
if(CCACHE_EXECUTABLE)
10+
set(CCACHE ON)
11+
if(MSVC)
12+
# See https://github.com/ccache/ccache/wiki/MS-Visual-Studio
13+
set(MSVC_CCACHE_WRAPPER_CONTENT "\"${CCACHE_EXECUTABLE}\" \"${CMAKE_CXX_COMPILER}\"")
14+
set(MSVC_CCACHE_WRAPPER_FILENAME wrapped-cl.bat)
15+
file(WRITE ${CMAKE_BINARY_DIR}/${MSVC_CCACHE_WRAPPER_FILENAME} "${MSVC_CCACHE_WRAPPER_CONTENT} %*")
16+
set(CMAKE_VS_GLOBALS
17+
"CLToolExe=${MSVC_CCACHE_WRAPPER_FILENAME}"
18+
"CLToolPath=${CMAKE_BINARY_DIR}"
19+
"TrackFileAccess=false"
20+
"UseMultiToolTask=true"
21+
"DebugInformationFormat=OldStyle"
22+
)
23+
else()
24+
list(APPEND CMAKE_C_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE})
25+
list(APPEND CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE})
26+
endif()
27+
elseif(CCACHE STREQUAL "AUTO")
28+
set(CCACHE OFF)
29+
else()
30+
message(FATAL_ERROR "ccache requested, but not found.")
31+
endif()
32+
mark_as_advanced(CCACHE_EXECUTABLE)
33+
endif()
34+
35+
if(WITH_NATPMP)
36+
find_package(NATPMP MODULE)
37+
if(NATPMP_FOUND)
38+
set(WITH_NATPMP ON)
39+
elseif(WITH_NATPMP STREQUAL "AUTO")
40+
message(WARNING "libnatpmp not found, disabling.\n"
41+
"To skip libnatpmp check, use \"-DWITH_NATPMP=OFF\".\n")
42+
set(WITH_NATPMP OFF)
43+
else()
44+
message(FATAL_ERROR "libnatpmp requested, but not found.")
45+
endif()
46+
endif()
47+
48+
if(WITH_MINIUPNPC)
49+
find_package(MiniUPnPc MODULE)
50+
if(MiniUPnPc_FOUND)
51+
set(WITH_MINIUPNPC ON)
52+
elseif(WITH_MINIUPNPC STREQUAL "AUTO")
53+
message(WARNING "libminiupnpc not found, disabling.\n"
54+
"To skip libminiupnpc check, use \"-DWITH_MINIUPNPC=OFF\".\n")
55+
set(WITH_MINIUPNPC OFF)
56+
else()
57+
message(FATAL_ERROR "libminiupnpc requested, but not found.")
58+
endif()
59+
endif()
60+
61+
if(WITH_ZMQ)
62+
if(MSVC)
63+
find_package(ZeroMQ CONFIG)
64+
else()
65+
# The ZeroMQ project has provided config files since v4.2.2.
66+
# TODO: Switch to find_package(ZeroMQ) at some point in the future.
67+
include(CrossPkgConfig)
68+
cross_pkg_check_modules(libzmq IMPORTED_TARGET libzmq>=4)
69+
if(libzmq_FOUND)
70+
set_property(TARGET PkgConfig::libzmq APPEND PROPERTY
71+
INTERFACE_COMPILE_DEFINITIONS $<$<PLATFORM_ID:Windows>:ZMQ_STATIC>
72+
)
73+
set_property(TARGET PkgConfig::libzmq APPEND PROPERTY
74+
INTERFACE_LINK_LIBRARIES $<$<PLATFORM_ID:Windows>:iphlpapi;ws2_32>
75+
)
76+
endif()
77+
endif()
78+
if(TARGET libzmq OR TARGET PkgConfig::libzmq)
79+
set(WITH_ZMQ ON)
80+
elseif(WITH_ZMQ STREQUAL "AUTO")
81+
message(WARNING "libzmq not found, disabling.\n"
82+
"To skip libzmq check, use \"-DWITH_ZMQ=OFF\".\n")
83+
set(WITH_ZMQ OFF)
84+
else()
85+
message(FATAL_ERROR "libzmq requested, but not found.")
86+
endif()
87+
endif()
88+
89+
include(CheckCXXSourceCompiles)
90+
if(WITH_USDT)
91+
check_cxx_source_compiles("
92+
#include <sys/sdt.h>
93+
94+
int main()
95+
{
96+
DTRACE_PROBE(\"context\", \"event\");
97+
}
98+
" HAVE_USDT_H
99+
)
100+
if(HAVE_USDT_H)
101+
set(ENABLE_TRACING TRUE)
102+
set(WITH_USDT ON)
103+
elseif(WITH_USDT STREQUAL "AUTO")
104+
set(WITH_USDT OFF)
105+
else()
106+
message(FATAL_ERROR "sys/sdt.h requested, but not found.")
107+
endif()
108+
endif()

src/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ add_library(bitcoin_consensus OBJECT EXCLUDE_FROM_ALL
2929
)
3030
target_link_libraries(bitcoin_consensus PRIVATE secp256k1)
3131

32+
if(WITH_ZMQ)
33+
add_subdirectory(zmq EXCLUDE_FROM_ALL)
34+
endif()
3235

3336
# Home for common functionality shared by different executables and libraries.
3437
# Similar to `bitcoin_util` library, but higher-level.
@@ -186,6 +189,9 @@ target_link_libraries(bitcoin_node
186189
Boost::headers
187190
libevent::libevent
188191
$<TARGET_NAME_IF_EXISTS:PkgConfig::libevent_pthreads>
192+
$<TARGET_NAME_IF_EXISTS:NATPMP::NATPMP>
193+
$<TARGET_NAME_IF_EXISTS:MiniUPnPc::MiniUPnPc>
194+
$<TARGET_NAME_IF_EXISTS:bitcoin_zmq>
189195
)
190196

191197

0 commit comments

Comments
 (0)