-
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 (4 of N) #10
Changes from all commits
75b9b6c
3bb3448
d37c9a2
e5e6bd3
a8917ab
b0351e3
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 |
---|---|---|
|
@@ -24,7 +24,7 @@ project("Bitcoin Core" | |
VERSION 24.99.0 | ||
DESCRIPTION "Bitcoin client software" | ||
HOMEPAGE_URL "https://bitcoincore.org/" | ||
LANGUAGES CXX C ASM | ||
LANGUAGES CXX ASM | ||
) | ||
|
||
set(CLIENT_VERSION_IS_RELEASE "false") | ||
|
@@ -52,16 +52,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) | |
set(CMAKE_CXX_EXTENSIONS OFF) | ||
|
||
set(configure_warnings) | ||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14) | ||
include(CheckPIESupported) | ||
check_pie_supported(OUTPUT_VARIABLE check_pie_output LANGUAGES CXX) | ||
if(NOT CMAKE_CXX_LINK_PIE_SUPPORTED) | ||
list(APPEND configure_warnings "PIE link options are not supported for executable targets: ${check_pie_output}.") | ||
endif() | ||
else() | ||
list(APPEND configure_warnings "No PIE options will be passed to a linker for executable targets.") | ||
endif() | ||
set(CMAKE_POSITION_INDEPENDENT_CODE ON) | ||
|
||
if(WIN32) | ||
#[=[ | ||
|
@@ -98,6 +88,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") | |
add_compile_definitions(MAC_OSX) | ||
endif() | ||
|
||
if(CMAKE_CROSSCOMPILING AND DEPENDS_ALLOW_HOST_PACKAGES) | ||
list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_SYSTEM_PREFIX_PATH}") | ||
endif() | ||
|
||
include(AddThreadsIfNeeded) | ||
add_threads_if_needed() | ||
|
||
|
@@ -119,6 +113,19 @@ include(cmake/secp256k1.cmake) | |
include(CheckStdFilesystem) | ||
check_std_filesystem() | ||
|
||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14) | ||
include(CheckPIESupported) | ||
check_pie_supported(OUTPUT_VARIABLE check_pie_output LANGUAGES CXX) | ||
if(CMAKE_CXX_LINK_PIE_SUPPORTED) | ||
set(CMAKE_POSITION_INDEPENDENT_CODE ON) | ||
endif() | ||
else() | ||
check_cxx_source_links_with_flags(-fPIE "int main(){}" COMPILER_SUPPORTS_PIE) | ||
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. This is missing a few things compared to the autotools check:
|
||
if(COMPILER_SUPPORTS_PIE) | ||
set(CMAKE_POSITION_INDEPENDENT_CODE ON) | ||
endif() | ||
endif() | ||
|
||
add_subdirectory(src) | ||
|
||
message("\n") | ||
|
@@ -127,6 +134,12 @@ message("=================") | |
message("Executables:") | ||
message(" bitcoind ............................ ${BUILD_DAEMON}") | ||
message("") | ||
if(CMAKE_CROSSCOMPILING) | ||
set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") | ||
else() | ||
set(cross_status "FALSE") | ||
endif() | ||
message("Cross compiling ....................... ${cross_status}") | ||
get_directory_property(definitions COMPILE_DEFINITIONS) | ||
string(REPLACE ";" " " definitions "${definitions}") | ||
message("Preprocessor defined macros ........... ${definitions}") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,15 +37,15 @@ function(add_libevent_if_needed) | |
return() | ||
endif() | ||
|
||
find_package(PkgConfig) | ||
pkg_check_modules(libevent REQUIRED libevent>=${libevent_minimum_version} IMPORTED_TARGET GLOBAL) | ||
include(CrossPkgConfig) | ||
cross_pkg_check_modules(libevent REQUIRED libevent>=${libevent_minimum_version} IMPORTED_TARGET GLOBAL) | ||
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. Unrelated to the changes here, but I found this little diamond in the CMake docs:
I mentioned that we should do this here: #7 (comment) Maybe slot in a switch to 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. Sorry, ignore this for now as it's more complicated than just switching to |
||
check_evhttp_connection_get_peer(PkgConfig::libevent) | ||
target_link_libraries(PkgConfig::libevent INTERFACE | ||
$<$<BOOL:${MINGW}>:iphlpapi;ws2_32> | ||
) | ||
add_library(libevent::libevent ALIAS PkgConfig::libevent) | ||
|
||
if(NOT WIN32) | ||
pkg_check_modules(libevent_pthreads REQUIRED libevent_pthreads>=${libevent_minimum_version} IMPORTED_TARGET) | ||
cross_pkg_check_modules(libevent_pthreads REQUIRED libevent_pthreads>=${libevent_minimum_version} IMPORTED_TARGET) | ||
endif() | ||
endfunction() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,8 +7,17 @@ function(add_threads_if_needed) | |
# require Threads. Therefore, a proper check will be | ||
# appropriate here. | ||
|
||
if(CMAKE_C_COMPILER_LOADED) | ||
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. Even with the explanation, I still don't understand what's going on here. What's the overlap between c/c++/mingw/threads? Is this an assertion to make sure we're never testing with a C compiler, or do we actually hit this? 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.
Yes, it is. We are testing C++ compiler only.
Otherwise errors mentioned by @TheCharlatan happen. |
||
message(FATAL_ERROR [=[ | ||
To make FindThreads check C++ language features, C language must be | ||
disabled. This is essential, at least, when cross-compiling for MinGW-w64 | ||
because two different threading models are available. | ||
]=] ) | ||
endif() | ||
|
||
set(THREADS_PREFER_PTHREAD_FLAG ON) | ||
find_package(Threads REQUIRED) | ||
set_target_properties(Threads::Threads PROPERTIES IMPORTED_GLOBAL TRUE) | ||
|
||
set(thread_local) | ||
if(MINGW) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# 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_package(PkgConfig REQUIRED) | ||
|
||
macro(cross_pkg_check_modules) | ||
if(CMAKE_CROSSCOMPILING) | ||
set(pkg_config_path_saved "$ENV{PKG_CONFIG_PATH}") | ||
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. This seems to imply that these hacks shouldn't be needed if 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. Indeed, this part was a bit problematic when I worked on it back in the day. I remember I did try the approach you mentioned. But cannot point the exact issue I faced. One of the point of the current implementation is it supports the |
||
set(pkg_config_libdir_saved "$ENV{PKG_CONFIG_LIBDIR}") | ||
set(ENV{PKG_CONFIG_PATH} ${PKG_CONFIG_PATH}) | ||
set(ENV{PKG_CONFIG_LIBDIR} ${PKG_CONFIG_LIBDIR}) | ||
pkg_check_modules(${ARGV}) | ||
set(ENV{PKG_CONFIG_PATH} ${pkg_config_path_saved}) | ||
set(ENV{PKG_CONFIG_LIBDIR} ${pkg_config_libdir_saved}) | ||
else() | ||
pkg_check_modules(${ARGV}) | ||
endif() | ||
endmacro() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
# This file is expected to be highly volatile and may still change substantially. | ||
|
||
set(CMAKE_SYSTEM_NAME @host_system@) | ||
set(CMAKE_SYSTEM_PROCESSOR @host_arch@) | ||
|
||
function(split_compiler_launcher env_compiler launcher compiler) | ||
set(${launcher}) | ||
list(GET ${env_compiler} 0 start_token) | ||
if(start_token STREQUAL "env") | ||
set(${compiler}) | ||
set(env_arg_parsing TRUE) | ||
foreach(token IN LISTS ${env_compiler}) | ||
if(env_arg_parsing) | ||
list(APPEND ${launcher} ${token}) | ||
set(env_arg_parsing FALSE) | ||
continue() | ||
elseif(token STREQUAL "-u") | ||
list(APPEND ${launcher} ${token}) | ||
set(env_arg_parsing TRUE) | ||
continue() | ||
endif() | ||
list(APPEND ${compiler} ${token}) | ||
endforeach() | ||
else() | ||
set(${compiler} ${${env_compiler}}) | ||
endif() | ||
set(${launcher} ${${launcher}} PARENT_SCOPE) | ||
set(${compiler} ${${compiler}} PARENT_SCOPE) | ||
endfunction() | ||
|
||
if(NOT CMAKE_C_COMPILER) | ||
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. Could you give a hint as to what's going on here? I'm a little lost :) 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. The goal is to handle every "compiler invocation command", which we have in our build and test environment, properly. Including such cases as follows:
The main part is done in the Rest of code makes it compatible with the supported range of CMake versions. 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. Won't this prohibit the use of 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.
The future use of |
||
set(DEPENDS_C_COMPILER_WITH_LAUNCHER @CC@) | ||
split_compiler_launcher(DEPENDS_C_COMPILER_WITH_LAUNCHER CMAKE_C_COMPILER_LAUNCHER CMAKE_C_COMPILER) | ||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) | ||
set(CMAKE_C_LINKER_LAUNCHER ${CMAKE_C_COMPILER_LAUNCHER}) | ||
endif() | ||
if(CMAKE_VERSION VERSION_LESS 3.19) | ||
set(DEPENDS_C_COMPILER_FLAGS ${CMAKE_C_COMPILER}) | ||
list(REMOVE_AT DEPENDS_C_COMPILER_FLAGS 0) | ||
string(REPLACE ";" " " DEPENDS_C_COMPILER_FLAGS "${DEPENDS_C_COMPILER_FLAGS}") | ||
list(GET CMAKE_C_COMPILER 0 CMAKE_C_COMPILER) | ||
endif() | ||
endif() | ||
set(CMAKE_C_FLAGS_INIT "${DEPENDS_C_COMPILER_FLAGS} @CPPFLAGS@ @CFLAGS@") | ||
|
||
if(NOT CMAKE_CXX_COMPILER) | ||
set(DEPENDS_CXX_COMPILER_WITH_LAUNCHER @CXX@) | ||
split_compiler_launcher(DEPENDS_CXX_COMPILER_WITH_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER CMAKE_CXX_COMPILER) | ||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) | ||
set(CMAKE_CXX_LINKER_LAUNCHER ${CMAKE_CXX_COMPILER_LAUNCHER}) | ||
endif() | ||
if(CMAKE_VERSION VERSION_LESS 3.19) | ||
set(DEPENDS_CXX_COMPILER_FLAGS ${CMAKE_CXX_COMPILER}) | ||
list(REMOVE_AT DEPENDS_CXX_COMPILER_FLAGS 0) | ||
string(REPLACE ";" " " DEPENDS_CXX_COMPILER_FLAGS "${DEPENDS_CXX_COMPILER_FLAGS}") | ||
list(GET CMAKE_CXX_COMPILER 0 CMAKE_CXX_COMPILER) | ||
endif() | ||
endif() | ||
set(CMAKE_CXX_FLAGS_INIT "${DEPENDS_CXX_COMPILER_FLAGS} @CPPFLAGS@ @CXXFLAGS@") | ||
|
||
if(NOT CMAKE_OBJCXX_COMPILER) | ||
set(DEPENDS_OBJCXX_COMPILER_WITH_LAUNCHER @CXX@) | ||
split_compiler_launcher(DEPENDS_OBJCXX_COMPILER_WITH_LAUNCHER CMAKE_OBJCXX_COMPILER_LAUNCHER CMAKE_OBJCXX_COMPILER) | ||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) | ||
set(CMAKE_OBJCXX_LINKER_LAUNCHER ${CMAKE_OBJCXX_COMPILER_LAUNCHER}) | ||
endif() | ||
if(CMAKE_VERSION VERSION_LESS 3.19) | ||
set(DEPENDS_OBJCXX_COMPILER_FLAGS ${CMAKE_OBJCXX_COMPILER}) | ||
list(REMOVE_AT DEPENDS_OBJCXX_COMPILER_FLAGS 0) | ||
string(REPLACE ";" " " DEPENDS_OBJCXX_COMPILER_FLAGS "${DEPENDS_OBJCXX_COMPILER_FLAGS}") | ||
list(GET CMAKE_OBJCXX_COMPILER 0 CMAKE_OBJCXX_COMPILER) | ||
endif() | ||
endif() | ||
set(CMAKE_OBJCXX_FLAGS_INIT "${DEPENDS_OBJCXX_COMPILER_FLAGS} @CPPFLAGS@ @CXXFLAGS@") | ||
|
||
set(CMAKE_AR "@AR@") | ||
set(CMAKE_RANLIB "@RANLIB@") | ||
set(CMAKE_STRIP "@STRIP@") | ||
set(CMAKE_OBJCOPY "@OBJCOPY@") | ||
set(CMAKE_INSTALL_NAME_TOOL "@INSTALL_NAME_TOOL@") | ||
set(OTOOL "@OTOOL@") | ||
|
||
set(CMAKE_FIND_ROOT_PATH "@depends_prefix@") | ||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) | ||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) | ||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) | ||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) | ||
set(PKG_CONFIG_PATH "@depends_prefix@/lib/pkgconfig") | ||
if("@allow_host_packages@" STREQUAL "1") | ||
set(DEPENDS_ALLOW_HOST_PACKAGES TRUE) | ||
else() | ||
set(DEPENDS_ALLOW_HOST_PACKAGES FALSE) | ||
set(PKG_CONFIG_LIBDIR "${PKG_CONFIG_PATH}") | ||
endif() | ||
set(QT_TRANSLATIONS_DIR "@depends_prefix@/translations") | ||
|
||
if(NOT WITH_GUI AND "@no_qt@" STREQUAL "1") | ||
set(WITH_GUI "no" CACHE STRING "") | ||
endif() | ||
|
||
if(NOT WITH_QRENCODE AND "@no_qr@" STREQUAL "1") | ||
set(WITH_QRENCODE OFF CACHE STRING "") | ||
endif() | ||
|
||
if(NOT WITH_ZMQ AND "@no_zmq@" STREQUAL "1") | ||
set(WITH_ZMQ OFF CACHE STRING "") | ||
endif() | ||
|
||
if(NOT ENABLE_WALLET AND "@no_wallet@" STREQUAL "1") | ||
set(ENABLE_WALLET OFF CACHE BOOL "") | ||
endif() | ||
|
||
if(NOT WITH_BDB AND "@no_bdb@" STREQUAL "1") | ||
set(WITH_BDB OFF CACHE STRING "") | ||
endif() | ||
|
||
if(NOT WITH_SQLITE AND "@no_sqlite@" STREQUAL "1") | ||
set(WITH_SQLITE OFF CACHE STRING "") | ||
endif() | ||
|
||
if(NOT WITH_MINIUPNPC AND "@no_upnp@" STREQUAL "1") | ||
set(WITH_MINIUPNPC OFF CACHE STRING "") | ||
endif() | ||
|
||
if(NOT WITH_NATPMP AND "@no_natpmp@" STREQUAL "1") | ||
set(WITH_NATPMP OFF CACHE STRING "") | ||
endif() | ||
|
||
if(NOT WITH_USDT AND "@no_usdt@" STREQUAL "1") | ||
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. Where is the line currently drawn between configuration already supported and configuration to be added later? We support usdt here, but don't support multiprocess, LTO, or some of the qt features. 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.
Well, it is vague, indeed.
See: bitcoin@1238ed5
Not implemented in the parent bitcoin#25797 yet. Sorry about that.
It is more complicated. For example, see bitcoin@50ac8b0. 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. Thanks for the references, I'll be sure to come back to them later. |
||
set(WITH_USDT OFF CACHE STRING "") | ||
endif() | ||
|
||
if(DEFINED ENV{PYTHONPATH}) | ||
set(PYTHONPATH "@depends_prefix@/native/lib/python3/dist-packages:$ENV{PYTHONPATH}") | ||
else() | ||
set(PYTHONPATH "@depends_prefix@/native/lib/python3/dist-packages") | ||
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.
Can't this be done in the toolchain file by conditionally setting the
CMAKE_FIND_ROOT_PATH_*
vars?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.
That was my initial idea as well :)
It turns out that a toolchain file is being processed more than once (the actual number of runs depends on CMake version). Therefore, its processing must be idempotent.
list(APPEND ...)
command is not idempotent. That is why it has been moved out of the toolchain file.