guix: split builds into Linux(gui) and macOS/Windows
What changed, and why it matters
This commit reorganizes how Bitcoin Core's official release builds are produced using the Guix build system. It splits Linux builds into two separate steps—one for command-line/daemon programs and one for the graphical wallet interface—and moves some build tools into a separate manifest file. There is no indication this fixes a security vulnerability or introduces a security-relevant bug; it is a build-system refactoring.
No security action required. Treat as a normal build-system maintenance change. Reviewers may optionally verify that the moved security-check.py and symbol-check.py invocations in package.sh still execute for all release artifacts, including the new split Linux/GUI path.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors contrib/guix build scripts: Linux builds now run build_linux.sh (non-GUI, NO_QT=1) and build_linux_gui.sh (GUI-only components) in separate Guix containers with manifest_build.scm and manifest_gui.scm respectively, while macOS/Windows continue using build.sh. It also moves security/symbol checks from build.sh into package.sh, adds helper functions (check_cross_paths, glibc_dynamic_linker) to setup.sh, and trims packages from manifest_build.scm into the new manifest_gui.scm. The diff shows no code changes to Bitcoin Core itself, no privilege changes, no network changes, and no cryptographic changes.
Changed components
contrib/guix/guix-buildcontrib/guix/libexec/build.shcontrib/guix/libexec/build_linux.shcontrib/guix/libexec/build_linux_gui.shcontrib/guix/libexec/package.shcontrib/guix/libexec/prelude.bashcontrib/guix/libexec/setup.shcontrib/guix/manifest_build.scmcontrib/guix/manifest_gui.scmInspect captured patch +330 / −129
diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build
index 1ab9cc7e..5b3eb3d9 100755
--- a/contrib/guix/guix-build
+++ b/contrib/guix/guix-build
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
export LC_ALL=C
-set -e -o pipefail
+set -o errexit -o pipefail
# Source the common prelude, which:
# 1. Checks if we're at the top directory of the Bitcoin Core repository
@@ -337,8 +337,8 @@ INFO: Building ${VERSION:?not set} for platform triple ${HOST:?not set}:
ADDITIONAL_GUIX_TIMEMACHINE_FLAGS: ${ADDITIONAL_GUIX_TIMEMACHINE_FLAGS}
EOF
- # Run the build script 'contrib/guix/libexec/build.sh' in the build
- # container specified by 'contrib/guix/manifest.scm'.
+ # Run the build scripts 'contrib/guix/libexec/*.sh' in the build
+ # containers specified by 'contrib/guix/manifest*.scm'.
#
# Explanation of `guix shell` flags:
#
@@ -403,39 +403,59 @@ EOF
# substitutes (pre-built packages) from servers that the user trusts.
# Please read the README.md in the same directory as this file for
# more information.
- #
- # shellcheck disable=SC2086
- time-machine shell --manifest="${PWD}/contrib/guix/manifest_build.scm" \
- --container \
- --writable-root \
- --pure \
- --no-cwd \
- --share="$PWD"=/bitcoin \
- --share="$DISTSRC_BASE"=/distsrc-base \
- --share="$OUTDIR_BASE"=/outdir-base \
- --expose="$(git rev-parse --git-common-dir)" \
- ${SOURCES_PATH:+--share="$SOURCES_PATH"} \
- ${BASE_CACHE:+--share="$BASE_CACHE"} \
- ${SDK_PATH:+--share="$SDK_PATH"} \
- --cores="$JOBS" \
- --keep-failed \
- --fallback \
- --link-profile \
- --root="$(profiledir_for_host "${HOST}")" \
- ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} \
- ${ADDITIONAL_GUIX_COMMON_FLAGS} ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \
- -- env HOST="$host" \
- DISTNAME="$DISTNAME" \
- JOBS="$JOBS" \
- SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \
- ${V:+V=1} \
- ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \
- ${BASE_CACHE:+BASE_CACHE="$BASE_CACHE"} \
- ${SDK_PATH:+SDK_PATH="$SDK_PATH"} \
- DISTSRC="$(distsrc_for_host "$HOST" "" /distsrc-base)" \
- OUTDIR="$(outdir_for_host "$HOST" "" /outdir-base)" \
- DIST_ARCHIVE_BASE=/outdir-base/dist-archive \
- bash -c "cd /bitcoin && bash contrib/guix/libexec/build.sh"
+ read -ra _guix_common_flags <<< "$ADDITIONAL_GUIX_COMMON_FLAGS"
+ read -ra _guix_env_flags <<< "$ADDITIONAL_GUIX_ENVIRONMENT_FLAGS"
+
+ shell_opts=(
+ --manifest="${PWD}/contrib/guix/manifest_build.scm"
+ --container
+ --writable-root
+ --pure
+ --no-cwd
+ --share="$PWD=/bitcoin"
+ --share="$DISTSRC_BASE=/distsrc-base"
+ --share="$OUTDIR_BASE=/outdir-base"
+ --expose="$(git rev-parse --git-common-dir)"
+ ${SOURCES_PATH:+--share="$SOURCES_PATH"}
+ ${BASE_CACHE:+--share="$BASE_CACHE"}
+ ${SDK_PATH:+--share="$SDK_PATH"}
+ --cores="$JOBS"
+ --keep-failed
+ --fallback
+ --link-profile
+ ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"}
+ "${_guix_common_flags[@]}" "${_guix_env_flags[@]}"
+ -- env HOST="$host" \
+ DISTNAME="$DISTNAME"
+ JOBS="$JOBS"
+ SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}"
+ ${V:+V=1}
+ ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"}
+ ${BASE_CACHE:+BASE_CACHE="$BASE_CACHE"}
+ ${SDK_PATH:+SDK_PATH="$SDK_PATH"}
+ DISTSRC="$(distsrc_for_host "$HOST" "" /distsrc-base)"
+ OUTDIR="$(outdir_for_host "$HOST" "" /outdir-base)"
+ DIST_ARCHIVE_BASE=/outdir-base/dist-archive
+ )
+
+ case "$HOST" in
+ *linux*)
+ time-machine shell --root="$(profiledir_for_host "${HOST}")" \
+ "${shell_opts[@]}" \
+ bash -c "cd /bitcoin && bash contrib/guix/libexec/build_linux.sh"
+
+ time-machine shell --manifest="${PWD}/contrib/guix/manifest_gui.scm" \
+ --root="$(profiledir_for_host "${HOST}"_gui)" \
+ "${shell_opts[@]}" \
+ bash -c "cd /bitcoin && bash contrib/guix/libexec/build_linux_gui.sh"
+ ;;
+ *)
+ time-machine shell --manifest="${PWD}/contrib/guix/manifest_gui.scm" \
+ --root="$(profiledir_for_host "${HOST}")" \
+ "${shell_opts[@]}" \
+ bash -c "cd /bitcoin && bash contrib/guix/libexec/build.sh"
+ ;;
+ esac
)
done
diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh
index 0ec058b8..3b42cda6 100755
--- a/contrib/guix/libexec/build.sh
+++ b/contrib/guix/libexec/build.sh
@@ -3,7 +3,7 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C
-set -e -o pipefail
+set -o errexit -o pipefail
# shellcheck source=setup.sh
source "$(dirname "${BASH_SOURCE[0]}")/setup.sh"
@@ -16,14 +16,8 @@ NATIVE_GCC="$(store_path gcc-toolchain)"
build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include"
build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include"
-case "$HOST" in
- *darwin*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;; # Required for native packages
- *mingw*) export LIBRARY_PATH="${NATIVE_GCC}/lib" ;;
- *)
- NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)"
- export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib"
- ;;
-esac
+# Required for native packages
+export LIBRARY_PATH="${NATIVE_GCC}/lib"
# Set environment variables to point the CROSS toolchain to the right
# includes/libs for $HOST
@@ -48,19 +42,6 @@ case "$HOST" in
# The CROSS toolchain for darwin uses the SDK and ignores environment variables.
# See depends/hosts/darwin.mk for more details.
;;
- *linux*)
- CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")"
- CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)"
- CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")"
- CROSS_GCC="$(store_path "gcc-cross-${HOST}")"
- CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)"
- CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories...
- CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one)
-
- export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include"
- export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}"
- export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib"
- ;;
*)
exit 1 ;;
esac
@@ -74,41 +55,18 @@ for p in "${PATHS[@]}"; do
fi
done
-# Determine the correct value for -Wl,--dynamic-linker for the current $HOST
-case "$HOST" in
- *linux*)
- glibc_dynamic_linker=$(
- case "$HOST" in
- x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;;
- arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;;
- aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;;
- riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;;
- powerpc64-linux-gnu) echo /lib64/ld64.so.1;;
- powerpc64le-linux-gnu) echo /lib64/ld64.so.2;;
- *) exit 1 ;;
- esac
- )
- ;;
-esac
-
####################
# Depends Building #
####################
-# Build the depends tree, overriding variables that assume multilib gcc
+# Build the depends tree
make -C depends --jobs="$JOBS" HOST="$HOST" \
${V:+V=1} \
${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \
${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \
${SDK_PATH+SDK_PATH="$SDK_PATH"} \
${build_CC+build_CC="$build_CC"} \
- ${build_CXX+build_CXX="$build_CXX"} \
- x86_64_linux_CC=x86_64-linux-gnu-gcc \
- x86_64_linux_CXX=x86_64-linux-gnu-g++ \
- x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \
- x86_64_linux_RANLIB=x86_64-linux-gnu-gcc-ranlib \
- x86_64_linux_NM=x86_64-linux-gnu-gcc-nm \
- x86_64_linux_STRIP=x86_64-linux-gnu-strip
+ ${build_CXX+build_CXX="$build_CXX"}
case "$HOST" in
*darwin*)
@@ -136,21 +94,11 @@ esac
# CXXFLAGS
HOST_CXXFLAGS="$HOST_CFLAGS"
-case "$HOST" in
- arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;;
-esac
-
# LDFLAGS
case "$HOST" in
- *linux*) HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -Wl,-O2" ;;
*mingw*) HOST_LDFLAGS="-Wl,--no-insert-timestamp" ;;
esac
-# EXE FLAGS
-case "$HOST" in
- *linux*) CMAKE_EXE_LINKER_FLAGS="-DCMAKE_EXE_LINKER_FLAGS=${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" ;;
-esac
-
mkdir -p "$DISTSRC"
(
cd "$DISTSRC"
@@ -165,14 +113,11 @@ mkdir -p "$DISTSRC"
--toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \
-DWITH_CCACHE=OFF \
-Werror=dev \
- ${CONFIGFLAGS} \
- ${CMAKE_EXE_LINKER_FLAGS+"$CMAKE_EXE_LINKER_FLAGS"}
+ ${CONFIGFLAGS}
# Build Bitcoin Core
cmake --build build -j "$JOBS"
- mkdir -p "$OUTDIR"
-
# Make the os-specific installers
case "$HOST" in
*mingw*)
@@ -194,13 +139,6 @@ mkdir -p "$DISTSRC"
cmake --install build --prefix "${INSTALLPATH}"
;;
esac
-
- # Perform basic security checks on installed executables.
- echo "Checking binary security on installed executables..."
- python3 "${DISTSRC}/contrib/guix/security-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"*
- # Check that executables only contain allowed version symbols.
- echo "Running symbol and dynamic library checks on installed executables..."
- python3 "${DISTSRC}/contrib/guix/symbol-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"*
) # $DISTSRC
# shellcheck source=package.sh
diff --git a/contrib/guix/libexec/build_linux.sh b/contrib/guix/libexec/build_linux.sh
new file mode 100755
index 00000000..15dc77ab
--- /dev/null
+++ b/contrib/guix/libexec/build_linux.sh
@@ -0,0 +1,98 @@
+#!/usr/bin/env bash
+# Copyright (c) The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or https://opensource.org/license/mit.
+export LC_ALL=C
+set -o errexit -o pipefail
+
+# shellcheck source=setup.sh
+source "$(dirname "${BASH_SOURCE[0]}")/setup.sh"
+
+# Set environment variables to point the NATIVE toolchain to the right
+# includes/libs
+NATIVE_GCC="$(store_path gcc-toolchain)"
+
+# Set native toolchain
+build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include"
+build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include"
+
+NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)"
+export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib"
+
+# Set environment variables to point the CROSS toolchain to the right
+# includes/libs for $HOST
+CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")"
+CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)"
+CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")"
+CROSS_GCC="$(store_path "gcc-cross-${HOST}")"
+CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)"
+CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories...
+CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one)
+
+export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include"
+export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}"
+export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib"
+
+check_cross_paths "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}"
+
+# Build the depends tree, overriding variables that assume multilib gcc
+make -C depends --jobs="$JOBS" HOST="$HOST" \
+ ${V:+V=1} \
+ ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \
+ ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \
+ ${build_CC+build_CC="$build_CC"} \
+ ${build_CXX+build_CXX="$build_CXX"} \
+ x86_64_linux_CC=x86_64-linux-gnu-gcc \
+ x86_64_linux_CXX=x86_64-linux-gnu-g++ \
+ x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \
+ x86_64_linux_RANLIB=x86_64-linux-gnu-gcc-ranlib \
+ x86_64_linux_NM=x86_64-linux-gnu-gcc-nm \
+ x86_64_linux_STRIP=x86_64-linux-gnu-strip \
+ NO_QT=1
+
+# CFLAGS
+HOST_CFLAGS="-O2 -g"
+HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;)
+HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=."
+
+# CXXFLAGS
+HOST_CXXFLAGS="$HOST_CFLAGS"
+
+case "$HOST" in
+ arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;;
+esac
+
+# LDFLAGS
+HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$(glibc_dynamic_linker "$HOST") -Wl,-O2"
+
+mkdir -p "$DISTSRC"
+(
+ cd "$DISTSRC"
+
+ # Extract the source tarball
+ tar --strip-components=1 -xf "${GIT_ARCHIVE}"
+
+ # Configure this DISTSRC for $HOST
+ env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \
+ cmake -S . -B build \
+ --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \
+ -Werror=dev \
+ -DBUILD_BENCH=OFF \
+ -DBUILD_FUZZ_BINARY=OFF \
+ -DBUILD_GUI=OFF \
+ -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \
+ -DCMAKE_SKIP_RPATH=TRUE \
+ -DREDUCE_EXPORTS=ON \
+ -DCMAKE_EXE_LINKER_FLAGS="${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" \
+ -DWITH_CCACHE=OFF
+
+ # Build Bitcoin Core
+ cmake --build build -j "$JOBS"
+
+ # Install built Bitcoin Core
+ cmake --install build
+)
+
+rm -rf "$DISTSRC"/build
+
+exit 0
diff --git a/contrib/guix/libexec/build_linux_gui.sh b/contrib/guix/libexec/build_linux_gui.sh
new file mode 100755
index 00000000..d14dda00
--- /dev/null
+++ b/contrib/guix/libexec/build_linux_gui.sh
@@ -0,0 +1,103 @@
+#!/usr/bin/env bash
+# Copyright (c) The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or https://opensource.org/license/mit.
+export LC_ALL=C
+set -o errexit -o pipefail
+
+# shellcheck source=setup.sh
+source "$(dirname "${BASH_SOURCE[0]}")/setup.sh"
+
+# Set environment variables to point the NATIVE toolchain to the right
+# includes/libs
+NATIVE_GCC="$(store_path gcc-toolchain)"
+
+# Set native toolchain
+build_CC="${NATIVE_GCC}/bin/gcc -isystem ${NATIVE_GCC}/include"
+build_CXX="${NATIVE_GCC}/bin/g++ -isystem ${NATIVE_GCC}/include/c++ -isystem ${NATIVE_GCC}/include"
+
+NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)"
+export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib"
+
+# Set environment variables to point the CROSS toolchain to the right
+# includes/libs for $HOST
+CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")"
+CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)"
+CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")"
+CROSS_GCC="$(store_path "gcc-cross-${HOST}")"
+CROSS_GCC_LIB_STORE="$(store_path "gcc-cross-${HOST}" lib)"
+CROSS_GCC_LIBS=( "${CROSS_GCC_LIB_STORE}/lib/gcc/${HOST}"/* ) # This expands to an array of directories...
+CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one)
+
+export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include"
+export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}"
+export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib"
+
+check_cross_paths "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}"
+
+# Build the depends tree, overriding variables that assume multilib gcc
+make -C depends --jobs="$JOBS" HOST="$HOST" \
+ ${V:+V=1} \
+ ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \
+ ${BASE_CACHE+BASE_CACHE="$BASE_CACHE"} \
+ ${build_CC+build_CC="$build_CC"} \
+ ${build_CXX+build_CXX="$build_CXX"} \
+ x86_64_linux_CC=x86_64-linux-gnu-gcc \
+ x86_64_linux_CXX=x86_64-linux-gnu-g++ \
+ x86_64_linux_AR=x86_64-linux-gnu-gcc-ar \
+ x86_64_linux_RANLIB=x86_64-linux-gnu-gcc-ranlib \
+ x86_64_linux_NM=x86_64-linux-gnu-gcc-nm \
+ x86_64_linux_STRIP=x86_64-linux-gnu-strip
+
+# CFLAGS
+HOST_CFLAGS="-O2 -g"
+HOST_CFLAGS+=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;)
+HOST_CFLAGS+=" -fdebug-prefix-map=${DISTSRC}/src=."
+
+# CXXFLAGS
+HOST_CXXFLAGS="$HOST_CFLAGS"
+
+case "$HOST" in
+ arm-linux-gnueabihf) HOST_CXXFLAGS="${HOST_CXXFLAGS} -Wno-psabi" ;;
+esac
+
+# LDFLAGS
+HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$(glibc_dynamic_linker "$HOST") -Wl,-O2"
+
+mkdir -p "$DISTSRC"
+(
+ cd "$DISTSRC"
+
+ # Extract the source tarball
+ tar --strip-components=1 -xf "${GIT_ARCHIVE}"
+
+ # Configure this DISTSRC for $HOST
+ env CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}" LDFLAGS="${HOST_LDFLAGS}" \
+ cmake -S . -B build \
+ --toolchain "${BASEPREFIX}/${HOST}/toolchain.cmake" \
+ -Werror=dev \
+ -DBUILD_BENCH=OFF \
+ -DBUILD_CLI=OFF \
+ -DBUILD_DAEMON=OFF \
+ -DBUILD_FUZZ_BINARY=OFF \
+ -DBUILD_GUI_TESTS=OFF \
+ -DBUILD_TESTS=OFF \
+ -DBUILD_TX=OFF \
+ -DBUILD_UTIL=OFF \
+ -DBUILD_WALLET_TOOL=OFF \
+ -DCMAKE_EXE_LINKER_FLAGS="${HOST_LDFLAGS} -static-libstdc++ -static-libgcc" \
+ -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \
+ -DCMAKE_SKIP_RPATH=TRUE \
+ -DREDUCE_EXPORTS=ON \
+ -DWITH_CCACHE=OFF
+
+ # Build Bitcoin Core
+ cmake --build build -j "$JOBS" --target bitcoin-gui bitcoin-qt
+
+ # Install built Bitcoin Core
+ cmake --install build --component bitcoin-gui
+ cmake --install build --component bitcoin-qt
+) # $DISTSRC
+
+# shellcheck source=package.sh
+source "$(dirname "${BASH_SOURCE[0]}")/package.sh"
diff --git a/contrib/guix/libexec/package.sh b/contrib/guix/libexec/package.sh
index 7228346a..d91fa634 100755
--- a/contrib/guix/libexec/package.sh
+++ b/contrib/guix/libexec/package.sh
@@ -8,6 +8,13 @@ set -e -o pipefail
(
cd "$DISTSRC"
+ # Perform basic security checks on installed executables.
+ echo "Checking binary security on installed executables..."
+ python3 "${DISTSRC}/contrib/guix/security-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"*
+ # Check that executables only contain allowed version symbols.
+ echo "Running symbol and dynamic library checks on installed executables..."
+ python3 "${DISTSRC}/contrib/guix/symbol-check.py" "${INSTALLPATH}/bin/"* "${INSTALLPATH}/libexec/"*
+
(
cd installed
@@ -32,7 +39,7 @@ set -e -o pipefail
esac
# copy over the example bitcoin.conf file. if contrib/devtools/gen-bitcoin-conf.sh
- # has not been run before buildling, this file will be a stub
+ # has not been run before building, this file will be a stub
cp "${DISTSRC}/share/examples/bitcoin.conf" "${DISTNAME}/"
cp -r "${DISTSRC}/share/rpcauth" "${DISTNAME}/share/"
diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash
index 23852767..994f6c5c 100644
--- a/contrib/guix/libexec/prelude.bash
+++ b/contrib/guix/libexec/prelude.bash
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
export LC_ALL=C
-set -e -o pipefail
+set -o errexit -o pipefail
source contrib/shell/realpath.bash
source contrib/shell/git-utils.bash
diff --git a/contrib/guix/libexec/setup.sh b/contrib/guix/libexec/setup.sh
index 37388f98..e8d70d59 100755
--- a/contrib/guix/libexec/setup.sh
+++ b/contrib/guix/libexec/setup.sh
@@ -3,7 +3,7 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://opensource.org/license/mit.
export LC_ALL=C
-set -e -o pipefail
+set -o errexit -o pipefail
# Environment variables for determinism
export TAR_OPTIONS="--no-same-owner --owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name"
@@ -61,6 +61,31 @@ store_path() {
--expression='s|"[[:space:]]*$||'
}
+# Sanity check CROSS_*_PATH directories
+check_cross_paths() {
+ local p paths
+ IFS=':' read -ra paths <<< "$1"
+ for p in "${paths[@]}"; do
+ if [ -n "$p" ] && [ ! -d "$p" ]; then
+ echo "'$p' doesn't exist or isn't a directory... Aborting..." >&2
+ return 1
+ fi
+ done
+}
+
+# Given a hostname, determine the correct value for -Wl,--dynamic-linker.
+glibc_dynamic_linker() {
+ case "$1" in
+ x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;;
+ arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;;
+ aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;;
+ riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;;
+ powerpc64-linux-gnu) echo /lib64/ld64.so.1 ;;
+ powerpc64le-linux-gnu) echo /lib64/ld64.so.2 ;;
+ *) exit 1 ;;
+ esac
+}
+
# Disable Guix ld auto-rpath behavior
export GUIX_LD_WRAPPER_DISABLE_RPATH=yes
diff --git a/contrib/guix/manifest_build.scm b/contrib/guix/manifest_build.scm
index 576021e6..b9f0dd9e 100644
--- a/contrib/guix/manifest_build.scm
+++ b/contrib/guix/manifest_build.scm
@@ -1,20 +1,14 @@
(use-modules (gnu packages)
((gnu packages bash) #:select (bash-minimal))
- (gnu packages bison)
((gnu packages cmake) #:select (cmake-minimal))
(gnu packages commencement)
- ((gnu packages compression) #:select (gzip xz zip))
+ ((gnu packages compression) #:select (gzip))
(gnu packages cross-base)
- (gnu packages gawk)
(gnu packages gcc)
- ((gnu packages installers) #:select (nsis-x86_64))
((gnu packages linux) #:select (linux-libre-headers-6.1))
(gnu packages llvm)
(gnu packages mingw)
- (gnu packages ninja)
- (gnu packages pkg-config)
((gnu packages python) #:select (python-minimal))
- ((gnu packages python-xyz) #:select (python-lief))
((gnu packages version-control) #:select (git-minimal))
(guix build-system trivial)
(guix download)
@@ -262,40 +256,29 @@ chain for " target " development."))
coreutils-minimal
;; File(system) inspection
grep
- diffutils
findutils
;; File transformation
patch
- gawk
sed
;; Compression and archiving
tar
gzip
- xz
;; Build tools
gcc-toolchain-14
cmake-minimal
gnu-make
- ninja
;; Scripting
python-minimal ;; (3.11)
;; Git
- git-minimal
- ;; Tests
- python-lief)
+ git-minimal)
(let ((target (getenv "HOST")))
(cond ((string-suffix? "-mingw32" target)
- (list (make-mingw-pthreads-cross-toolchain "x86_64-w64-mingw32")
- nsis-x86_64
- zip))
+ (list (make-mingw-pthreads-cross-toolchain "x86_64-w64-mingw32")))
((string-contains target "-linux-")
- (list bison
- pkg-config
- (list gcc-toolchain-14 "static")
+ (list (list gcc-toolchain-14 "static")
(make-bitcoin-cross-toolchain target)))
((string-contains target "darwin")
(list clang-toolchain-19
lld-19
- (make-lld-wrapper lld-19 #:lld-as-ld? #t)
- zip))
+ (make-lld-wrapper lld-19 #:lld-as-ld? #t)))
(else '())))))
diff --git a/contrib/guix/manifest_gui.scm b/contrib/guix/manifest_gui.scm
new file mode 100644
index 00000000..fdb9a32b
--- /dev/null
+++ b/contrib/guix/manifest_gui.scm
@@ -0,0 +1,27 @@
+(use-modules (gnu packages bison)
+ ((gnu packages compression) #:select (xz zip))
+ (gnu packages gawk)
+ ((gnu packages installers) #:select (nsis-x86_64))
+ (gnu packages ninja)
+ (gnu packages pkg-config)
+ ((gnu packages python-xyz) #:select (python-lief)))
+
+(packages->manifest
+ (append
+ (list ;; Compression and archiving
+ xz
+ ;; Build tools
+ ninja
+ ;; Tests
+ python-lief)
+ (let ((target (getenv "HOST")))
+ (cond ((string-suffix? "-mingw32" target)
+ (list zip
+ nsis-x86_64))
+ ((string-contains target "-linux-")
+ (list bison
+ gawk
+ pkg-config))
+ ((string-contains target "darwin")
+ (list zip))
+ (else '())))))
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.