From 75b9b6c7c23ecd100b868bf397f3e6f4eddb7e32 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 12 Mar 2023 13:34:08 +0000 Subject: [PATCH 1/6] [FIXUP] cmake: Drop C language from the global project Must be squashed with the commit 91f28a6a961f962e0408130cbc46d9aa8cc4b84b "cmake: Add root `CMakeLists.txt` file". --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 35ea1d0bdbb76..9424387a90c8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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") From 3bb3448b90e0664da9cf57a90a063ad5555e5ac2 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 12 Mar 2023 13:34:25 +0000 Subject: [PATCH 2/6] [FIXUP] cmake: Enable C language for libsecp256k1 Must be squashed with the commit eb3546f2235fe135328b2999053a9692d80cd6e0 "cmake: Build `secp256k1` static library". --- cmake/secp256k1.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/secp256k1.cmake b/cmake/secp256k1.cmake index d965493e79749..fd1d04198ec09 100644 --- a/cmake/secp256k1.cmake +++ b/cmake/secp256k1.cmake @@ -6,6 +6,7 @@ # support has been merged we should switch to using the upstream CMake # buildsystem. +enable_language(C) set(CMAKE_C_STANDARD 90) set(CMAKE_C_EXTENSIONS OFF) From d37c9a248432bb9ec56f2bd9025e0b895f46c737 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 24 Mar 2023 17:47:57 +0000 Subject: [PATCH 3/6] [FIXUP] cmake: Ensure C language is disabled for FindThreads Must be squashed with the commit d028a49c35abe55d6f53c2515cab30d30e726b08 "cmake: Build `bitcoin_util` static library". --- cmake/module/AddThreadsIfNeeded.cmake | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cmake/module/AddThreadsIfNeeded.cmake b/cmake/module/AddThreadsIfNeeded.cmake index d11e9e5205566..2939f1a0c6fcb 100644 --- a/cmake/module/AddThreadsIfNeeded.cmake +++ b/cmake/module/AddThreadsIfNeeded.cmake @@ -7,8 +7,17 @@ function(add_threads_if_needed) # require Threads. Therefore, a proper check will be # appropriate here. + if(CMAKE_C_COMPILER_LOADED) + 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) From e5e6bd3a4b1b65e207c342b6f9362086f9cfded7 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 24 Mar 2023 20:33:34 +0000 Subject: [PATCH 4/6] build: Generate `share/toolchain.cmake` in depends --- depends/Makefile | 32 ++++++++- depends/toolchain.cmake.in | 137 +++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 depends/toolchain.cmake.in diff --git a/depends/Makefile b/depends/Makefile index 27bf804c6b09b..3f1bcaa8bb669 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -190,6 +190,7 @@ $(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain) include funcs.mk final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in) +final_build_id_long+=$(shell $(build_SHA256SUM) toolchain.cmake.in) final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)) $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) rm -rf $(@D) @@ -257,6 +258,34 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ $< > $@ touch $@ +$(host_prefix)/share/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_$(final_build_id) + @mkdir -p $(@D) + sed -e 's|@host_system@|$($(host_os)_cmake_system)|' \ + -e 's|@host_arch@|$(host_arch)|' \ + -e 's|@CC@|$(host_CC)|' \ + -e 's|@CXX@|$(host_CXX)|' \ + -e 's|@AR@|$(host_AR)|' \ + -e 's|@RANLIB@|$(host_RANLIB)|' \ + -e 's|@STRIP@|$(host_STRIP)|' \ + -e 's|@OBJCOPY@|$(host_OBJCOPY)|' \ + -e 's|@INSTALL_NAME_TOOL@|$(host_INSTALL_NAME_TOOL)|' \ + -e 's|@OTOOL@|$(host_OTOOL)|' \ + -e 's|@depends_prefix@|$(host_prefix)|' \ + -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \ + -e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS) $(host_$(release_type)_CXXFLAGS))|' \ + -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \ + -e 's|@allow_host_packages@|$(ALLOW_HOST_PACKAGES)|' \ + -e 's|@no_qt@|$(NO_QT)|' \ + -e 's|@no_qr@|$(NO_QR)|' \ + -e 's|@no_zmq@|$(NO_ZMQ)|' \ + -e 's|@no_wallet@|$(NO_WALLET)|' \ + -e 's|@no_bdb@|$(NO_BDB)|' \ + -e 's|@no_sqlite@|$(NO_SQLITE)|' \ + -e 's|@no_upnp@|$(NO_UPNP)|' \ + -e 's|@no_natpmp@|$(NO_NATPMP)|' \ + -e 's|@no_usdt@|$(NO_USDT)|' \ + $< > $@ + touch $@ define check_or_remove_cached mkdir -p $(BASE_CACHE)/$(host)/$(package) && cd $(BASE_CACHE)/$(host)/$(package); \ @@ -278,6 +307,7 @@ check-sources: @$(foreach package,$(all_packages),$(call check_or_remove_sources,$(package));) $(host_prefix)/share/config.site: check-packages +$(host_prefix)/share/toolchain.cmake: check-packages check-packages: check-sources @@ -287,7 +317,7 @@ clean-all: clean clean: @rm -rf $(WORK_PATH) $(BASE_CACHE) $(BUILD) *.log -install: check-packages $(host_prefix)/share/config.site +install: check-packages $(host_prefix)/share/config.site $(host_prefix)/share/toolchain.cmake download-one: check-sources $(all_sources) diff --git a/depends/toolchain.cmake.in b/depends/toolchain.cmake.in new file mode 100644 index 0000000000000..59c98d745209d --- /dev/null +++ b/depends/toolchain.cmake.in @@ -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) + 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") + 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() From a8917aba8933772dba00fde33b0988fbca9f0174 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 12 Mar 2023 17:15:42 +0000 Subject: [PATCH 5/6] cmake: Add cross-compiling support To configure CMake for cross-compiling, use `--toolchain depends/${HOST}/share/toolchain.cmake` command-line option. --- CMakeLists.txt | 10 ++++++++++ cmake/module/AddLibeventIfNeeded.cmake | 6 +++--- cmake/module/CrossPkgConfig.cmake | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 cmake/module/CrossPkgConfig.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 9424387a90c8d..110619e53efff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,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() @@ -127,6 +131,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}") diff --git a/cmake/module/AddLibeventIfNeeded.cmake b/cmake/module/AddLibeventIfNeeded.cmake index 186095700b83a..d6e6ff1397ab7 100644 --- a/cmake/module/AddLibeventIfNeeded.cmake +++ b/cmake/module/AddLibeventIfNeeded.cmake @@ -37,8 +37,8 @@ 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) check_evhttp_connection_get_peer(PkgConfig::libevent) target_link_libraries(PkgConfig::libevent INTERFACE $<$:iphlpapi;ws2_32> @@ -46,6 +46,6 @@ function(add_libevent_if_needed) 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() diff --git a/cmake/module/CrossPkgConfig.cmake b/cmake/module/CrossPkgConfig.cmake new file mode 100644 index 0000000000000..4d845a60fe3e3 --- /dev/null +++ b/cmake/module/CrossPkgConfig.cmake @@ -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}") + 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() From b0351e34b79c0b361623f9bb923dcfd4129344f5 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Mon, 13 Mar 2023 17:24:26 +0000 Subject: [PATCH 6/6] [FIXUP] cmake: Rework PIC/PIE logic Must be squashed with the commit 91f28a6a961f962e0408130cbc46d9aa8cc4b84b "cmake: Add root `CMakeLists.txt` file". --- CMakeLists.txt | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 110619e53efff..c9d4fc6dec212 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) #[=[ @@ -123,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) + if(COMPILER_SUPPORTS_PIE) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + endif() +endif() + add_subdirectory(src) message("\n")