-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
build: Add CMake-based build system (5 of N) #13
Changes from all commits
480c8cb
15bcb8e
9412a2e
ba50cad
9587ed7
b195c9c
697c397
8ee7537
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
At this point I agree with that and I'd prefer to just never start with this tri-state stuff as it's quite not-cmake-like. But I realize I originally asked for 1:1 feature parity with autotools for the sake of review, so it's not really fair to ask for that change now. How about a comment above with a loud warning that says "These tri-state options will be removed and most features will become opt-in by default before merging into master" ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
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") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 $<$<PLATFORM_ID:Windows>:MINIUPNP_STATICLIB> | ||
) | ||
endif() | ||
|
||
mark_as_advanced( | ||
MiniUPnPc_INCLUDE_DIR | ||
MiniUPnPc_LIBRARY | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 $<$<PLATFORM_ID:Windows>:NATPMP_STATICLIB> | ||
) | ||
endif() | ||
|
||
mark_as_advanced( | ||
NATPMP_INCLUDE_DIR | ||
NATPMP_LIBRARY | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
) | ||
Comment on lines
+11
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apparently, this code does not work with cache 4.8 ( Going to investigate the issue, but I'm really hoping this won't be a blocker for this PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ccache 4.8 is broken, ccache 4.7.4, 4.7.5 work fine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What/how is it broken in 4.8? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Following https://github.com/ccache/ccache/wiki/MS-Visual-Studio literally for the simplest source code like "int main { return 0; }" works for 4.7, but 4.8 reports zero of "cacheable calls". For example, https://cirrus-ci.com/task/6670364843966464. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Has this been reported upstream? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
ccache/ccache#1262 is somewhat related. |
||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. zmq started shipping a cmake config file starting with v4.2.2. Once we bump our zmq requirement in the future, we'll be able to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
But not Ubuntu's libzmq3-dev packages, unfortunately. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still, mind adding a note that it's supported upstream and we'll be able to switch at some point in the future? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sure. I'll add it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
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 $<$<PLATFORM_ID:Windows>:ZMQ_STATIC> | ||
) | ||
set_property(TARGET PkgConfig::libzmq APPEND PROPERTY | ||
INTERFACE_LINK_LIBRARIES $<$<PLATFORM_ID:Windows>: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 <sys/sdt.h> | ||
|
||
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() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "opt-in by default" mean? That there will be just two options to choose from (not 3): ON and OFF, that it will be ON by default and (it follows that) if the corresponding library is not found, then it will result in an error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. It means that basically all features/options will be OFF by default, and builders will have to actively opt-in to what they want. If they opt-in to something, and do not have the required libs/prerequisites, the build will error.