diff --git a/CMakeLists.txt b/CMakeLists.txt index c9d4fc6dec212..ed3178b269773 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,19 @@ option(ASM "Use assembly routines." ON) cmake_dependent_option(CXX20 "Enable compilation in C++20 mode." OFF "NOT MSVC" ON) option(THREADLOCAL "Enable features that depend on the C++ thread_local keyword (currently just thread names in debug logs)." ON) +# TODO: These tri-state options will be removed and most features +# will become opt-in by default before merging into master. +include(TristateOption) +tristate_option(CCACHE "Use ccache for compiling." "if ccache is found." AUTO) +tristate_option(WITH_NATPMP "Enable NAT-PMP." "if libnatpmp is found." AUTO) +tristate_option(WITH_MINIUPNPC "Enable UPnP." "if libminiupnpc is found." AUTO) +tristate_option(WITH_ZMQ "Enable ZMQ notifications." "if libzmq is found." AUTO) +tristate_option(WITH_USDT + "Enable tracepoints for Userspace, Statically Defined Tracing." + "if sys/sdt.h is found." + AUTO +) + if(CXX20) set(CMAKE_CXX_STANDARD 20) else() @@ -113,6 +126,8 @@ include(cmake/secp256k1.cmake) include(CheckStdFilesystem) check_std_filesystem() +include(cmake/optional.cmake) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14) include(CheckPIESupported) check_pie_supported(OUTPUT_VARIABLE check_pie_output LANGUAGES CXX) @@ -133,6 +148,11 @@ message("Configure summary") message("=================") message("Executables:") message(" bitcoind ............................ ${BUILD_DAEMON}") +message("Optional packages:") +message(" NAT-PMP ............................. ${WITH_NATPMP}") +message(" UPnP ................................ ${WITH_MINIUPNPC}") +message(" ZeroMQ .............................. ${WITH_ZMQ}") +message(" USDT tracing ........................ ${WITH_USDT}") message("") if(CMAKE_CROSSCOMPILING) set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") @@ -175,6 +195,7 @@ else() message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") endif() message("Use assembly routines ................. ${ASM}") +message("Use ccache for compiling .............. ${CCACHE}") message("\n") if(configure_warnings) message(" ******\n") diff --git a/cmake/bitcoin-config.h.in b/cmake/bitcoin-config.h.in index 7a3cf24f440a5..ed70bb5e8f8c8 100644 --- a/cmake/bitcoin-config.h.in +++ b/cmake/bitcoin-config.h.in @@ -33,6 +33,10 @@ /* Copyright year */ #define COPYRIGHT_YEAR @COPYRIGHT_YEAR@ +/* Define to 1 to enable tracepoints for Userspace, Statically Defined Tracing + */ +#cmakedefine ENABLE_TRACING 1 + /* Define this symbol if you have __builtin_clzl */ #cmakedefine HAVE_BUILTIN_CLZL 1 diff --git a/cmake/module/AddBoostIfNeeded.cmake b/cmake/module/AddBoostIfNeeded.cmake index d55f90a017364..a31ed10a9f58b 100644 --- a/cmake/module/AddBoostIfNeeded.cmake +++ b/cmake/module/AddBoostIfNeeded.cmake @@ -17,15 +17,6 @@ function(add_boost_if_needed) directory and other added INTERFACE properties. ]=] - if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND BREW_COMMAND) - execute_process( - COMMAND ${BREW_COMMAND} --prefix boost - OUTPUT_VARIABLE BOOST_ROOT - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - endif() - set(Boost_NO_BOOST_CMAKE ON) find_package(Boost 1.64.0 REQUIRED) set_target_properties(Boost::boost PROPERTIES IMPORTED_GLOBAL TRUE) diff --git a/cmake/module/AddLibeventIfNeeded.cmake b/cmake/module/AddLibeventIfNeeded.cmake index ddd159fb3b4f5..302d068fe916c 100644 --- a/cmake/module/AddLibeventIfNeeded.cmake +++ b/cmake/module/AddLibeventIfNeeded.cmake @@ -2,9 +2,11 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +# Check whether evhttp_connection_get_peer expects const char**. +# See https://github.com/libevent/libevent/commit/a18301a2bb160ff7c3ffaf5b7653c39ffe27b385 macro(check_evhttp_connection_get_peer target) - # Check whether evhttp_connection_get_peer expects const char**. - # Fail if neither are available. + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_LIBRARIES ${target}) check_cxx_source_compiles(" #include #include @@ -18,6 +20,7 @@ macro(check_evhttp_connection_get_peer target) } " HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR ) + cmake_pop_check_state() target_compile_definitions(${target} INTERFACE $<$:HAVE_EVHTTP_CONNECTION_GET_PEER_CONST_CHAR=1> ) @@ -38,7 +41,10 @@ function(add_libevent_if_needed) endif() include(CrossPkgConfig) - cross_pkg_check_modules(libevent REQUIRED libevent>=${libevent_minimum_version} IMPORTED_TARGET GLOBAL) + cross_pkg_check_modules(libevent + REQUIRED IMPORTED_TARGET GLOBAL + libevent>=${libevent_minimum_version} + ) check_evhttp_connection_get_peer(PkgConfig::libevent) target_link_libraries(PkgConfig::libevent INTERFACE $<$:iphlpapi;ssp;ws2_32> @@ -46,6 +52,9 @@ function(add_libevent_if_needed) add_library(libevent::libevent ALIAS PkgConfig::libevent) if(NOT WIN32) - cross_pkg_check_modules(libevent_pthreads REQUIRED libevent_pthreads>=${libevent_minimum_version} IMPORTED_TARGET) + cross_pkg_check_modules(libevent_pthreads + REQUIRED IMPORTED_TARGET GLOBAL + libevent_pthreads>=${libevent_minimum_version} + ) endif() endfunction() diff --git a/cmake/module/FindMiniUPnPc.cmake b/cmake/module/FindMiniUPnPc.cmake new file mode 100644 index 0000000000000..dd3a223104b1c --- /dev/null +++ b/cmake/module/FindMiniUPnPc.cmake @@ -0,0 +1,84 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +if(NOT MSVC) + include(CrossPkgConfig) + cross_pkg_check_modules(PC_MiniUPnPc QUIET miniupnpc) +endif() + +find_path(MiniUPnPc_INCLUDE_DIR + NAMES miniupnpc/miniupnpc.h + PATHS ${PC_MiniUPnPc_INCLUDE_DIRS} +) + +if(MiniUPnPc_INCLUDE_DIR) + file( + STRINGS "${MiniUPnPc_INCLUDE_DIR}/miniupnpc/miniupnpc.h" version_strings + REGEX "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+[0-9]+" + ) + string(REGEX REPLACE "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+([0-9]+)" "\\1" MiniUPnPc_API_VERSION "${version_strings}") + + # The minimum supported miniUPnPc API version is set to 17. This excludes + # versions with known vulnerabilities. + if(MiniUPnPc_API_VERSION GREATER_EQUAL 17) + set(MiniUPnPc_API_VERSION_OK TRUE) + endif() +endif() + +if(MSVC) + cmake_path(GET MiniUPnPc_INCLUDE_DIR PARENT_PATH MiniUPnPc_IMPORTED_PATH) + find_library(MiniUPnPc_LIBRARY_DEBUG + NAMES miniupnpc PATHS ${MiniUPnPc_IMPORTED_PATH}/debug/lib + NO_DEFAULT_PATH + ) + find_library(MiniUPnPc_LIBRARY_RELEASE + NAMES miniupnpc PATHS ${MiniUPnPc_IMPORTED_PATH}/lib + NO_DEFAULT_PATH + ) + set(MiniUPnPc_required MiniUPnPc_IMPORTED_PATH) +else() + find_library(MiniUPnPc_LIBRARY + NAMES miniupnpc + PATHS ${PC_MiniUPnPc_LIBRARY_DIRS} + ) + set(MiniUPnPc_required MiniUPnPc_LIBRARY) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(MiniUPnPc + REQUIRED_VARS ${MiniUPnPc_required} MiniUPnPc_INCLUDE_DIR MiniUPnPc_API_VERSION_OK +) + +if(MiniUPnPc_FOUND AND NOT TARGET MiniUPnPc::MiniUPnPc) + add_library(MiniUPnPc::MiniUPnPc UNKNOWN IMPORTED) + set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${MiniUPnPc_INCLUDE_DIR}" + ) + if(MSVC) + if(MiniUPnPc_LIBRARY_DEBUG) + set_property(TARGET MiniUPnPc::MiniUPnPc APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES + IMPORTED_LOCATION_DEBUG "${MiniUPnPc_LIBRARY_DEBUG}" + ) + endif() + if(MiniUPnPc_LIBRARY_RELEASE) + set_property(TARGET MiniUPnPc::MiniUPnPc APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES + IMPORTED_LOCATION_RELEASE "${MiniUPnPc_LIBRARY_RELEASE}" + ) + endif() + else() + set_target_properties(MiniUPnPc::MiniUPnPc PROPERTIES + IMPORTED_LOCATION "${MiniUPnPc_LIBRARY}" + ) + endif() + set_property(TARGET MiniUPnPc::MiniUPnPc PROPERTY + INTERFACE_COMPILE_DEFINITIONS USE_UPNP=1 $<$:MINIUPNP_STATICLIB> + ) +endif() + +mark_as_advanced( + MiniUPnPc_INCLUDE_DIR + MiniUPnPc_LIBRARY +) diff --git a/cmake/module/FindNATPMP.cmake b/cmake/module/FindNATPMP.cmake new file mode 100644 index 0000000000000..973fb9b0d06cd --- /dev/null +++ b/cmake/module/FindNATPMP.cmake @@ -0,0 +1,32 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +find_path(NATPMP_INCLUDE_DIR + NAMES natpmp.h +) + +find_library(NATPMP_LIBRARY + NAMES natpmp +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(NATPMP + REQUIRED_VARS NATPMP_LIBRARY NATPMP_INCLUDE_DIR +) + +if(NATPMP_FOUND AND NOT TARGET NATPMP::NATPMP) + add_library(NATPMP::NATPMP UNKNOWN IMPORTED) + set_target_properties(NATPMP::NATPMP PROPERTIES + IMPORTED_LOCATION "${NATPMP_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${NATPMP_INCLUDE_DIR}" + ) + set_property(TARGET NATPMP::NATPMP PROPERTY + INTERFACE_COMPILE_DEFINITIONS USE_NATPMP=1 $<$:NATPMP_STATICLIB> + ) +endif() + +mark_as_advanced( + NATPMP_INCLUDE_DIR + NATPMP_LIBRARY +) diff --git a/cmake/module/TristateOption.cmake b/cmake/module/TristateOption.cmake new file mode 100644 index 0000000000000..1bff5bd14aeb2 --- /dev/null +++ b/cmake/module/TristateOption.cmake @@ -0,0 +1,21 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# A tri-state option with three possible values: AUTO, OFF and ON (case-insensitive). +# TODO: This function will be removed before merging into master. +function(tristate_option variable description_text auto_means_on_condition_text default_value) + set(${variable} ${default_value} CACHE STRING + "${description_text} \"AUTO\" means \"ON\" ${auto_means_on_condition_text}" + ) + + set(expected_values AUTO OFF ON) + set_property(CACHE ${variable} PROPERTY STRINGS ${expected_values}) + + string(TOUPPER "${${variable}}" value) + if(NOT value IN_LIST expected_values) + message(FATAL_ERROR "${variable} value is \"${${variable}}\", but must be one of \"AUTO\", \"OFF\" or \"ON\".") + endif() + + set(${${variable}} ${value} PARENT_SCOPE) +endfunction() diff --git a/cmake/optional.cmake b/cmake/optional.cmake new file mode 100644 index 0000000000000..0cb454af3b57d --- /dev/null +++ b/cmake/optional.cmake @@ -0,0 +1,108 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# Optional features and packages. + +if(CCACHE) + find_program(CCACHE_EXECUTABLE ccache) + if(CCACHE_EXECUTABLE) + set(CCACHE ON) + if(MSVC) + # See https://github.com/ccache/ccache/wiki/MS-Visual-Studio + set(MSVC_CCACHE_WRAPPER_CONTENT "\"${CCACHE_EXECUTABLE}\" \"${CMAKE_CXX_COMPILER}\"") + set(MSVC_CCACHE_WRAPPER_FILENAME wrapped-cl.bat) + file(WRITE ${CMAKE_BINARY_DIR}/${MSVC_CCACHE_WRAPPER_FILENAME} "${MSVC_CCACHE_WRAPPER_CONTENT} %*") + set(CMAKE_VS_GLOBALS + "CLToolExe=${MSVC_CCACHE_WRAPPER_FILENAME}" + "CLToolPath=${CMAKE_BINARY_DIR}" + "TrackFileAccess=false" + "UseMultiToolTask=true" + "DebugInformationFormat=OldStyle" + ) + else() + list(APPEND CMAKE_C_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE}) + list(APPEND CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE}) + endif() + elseif(CCACHE STREQUAL "AUTO") + set(CCACHE OFF) + else() + message(FATAL_ERROR "ccache requested, but not found.") + endif() + mark_as_advanced(CCACHE_EXECUTABLE) +endif() + +if(WITH_NATPMP) + find_package(NATPMP MODULE) + if(NATPMP_FOUND) + set(WITH_NATPMP ON) + elseif(WITH_NATPMP STREQUAL "AUTO") + message(WARNING "libnatpmp not found, disabling.\n" + "To skip libnatpmp check, use \"-DWITH_NATPMP=OFF\".\n") + set(WITH_NATPMP OFF) + else() + message(FATAL_ERROR "libnatpmp requested, but not found.") + endif() +endif() + +if(WITH_MINIUPNPC) + find_package(MiniUPnPc MODULE) + if(MiniUPnPc_FOUND) + set(WITH_MINIUPNPC ON) + elseif(WITH_MINIUPNPC STREQUAL "AUTO") + message(WARNING "libminiupnpc not found, disabling.\n" + "To skip libminiupnpc check, use \"-DWITH_MINIUPNPC=OFF\".\n") + set(WITH_MINIUPNPC OFF) + else() + message(FATAL_ERROR "libminiupnpc requested, but not found.") + endif() +endif() + +if(WITH_ZMQ) + if(MSVC) + find_package(ZeroMQ CONFIG) + else() + # The ZeroMQ project has provided config files since v4.2.2. + # TODO: Switch to find_package(ZeroMQ) at some point in the future. + include(CrossPkgConfig) + cross_pkg_check_modules(libzmq IMPORTED_TARGET libzmq>=4) + if(libzmq_FOUND) + set_property(TARGET PkgConfig::libzmq APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS $<$:ZMQ_STATIC> + ) + set_property(TARGET PkgConfig::libzmq APPEND PROPERTY + INTERFACE_LINK_LIBRARIES $<$:iphlpapi;ws2_32> + ) + endif() + endif() + if(TARGET libzmq OR TARGET PkgConfig::libzmq) + set(WITH_ZMQ ON) + elseif(WITH_ZMQ STREQUAL "AUTO") + message(WARNING "libzmq not found, disabling.\n" + "To skip libzmq check, use \"-DWITH_ZMQ=OFF\".\n") + set(WITH_ZMQ OFF) + else() + message(FATAL_ERROR "libzmq requested, but not found.") + endif() +endif() + +include(CheckCXXSourceCompiles) +if(WITH_USDT) + check_cxx_source_compiles(" + #include + + int main() + { + DTRACE_PROBE(\"context\", \"event\"); + } + " HAVE_USDT_H + ) + if(HAVE_USDT_H) + set(ENABLE_TRACING TRUE) + set(WITH_USDT ON) + elseif(WITH_USDT STREQUAL "AUTO") + set(WITH_USDT OFF) + else() + message(FATAL_ERROR "sys/sdt.h requested, but not found.") + endif() +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bac6fddc742d3..b5afba7b6e59a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,6 +29,9 @@ add_library(bitcoin_consensus OBJECT EXCLUDE_FROM_ALL ) target_link_libraries(bitcoin_consensus PRIVATE secp256k1) +if(WITH_ZMQ) + add_subdirectory(zmq EXCLUDE_FROM_ALL) +endif() # Home for common functionality shared by different executables and libraries. # Similar to `bitcoin_util` library, but higher-level. @@ -186,6 +189,9 @@ target_link_libraries(bitcoin_node Boost::headers libevent::libevent $ + $ + $ + $ ) diff --git a/src/zmq/CMakeLists.txt b/src/zmq/CMakeLists.txt new file mode 100644 index 0000000000000..39cef32fceb42 --- /dev/null +++ b/src/zmq/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +add_library(bitcoin_zmq STATIC + zmqabstractnotifier.cpp + zmqnotificationinterface.cpp + zmqpublishnotifier.cpp + zmqrpc.cpp + zmqutil.cpp +) +target_compile_definitions(bitcoin_zmq + INTERFACE + ENABLE_ZMQ=1 +) +target_link_libraries(bitcoin_zmq + PRIVATE + leveldb + univalue + $ + $ +)