diff --git a/chronik/CMakeLists.txt b/chronik/CMakeLists.txt index 83fd25afc..7614a036e 100644 --- a/chronik/CMakeLists.txt +++ b/chronik/CMakeLists.txt @@ -1,211 +1,212 @@ # Copyright (c) 2022 The Bitcoin developers set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) include(FetchContent) FetchContent_Declare( Corrosion GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git GIT_TAG v0.4.7 ) FetchContent_MakeAvailable(Corrosion) set(REQUIRED_RUST_VERSION "1.76.0") if(Rust_VERSION VERSION_LESS REQUIRED_RUST_VERSION) message(FATAL_ERROR "Minimum required Rust version is " "${REQUIRED_RUST_VERSION}, but found ${Rust_VERSION}. " "Use `rustup update stable` to update.") endif() set(CARGO_BUILD_DIR "${CMAKE_BINARY_DIR}/cargo/build") set_property(DIRECTORY "${CMAKE_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${CARGO_BUILD_DIR}" ) get_property( RUSTC_EXECUTABLE TARGET Rust::Rustc PROPERTY IMPORTED_LOCATION ) get_filename_component(RUST_BIN_DIR ${RUSTC_EXECUTABLE} DIRECTORY) include(DoOrFail) find_program_or_fail(RUSTDOC_EXECUTABLE rustdoc PATHS "${RUST_BIN_DIR}" ) set(CHRONIK_CARGO_FLAGS --locked) if(BUILD_BITCOIN_CHRONIK_PLUGINS) set(CHRONIK_FEATURE_FLAGS --features plugins) endif() function(add_cargo_custom_target TARGET) add_custom_target(${TARGET} COMMAND "${CMAKE_COMMAND}" -E env CARGO_TARGET_DIR="${CARGO_BUILD_DIR}" CARGO_BUILD_RUSTC="$" CARGO_BUILD_RUSTDOC="${RUSTDOC_EXECUTABLE}" "$" ${CHRONIK_CARGO_FLAGS} ${ARGN} WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" ) endfunction() function(add_crate_test_targets CRATE) set(CRATE_TEST_TARGET "check-crate-${CRATE}") add_custom_target("${CRATE_TEST_TARGET}") set(CLIPPY_TARGET "${CRATE_TEST_TARGET}-clippy") add_cargo_custom_target("${CLIPPY_TARGET}" clippy --package "${CRATE}-*" -- -D warnings ) set(TEST_TARGET "${CRATE_TEST_TARGET}-test") add_cargo_custom_target("${TEST_TARGET}" test --package "${CRATE}-*" ) add_dependencies("${CRATE_TEST_TARGET}" "${CLIPPY_TARGET}" "${TEST_TARGET}" ) add_dependencies("check-crates" "${CRATE_TEST_TARGET}" ) endfunction() add_custom_target("check-crates") add_crate_test_targets(abc-rust) add_crate_test_targets(bitcoinsuite) add_crate_test_targets(chronik) # Compile Rust, generates chronik-lib corrosion_import_crate( MANIFEST_PATH "chronik-lib/Cargo.toml" + NO_LINKER_OVERRIDE FLAGS ${CHRONIK_CARGO_FLAGS} ${CHRONIK_FEATURE_FLAGS} ) set(Rust_TRIPLE "${Rust_CARGO_TARGET_ARCH}" "${Rust_CARGO_TARGET_VENDOR}" "${Rust_CARGO_TARGET_OS}" ) if (Rust_CARGO_TARGET_ENV) list(APPEND Rust_TRIPLE "${Rust_CARGO_TARGET_ENV}") endif() list(JOIN Rust_TRIPLE "-" Rust_CARGO_TARGET) # cxx crate generates some source files at this location set(CXXBRIDGE_GENERATED_FOLDER "${CARGO_BUILD_DIR}/${Rust_CARGO_TARGET}/cxxbridge") set(CHRONIK_BRIDGE_GENERATED_CPP_FILES "${CXXBRIDGE_GENERATED_FOLDER}/chronik-bridge/src/ffi.rs.cc") set(CHRONIK_LIB_GENERATED_CPP_FILES "${CXXBRIDGE_GENERATED_FOLDER}/chronik-lib/src/ffi.rs.cc") add_custom_command( OUTPUT ${CHRONIK_BRIDGE_GENERATED_CPP_FILES} ${CHRONIK_LIB_GENERATED_CPP_FILES} COMMAND "${CMAKE_COMMAND}" -E env "echo" "Generating cxx bridge files" DEPENDS $ ) # Chronik-bridge library # Contains all the C++ functions used by Rust, and the code bridging both add_library(chronik-bridge chronik-cpp/chronik_bridge.cpp chronik-cpp/util/hash.cpp ${CHRONIK_BRIDGE_GENERATED_CPP_FILES} ) target_include_directories(chronik-bridge PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}" "${CXXBRIDGE_GENERATED_FOLDER}" ) target_link_libraries(chronik-bridge util leveldb ) # Chronik library # Compiles and links all the Chronik code, and exposes chronik::Start and # chronik::Stop to run the indexer from C++. add_library(chronik chronik-cpp/chronik.cpp chronik-cpp/chronik_validationinterface.cpp ${CHRONIK_LIB_GENERATED_CPP_FILES} ) target_link_libraries(chronik chronik-bridge chronik-lib ) # Plugins require us to link agains libpython if(BUILD_BITCOIN_CHRONIK_PLUGINS) find_package(Python COMPONENTS Interpreter Development) message("Adding Python_LIBRARIES: ${Python_LIBRARIES}") target_link_libraries(chronik ${Python_LIBRARIES}) endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") # mio crate (dependency of tokio) requires winternl.h, found in ntdll find_package(NTDLL REQUIRED) target_link_libraries(chronik NTDLL::ntdll) # rocksdb requires items from rpcdce.h, found in rpcrt4 find_package(RPCRT4 REQUIRED) target_link_libraries(chronik RPCRT4::rpcrt4) endif() # Rocksdb requires "atomic" include(AddCompilerFlags) custom_check_linker_flag(LINKER_HAS_ATOMIC "-latomic") if(LINKER_HAS_ATOMIC) target_link_libraries(chronik atomic) endif() # Add chronik to server target_link_libraries(server chronik # TODO: We need to add the library again, otherwise gcc linking fails. # It's not clear yet why this is the case. chronik-bridge ) # Install the directory containing the proto files. The trailing slash ensures # the directory is not duplicated (see # https://cmake.org/cmake/help/v3.16/command/install.html#installing-directories) set(CHRONIK_PROTO_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/chronik-proto/proto/") set(CHRONIK_PROTO_COMPONENT "chronik-proto") install( DIRECTORY "${CHRONIK_PROTO_DIRECTORY}" DESTINATION "proto" COMPONENT "${CHRONIK_PROTO_COMPONENT}" ) add_custom_target("install-${CHRONIK_PROTO_COMPONENT}" COMMENT "Installing component ${CHRONIK_PROTO_COMPONENT}" COMMAND "${CMAKE_COMMAND}" -E env CMAKE_INSTALL_ALWAYS=ON "${CMAKE_COMMAND}" -DCOMPONENT="${CHRONIK_PROTO_COMPONENT}" -DCMAKE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}" -P cmake_install.cmake WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" ) diff --git a/contrib/guix/guix-build b/contrib/guix/guix-build index a97e3eb4a..d2ba69432 100755 --- a/contrib/guix/guix-build +++ b/contrib/guix/guix-build @@ -1,457 +1,459 @@ #!/usr/bin/env bash export LC_ALL=C set -e -o pipefail # Source the common prelude, which: # 1. Checks if we're at the top directory of the Bitcoin ABC repository # 2. Defines a few common functions and variables # # shellcheck source=libexec/prelude.bash source "$(dirname "${BASH_SOURCE[0]}")/libexec/prelude.bash" ################### ## SANITY CHECKS ## ################### ################ # Required non-builtin commands should be invocable ################ check_tools cat mkdir make getent curl git guix ################ # GUIX_BUILD_OPTIONS should be empty ################ # # GUIX_BUILD_OPTIONS is an environment variable recognized by guix commands that # can perform builds. This seems like what we want instead of # ADDITIONAL_GUIX_COMMON_FLAGS, but the value of GUIX_BUILD_OPTIONS is actually # _appended_ to normal command-line options. Meaning that they will take # precedence over the command-specific ADDITIONAL_GUIX__FLAGS. # # This seems like a poor user experience. Thus we check for GUIX_BUILD_OPTIONS's # existence here and direct users of this script to use our (more flexible) # custom environment variables. if [ -n "$GUIX_BUILD_OPTIONS" ]; then cat << EOF Error: Environment variable GUIX_BUILD_OPTIONS is not empty: '$GUIX_BUILD_OPTIONS' Unfortunately this script is incompatible with GUIX_BUILD_OPTIONS, please unset GUIX_BUILD_OPTIONS and use ADDITIONAL_GUIX_COMMON_FLAGS to set build options across guix commands or ADDITIONAL_GUIX__FLAGS to set build options for a specific guix command. See contrib/guix/README.md for more details. EOF exit 1 fi ################ # The git worktree should not be dirty ################ if ! git diff-index --quiet HEAD -- && [ -z "$FORCE_DIRTY_WORKTREE" ]; then cat << EOF ERR: The current git worktree is dirty, which may lead to broken builds. Aborting... Hint: To make your git worktree clean, You may want to: 1. Commit your changes, 2. Stash your changes, or 3. Set the 'FORCE_DIRTY_WORKTREE' environment variable if you insist on using a dirty worktree EOF exit 1 fi ################ # Build directories should not exist ################ # Default to building for all supported HOSTs (overridable by environment) # TODO: support x86_64-apple-darwin, arm64-apple-darwin, export HOSTS="${HOSTS:-x86_64-linux-gnu x86_64-w64-mingw32 arm-linux-gnueabihf aarch64-linux-gnu}" # Usage: distsrc_for_host HOST # # HOST: The current platform triple we're building for # distsrc_for_host() { echo "distsrc-${VERSION}-${1}" } # Accumulate a list of build directories that already exist... hosts_distsrc_exists="" for host in $HOSTS; do if [ -e "$(distsrc_for_host "$host")" ]; then hosts_distsrc_exists+=" ${host}" fi done if [ -n "$hosts_distsrc_exists" ]; then # ...so that we can print them out nicely in an error message cat << EOF ERR: Build directories already exist for the following platform triples you're attempting to build, probably because of previous builds. Please remove, or otherwise deal with them prior to starting another build. Aborting... Hint: To blow everything away, you may want to use: $ ./contrib/guix/guix-clean Specifically, this will remove all files without an entry in the index, excluding the SDK directory, the depends download cache, the depends built packages cache, the garbage collector roots for Guix environments, and the output directory. EOF for host in $hosts_distsrc_exists; do echo " ${host} '$(distsrc_for_host "$host")'" done exit 1 fi ################ # When building for darwin, the macOS SDK should exist ################ for host in $HOSTS; do case "$host" in *darwin*) OSX_SDK="$(make -C "${PWD}/depends" --no-print-directory HOST="$host" print-OSX_SDK | sed 's@^[^=]\+=@@g')" if [ -e "$OSX_SDK" ]; then echo "Found macOS SDK at '${OSX_SDK}', using..." break else echo "macOS SDK does not exist at '${OSX_SDK}', please place the extracted, untarred SDK there to perform darwin builds, or define SDK_PATH environment variable. Exiting..." exit 1 fi ;; esac done ################ # current disk should have enough space ################ avail_KiB="$(df -Pk . | sed 1d | tr -s ' ' | cut -d' ' -f4)" total_required_KiB=0 for host in $HOSTS; do case "$host" in *darwin*) required_KiB=440000 ;; *mingw*) required_KiB=7600000 ;; *) required_KiB=6400000 ;; esac total_required_KiB=$((total_required_KiB+required_KiB)) done if (( total_required_KiB > avail_KiB )); then total_required_GiB=$((total_required_KiB / 1048576)) avail_GiB=$((avail_KiB / 1048576)) echo "Performing a Bitcoin ABC Guix build for the selected HOSTS requires ${total_required_GiB} GiB, however, only ${avail_GiB} GiB is available. Please free up some disk space before performing the build." exit 1 fi ################ # Check that we can connect to the guix-daemon ################ cat << EOF Checking that we can connect to the guix-daemon... Hint: If this hangs, you may want to try turning your guix-daemon off and on again. EOF if ! guix gc --list-failures > /dev/null; then cat << EOF ERR: Failed to connect to the guix-daemon, please ensure that one is running and reachable. EOF exit 1 fi # Developer note: we could use `guix repl` for this check and run: # # (import (guix store)) (close-connection (open-connection)) # # However, the internal API is likely to change more than the CLI invocation ################ # Services database must have basic entries ################ if ! getent services http https ftp > /dev/null 2>&1; then cat << EOF ERR: Your system's C library cannot find service database entries for at least one of the following services: http, https, ftp. Hint: Most likely, /etc/services does not exist yet (common for docker images and minimal distros), or you don't have permissions to access it. If /etc/services does not exist yet, you may want to install the appropriate package for your distro which provides it. On Debian/Ubuntu: netbase On Arch Linux: iana-etc For more information, see: getent(1), services(5) EOF fi ######### # SETUP # ######### # Determine the maximum number of jobs to run simultaneously (overridable by # environment) JOBS="${JOBS:-$(nproc)}" # Usage: host_to_commonname HOST # # HOST: The current platform triple we're building for # host_to_commonname() { case "$1" in *darwin*) echo osx ;; *mingw*) echo win ;; *linux*) echo linux ;; *) exit 1 ;; esac } # Determine the reference time used for determinism (overridable by environment) SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git -c log.showSignature=false log --format=%at -1)}" # Precious directories are those which should not be cleaned between successive # guix builds depends_precious_dir_names='SOURCES_PATH BASE_CACHE SDK_PATH' precious_dir_names="${depends_precious_dir_names} OUTDIR_BASE PROFILES_BASE" # Usage: contains IFS-SEPARATED-LIST ITEM contains() { for i in ${1}; do if [ "$i" = "${2}" ]; then return 0 # Found! fi done return 1 } # If the user explicitly specified a precious directory, create it so we # can map it into the container for precious_dir_name in $precious_dir_names; do precious_dir_path="${!precious_dir_name}" if [ -n "$precious_dir_path" ]; then if [ ! -e "$precious_dir_path" ]; then mkdir -p "$precious_dir_path" elif [ -L "$precious_dir_path" ]; then echo "ERR: ${precious_dir_name} cannot be a symbolic link" exit 1 elif [ ! -d "$precious_dir_path" ]; then echo "ERR: ${precious_dir_name} must be a directory" exit 1 fi fi done mkdir -p "$VAR_BASE" # Record the _effective_ values of precious directories such that guix-clean can # avoid clobbering them if appropriate. # # shellcheck disable=SC2046,SC2086 { # Get depends precious dir definitions from depends make -C "${PWD}/depends" \ --no-print-directory \ -- $(printf "print-%s\n" $depends_precious_dir_names) # Get remaining precious dir definitions from the environment for precious_dir_name in $precious_dir_names; do precious_dir_path="${!precious_dir_name}" if ! contains "$depends_precious_dir_names" "$precious_dir_name"; then echo "${precious_dir_name}=${precious_dir_path}" fi done } > "${VAR_BASE}/precious_dirs" # Make sure an output directory exists for our builds OUTDIR_BASE="${OUTDIR_BASE:output}" mkdir -p "$OUTDIR_BASE" # Download the depends sources now as we won't have internet access in the build # container for host in $HOSTS; do make -C "${PWD}/depends" -j"$JOBS" download-"$(host_to_commonname "$host")" ${V:+V=1} ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} done # Usage: outdir_for_host HOST SUFFIX # # HOST: The current platform triple we're building for # outdir_for_host() { echo "${OUTDIR_BASE}/${1}${2:+-${2}}" } # Usage: profiledir_for_host HOST SUFFIX # # HOST: The current platform triple we're building for # profiledir_for_host() { echo "${PROFILES_BASE}/${1}${2:+-${2}}" } ######### # BUILD # ######### # Function to be called when building for host ${1} and the user interrupts the # build int_trap() { cat << EOF ** INT received while building ${1}, you may want to clean up the relevant work directories (e.g. distsrc-*) before rebuilding Hint: To blow everything away, you may want to use: $ ./contrib/guix/guix-clean Specifically, this will remove all files without an entry in the index, excluding the SDK directory, the depends download cache, the depends built packages cache, the garbage collector roots for Guix environments, and the output directory. EOF } # Deterministically build Bitcoin ABC # shellcheck disable=SC2153 for host in $HOSTS; do # Display proper warning when the user interrupts the build trap 'int_trap ${host}' INT ( # Required for 'contrib/guix/manifest.scm' to output the right manifest # for the particular $HOST we're building for export HOST="$host" # shellcheck disable=SC2030 cat << EOF INFO: Building ${VERSION:?not set} for platform triple ${HOST:?not set}: ...using reference timestamp: ${SOURCE_DATE_EPOCH:?not set} ...running at most ${JOBS:?not set} jobs ...from worktree directory: '${PWD}' ...bind-mounted in container to: '/bitcoin' ...in build directory: '$(distsrc_for_host "$HOST")' ...bind-mounted in container to: /bitcoin/$(distsrc_for_host "$HOST") ...outputting in: '$(outdir_for_host "$HOST")' ...bind-mounted in container to: '$(OUTDIR_BASE=/outdir-base && outdir_for_host "$HOST")' EOF # Run the build script 'contrib/guix/libexec/build.sh' in the build # container specified by 'contrib/guix/manifest.scm'. # # Explanation of `guix shell` flags: # # --container run command within an isolated container # # Running in an isolated container minimizes build-time differences # between machines and improves reproducibility # # --pure unset existing environment variables # # Same rationale as --container # # --no-cwd do not share current working directory with an # isolated container # # When --container is specified, the default behavior is to share # the current working directory with the isolated container at the # same exact path (e.g. mapping '/home/satoshi/bitcoin/' to # '/home/satoshi/bitcoin/'). This means that the $PWD inside the # container becomes a source of irreproducibility. --no-cwd disables # this behaviour. # # --share=SPEC for containers, share writable host file system # according to SPEC # # --share="$PWD"=/bitcoin # # maps our current working directory to /bitcoin # inside the isolated container, which we later cd # into. # # While we don't want to map our current working directory to the # same exact path (as this introduces irreproducibility), we do want # it to be at a _fixed_ path _somewhere_ inside the isolated # container so that we have something to build. '/bitcoin' was # chosen arbitrarily. # # ${SOURCES_PATH:+--share="$SOURCES_PATH"} # # make the downloaded depends sources path available # inside the isolated container # # The isolated container has no network access as it's in a # different network namespace from the main machine, so we have to # make the downloaded depends sources available to it. The sources # should have been downloaded prior to this invocation. # # --keep-failed keep build tree of failed builds # # When builds of the Guix environment itself (not Bitcoin ABC) # fail, it is useful for the build tree to be kept for debugging # purposes. # # ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} # # fetch substitute from SUBSTITUTE_URLS if they are # authorized # # Depending on the user's security model, it may be desirable to use # 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,SC2031 time-machine shell --manifest="${PWD}/contrib/guix/manifest.scm" \ --container \ --pure \ + --network \ + --emulate-fhs \ --no-cwd \ --share="$PWD"=/bitcoin \ --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")" \ OUTDIR="$(OUTDIR_BASE=/outdir-base && outdir_for_host "$HOST")" \ DIST_ARCHIVE_BASE=/outdir-base/dist-archive \ bash -c "cd /bitcoin && bash contrib/guix/libexec/build.sh" ) done diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index f18f86df2..9f1aab156 100755 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -1,342 +1,363 @@ #!/usr/bin/env bash # Copyright (c) 2019-2023 The Bitcoin developers # 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 export TZ=UTC # Although Guix _does_ set umask when building its own packages (in our case, # this is all packages in manifest.scm), it does not set it for `guix # shell`. It does make sense for at least `guix shell --container` # to set umask, so if that change gets merged upstream and we bump the # time-machine to a commit which includes the aforementioned change, we can # remove this line. # # This line should be placed before any commands which creates files. umask 0022 if [ -n "$V" ]; then # Print both unexpanded (-v) and expanded (-x) forms of commands as they are # read from this file. set -vx # Set VERBOSE for CMake-based builds export VERBOSE="$V" fi # Check that required environment variables are set cat << EOF Required environment variables as seen inside the container: DIST_ARCHIVE_BASE: ${DIST_ARCHIVE_BASE:?not set} DISTNAME: ${DISTNAME:?not set} HOST: ${HOST:?not set} SOURCE_DATE_EPOCH: ${SOURCE_DATE_EPOCH:?not set} JOBS: ${JOBS:?not set} DISTSRC: ${DISTSRC:?not set} OUTDIR: ${OUTDIR:?not set} EOF ACTUAL_OUTDIR="${OUTDIR}" OUTDIR="${DISTSRC}/output" ##################### # Environment Setup # ##################### # The depends folder also serves as a base-prefix for depends packages for # $HOSTs after successfully building. BASEPREFIX="${PWD}/depends" # Given a package name and an output name, return the path of that output in our # current guix environment store_path() { grep --extended-regexp "/[^-]{32}-${1}-[^-]+${2:+-${2}}" "${GUIX_ENVIRONMENT}/manifest" \ | head --lines=1 \ | sed --expression='s|\x29*$||' \ --expression='s|^[[:space:]]*"||' \ --expression='s|"[[:space:]]*$||' } # Set environment variables to point the NATIVE toolchain to the right # includes/libs NATIVE_GCC="$(store_path gcc-toolchain)" NATIVE_GCC_STATIC="$(store_path gcc-toolchain static)" +NATIVE_GCC_LIBS="$(store_path gcc lib)" unset LIBRARY_PATH unset CPATH unset C_INCLUDE_PATH unset CPLUS_INCLUDE_PATH unset OBJC_INCLUDE_PATH unset OBJCPLUS_INCLUDE_PATH -export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib" +export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC_STATIC}/lib:${NATIVE_GCC_LIBS}/lib" export C_INCLUDE_PATH="${NATIVE_GCC}/include" export CPLUS_INCLUDE_PATH="${NATIVE_GCC}/include/c++:${NATIVE_GCC}/include" export OBJC_INCLUDE_PATH="${NATIVE_GCC}/include" export OBJCPLUS_INCLUDE_PATH="${NATIVE_GCC}/include/c++:${NATIVE_GCC}/include" # Set environment variables to point the CROSS toolchain to the right # includes/libs for $HOST case "$HOST" in *mingw*) # Determine output paths to use in CROSS_* environment variables CROSS_GLIBC="$(store_path "mingw-w64-x86_64-winpthreads")" CROSS_GCC_ROOT="$(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) # The search path ordering is generally: # 1. gcc-related search paths # 2. libc-related search paths # 2. kernel-header-related search paths (not applicable to mingw-w64 hosts) export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include" export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC_ROOT}/include/c++:${CROSS_GCC_ROOT}/include/c++/${HOST}:${CROSS_GCC_ROOT}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" export CROSS_LIBRARY_PATH="${CROSS_GCC_LIB_STORE}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib" ;; *darwin*) # 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_ROOT="$(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_CC="${CROSS_GCC_ROOT}/bin/${HOST}-gcc" export CROSS_CXX="${CROSS_GCC_ROOT}/bin/${HOST}-g++" 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_ROOT}/include/c++:${CROSS_GCC_ROOT}/include/c++/${HOST}:${CROSS_GCC_ROOT}/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 # Sanity check CROSS_(CC|CXX) for compiler in "${CROSS_CC}" "${CROSS_CXX}"; do if [ -n "${compiler}" ] && [ ! -f "${compiler}" ]; then echo "'${compiler}' doesn't exist... Aborting..." exit 1 fi done # Sanity check CROSS_*_PATH directories IFS=':' read -ra PATHS <<< "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" for p in "${PATHS[@]}"; do if [ -n "$p" ] && [ ! -d "$p" ]; then echo "'$p' doesn't exist or isn't a directory... Aborting..." exit 1 fi done # Disable Guix ld auto-rpath behavior case "$HOST" in *darwin*) # The auto-rpath behavior is necessary for darwin builds as some native # tools built by depends refer to and depend on Guix-built native # libraries # # After the native packages in depends are built, the ld wrapper should # no longer affect our build, as clang would instead reach for # x86_64-apple-darwin-ld from cctools ;; *) export GUIX_LD_WRAPPER_DISABLE_RPATH=yes ;; esac # Make /usr/bin if it doesn't exist [ -e /usr/bin ] || mkdir -p /usr/bin # Symlink file and env to a conventional path [ -e /usr/bin/file ] || ln -s --no-dereference "$(command -v file)" /usr/bin/file [ -e /usr/bin/env ] || ln -s --no-dereference "$(command -v env)" /usr/bin/env # 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 ;; *) exit 1 ;; esac ) ;; esac # Environment variables for determinism export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" export TZ="UTC" case "$HOST" in *darwin*) # cctools AR, unlike GNU binutils AR, does not have a deterministic mode # or a configure flag to enable determinism by default, it only # understands if this env-var is set or not. See: # # https://github.com/tpoechtrager/cctools-port/blob/55562e4073dea0fbfd0b20e0bf69ffe6390c7f97/cctools/ar/archive.c#L334 export ZERO_AR_DATE=yes ;; esac #################### # Depends Building # #################### # 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"} \ ${SDK_PATH+SDK_PATH="$SDK_PATH"} \ 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 \ FORCE_USE_SYSTEM_CLANG=1 ########################### # Source Tarball Building # ########################### # Toolchain case "$HOST" in *mingw*) CMAKE_TOOLCHAIN_FILE="/bitcoin/cmake/platforms/Win64.cmake" + RUST_TARGET="x86_64-pc-windows-gnu" ;; aarch64-linux-gnu) CMAKE_TOOLCHAIN_FILE="/bitcoin/cmake/platforms/LinuxAArch64.cmake" + RUST_TARGET="aarch64-unknown-linux-gnu" ;; arm-linux-gnueabihf) CMAKE_TOOLCHAIN_FILE="/bitcoin/cmake/platforms/LinuxARM.cmake" + RUST_TARGET="arm-unknown-linux-gnueabihf" ;; x86_64-linux-gnu) CMAKE_TOOLCHAIN_FILE="/bitcoin/cmake/platforms/Linux64.cmake" + RUST_TARGET="x86_64-unknown-linux-gnu" ;; *darwin*) CMAKE_TOOLCHAIN_FILE="/bitcoin/cmake/platforms/OSX.cmake" + RUST_TARGET="x86_64-apple-darwin" ;; esac +curl -sSf https://static.rust-lang.org/rustup/archive/1.26.0/x86_64-unknown-linux-gnu/rustup-init -o rustup-init +echo "0b2f6c8f85a3d02fde2efc0ced4657869d73fccfce59defb4e8d29233116e6db rustup-init" | sha256sum -c +chmod +x rustup-init +./rustup-init -y --default-toolchain=1.76.0 +# shellcheck disable=SC1091 +source "$HOME/.cargo/env" +rustup target add "${RUST_TARGET}" + mkdir -p source_package pushd source_package rm -f CMakeCache.txt cmake -GNinja .. \ -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} \ -DBUILD_BITCOIN_WALLET=OFF \ -DBUILD_BITCOIN_CHRONIK=OFF \ -DBUILD_BITCOIN_QT=OFF \ -DBUILD_BITCOIN_ZMQ=OFF \ -DENABLE_QRCODE=OFF \ -DENABLE_NATPMP=OFF \ -DENABLE_UPNP=OFF \ -DUSE_JEMALLOC=OFF \ -DENABLE_CLANG_TIDY=OFF \ -DENABLE_BIP70=OFF \ -DUSE_LINKER= ninja package_source SOURCEDIST=$(echo bitcoin-abc-*.tar.gz) mv ${SOURCEDIST} .. popd rm -rf source_package DISTNAME=${SOURCEDIST//.tar.*/} mkdir -p "$OUTDIR" OUTDIR=$(realpath "${OUTDIR}") ########################### # Binary Tarball Building # ########################### # CFLAGS HOST_CFLAGS=$(find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) case "$HOST" in *linux*) HOST_CFLAGS+=" -ffile-prefix-map=${PWD}=." ;; *mingw*) HOST_CFLAGS+=" -fno-ident" ;; *darwin*) unset HOST_CFLAGS ;; 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" ;; *mingw*) HOST_LDFLAGS="-Wl,--no-insert-timestamp" ;; esac # CMake flags case "$HOST" in *mingw*) CMAKE_EXTRA_OPTIONS=(-DBUILD_BITCOIN_SEEDER=OFF -DCPACK_PACKAGE_FILE_NAME="${DISTNAME}-win64-setup-unsigned") ;; *linux*) - CMAKE_EXTRA_OPTIONS=(-DENABLE_STATIC_LIBSTDCXX=ON -DENABLE_GLIBC_BACK_COMPAT=ON -DUSE_LINKER=) + CMAKE_EXTRA_OPTIONS=(-DENABLE_STATIC_LIBSTDCXX=ON -DENABLE_GLIBC_BACK_COMPAT=ON -DBUILD_BITCOIN_CHRONIK=ON -DUSE_LINKER=) ;; *darwin*) CMAKE_EXTRA_OPTIONS=(-DGENISOIMAGE_EXECUTABLE="${WRAP_DIR}/genisoimage") ;; esac # Make $HOST-specific native binaries from depends available in $PATH export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" mkdir -p "$DISTSRC" ( cd "$DISTSRC" # Setup the directory where our Bitcoin ABC build for HOST will be # installed. This directory will also later serve as the input for our # binary tarballs. INSTALLPATH=$(pwd)/installed/${DISTNAME} mkdir -p "${INSTALLPATH}" - + # Needed for rustup, cargo and rustc + export LD_LIBRARY_PATH="${LIBRARY_PATH}" + # rocksdb-sys uses libclang to parse the headers but it doesn't know what + # the host arch is. As a consequence it fails to parse gnu/stubs.h if the + # multilib headers are not installed because it falls back to the 32 bits + # variant gnu/stubs-32.h that guix don't provide. + # Instead we can instruct clang to use the correct arch. + export BINDGEN_EXTRA_CLANG_ARGS="-D__x86_64__ -D__LP64__ -U__ILP32__" cmake -GNinja .. \ -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} \ -DCLIENT_VERSION_IS_RELEASE=ON \ -DENABLE_CLANG_TIDY=OFF \ -DENABLE_REDUCE_EXPORTS=ON \ -DCMAKE_INSTALL_PREFIX="${INSTALLPATH}" \ -DCCACHE=OFF \ -DCMAKE_C_FLAGS="${HOST_CFLAGS}" \ -DCMAKE_CXX_FLAGS="${HOST_CXXFLAGS}" \ -DCMAKE_EXE_LINKER_FLAGS="${HOST_LDFLAGS}" \ "${CMAKE_EXTRA_OPTIONS[@]}" # Build Bitcoin ABC ninja ninja security-check ninja symbol-check ninja install-debug cd installed find ${DISTNAME} -not -name "*.dbg" | sort | tar --mtime=@${SOURCE_DATE_EPOCH} --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${HOST}.tar.gz find ${DISTNAME} -name "*.dbg" | sort | tar --mtime=@${SOURCE_DATE_EPOCH} --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${HOST}-debug.tar.gz ) # $DISTSRC rm -rf "$ACTUAL_OUTDIR" mv --no-target-directory "$OUTDIR" "$ACTUAL_OUTDIR" \ || ( rm -rf "$ACTUAL_OUTDIR" && exit 1 ) mv ${SOURCEDIST} "$ACTUAL_OUTDIR" ( cd /outdir-base find "$ACTUAL_OUTDIR" -type f -print0 \ | xargs -0 realpath --relative-base="$PWD" \ | xargs sha256sum \ | sort -k2 \ | sponge "$ACTUAL_OUTDIR"/SHA256SUMS.part ) diff --git a/contrib/guix/libexec/prelude.bash b/contrib/guix/libexec/prelude.bash index c2cced156..da6a5f18a 100644 --- a/contrib/guix/libexec/prelude.bash +++ b/contrib/guix/libexec/prelude.bash @@ -1,78 +1,78 @@ #!/usr/bin/env bash export LC_ALL=C set -e -o pipefail # shellcheck source=contrib/shell/realpath.bash source contrib/shell/realpath.bash # shellcheck source=contrib/shell/git-utils.bash source contrib/shell/git-utils.bash ################ # Required non-builtin commands should be invocable ################ check_tools() { for cmd in "$@"; do if ! command -v "$cmd" > /dev/null 2>&1; then echo "ERR: This script requires that '$cmd' is installed and available in your \$PATH" exit 1 fi done } check_tools cat env readlink dirname basename git ################ # We should be at the top directory of the repository ################ same_dir() { local resolved1 resolved2 resolved1="$(bash_realpath "${1}")" resolved2="$(bash_realpath "${2}")" [ "$resolved1" = "$resolved2" ] } if ! same_dir "${PWD}" "$(git_root)"; then cat << EOF ERR: This script must be invoked from the top level of the git repository Hint: This may look something like: env FOO=BAR ./contrib/guix/guix- EOF exit 1 fi ################ # Execute "$@" in a pinned, possibly older version of Guix, for reproducibility # across time. time-machine() { # shellcheck disable=SC2086 guix time-machine --url=https://git.savannah.gnu.org/git/guix.git \ - --commit=160f78a4d92205df986ed9efcce7d3aac188cb24 \ + --commit=afdcba78558bd7a33f517716e69bb9494297064d \ --cores="$JOBS" \ --keep-failed \ --fallback \ ${SUBSTITUTE_URLS:+--substitute-urls="$SUBSTITUTE_URLS"} \ ${ADDITIONAL_GUIX_COMMON_FLAGS} ${ADDITIONAL_GUIX_TIMEMACHINE_FLAGS} \ -- "$@" } ################ # Set common variables ################ VERSION="${FORCE_VERSION:-$(git_head_version)}" DISTNAME="${DISTNAME:-bitcoin-${VERSION}}" out_base_basename="output" OUTDIR_BASE="${OUTDIR_BASE:-${out_base_basename}}" var_base_basename="var" VAR_BASE="${VAR_BASE:-${var_base_basename}}" profiles_base_basename="profiles" PROFILES_BASE="${PROFILES_BASE:-${VAR_BASE}/${profiles_base_basename}}" diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 718567d66..4737d54b4 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -1,615 +1,621 @@ (use-modules (gnu packages) (gnu packages autotools) ((gnu packages bash) #:select (bash-minimal)) (gnu packages bison) ((gnu packages certs) #:select (nss-certs)) ((gnu packages cdrom) #:select (xorriso)) ((gnu packages cmake) #:select (cmake-minimal)) (gnu packages commencement) (gnu packages compression) (gnu packages cross-base) + (gnu packages curl) (gnu packages file) (gnu packages gawk) (gnu packages gcc) (gnu packages gperf) ((gnu packages installers) #:select (nsis-x86_64)) ((gnu packages linux) #:select (linux-libre-headers-5.15 util-linux)) (gnu packages llvm) (gnu packages mingw) (gnu packages moreutils) (gnu packages ninja) (gnu packages perl) (gnu packages pkg-config) ((gnu packages python) #:select (python-minimal)) ((gnu packages python-build) #:select (python-tomli)) ((gnu packages python-crypto) #:select (python-asn1crypto)) ((gnu packages python-web) #:select (python-requests)) ((gnu packages tls) #:select (openssl)) ((gnu packages version-control) #:select (git-minimal)) (guix build-system cmake) (guix build-system gnu) (guix build-system python) (guix build-system trivial) (guix gexp) (guix git-download) ((guix licenses) #:prefix license:) (guix packages) ((guix utils) #:select (substitute-keyword-arguments))) (define-syntax-rule (search-our-patches file-name ...) "Return the list of absolute file names corresponding to each FILE-NAME found in ./patches relative to the current file." (parameterize ((%patch-path (list (string-append (dirname (current-filename)) "/patches")))) (list (search-patch file-name) ...))) (define building-on (string-append "--build=" (list-ref (string-split (%current-system) #\-) 0) "-guix-linux-gnu")) (define (make-cross-toolchain target base-gcc-for-libc base-kernel-headers base-libc base-gcc) "Create a cross-compilation toolchain package for TARGET" (let* ((xbinutils (cross-binutils target)) ;; 1. Build a cross-compiling gcc without targeting any libc, derived ;; from BASE-GCC-FOR-LIBC (xgcc-sans-libc (cross-gcc target #:xgcc base-gcc-for-libc #:xbinutils xbinutils)) ;; 2. Build cross-compiled kernel headers with XGCC-SANS-LIBC, derived ;; from BASE-KERNEL-HEADERS (xkernel (cross-kernel-headers target #:linux-headers base-kernel-headers #:xgcc xgcc-sans-libc #:xbinutils xbinutils)) ;; 3. Build a cross-compiled libc with XGCC-SANS-LIBC and XKERNEL, ;; derived from BASE-LIBC (xlibc (cross-libc target #:libc base-libc #:xgcc xgcc-sans-libc #:xbinutils xbinutils #:xheaders xkernel)) ;; 4. Build a cross-compiling gcc targeting XLIBC, derived from ;; BASE-GCC (xgcc (cross-gcc target #:xgcc base-gcc #:xbinutils xbinutils #:libc xlibc))) ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and ;; XGCC (package (name (string-append target "-toolchain")) (version (package-version xgcc)) (source #f) (build-system trivial-build-system) (arguments '(#:builder (begin (mkdir %output) #t))) (propagated-inputs `(("binutils" ,xbinutils) ("libc" ,xlibc) ("libc:static" ,xlibc "static") ("gcc" ,xgcc) ("gcc-lib" ,xgcc "lib"))) (synopsis (string-append "Complete GCC tool chain for " target)) (description (string-append "This package provides a complete GCC tool chain for " target " development.")) (home-page (package-home-page xgcc)) (license (package-license xgcc))))) (define base-gcc gcc-10) (define base-linux-kernel-headers linux-libre-headers-5.15) (define* (make-bitcoin-cross-toolchain target #:key (base-gcc-for-libc linux-base-gcc) (base-kernel-headers base-linux-kernel-headers) (base-libc glibc-2.28) (base-gcc linux-base-gcc)) "Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values desirable for building Bitcoin ABC release binaries." (make-cross-toolchain target base-gcc-for-libc base-kernel-headers base-libc base-gcc)) (define (gcc-mingw-patches gcc) (package-with-extra-patches gcc (search-our-patches "gcc-remap-guix-store.patch" "vmov-alignment.patch"))) (define (make-mingw-pthreads-cross-toolchain target) "Create a cross-compilation toolchain package for TARGET" (let* ((xbinutils (cross-binutils target)) (pthreads-xlibc mingw-w64-x86_64-winpthreads) (pthreads-xgcc (cross-gcc target #:xgcc (gcc-mingw-patches mingw-w64-base-gcc) #:xbinutils xbinutils #:libc pthreads-xlibc))) ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and ;; XGCC (package (name (string-append target "-posix-toolchain")) (version (package-version pthreads-xgcc)) (source #f) (build-system trivial-build-system) (arguments '(#:builder (begin (mkdir %output) #t))) (propagated-inputs `(("binutils" ,xbinutils) ("libc" ,pthreads-xlibc) ("gcc" ,pthreads-xgcc) ("gcc-lib" ,pthreads-xgcc "lib"))) (synopsis (string-append "Complete GCC tool chain for " target)) (description (string-append "This package provides a complete GCC tool chain for " target " development.")) (home-page (package-home-page pthreads-xgcc)) (license (package-license pthreads-xgcc))))) ;; While LIEF is packaged in Guix, we maintain our own package, ;; to simplify building, and more easily apply updates. ;; Moreover, the Guix's package uses cmake, which caused build ;; failure; see https://github.com/bitcoin/bitcoin/pull/27296. (define-public python-lief (package (name "python-lief") (version "0.13.2") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/lief-project/LIEF") (commit version))) (file-name (git-file-name name version)) (modules '((guix build utils))) (snippet '(begin ;; Configure build for Python bindings. (substitute* "api/python/config-default.toml" (("(ninja = )true" all m) (string-append m "false")) (("(parallel-jobs = )0" all m) (string-append m (number->string (parallel-job-count))))))) (sha256 (base32 "0y48x358ppig5xp97ahcphfipx7cg9chldj2q5zrmn610fmi4zll")))) (build-system python-build-system) (native-inputs (list cmake-minimal python-tomli)) (arguments (list #:tests? #f ;needs network #:phases #~(modify-phases %standard-phases (add-before 'build 'change-directory (lambda _ (chdir "api/python"))) (replace 'build (lambda _ (invoke "python" "setup.py" "build")))))) (home-page "https://github.com/lief-project/LIEF") (synopsis "Library to instrument executable formats") (description "@code{python-lief} is a cross platform library which can parse, modify and abstract ELF, PE and MachO formats.") (license license:asl2.0))) (define osslsigncode (package (name "osslsigncode") (version "2.5") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/mtrojnar/osslsigncode") (commit version))) (sha256 (base32 "1j47vwq4caxfv0xw68kw5yh00qcpbd56d7rq6c483ma3y7s96yyz")))) (build-system cmake-build-system) (inputs `(("openssl", openssl))) (home-page "https://github.com/mtrojnar/osslsigncode") (synopsis "Authenticode signing and timestamping tool") (description "osslsigncode is a small tool that implements part of the functionality of the Microsoft tool signtool.exe - more exactly the Authenticode signing and timestamping. But osslsigncode is based on OpenSSL and cURL, and thus should be able to compile on most platforms where these exist.") (license license:gpl3+))) ; license is with openssl exception (define-public python-elfesteem (let ((commit "2eb1e5384ff7a220fd1afacd4a0170acff54fe56")) (package (name "python-elfesteem") (version (git-version "0.1" "1" commit)) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/LRGH/elfesteem") (commit commit))) (file-name (git-file-name name commit)) (sha256 (base32 "07x6p8clh11z8s1n2kdxrqwqm2almgc5qpkcr9ckb6y5ivjdr5r6")))) (build-system python-build-system) ;; There are no tests, but attempting to run python setup.py test leads to ;; PYTHONPATH problems, just disable the test (arguments '(#:tests? #f)) (home-page "https://github.com/LRGH/elfesteem") (synopsis "ELF/PE/Mach-O parsing library") (description "elfesteem parses ELF, PE and Mach-O files.") (license license:lgpl2.1)))) (define-public python-oscrypto (package (name "python-oscrypto") (version "1.3.0") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/wbond/oscrypto") (commit version))) (file-name (git-file-name name version)) (sha256 (base32 "1v5wkmzcyiqy39db8j2dvkdrv2nlsc48556h73x4dzjwd6kg4q0a")) (patches (search-our-patches "oscrypto-hard-code-openssl.patch")))) (build-system python-build-system) (native-search-paths (list (search-path-specification (variable "SSL_CERT_FILE") (file-type 'regular) (separator #f) ;single entry (files '("etc/ssl/certs/ca-certificates.crt"))))) (propagated-inputs `(("python-asn1crypto" ,python-asn1crypto) ("openssl" ,openssl))) (arguments `(#:phases (modify-phases %standard-phases (add-after 'unpack 'hard-code-path-to-libscrypt (lambda* (#:key inputs #:allow-other-keys) (let ((openssl (assoc-ref inputs "openssl"))) (substitute* "oscrypto/__init__.py" (("@GUIX_OSCRYPTO_USE_OPENSSL@") (string-append openssl "/lib/libcrypto.so" "," openssl "/lib/libssl.so"))) #t))) (add-after 'unpack 'disable-broken-tests (lambda _ ;; This test is broken as there is no keyboard interrupt. (substitute* "tests/test_trust_list.py" (("^(.*)class TrustListTests" line indent) (string-append indent "@unittest.skip(\"Disabled by Guix\")\n" line))) (substitute* "tests/test_tls.py" (("^(.*)class TLSTests" line indent) (string-append indent "@unittest.skip(\"Disabled by Guix\")\n" line))) #t)) (replace 'check (lambda _ (invoke "python" "run.py" "tests") #t))))) (home-page "https://github.com/wbond/oscrypto") (synopsis "Compiler-free Python crypto library backed by the OS") (description "oscrypto is a compilation-free, always up-to-date encryption library for Python.") (license license:expat))) (define-public python-oscryptotests (package (inherit python-oscrypto) (name "python-oscryptotests") (propagated-inputs `(("python-oscrypto" ,python-oscrypto))) (arguments `(#:tests? #f #:phases (modify-phases %standard-phases (add-after 'unpack 'hard-code-path-to-libscrypt (lambda* (#:key inputs #:allow-other-keys) (chdir "tests") #t))))))) (define-public python-certvalidator (let ((commit "a145bf25eb75a9f014b3e7678826132efbba6213")) (package (name "python-certvalidator") (version (git-version "0.1" "1" commit)) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/achow101/certvalidator") (commit commit))) (file-name (git-file-name name commit)) (sha256 (base32 "1qw2k7xis53179lpqdqyylbcmp76lj7sagp883wmxg5i7chhc96k")))) (build-system python-build-system) (propagated-inputs `(("python-asn1crypto" ,python-asn1crypto) ("python-oscrypto" ,python-oscrypto) ("python-oscryptotests", python-oscryptotests))) ;; certvalidator tests import oscryptotests (arguments `(#:phases (modify-phases %standard-phases (add-after 'unpack 'disable-broken-tests (lambda _ (substitute* "tests/test_certificate_validator.py" (("^(.*)class CertificateValidatorTests" line indent) (string-append indent "@unittest.skip(\"Disabled by Guix\")\n" line))) (substitute* "tests/test_crl_client.py" (("^(.*)def test_fetch_crl" line indent) (string-append indent "@unittest.skip(\"Disabled by Guix\")\n" line))) (substitute* "tests/test_ocsp_client.py" (("^(.*)def test_fetch_ocsp" line indent) (string-append indent "@unittest.skip(\"Disabled by Guix\")\n" line))) (substitute* "tests/test_registry.py" (("^(.*)def test_build_paths" line indent) (string-append indent "@unittest.skip(\"Disabled by Guix\")\n" line))) (substitute* "tests/test_validate.py" (("^(.*)def test_revocation_mode_hard" line indent) (string-append indent "@unittest.skip(\"Disabled by Guix\")\n" line))) (substitute* "tests/test_validate.py" (("^(.*)def test_revocation_mode_soft" line indent) (string-append indent "@unittest.skip(\"Disabled by Guix\")\n" line))) #t)) (replace 'check (lambda _ (invoke "python" "run.py" "tests") #t))))) (home-page "https://github.com/wbond/certvalidator") (synopsis "Python library for validating X.509 certificates and paths") (description "certvalidator is a Python library for validating X.509 certificates or paths. Supports various options, including: validation at a specific moment in time, whitelisting and revocation checks.") (license license:expat)))) (define-public python-altgraph (package (name "python-altgraph") (version "0.17") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/ronaldoussoren/altgraph") (commit (string-append "v" version)))) (file-name (git-file-name name version)) (sha256 (base32 "09sm4srvvkw458pn48ga9q7ykr4xlz7q8gh1h9w7nxpf001qgpwb")))) (build-system python-build-system) (home-page "https://github.com/ronaldoussoren/altgraph") (synopsis "Python graph (network) package") (description "altgraph is a fork of graphlib: a graph (network) package for constructing graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with graphviz output.") (license license:expat))) (define-public python-macholib (package (name "python-macholib") (version "1.14") (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/ronaldoussoren/macholib") (commit (string-append "v" version)))) (file-name (git-file-name name version)) (sha256 (base32 "0aislnnfsza9wl4f0vp45ivzlc0pzhp9d4r08700slrypn5flg42")))) (build-system python-build-system) (propagated-inputs `(("python-altgraph" ,python-altgraph))) (arguments '(#:phases (modify-phases %standard-phases (add-after 'unpack 'disable-broken-tests (lambda _ ;; This test is broken as there is no keyboard interrupt. (substitute* "macholib_tests/test_command_line.py" (("^(.*)class TestCmdLine" line indent) (string-append indent "@unittest.skip(\"Disabled by Guix\")\n" line))) (substitute* "macholib_tests/test_dyld.py" (("^(.*)def test_\\S+_find" line indent) (string-append indent "@unittest.skip(\"Disabled by Guix\")\n" line)) (("^(.*)def testBasic" line indent) (string-append indent "@unittest.skip(\"Disabled by Guix\")\n" line)) ) #t))))) (home-page "https://github.com/ronaldoussoren/macholib") (synopsis "Python library for analyzing and editing Mach-O headers") (description "macholib is a Macho-O header analyzer and editor. It's typically used as a dependency analysis tool, and also to rewrite dylib references in Mach-O headers to be @executable_path relative. Though this tool targets a platform specific file format, it is pure python code that is platform and endian independent.") (license license:expat))) (define-public python-signapple (let ((commit "8a945a2e7583be2665cf3a6a89d665b70ecd1ab6")) (package (name "python-signapple") (version (git-version "0.1" "1" commit)) (source (origin (method git-fetch) (uri (git-reference (url "https://github.com/achow101/signapple") (commit commit))) (file-name (git-file-name name commit)) (sha256 (base32 "0fr1hangvfyiwflca6jg5g8zvg3jc9qr7vd2c12ff89pznf38dlg")))) (build-system python-build-system) (propagated-inputs `(("python-asn1crypto" ,python-asn1crypto) ("python-oscrypto" ,python-oscrypto) ("python-certvalidator" ,python-certvalidator) ("python-elfesteem" ,python-elfesteem) ("python-requests" ,python-requests) ("python-macholib" ,python-macholib))) ;; There are no tests, but attempting to run python setup.py test leads to ;; problems, just disable the test (arguments '(#:tests? #f)) (home-page "https://github.com/achow101/signapple") (synopsis "Mach-O binary signature tool") (description "signapple is a Python tool for creating, verifying, and inspecting signatures in Mach-O binaries.") (license license:expat)))) (define-public mingw-w64-base-gcc (package (inherit base-gcc) (arguments (substitute-keyword-arguments (package-arguments base-gcc) ((#:configure-flags flags) `(append ,flags ;; https://gcc.gnu.org/install/configure.html (list "--enable-threads=posix", building-on))) ((#:make-flags flags) ;; Uses the SSP functions from glibc instead of from libssp.so. ;; Our 'symbol-check' script will complain if we link against libssp.so, ;; and thus will ensure that this works properly. `(cons "gcc_cv_libc_provides_ssp=yes" ,flags)))))) (define-public linux-base-gcc (package (inherit base-gcc) (arguments (substitute-keyword-arguments (package-arguments base-gcc) ((#:configure-flags flags) `(append ,flags ;; https://gcc.gnu.org/install/configure.html (list "--enable-initfini-array=yes", "--enable-default-ssp=yes", "--enable-default-pie=yes", building-on))) ((#:phases phases) `(modify-phases ,phases ;; Given a XGCC package, return a modified package that replace each instance of ;; -rpath in the default system spec that's inserted by Guix with -rpath-link (add-after 'pre-configure 'replace-rpath-with-rpath-link (lambda _ (substitute* (cons "gcc/config/rs6000/sysv4.h" (find-files "gcc/config" "^gnu-user.*\\.h$")) (("-rpath=") "-rpath-link=")) #t)))))))) (define-public glibc-2.28 (package (inherit glibc-2.31) (version "2.28") (source (origin (method git-fetch) (uri (git-reference (url "https://sourceware.org/git/glibc.git") (commit "c9e58ae23402eb82877de90fd8a18519c086ed87"))) (file-name (git-file-name "glibc" "c9e58ae23402eb82877de90fd8a18519c086ed87")) (sha256 (base32 "0wm0if2n4z48kpn85va6yb4iac34crds2f55ddpz1hykx6jp1pb6")) (patches (search-our-patches "glibc-2.28-fcommon.patch" "glibc-2.28-guix-prefix.patch" "glibc-2.28-no-librt.patch")))) (arguments (substitute-keyword-arguments (package-arguments glibc) ((#:configure-flags flags) `(append ,flags ;; https://www.gnu.org/software/libc/manual/html_node/Configuring-and-compiling.html (list "--enable-stack-protector=all", "--enable-bind-now", "--disable-werror", building-on))) ((#:phases phases) `(modify-phases ,phases (add-before 'configure 'set-etc-rpc-installation-directory (lambda* (#:key outputs #:allow-other-keys) ;; Install the rpc data base file under `$out/etc/rpc'. ;; Otherwise build will fail with "Permission denied." (let ((out (assoc-ref outputs "out"))) (substitute* "sunrpc/Makefile" (("^\\$\\(inst_sysconfdir\\)/rpc(.*)$" _ suffix) (string-append out "/etc/rpc" suffix "\n")) (("^install-others =.*$") (string-append "install-others = " out "/etc/rpc\n")))))))))))) (packages->manifest (append (list ;; The Basics bash-minimal which coreutils-minimal util-linux gperf ;; File(system) inspection file grep diffutils findutils ;; File transformation patch gawk sed moreutils ;; Compression and archiving tar bzip2 gzip xz + zlib ;; Build tools cmake-minimal ninja gnu-make libtool autoconf-2.71 automake pkg-config bison ;; Native GCC 10 toolchain gcc-toolchain-10 (list gcc-toolchain-10 "static") + (list gcc "lib") ;; Scripting python-minimal ;; (3.10) perl ;; Git git-minimal ;; Tests - python-lief) + python-lief + ;; Web + curl + nss-certs) (let ((target (getenv "HOST"))) (cond ((string-suffix? "-mingw32" target) ;; Windows (list zip (make-mingw-pthreads-cross-toolchain "x86_64-w64-mingw32") nsis-x86_64 nss-certs osslsigncode)) ((string-contains target "-linux-") - (list (make-bitcoin-cross-toolchain target))) + (list clang-10 (make-bitcoin-cross-toolchain target))) ((string-contains target "darwin") (list clang-toolchain-10 binutils xorriso python-signapple)) (else '())))))