Files
bitcoin/contrib/macdeploy
merge-script 2bb06bcaf2 Merge bitcoin/bitcoin#31679: cmake: Install internal binaries to <prefix>/libexec/
f49840dd90 doc: Fix typo in files.md (Ryan Ofsky)
f5cf0b1ccc bitcoin wrapper: improve help output (Ryan Ofsky)
c810b168b8 doc: Add description of installed files to files.md (Ryan Ofsky)
94ffd01a02 doc: Add release notes describing libexec/ binaries (Ryan Ofsky)
cd97905ebc cmake: Move internal binaries from bin/ to libexec/ (Ryan Ofsky)

Pull request description:

  This change moves binaries that are not typically invoked directly by users from the `bin/` directory to the `libexec/` directory in CMake installs and binary releases. The goal of the PR is to introduce a distinction between internal and external binaries so starting with #31802, we can use IPC to implement features in new binaries without adding those binaries to the CLI. The change also helps reduce clutter in `bin/`, making it easier for users to identify useful tools to run. Summary of changes:

  - For **source builds** (i.e. developer builds) — There are no changes.
  - For **source installs** (i.e. `cmake --install` result) — `test_bitcoin`, `test_bitcoin-qt`, and `bench_bitcoin` are installed in `${CMAKE_PREFIX_PATH}/libexec` instead of `${CMAKE_PREFIX_PATH}/bin`, so they are no longer on the system `PATH`. However, they can still be invoked from the `libexec/` directory, or from the CLI as `bitcoin test`, `bitcoin test-gui`, and `bitcoin bench`, respectively.
  - For **binary releases** — Since `test_bitcoin` is the only test binary enabled in releases, the only change is moving `test_bitcoin` from `bin/` to `libexec/`.

  <details><summary>Details</summary>
  <p>

   The table below shows the install location of each binary after this change, and the availability of each binary.

  | Binary               | Location     | Availability         | Change                        |
  |----------------------|--------------|----------------------|-------------------------------|
  | `bitcoin`            | `bin/`       | 📦 Binary release (since #31375) | Unchanged                     |
  | `bitcoin-cli`        | `bin/`       | 📦 Binary release     | Unchanged                     |
  | `bitcoind`           | `bin/`       | 📦 Binary release     | Unchanged                     |
  | `bitcoin-qt`         | `bin/`       | 📦 Binary release     | Unchanged                     |
  | `bitcoin-tx`         | `bin/`       | 📦 Binary release     | Unchanged                     |
  | `bitcoin-util`       | `bin/`       | 📦 Binary release     | Unchanged                     |
  | `bitcoin-wallet`     | `bin/`       | 📦 Binary release     | Unchanged                     |
  | `bench_bitcoin`      | `libexec/`   | 🛠 Source build only  | Moved from `bin/`             |
  | `bitcoin-chainstate` | `libexec/`   | 🛠 Source build only  | Newly installed (was built)   |
  | `bitcoin-gui`        | `libexec/`   | 🛠 Source build only (until #31802) | Moved from `bin/`             |
  | `bitcoin-node`       | `libexec/`   | 🛠 Source build only (until #31802) | Moved from `bin/`             |
  | `test_bitcoin`       | `libexec/`    | 📦 Binary release     | Moved from `bin/`             |
  | `test_bitcoin-qt`    | `libexec/`   | 🛠 Source build only  | Moved from `bin/`             |

  </p>
  </details>

  ---

  This PR is part of the [process separation project](https://github.com/bitcoin/bitcoin/issues/28722).

ACKs for top commit:
  l0rinc:
    re-ACK f49840dd90
  Sjors:
    re-ACK f49840dd90
  achow101:
    ACK f49840dd90
  janb84:
    re ACK f49840dd90
  BrandonOdiwuor:
    Tested ACK f49840dd90
  hodlinator:
    re-ACK f49840dd90
  willcl-ark:
    utACK f49840dd90

Tree-SHA512: 858a2e1a53db11ee3c5c759bfdeea566f242b9ce5e8a898fa435222e41662b8184577c0dc2c4c058294b4de41d8cb3ba3e5d24c748c280efa4a3f84e3ec4344d
2025-08-07 14:53:26 +01:00
..
2025-06-03 08:09:28 +01:00

MacOS Deployment

The macdeployqtplus script should not be run manually. Instead, after building as usual:

make deploy

When complete, it will have produced Bitcoin-Core.zip.

SDK Extraction

Step 1: Obtaining Xcode.app

A free Apple Developer Account is required to proceed.

Our macOS SDK can be extracted from Xcode_15.xip.

Alternatively, after logging in to your account go to 'Downloads', then 'More' and search for Xcode 15.

An Apple ID and cookies enabled for the hostname are needed to download this.

The sha256sum of the downloaded XIP archive should be 4daaed2ef2253c9661779fa40bfff50655dc7ec45801aba5a39653e7bcdde48e.

To extract the .xip on Linux:

# Install/clone tools needed for extracting Xcode.app
apt install cpio
git clone https://github.com/bitcoin-core/apple-sdk-tools.git

# Unpack the .xip and place the resulting Xcode.app in your current
# working directory
python3 apple-sdk-tools/extract_xcode.py -f Xcode_15.xip | cpio -d -i

On macOS:

xip -x Xcode_15.xip

Step 2: Generating the SDK tarball from Xcode.app

To generate the SDK, run the script gen-sdk with the path to Xcode.app (extracted in the previous stage) as the first argument.

./contrib/macdeploy/gen-sdk '/path/to/Xcode.app'

The generated archive should be: Xcode-15.0-15A240d-extracted-SDK-with-libcxx-headers.tar.gz. The sha256sum should be c0c2e7bb92c1fee0c4e9f3a485e4530786732d6c6dd9e9f418c282aa6892f55d.

Deterministic macOS App Notes

macOS Applications are created on Linux using a recent LLVM.

All builds must target an Apple SDK. These SDKs are free to download, but not redistributable. See the SDK Extraction notes above for how to obtain it.

The Guix build process has been designed to avoid including the SDK's files in Guix's outputs. All interim tarballs are fully deterministic and may be freely redistributed.

Using an Apple-blessed key to sign binaries is a requirement to produce (distributable) macOS binaries. Because this private key cannot be shared, we'll have to be a bit creative in order for the build process to remain somewhat deterministic. Here's how it works:

  • Builders use Guix to create an unsigned release. This outputs an unsigned ZIP which users may choose to bless, self-codesign, and run. It also outputs an unsigned app structure in the form of a tarball.
  • The Apple keyholder uses this unsigned app to create a detached signature, using the included script. Detached signatures are available from this repository.
  • Builders feed the unsigned app + detached signature back into Guix, which combines the pieces into a deterministic ZIP.