diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index b646a3e2a9d3..7a970cf911e5 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -148,7 +148,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ _BITCOIN_QT_CHECK_STATIC_PLUGIN([QWindowsIntegrationPlugin], [-lqwindows]) _BITCOIN_QT_CHECK_STATIC_PLUGIN([QWindowsVistaStylePlugin], [-lqwindowsvistastyle]) AC_DEFINE([QT_QPA_PLATFORM_WINDOWS], [1], [Define this symbol if the qt platform is windows]) - elif test "$TARGET_OS" = "linux"; then + elif test "$TARGET_OS" = "linux" -o "$TARGET_OS" = "freebsd"; then _BITCOIN_QT_CHECK_STATIC_PLUGIN([QXcbIntegrationPlugin], [-lqxcb]) AC_DEFINE([QT_QPA_PLATFORM_XCB], [1], [Define this symbol if the qt platform is xcb]) elif test "$TARGET_OS" = "darwin"; then diff --git a/configure.ac b/configure.ac index 38fac3bbfbea..68551386d587 100644 --- a/configure.ac +++ b/configure.ac @@ -237,12 +237,6 @@ AC_ARG_ENABLE([lcov-branch-coverage], [use_lcov_branch=yes], [use_lcov_branch=no]) -AC_ARG_ENABLE([threadlocal], - [AS_HELP_STRING([--enable-threadlocal], - [enable features that depend on the c++ thread_local keyword (currently just thread names in debug logs). (default is to enable if there is platform support)])], - [use_thread_local=$enableval], - [use_thread_local=auto]) - AC_ARG_ENABLE([zmq], [AS_HELP_STRING([--disable-zmq], [disable ZMQ notifications])], @@ -952,8 +946,8 @@ case $host in *linux*) TARGET_OS=linux ;; - *bsd*) - TARGET_OS=bsd + *freebsd*) + TARGET_OS=freebsd ;; esac @@ -1192,45 +1186,6 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ [AC_MSG_RESULT([no])] ) -if test "$use_thread_local" = "yes" || test "$use_thread_local" = "auto"; then - TEMP_LDFLAGS="$LDFLAGS" - LDFLAGS="$TEMP_LDFLAGS $PTHREAD_CFLAGS" - AC_MSG_CHECKING([for thread_local support]) - AC_LINK_IFELSE([AC_LANG_SOURCE([ - #include - static thread_local int foo = 0; - static void run_thread() { foo++;} - int main(){ - for(int i = 0; i < 10; i++) { std::thread(run_thread).detach();} - return foo; - } - ])], - [ - case $host in - *mingw*) - dnl mingw32's implementation of thread_local has also been shown to behave - dnl erroneously under concurrent usage; see: - dnl https://gist.github.com/jamesob/fe9a872051a88b2025b1aa37bfa98605 - AC_MSG_RESULT([no]) - ;; - *freebsd*) - dnl FreeBSD's implementation of thread_local is also buggy (per - dnl https://groups.google.com/d/msg/bsdmailinglist/22ncTZAbDp4/Dii_pII5AwAJ) - AC_MSG_RESULT([no]) - ;; - *) - AC_DEFINE([HAVE_THREAD_LOCAL], [1], [Define if thread_local is supported.]) - AC_MSG_RESULT([yes]) - ;; - esac - ], - [ - AC_MSG_RESULT([no]) - ] - ) - LDFLAGS="$TEMP_LDFLAGS" -fi - BACKTRACE_FLAGS= BACKTRACE_LDFLAGS= BACKTRACE_LIBS= @@ -1240,17 +1195,19 @@ if test "$enable_stacktraces" != "no"; then BACKTRACE_LIBS="$BACKTRACE_LIBS -ldbghelp" else AC_CHECK_HEADERS([execinfo.h], [ - if test "$TARGET_OS" = "bsd"; then - AC_SEARCH_LIBS([backtrace], [execinfo], [ - BACKTRACE_LIBS="$BACKTRACE_LIBS -lexecinfo" - ], [ - if test "$enable_stacktraces" = "yes"; then - AC_MSG_ERROR([--enable-stacktraces was specified but cannot locate libexecinfo]) - fi - AC_MSG_WARN([cannot locate libexecinfo, stacktraces will be disabled]) - enable_stacktraces=no - ]) - fi + case $host in + *bsd*) + AC_SEARCH_LIBS([backtrace], [execinfo], [ + BACKTRACE_LIBS="$BACKTRACE_LIBS -lexecinfo" + ], [ + if test "$enable_stacktraces" = "yes"; then + AC_MSG_ERROR([--enable-stacktraces was specified but cannot locate libexecinfo]) + fi + AC_MSG_WARN([cannot locate libexecinfo, stacktraces will be disabled]) + enable_stacktraces=no + ]) + ;; + esac AX_CHECK_LINK_FLAG([-Wl,-export-dynamic], [BACKTRACE_LDFLAGS="$BACKTRACE_LDFLAGS -Wl,-export-dynamic"], [ AX_CHECK_LINK_FLAG([-rdynamic], [BACKTRACE_LDFLAGS="$BACKTRACE_LDFLAGS -rdynamic"], [ if test "$enable_stacktraces" = "yes"; then diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index a89cd32e83d2..13d0a5d398b1 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -163,7 +163,8 @@ 'msvcrt.dll', # C standard library for MSVC 'SHELL32.dll', # shell API 'WS2_32.dll', # sockets -'bcrypt.dll', +'bcrypt.dll', # crypto API +'dbghelp.dll', # debugging routines # bitcoin-qt only 'dwmapi.dll', # desktop window manager 'GDI32.dll', # graphics device interface @@ -285,7 +286,8 @@ def check_ELF_ABI(binary) -> bool: CHECKS = { lief.EXE_FORMATS.ELF: [ ('IMPORTED_SYMBOLS', check_imported_symbols), - ('EXPORTED_SYMBOLS', check_exported_symbols), + # Dash: We export symbols aggressively to aid in backtrace generation + # ('EXPORTED_SYMBOLS', check_exported_symbols), ('LIBRARY_DEPENDENCIES', check_ELF_libraries), ('INTERPRETER_NAME', check_ELF_interpreter), ('ABI', check_ELF_ABI), diff --git a/depends/Makefile b/depends/Makefile index 53a5f23f1f79..c8510f4cc010 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -52,7 +52,6 @@ C_STANDARD ?= c11 CXX_STANDARD ?= c++20 BUILD = $(shell ./config.guess) -HOST ?= $(BUILD) PATCHES_PATH = $(BASEDIR)/patches BASEDIR = $(CURDIR) HASH_LENGTH:=11 @@ -61,11 +60,6 @@ DOWNLOAD_RETRIES:=3 HOST_ID_SALT ?= salt BUILD_ID_SALT ?= salt -host:=$(BUILD) -ifneq ($(HOST),) -host:=$(HOST) -endif - ifneq ($(DEBUG),) release_type=debug else @@ -75,9 +69,15 @@ endif base_build_dir=$(WORK_PATH)/build base_staging_dir=$(WORK_PATH)/staging base_download_dir=$(WORK_PATH)/download -canonical_host:=$(shell ./config.sub $(HOST)) build:=$(shell ./config.sub $(BUILD)) +host:=$(build) +ifneq ($(HOST),) +host:=$(HOST) +endif +HOST ?= $(BUILD) +canonical_host:=$(shell ./config.sub $(HOST)) + build_arch =$(firstword $(subst -, ,$(build))) build_vendor=$(word 2,$(subst -, ,$(build))) full_build_os:=$(subst $(build_arch)-$(build_vendor)-,,$(build)) diff --git a/depends/README.md b/depends/README.md index dcafd548cc01..3e44a66b7621 100644 --- a/depends/README.md +++ b/depends/README.md @@ -1,16 +1,59 @@ -### Usage +# Depends build + +This is a system of building and caching dependencies necessary for building +Dash Core. It supports cross-compilation. For more details see [description.md](description.md), +as well as [packages.md](packages.md) for how to add packages. + +## Usage + +### Ubuntu & Debian + + apt install automake bison cmake curl libtool make patch pkg-config python3 xz-utils To build dependencies for the current arch+OS: make -To build for another arch/OS: +### macOS - make HOST=host-platform-triplet +Install Xcode Command Line Tools and Homebrew Package Manager, +see [build-osx.md](../doc/build-osx.md). -For example: + brew install cmake make ninja - make HOST=x86_64-w64-mingw32 -j4 +To build dependencies for the current arch+OS: + + gmake + +### FreeBSD + + pkg install bash + +Skip the following packages if you don't intend to use the GUI and will build with [`NO_QT=1`](#dependency-options): + + pkg install bison ninja pkgconf python3 + +To build dependencies for the current arch+OS: + + gmake + +### NetBSD + + pkgin install bash gmake + +To build dependencies for the current arch+OS: + + gmake + +### OpenBSD + + pkg_add bash gmake gtar + +To build dependencies for the current arch+OS: + + gmake + +## Configuring Dash Core **Dash Core's `configure` script by default will ignore the depends output.** In order for it to pick up libraries, tools, and settings from the depends build, @@ -23,6 +66,53 @@ created. To use it during compilation: The default install prefix when using `config.site` is `--prefix=depends/`, so depends build outputs will be installed in that location. +## Dependency Options + +The following can be set when running make: `make FOO=bar` + +- `SOURCES_PATH`: Downloaded sources will be placed here +- `BASE_CACHE`: Built packages will be placed here +- `SDK_PATH`: Path where SDKs can be found (used by macOS) +- `FALLBACK_DOWNLOAD_PATH`: If a source file can't be fetched, try here before giving up +- `C_STANDARD`: Set the C standard version used. Defaults to `c11`. +- `CXX_STANDARD`: Set the C++ standard version used. Defaults to `c++20`. +- `NO_BOOST`: Don't download/build/cache Boost +- `NO_LIBEVENT`: Don't download/build/cache Libevent +- `NO_QT`: Don't download/build/cache Qt and its dependencies +- `NO_QR`: Don't download/build/cache packages needed for enabling qrencode +- `NO_ZMQ`: Don't download/build/cache packages needed for enabling ZeroMQ +- `NO_WALLET`: Don't download/build/cache libs needed to enable the wallet +- `NO_BDB`: Don't download/build/cache BerkeleyDB +- `NO_SQLITE`: Don't download/build/cache SQLite +- `NO_UPNP`: Don't download/build/cache packages needed for enabling UPnP +- `NO_NATPMP`: Don't download/build/cache packages needed for enabling NAT-PMP +- `NO_USDT`: Don't download/build/cache packages needed for enabling USDT tracepoints +- `ALLOW_HOST_PACKAGES`: Packages that are missed in dependencies (due to `NO_*` option or + build script logic) are searched for among the host system packages using + `pkg-config`. It allows building with packages of other (newer) versions +- `MULTIPROCESS`: build libmultiprocess (experimental, requires cmake) +- `DEBUG`: Disable some optimizations and enable more runtime checking +- `HOST_ID_SALT`: Optional salt to use when generating host package ids +- `BUILD_ID_SALT`: Optional salt to use when generating build package ids +- `LOG`: Use file-based logging for individual packages. During a package build its log file + resides in the `depends` directory, and the log file is printed out automatically in case + of build error. After successful build log files are moved along with package archives +- `LTO`: Enable options needed for LTO. Does not add `-flto` related options to *FLAGS. +- `NO_HARDEN=1`: Don't use hardening options when building packages + +If some packages are not built, for example `make NO_WALLET=1`, the appropriate +options will be passed to Dash Core's configure. In this case, `--disable-wallet`. + +## Cross compilation + +To build for another arch/OS: + + make HOST=host-platform-triplet + +For example: + + make HOST=x86_64-w64-mingw32 -j4 + Common `host-platform-triplet`s for cross compilation are: - `i686-pc-linux-gnu` for Linux 32 bit @@ -41,13 +131,7 @@ Common `host-platform-triplet`s for cross compilation are: - `aarch64-linux-android` for Android ARM 64 bit - `x86_64-linux-android` for Android x86 64 bit -The paths are automatically configured and no other options are needed unless targeting [Android](../doc/build-android.md). - -### Install the required dependencies: Ubuntu & Debian - -#### Common - - apt install automake bison cmake curl libtool make patch pkg-config python3 xz-utils +The paths are automatically configured and no other options are needed. #### For macOS cross compilation @@ -60,7 +144,7 @@ For more information, see [SDK Extraction](../contrib/macdeploy/README.md#sdk-ex #### For Win64 cross compilation -- see [build-windows.md](../doc/build-windows.md#cross-compilation-for-ubuntu-and-windows-subsystem-for-linux) + apt install g++-mingw-w64-x86-64-posix #### For linux (including i386, ARM) cross compilation @@ -88,60 +172,9 @@ For linux S390X cross compilation: sudo apt-get install g++-s390x-linux-gnu binutils-s390x-linux-gnu -### Install the required dependencies: FreeBSD - - pkg install bash - -### Install the required dependencies: OpenBSD - - pkg_add bash gtar - -### Dependency Options - -The following can be set when running make: `make FOO=bar` - -- `SOURCES_PATH`: Downloaded sources will be placed here -- `BASE_CACHE`: Built packages will be placed here -- `SDK_PATH`: Path where SDKs can be found (used by macOS) -- `FALLBACK_DOWNLOAD_PATH`: If a source file can't be fetched, try here before giving up -- `C_STANDARD`: Set the C standard version used. Defaults to `c11`. -- `CXX_STANDARD`: Set the C++ standard version used. Defaults to `c++20`. -- `NO_BOOST`: Don't download/build/cache Boost -- `NO_LIBEVENT`: Don't download/build/cache Libevent -- `NO_QT`: Don't download/build/cache Qt and its dependencies -- `NO_QR`: Don't download/build/cache packages needed for enabling qrencode -- `NO_ZMQ`: Don't download/build/cache packages needed for enabling ZeroMQ -- `NO_WALLET`: Don't download/build/cache libs needed to enable the wallet -- `NO_BDB`: Don't download/build/cache BerkeleyDB -- `NO_SQLITE`: Don't download/build/cache SQLite -- `NO_UPNP`: Don't download/build/cache packages needed for enabling UPnP -- `NO_NATPMP`: Don't download/build/cache packages needed for enabling NAT-PMP -- `NO_USDT`: Don't download/build/cache packages needed for enabling USDT tracepoints -- `ALLOW_HOST_PACKAGES`: Packages that are missed in dependencies (due to `NO_*` option or - build script logic) are searched for among the host system packages using - `pkg-config`. It allows building with packages of other (newer) versions -- `MULTIPROCESS`: build libmultiprocess (experimental, requires cmake) -- `DEBUG`: Disable some optimizations and enable more runtime checking -- `HOST_ID_SALT`: Optional salt to use when generating host package ids -- `BUILD_ID_SALT`: Optional salt to use when generating build package ids -- `LOG`: Use file-based logging for individual packages. During a package build its log file - resides in the `depends` directory, and the log file is printed out automatically in case - of build error. After successful build log files are moved along with package archives -- `LTO`: Enable options needed for LTO. Does not add `-flto` related options to *FLAGS. -- `NO_HARDEN=1`: Don't use hardening options when building packages - -If some packages are not built, for example `make NO_WALLET=1`, the appropriate -options will be passed to Dash Core's configure. In this case, `--disable-wallet`. - ### Additional targets download: run 'make download' to fetch all sources without building them download-osx: run 'make download-osx' to fetch all sources needed for macOS builds download-win: run 'make download-win' to fetch all sources needed for win builds download-linux: run 'make download-linux' to fetch all sources needed for linux builds - - -### Other documentation - -- [description.md](description.md): General description of the depends system -- [packages.md](packages.md): Steps for adding packages diff --git a/depends/builders/freebsd.mk b/depends/builders/freebsd.mk index 465f58e04dc7..910de28bf36f 100644 --- a/depends/builders/freebsd.mk +++ b/depends/builders/freebsd.mk @@ -1,5 +1,9 @@ build_freebsd_CC=clang build_freebsd_CXX=clang++ -build_freebsd_SHA256SUM = shasum -a 256 +build_freebsd_SHA256SUM = sha256sum build_freebsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o + +# freebsd host on freebsd builder: override freebsd host preferences. +freebsd_CC = clang +freebsd_CXX = clang++ diff --git a/depends/builders/openbsd.mk b/depends/builders/openbsd.mk index 9c94c4baae7a..6aeb14312587 100644 --- a/depends/builders/openbsd.mk +++ b/depends/builders/openbsd.mk @@ -1,9 +1,13 @@ build_openbsd_CC = clang build_openbsd_CXX = clang++ -build_openbsd_SHA256SUM = sha256 +build_openbsd_SHA256SUM = sha256 -r build_openbsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o build_openbsd_TAR = gtar # openBSD touch doesn't understand -h build_openbsd_TOUCH = touch -m -t 200001011200 + +# openbsd host on openbsd builder: override openbsd host preferences. +openbsd_CC = clang +openbsd_CXX = clang++ diff --git a/depends/config.guess b/depends/config.guess index cdfc4392047c..48a684601bd2 100755 --- a/depends/config.guess +++ b/depends/config.guess @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2023 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2023-08-22' +timestamp='2024-07-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -60,7 +60,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2023 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -123,7 +123,7 @@ set_cc_for_build() { dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" - for driver in cc gcc c89 c99 ; do + for driver in cc gcc c17 c99 c89 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break @@ -165,6 +165,8 @@ Linux|GNU|GNU/*) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu + #elif defined(__LLVM_LIBC__) + LIBC=llvm #else #include /* First heuristic to detect musl libc. */ @@ -632,7 +634,8 @@ EOF sed 's/^ //' << EOF > "$dummy.c" #include - main() + int + main () { if (!__power_pc()) exit(1); @@ -716,7 +719,8 @@ EOF #include #include - int main () + int + main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); @@ -1593,6 +1597,9 @@ EOF *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; + *:Ironclad:*:*) + GUESS=$UNAME_MACHINE-unknown-ironclad + ;; esac # Do we have a guess based on uname results? @@ -1616,6 +1623,7 @@ cat > "$dummy.c" <." version="\ GNU config.sub ($timestamp) -Copyright 1992-2023 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -120,7 +120,6 @@ case $# in esac # Split fields of configuration type -# shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 @@ -1845,7 +2237,7 @@ case $kernel-$os-$obj in echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 exit 1 ;; - kfreebsd*-gnu*- | kopensolaris*-gnu*-) + kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-) ;; vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) ;; @@ -1853,6 +2245,8 @@ case $kernel-$os-$obj in ;; os2-emx-) ;; + rtmk-nova-) + ;; *-eabi*- | *-gnueabi*-) ;; none--*) @@ -1879,7 +2273,7 @@ case $vendor in *-riscix*) vendor=acorn ;; - *-sunos*) + *-sunos* | *-solaris*) vendor=sun ;; *-cnk* | *-aix*) diff --git a/depends/funcs.mk b/depends/funcs.mk index 93bd9a87fde9..964be8ea61c5 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -35,7 +35,7 @@ endef define fetch_file ( $(call fetch_file_inner,$(1),$(2),$(3),$(4),$(5)) || \ - $(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(3),$(4),$(5))) + $(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(4),$(4),$(5))) endef define int_get_build_recipe_hash diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index a50e36110dc0..845ff03d6bae 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -19,6 +19,7 @@ clangxx_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang++") darwin_AR=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-ar") darwin_DSYMUTIL=$(shell $(SHELL) $(.SHELLFLAGS) "command -v dsymutil") darwin_NM=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-nm") +darwin_OBJCOPY=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-objcopy") darwin_OBJDUMP=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-objdump") darwin_RANLIB=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-ranlib") darwin_STRIP=$(shell $(SHELL) $(.SHELLFLAGS) "command -v llvm-strip") diff --git a/depends/packages/capnp.mk b/depends/packages/capnp.mk index 7f41d3b5a4ed..0964ede3d31b 100644 --- a/depends/packages/capnp.mk +++ b/depends/packages/capnp.mk @@ -4,6 +4,8 @@ $(package)_download_path=$(native_$(package)_download_path) $(package)_download_file=$(native_$(package)_download_file) $(package)_file_name=$(native_$(package)_file_name) $(package)_sha256_hash=$(native_$(package)_sha256_hash) +$(package)_patches=abi_placement_new.patch +$(package)_patches += fix_openbsd_build.patch define $(package)_set_vars := $(package)_config_opts := -DBUILD_TESTING=OFF @@ -12,6 +14,11 @@ define $(package)_set_vars := $(package)_cxxflags += -fdebug-prefix-map=$($(package)_extract_dir)=/usr -fmacro-prefix-map=$($(package)_extract_dir)=/usr endef +define $(package)_preprocess_cmds + patch -p2 < $($(package)_patch_dir)/abi_placement_new.patch && \ + patch -p2 < $($(package)_patch_dir)/fix_openbsd_build.patch +endef + define $(package)_config_cmds $($(package)_cmake) . endef diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index 4356c72129cc..bcc7cd067030 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -6,6 +6,7 @@ $(package)_sha256_hash=92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346 $(package)_patches=cmake_fixups.patch $(package)_patches += fix_mingw_link.patch $(package)_patches += netbsd_fixup.patch +$(package)_patches += winver_fixup.patch $(package)_build_subdir=build # When building for Windows, we set _WIN32_WINNT to target the same Windows @@ -20,14 +21,15 @@ define $(package)_set_vars $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601 ifeq ($(NO_HARDEN),) - $(package)_cppflags+=-D_FORTIFY_SOURCE=3 + $(package)_cppflags += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 endif endef define $(package)_preprocess_cmds patch -p1 < $($(package)_patch_dir)/cmake_fixups.patch && \ patch -p1 < $($(package)_patch_dir)/fix_mingw_link.patch && \ - patch -p1 < $($(package)_patch_dir)/netbsd_fixup.patch + patch -p1 < $($(package)_patch_dir)/netbsd_fixup.patch && \ + patch -p1 < $($(package)_patch_dir)/winver_fixup.patch endef define $(package)_config_cmds diff --git a/depends/packages/native_capnp.mk b/depends/packages/native_capnp.mk index e67b103716f4..c886d8e239df 100644 --- a/depends/packages/native_capnp.mk +++ b/depends/packages/native_capnp.mk @@ -4,6 +4,7 @@ $(package)_download_path=https://capnproto.org/ $(package)_download_file=capnproto-c++-$($(package)_version).tar.gz $(package)_file_name=capnproto-cxx-$($(package)_version).tar.gz $(package)_sha256_hash=07167580e563f5e821e3b2af1c238c16ec7181612650c5901330fa9a0da50939 +$(package)_patches=fix_openbsd_build.patch define $(package)_set_vars $(package)_config_opts := -DBUILD_TESTING=OFF @@ -11,6 +12,10 @@ define $(package)_set_vars $(package)_config_opts += -DWITH_ZLIB=OFF endef +define $(package)_preprocess_cmds + patch -p2 < $($(package)_patch_dir)/fix_openbsd_build.patch +endef + define $(package)_config_cmds $($(package)_cmake) . endef diff --git a/depends/packages/native_libmultiprocess.mk b/depends/packages/native_libmultiprocess.mk index 2e30be434cd1..8273f1508466 100644 --- a/depends/packages/native_libmultiprocess.mk +++ b/depends/packages/native_libmultiprocess.mk @@ -1,6 +1,6 @@ package=native_libmultiprocess $(package)_version=6aca5f389bacf2942394b8738bbe15d6c9edfb9b -$(package)_download_path=https://github.com/chaincodelabs/libmultiprocess/archive +$(package)_download_path=https://github.com/bitcoin-core/libmultiprocess/archive $(package)_file_name=$($(package)_version).tar.gz $(package)_sha256_hash=2efeed53542bc1d8af3291f2b6f0e5d430d86a5e04e415ce33c136f2c226a51d $(package)_dependencies=native_capnp diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 40f9ae6ad577..7e0bb2633219 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -10,6 +10,7 @@ qrencode_darwin_packages = qrencode qrencode_mingw32_packages = qrencode qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig libxkbcommon libxcb_util libxcb_util_render libxcb_util_keysyms libxcb_util_image libxcb_util_wm +qt_freebsd_packages:=$(qt_linux_packages) qt_android_packages=qt qt_darwin_packages=qt qt_mingw32_packages=qt diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index 6c8eb44984f2..18aedcf7afcf 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -4,7 +4,8 @@ $(package)_download_path=https://download.qt.io/archive/qt/5.15/$($(package)_ver $(package)_suffix=everywhere-opensource-src-$($(package)_version).tar.xz $(package)_file_name=qtbase-$($(package)_suffix) $(package)_sha256_hash=7b632550ea1048fc10c741e46e2e3b093e5ca94dfa6209e9e0848800e247023b -$(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon libxcb_util libxcb_util_render libxcb_util_keysyms libxcb_util_image libxcb_util_wm +$(package)_linux_dependencies := freetype fontconfig libxcb libxkbcommon libxcb_util libxcb_util_render libxcb_util_keysyms libxcb_util_image libxcb_util_wm +$(package)_freebsd_dependencies := $($(package)_linux_dependencies) $(package)_qt_libs=corelib network widgets gui plugins testlib $(package)_linguist_tools = lrelease lupdate lconvert $(package)_patches = qt.pro @@ -161,6 +162,7 @@ $(package)_config_opts_linux += -dbus-runtime ifneq ($(LTO),) $(package)_config_opts_linux += -ltcg endif +$(package)_config_opts_freebsd := $$($(package)_config_opts_linux) ifneq (,$(findstring clang,$($(package)_cxx))) ifneq (,$(findstring -stdlib=libc++,$($(package)_cxx))) diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk index 29c349a21b5b..0a534556ee4a 100644 --- a/depends/packages/xproto.mk +++ b/depends/packages/xproto.mk @@ -21,6 +21,8 @@ define $(package)_build_cmds $(MAKE) endef +# mkdir detection is broken on Alpine. Set MKDIRPROG to ensure we always +# use "mkdir -p", and avoid parallelism issues during install. define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install + $(MAKE) MKDIRPROG="mkdir -p" DESTDIR=$($(package)_staging_dir) install endef diff --git a/depends/patches/capnp/abi_placement_new.patch b/depends/patches/capnp/abi_placement_new.patch new file mode 100644 index 000000000000..9aef85db8e86 --- /dev/null +++ b/depends/patches/capnp/abi_placement_new.patch @@ -0,0 +1,71 @@ +From 74560f26f75dda4257dce541ca362a1e763b2971 Mon Sep 17 00:00:00 2001 +From: Ryan Ofsky +Date: Thu, 6 Feb 2025 08:39:05 -0500 +Subject: [PATCH 1/1] Avoid gcc/clang ABI incompatibility caused by + PlacementNew + +GCC and clang do not use same calling convention for passing empty struct +parameters. There is more information about this in +https://itanium-cxx-abi.github.io/cxx-abi/cxx-abi-dev/archives/2015-December/002869.html + +Unfortunately this can create an issue in capnproto if it is built without +optimizations in GCC, and the resulting static libraries are used in a clang +program, or vice versa. + +Depending on what order libraries are specified on the linker command line, and +whether code compiled with the other compiler is calling any header functions +that cause weak a `operator new(unsigned int, kj::_::PlacementNew, void*)` +symbol to be defined in its own objects, this can cause the linker to link a +GCC-generated `kj::ctor` with a clang-generated `operator new`, and the +resulting program to crash due to the compilers using different calling +conventions for `operator new`. + +This problem is difficult to avoid in general, but pretty easy to avoid here by +changing `operator new` parameter order so the empty struct parameter is last. + +This change should be beneficial for capnproto users that may be compiling it +without optimizations, and not necessarily using a single compiler to build all +their dependencies. + +The problem does not occur if any optimizations are enabled because `operator +new` calls are inlined in that case. +--- + c++/src/kj/common.h | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/c++/src/kj/common.h b/c++/src/kj/common.h +index b8edde3c..28ab11d6 100644 +--- a/c++/src/kj/common.h ++++ b/c++/src/kj/common.h +@@ -1034,24 +1034,27 @@ private: + + // We want placement new, but we don't want to #include . operator new cannot be defined in + // a namespace, and defining it globally conflicts with the definition in . So we have to +-// define a dummy type and an operator new that uses it. ++// define a dummy type and an operator new that uses it. The dummy type is intentionally passed ++// as the last parameter so clang and GCC ABI calling conventions for empty struct struct parameters ++// are compatible, and there are not segfaults trying to call clang operator new/delete from GCC or ++// vice versa. + + namespace _ { // private + struct PlacementNew {}; + } // namespace _ (private) + } // namespace kj + +-inline void* operator new(size_t, kj::_::PlacementNew, void* __p) noexcept { ++inline void* operator new(size_t, void* __p, kj::_::PlacementNew) noexcept { + return __p; + } + +-inline void operator delete(void*, kj::_::PlacementNew, void* __p) noexcept {} ++inline void operator delete(void*, void* __p, kj::_::PlacementNew) noexcept {} + + namespace kj { + + template + inline void ctor(T& location, Params&&... params) { +- new (_::PlacementNew(), &location) T(kj::fwd(params)...); ++ new (&location, _::PlacementNew()) T(kj::fwd(params)...); + } + + template diff --git a/depends/patches/capnp/fix_openbsd_build.patch b/depends/patches/capnp/fix_openbsd_build.patch new file mode 100644 index 000000000000..eb143c61e4dc --- /dev/null +++ b/depends/patches/capnp/fix_openbsd_build.patch @@ -0,0 +1,71 @@ +From 0cd1792332dce6a3afae6e2bc2939da69fea65fa Mon Sep 17 00:00:00 2001 +From: Sebastian Falbesoner +Date: Sat, 31 May 2025 00:49:44 +0200 +Subject: [PATCH 1/2] In cidr.c++, include on all non-Windows + systems + +The motivation for this commit is to fix the build for OpenBSD, +but it may also solves the same potential problem for other systems +without causing any harm. + +Suggested already twice, see +https://github.com/capnproto/capnproto/pull/1846#discussion_r1399499535 +https://github.com/capnproto/capnproto/pull/1907#discussion_r1452602424 +--- + c++/src/kj/cidr.c++ | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/c++/src/kj/cidr.c++ b/c++/src/kj/cidr.c++ +index 6a1fa32e..9432b8f4 100644 +--- a/c++/src/kj/cidr.c++ ++++ b/c++/src/kj/cidr.c++ +@@ -39,9 +39,6 @@ + #else + #include + #include +-#endif +- +-#if __FreeBSD__ + #include + #endif + +-- +2.49.0 + + +From 2e76d17db3fc484061487c0779b16495939d30c3 Mon Sep 17 00:00:00 2001 +From: Sebastian Falbesoner +Date: Sat, 31 May 2025 01:06:42 +0200 +Subject: [PATCH 2/2] Don't set KJ_USE_KQUEUE on OpenBSD + +OpenBSD doesn't support user event filters yet, hence +the build fails as it misses the symbol EVFILT_USER in +the kqueue implementation in async-unix.c++. Fix that +by not setting KJ_USE_KQUEUE on OpenBSD, so the poll()- +based implementation is used instead. + +Suggested in +https://github.com/capnproto/capnproto/pull/1907/commits/829d3f03735f8f6762a50fc346db56bf02140f02#r1452600300 +--- + c++/src/kj/async-unix.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/c++/src/kj/async-unix.h b/c++/src/kj/async-unix.h +index 665305ea..e66ad8e4 100644 +--- a/c++/src/kj/async-unix.h ++++ b/c++/src/kj/async-unix.h +@@ -37,8 +37,9 @@ KJ_BEGIN_HEADER + #if __linux__ + // Default to epoll on Linux. + #define KJ_USE_EPOLL 1 +-#elif __APPLE__ || __FreeBSD__ || __OpenBSD__ || __NetBSD__ || __DragonFly__ +-// MacOS and BSDs prefer kqueue() for event notification. ++#elif __APPLE__ || __FreeBSD__ || __NetBSD__ || __DragonFly__ ++// MacOS and most BSDs prefer kqueue() for event notification. ++// (Note that OpenBSD's kqueue(2) doesn't support user event filters yet) + #define KJ_USE_KQUEUE 1 + #endif + #endif +-- +2.49.0 + diff --git a/depends/patches/libevent/winver_fixup.patch b/depends/patches/libevent/winver_fixup.patch new file mode 100644 index 000000000000..4995c356f942 --- /dev/null +++ b/depends/patches/libevent/winver_fixup.patch @@ -0,0 +1,122 @@ +Cherry-picked from a14ff91254f40cf36e0fee199e26fb11260fab49. + +move _WIN32_WINNT defintions before first #include + +_WIN32_WINNT and WIN32_LEAN_AND_MEAN need to be defined +before the windows.h is included for the first time. +Avoid the confusion of indirect #include by defining +before any. + +diff --git a/event_iocp.c b/event_iocp.c +index 6b2a2e15..4955e426 100644 +--- a/event_iocp.c ++++ b/event_iocp.c +@@ -23,12 +23,14 @@ + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +-#include "evconfig-private.h" + + #ifndef _WIN32_WINNT + /* Minimum required for InitializeCriticalSectionAndSpinCount */ + #define _WIN32_WINNT 0x0403 + #endif ++ ++#include "evconfig-private.h" ++ + #include + #include + #include +diff --git a/evthread_win32.c b/evthread_win32.c +index 2ec80560..8647f72b 100644 +--- a/evthread_win32.c ++++ b/evthread_win32.c +@@ -23,18 +23,21 @@ + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +-#include "event2/event-config.h" +-#include "evconfig-private.h" + + #ifdef _WIN32 + #ifndef _WIN32_WINNT + /* Minimum required for InitializeCriticalSectionAndSpinCount */ + #define _WIN32_WINNT 0x0403 + #endif +-#include + #define WIN32_LEAN_AND_MEAN ++#endif ++ ++#include "event2/event-config.h" ++#include "evconfig-private.h" ++ ++#ifdef _WIN32 ++#include + #include +-#undef WIN32_LEAN_AND_MEAN + #include + #endif + +diff --git a/evutil.c b/evutil.c +index 9817f086..8537ffe8 100644 +--- a/evutil.c ++++ b/evutil.c +@@ -24,6 +24,14 @@ + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#ifdef _WIN32 ++#ifndef _WIN32_WINNT ++/* For structs needed by GetAdaptersAddresses */ ++#define _WIN32_WINNT 0x0501 ++#endif ++#define WIN32_LEAN_AND_MEAN ++#endif ++ + #include "event2/event-config.h" + #include "evconfig-private.h" + +@@ -31,15 +39,10 @@ + #include + #include + #include +-#define WIN32_LEAN_AND_MEAN + #include +-#undef WIN32_LEAN_AND_MEAN + #include + #include + #include +-#undef _WIN32_WINNT +-/* For structs needed by GetAdaptersAddresses */ +-#define _WIN32_WINNT 0x0501 + #include + #include + #endif +diff --git a/listener.c b/listener.c +index f5c00c9c..d1080e76 100644 +--- a/listener.c ++++ b/listener.c +@@ -24,16 +24,19 @@ + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++#ifdef _WIN32 ++#ifndef _WIN32_WINNT ++/* Minimum required for InitializeCriticalSectionAndSpinCount */ ++#define _WIN32_WINNT 0x0403 ++#endif ++#endif ++ + #include "event2/event-config.h" + #include "evconfig-private.h" + + #include + + #ifdef _WIN32 +-#ifndef _WIN32_WINNT +-/* Minimum required for InitializeCriticalSectionAndSpinCount */ +-#define _WIN32_WINNT 0x0403 +-#endif + #include + #include + #include diff --git a/depends/patches/native_capnp/fix_openbsd_build.patch b/depends/patches/native_capnp/fix_openbsd_build.patch new file mode 100644 index 000000000000..eb143c61e4dc --- /dev/null +++ b/depends/patches/native_capnp/fix_openbsd_build.patch @@ -0,0 +1,71 @@ +From 0cd1792332dce6a3afae6e2bc2939da69fea65fa Mon Sep 17 00:00:00 2001 +From: Sebastian Falbesoner +Date: Sat, 31 May 2025 00:49:44 +0200 +Subject: [PATCH 1/2] In cidr.c++, include on all non-Windows + systems + +The motivation for this commit is to fix the build for OpenBSD, +but it may also solves the same potential problem for other systems +without causing any harm. + +Suggested already twice, see +https://github.com/capnproto/capnproto/pull/1846#discussion_r1399499535 +https://github.com/capnproto/capnproto/pull/1907#discussion_r1452602424 +--- + c++/src/kj/cidr.c++ | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/c++/src/kj/cidr.c++ b/c++/src/kj/cidr.c++ +index 6a1fa32e..9432b8f4 100644 +--- a/c++/src/kj/cidr.c++ ++++ b/c++/src/kj/cidr.c++ +@@ -39,9 +39,6 @@ + #else + #include + #include +-#endif +- +-#if __FreeBSD__ + #include + #endif + +-- +2.49.0 + + +From 2e76d17db3fc484061487c0779b16495939d30c3 Mon Sep 17 00:00:00 2001 +From: Sebastian Falbesoner +Date: Sat, 31 May 2025 01:06:42 +0200 +Subject: [PATCH 2/2] Don't set KJ_USE_KQUEUE on OpenBSD + +OpenBSD doesn't support user event filters yet, hence +the build fails as it misses the symbol EVFILT_USER in +the kqueue implementation in async-unix.c++. Fix that +by not setting KJ_USE_KQUEUE on OpenBSD, so the poll()- +based implementation is used instead. + +Suggested in +https://github.com/capnproto/capnproto/pull/1907/commits/829d3f03735f8f6762a50fc346db56bf02140f02#r1452600300 +--- + c++/src/kj/async-unix.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/c++/src/kj/async-unix.h b/c++/src/kj/async-unix.h +index 665305ea..e66ad8e4 100644 +--- a/c++/src/kj/async-unix.h ++++ b/c++/src/kj/async-unix.h +@@ -37,8 +37,9 @@ KJ_BEGIN_HEADER + #if __linux__ + // Default to epoll on Linux. + #define KJ_USE_EPOLL 1 +-#elif __APPLE__ || __FreeBSD__ || __OpenBSD__ || __NetBSD__ || __DragonFly__ +-// MacOS and BSDs prefer kqueue() for event notification. ++#elif __APPLE__ || __FreeBSD__ || __NetBSD__ || __DragonFly__ ++// MacOS and most BSDs prefer kqueue() for event notification. ++// (Note that OpenBSD's kqueue(2) doesn't support user event filters yet) + #define KJ_USE_KQUEUE 1 + #endif + #endif +-- +2.49.0 + diff --git a/doc/build-windows.md b/doc/build-windows.md index 91d1b86cef54..873d8d67af62 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -27,24 +27,8 @@ The steps below can be performed on Ubuntu or WSL. The depends system will also work on other Linux distributions, however the commands for installing the toolchain will be different. -First, install the general dependencies: - - sudo apt-get install build-essential libtool autotools-dev automake pkg-config bsdmainutils curl git bison - -A host toolchain (`build-essential`) is necessary because some dependency -packages need to build host utilities that are used in the build process. - -See [dependencies.md](dependencies.md) for a complete overview. - -## Building for 64-bit Windows - -The first step is to install the mingw-w64 cross-compilation tool chain: - -```sh -sudo apt install g++-mingw-w64-x86-64-posix -``` - -Once the toolchain is installed the build steps are common: +See [README.md](../depends/README.md) in the depends directory for which +dependencies to install and [dependencies.md](dependencies.md) for a complete overview. Note that for WSL the Dash Core source path MUST be somewhere in the default mount file system, for example /usr/src/dash, AND not under /mnt/d/. If this is not the case the dependency autoconf scripts will fail. diff --git a/doc/design/multiprocess.md b/doc/design/multiprocess.md index 3463130110dd..6e305c0f9b24 100644 --- a/doc/design/multiprocess.md +++ b/doc/design/multiprocess.md @@ -19,7 +19,7 @@ The `-debug=ipc` command line option can be used to see requests and responses b ## Installation -The multiprocess feature requires [Cap'n Proto](https://capnproto.org/) and [libmultiprocess](https://github.com/chaincodelabs/libmultiprocess) as dependencies. A simple way to get starting using it without installing these dependencies manually is to use the [depends system](../depends) with the `MULTIPROCESS=1` [dependency option](../depends#dependency-options) passed to make: +The multiprocess feature requires [Cap'n Proto](https://capnproto.org/) and [libmultiprocess](https://github.com/bitcoin-core/libmultiprocess) as dependencies. A simple way to get starting using it without installing these dependencies manually is to use the [depends system](../depends) with the `MULTIPROCESS=1` [dependency option](../depends#dependency-options) passed to make: ``` cd @@ -32,7 +32,7 @@ DASHD=dash-node test/functional/test_runner.py The configure script will pick up settings and library locations from the depends directory, so there is no need to pass `--enable-multiprocess` as a separate flag when using the depends system (it's controlled by the `MULTIPROCESS=1` option). -Alternately, you can install [Cap'n Proto](https://capnproto.org/) and [libmultiprocess](https://github.com/chaincodelabs/libmultiprocess) packages on your system, and just run `./configure --enable-multiprocess` without using the depends system. The configure script will be able to locate the installed packages via [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/). See [Installation](https://github.com/chaincodelabs/libmultiprocess#installation) section of the libmultiprocess readme for install steps. See [build-unix.md](build-unix.md) and [build-osx.md](build-osx.md) for information about installing dependencies in general. +Alternately, you can install [Cap'n Proto](https://capnproto.org/) and [libmultiprocess](https://github.com/bitcoin-core/libmultiprocess) packages on your system, and just run `./configure --enable-multiprocess` without using the depends system. The configure script will be able to locate the installed packages via [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/). See [Installation](https://github.com/bitcoin-core/libmultiprocess#installation) section of the libmultiprocess readme for install steps. See [build-unix.md](build-unix.md) and [build-osx.md](build-osx.md) for information about installing dependencies in general. ## IPC implementation details @@ -48,7 +48,7 @@ interface method invokes the implementation directly. When code is running in different processes, calling an interface method invokes a proxy interface implementation that communicates with a remote process and invokes the real implementation in the remote process. The -[libmultiprocess](https://github.com/chaincodelabs/libmultiprocess) code +[libmultiprocess](https://github.com/bitcoin-core/libmultiprocess) code generation tool internally generates proxy client classes and proxy server classes for this purpose that are thin wrappers around Cap'n Proto [client](https://capnproto.org/cxxrpc.html#clients) and @@ -67,6 +67,6 @@ a corresponding thread in the invoked process responsible for executing all method calls from the source thread, without blocking I/O or holding up another call, and using the same thread local variables, locks, and callbacks between calls. The forwarding, tracking, and threading is implemented inside the -[libmultiprocess](https://github.com/chaincodelabs/libmultiprocess) library +[libmultiprocess](https://github.com/bitcoin-core/libmultiprocess) library which has the design goal of making calls between processes look like calls in the same process to the extent possible. diff --git a/src/init/common.cpp b/src/init/common.cpp index fc1cc551aa1b..0a1bff80d48d 100644 --- a/src/init/common.cpp +++ b/src/init/common.cpp @@ -67,11 +67,7 @@ void AddLoggingArgs(ArgsManager& argsman) argsman.AddArg("-logips", strprintf("Include IP addresses in debug output (default: %u)", DEFAULT_LOGIPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-loglevel=|:", strprintf("Set the global or per-category severity level for logging categories enabled with the -debug configuration option or the logging RPC: %s (default=%s); warning and error levels are always logged. If : is supplied, the setting will override the global one and may be specified multiple times to set multiple category-specific levels. can be: %s.", LogInstance().LogLevelsString(), LogInstance().LogLevelToStr(BCLog::DEFAULT_LOG_LEVEL), LogInstance().LogCategoriesString()), ArgsManager::DISALLOW_NEGATION | ArgsManager::DISALLOW_ELISION | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logtimestamps", strprintf("Prepend debug output with timestamp (default: %u)", DEFAULT_LOGTIMESTAMPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); -#ifdef HAVE_THREAD_LOCAL argsman.AddArg("-logthreadnames", strprintf("Prepend debug output with name of the originating thread (only available on platforms supporting thread_local) (default: %u)", DEFAULT_LOGTHREADNAMES), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); -#else - argsman.AddHiddenArgs({"-logthreadnames"}); -#endif argsman.AddArg("-logsourcelocations", strprintf("Prepend debug output with name of the originating source location (source file, line number and function name) (default: %u)", DEFAULT_LOGSOURCELOCATIONS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -daemon. To disable logging to file, set -nodebuglogfile)", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); @@ -85,9 +81,7 @@ void SetLoggingOptions(const ArgsManager& args) LogInstance().m_print_to_console = args.GetBoolArg("-printtoconsole", !args.GetBoolArg("-daemon", false)); LogInstance().m_log_timestamps = args.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); LogInstance().m_log_time_micros = args.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); -#ifdef HAVE_THREAD_LOCAL LogInstance().m_log_threadnames = args.GetBoolArg("-logthreadnames", DEFAULT_LOGTHREADNAMES); -#endif LogInstance().m_log_sourcelocations = args.GetBoolArg("-logsourcelocations", DEFAULT_LOGSOURCELOCATIONS); fLogIPs = args.GetBoolArg("-logips", DEFAULT_LOGIPS); diff --git a/src/sync.cpp b/src/sync.cpp index 1747b69f6fee..5e7067e226cc 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -41,11 +41,11 @@ struct CLockLocation { const char* pszFile, int nLine, bool fTryIn, - const std::string& thread_name) + std::string&& thread_name) : fTry(fTryIn), mutexName(pszName), sourceFile(pszFile), - m_thread_name(thread_name), + m_thread_name(std::move(thread_name)), sourceLine(nLine) {} std::string ToString() const @@ -64,7 +64,7 @@ struct CLockLocation { bool fTry; std::string mutexName; std::string sourceFile; - const std::string& m_thread_name; + const std::string m_thread_name; int sourceLine; }; diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h index ae4896c764ac..0ad25583ce4b 100644 --- a/src/test/util/setup_common.h +++ b/src/test/util/setup_common.h @@ -48,9 +48,8 @@ std::ostream& operator<<(typename std::enable_if::value, std::os /** * This global and the helpers that use it are not thread-safe. * - * If thread-safety is needed, the global could be made thread_local (given - * that thread_local is supported on all architectures we support) or a - * per-thread instance could be used in the multi-threaded test. + * If thread-safety is needed, a per-thread instance could be + * used in the multi-threaded test. */ extern FastRandomContext g_insecure_rand_ctx; diff --git a/src/test/util_threadnames_tests.cpp b/src/test/util_threadnames_tests.cpp index dbb5423a77f2..3ddf3390615f 100644 --- a/src/test/util_threadnames_tests.cpp +++ b/src/test/util_threadnames_tests.cpp @@ -11,10 +11,6 @@ #include #include -#if defined(HAVE_CONFIG_H) -#include -#endif - #include BOOST_AUTO_TEST_SUITE(util_threadnames_tests) @@ -53,11 +49,6 @@ std::set RenameEnMasse(int num_threads) */ BOOST_AUTO_TEST_CASE(util_threadnames_test_rename_threaded) { -#if !defined(HAVE_THREAD_LOCAL) - // This test doesn't apply to platforms where we don't have thread_local. - return; -#endif - std::set names = RenameEnMasse(100); BOOST_CHECK_EQUAL(names.size(), 100U); diff --git a/src/util/threadnames.cpp b/src/util/threadnames.cpp index 3f821e178214..d3ced175fef4 100644 --- a/src/util/threadnames.cpp +++ b/src/util/threadnames.cpp @@ -6,6 +6,7 @@ #include #endif +#include #include #include #include @@ -38,31 +39,30 @@ static void SetThreadName(const char* name) #endif } -// If we have thread_local, just keep thread ID and name in a thread_local -// global. -#if defined(HAVE_THREAD_LOCAL) - -static thread_local std::string g_thread_name; -const std::string& util::ThreadGetInternalName() { return g_thread_name; } +/** + * The name of the thread. We use char array instead of std::string to avoid + * complications with running a destructor when the thread exits. Avoid adding + * other thread_local variables. + * @see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=278701 + */ +static thread_local char g_thread_name[128]{'\0'}; +std::string util::ThreadGetInternalName() { return g_thread_name; } //! Set the in-memory internal name for this thread. Does not affect the process //! name. -static void SetInternalName(std::string name) { g_thread_name = std::move(name); } - -// Without thread_local available, don't handle internal name at all. -#else - -static const std::string empty_string; -const std::string& util::ThreadGetInternalName() { return empty_string; } -static void SetInternalName(std::string name) { } -#endif +static void SetInternalName(const std::string& name) +{ + const size_t copy_bytes{std::min(sizeof(g_thread_name) - 1, name.length())}; + std::memcpy(g_thread_name, name.data(), copy_bytes); + g_thread_name[copy_bytes] = '\0'; +} -void util::ThreadRename(std::string&& name) +void util::ThreadRename(const std::string& name) { SetThreadName(("d-" + name).c_str()); - SetInternalName(std::move(name)); + SetInternalName(name); } -void util::ThreadSetInternalName(std::string&& name) +void util::ThreadSetInternalName(const std::string& name) { - SetInternalName(std::move(name)); + SetInternalName(name); } diff --git a/src/util/threadnames.h b/src/util/threadnames.h index 64b2689cf137..adca8c30009e 100644 --- a/src/util/threadnames.h +++ b/src/util/threadnames.h @@ -12,14 +12,14 @@ namespace util { //! as its system thread name. //! @note Do not call this for the main thread, as this will interfere with //! UNIX utilities such as top and killall. Use ThreadSetInternalName instead. -void ThreadRename(std::string&&); +void ThreadRename(const std::string&); //! Set the internal (in-memory) name of the current thread only. -void ThreadSetInternalName(std::string&&); +void ThreadSetInternalName(const std::string&); //! Get the thread's internal (in-memory) name; used e.g. for identification in //! logging. -const std::string& ThreadGetInternalName(); +std::string ThreadGetInternalName(); } // namespace util