Bitcoin Core depends 依赖构建系统详解:从本机编译到跨平台交叉编译的完整实战
本文围绕 Bitcoin Core 仓库中的 depends 依赖构建系统展开:它负责下载、校验、编译并缓存构建 Bitcoin Core 所需的全部第三方库,并原生支持交叉编译。读完本文,你将掌握在 Ubuntu/Debian、macOS、FreeBSD、NetBSD、OpenBSD、Alpine 六大平台上构建依赖的完整命令,理解 NO_QT/NO_WALLET 等全部构建开关的底层机制,学会通过 toolchain.cmake 将依赖产物接入 CMake 构建流程,以及 Linux/Windows/macOS 三大方向交叉编译的工具链安装细节。
depends 系统的设计定位
depends 是“构建并缓存 Bitcoin Core 所需依赖的系统”,同时支持交叉编译(见 depends/README.md)。它与多数同类系统的差异在 depends/description.md 中有完整阐述,共六点设计原则:
- 构建机(builder)与目标机(host)无关:理论上,运行在任意 OS/架构的机器上都可以为目标平台产出二进制。实践中,默认工具链不适用时需要在构建侧显式指定工具,新宿主平台需要修正各包的适配配置。
- 不依赖时间戳:通过“文件是否存在”判断哪些内容需要构建。这使得构建结果可分发、易被自动化构建器消费。
- 每个包构建时只能看到声明过的依赖:每个包的 sysroot 都会被清空后再安装(递归)依赖,保证构建确定性,不会有未知文件引入副作用。
- 每个包独立缓存、按需重建:构建前会为每个包生成唯一的 build-id,它是“构建该包所用全部文件(Makefile、包定义等)哈希 + 各递归依赖同样数据哈希”的组合。任何一个包的构建配方变更,该包及其所有下游都会重建;如果主 Makefile(
Makefile、funcs.mk等)变更,则所有包重建。构建结果以 tarball 形式缓存,可复用、可分发。 - 构建结果(相对)确定:每个包都经过配置与打补丁,确保在合理约束内多次构建产出一致。时间戳注入等无法避免的因素超出该系统范围,且工具链本身必须具备确定性产出能力。
- 源码自动抓取并校验:每个包必须定义源码位置与校验和,校验失败则构建直接失败;源码可以预置和缓存。
- 自清理:构建目录与 staging 目录用后即清,缓存结果的旧版本在成功构建后删除,自动化构建器无需人工干预。
这些设计直接落实在源码中:包级 build-id 的计算见 depends/funcs.mk(int_get_build_id 将包名、版本、配方哈希、release_type 及全部依赖的 build-id 拼接后取 SHA256 前 11 位),工具链指纹则由 depends/gen_id 生成——它把 CC/CXX/各 *FLAGS/AR/NM/STRIP 等工具的实际 --version 输出哈希成一个“make 安全”的 id,编译器或编译标准一变,缓存自动失效。
各平台使用方式
以下命令均需在 depends 目录下执行,先安装构建侧工具,再触发构建。
Ubuntu & Debian
apt install cmake curl make patch
如果不打算使用 GUI、且打算以 NO_QT=1 方式构建(见下文“依赖选项”),可以跳过下一组包:
apt install bison g++ ninja-build pkgconf python3 xz-utils
构建当前架构 + 操作系统的依赖:
make
macOS
先安装 Xcode Command Line Tools 与 Homebrew(参考 doc/build-osx.md),然后:
brew install cmake make ninja
构建当前架构 + 操作系统的依赖(macOS 自带 make 是 BSD make,须用 gmake):
gmake
FreeBSD
pkg install bash cmake curl gmake
不使用 GUI(NO_QT=1)时可跳过:
pkg install bison ninja pkgconf python3
构建命令:gmake。
NetBSD
pkgin install bash cmake curl gmake perl
构建命令:gmake。
OpenBSD
pkg_add bash cmake curl gmake gtar
不使用 GUI(NO_QT=1)时可跳过:
pkg_add bison ninja
构建命令:gmake。
Alpine
apk add bash build-base cmake curl make patch
不使用 GUI(NO_QT=1)时可跳过:
apk add bison linux-headers samurai pkgconf python3
构建命令:make。
说明:Qt 相关依赖(xcb 系列、fontconfig、freetype 等,见 depends/packages 目录下的
qt.mk、libxcb*.mk、fontconfig.mk等)体积庞大,故各平台都把 GUI 依赖列为可选安装项。
将依赖产物接入 Bitcoin Core 构建(toolchain 文件)
配置 Bitcoin Core 时,CMake 默认会忽略 depends 的输出。 必须显式指定 toolchain 文件,CMake 才能拾取 depends 构建出的库、工具与设置。以上述 Ubuntu 示例为例,构建完成后会生成 depends/x86_64-pc-linux-gnu/toolchain.cmake:
cmake -B build --toolchain depends/x86_64-pc-linux-gnu/toolchain.cmake
构建结束时 Makefile 也会打印提示:To build Bitcoin Core with these packages, pass '--toolchain <host目录>/toolchain.cmake' to the first CMake invocation.(见 depends/Makefile)。
这个 toolchain.cmake 并非手写文件,而是由 depends/toolchain.cmake.in 模板经 sed 替换生成,它完成三件关键工作:
- 注入编译参数:把 depends 计算的
CC/CXX、CFLAGS/CXXFLAGS(含 release/debug 变体)、LDFLAGS与交叉编译器(CMAKE_C_COMPILER_TARGET等)写入 CMake 缓存; - 隔离查找路径:
set(CMAKE_FIND_ROOT_PATH ...)配合CMAKE_FIND_ROOT_PATH_MODE_LIBRARY/INCLUDE/PACKAGE ONLY,强制 CMake 只在 depends 产物目录内找库头文件,避免误用宿主系统库; - 自动推导功能开关:模板末尾按
@qt_packages@、@wallet_packages@等占位符是否为空,直接写入BUILD_GUI、ENABLE_WALLET、WITH_ZMQ、WITH_USDT、ENABLE_IPC等 CMake 缓存变量——这就是“未构建某组包时 CMake 变量会被自动设置”的实现位置(见 depends/toolchain.cmake.in)。
依赖选项(make 变量)
以下变量可在运行 make 时以 make FOO=bar 方式设置(完整清单见 depends/README.md):
| 变量 | 作用 |
|---|---|
SOURCES_PATH |
下载源码的存放位置 |
BASE_CACHE |
构建产物(缓存包)的存放位置 |
SDK_PATH |
SDK 查找路径(macOS 用) |
FALLBACK_DOWNLOAD_PATH |
源码主地址抓取失败时的备用抓取路径,默认 https://bitcoincore.org/depends-sources(见 depends/Makefile) |
C_STANDARD |
使用的 C 标准版本,默认 c11 |
CXX_STANDARD |
使用的 C++ 标准版本,默认 c++20 |
NO_BOOST |
不下载/构建/缓存 Boost |
NO_QT |
不下载/构建/缓存 Qt 及其依赖 |
NO_QR |
不下载/构建/缓存 qrencode 所需包 |
NO_ZMQ |
不下载/构建/缓存 ZeroMQ 所需包 |
NO_WALLET |
不下载/构建/缓存钱包所需的库(SQLite) |
NO_USDT |
不下载/构建/缓存 USDT 追踪点所需包 |
NO_IPC |
不构建 Cap’n Proto 与 libmultiprocess 包,Windows 上默认为 1 |
DEBUG |
关闭部分优化并启用更多运行时检查 |
HOST_ID_SALT / BUILD_ID_SALT |
生成 host/build 包 id 时使用的可选盐值 |
LOG |
对单个包启用文件日志;构建期间日志文件位于 depends 目录,构建出错时自动打印;构建成功后日志随包归档一起移动 |
LTO |
启用 LTO 所需选项(不会向 *FLAGS 追加 -flto 相关选项) |
从源码结构看,这些开关的实现非常简洁:depends/Makefile 用 boost_packages_$(NO_BOOST) = $(boost_packages) 这类“以变量值为下标”的技巧——NO_QT=1 时 qt_packages_1 为空,Qt 整组包(含 qrencode、xcb 家族)就被排除出 packages 列表;其中 NO_IPC 默认值由宿主三元组推导(NO_IPC ?= $(if $(findstring mingw32,$(HOST)),1,),即 Windows 目标默认关闭 IPC)。
当某些包未构建(例如 make NO_WALLET=1),生成 Bitcoin Core 构建系统时对应的 CMake 缓存变量会被自动设置,例如 -DENABLE_WALLET=OFF——其落点即上文 toolchain 模板中的 ENABLE_WALLET OFF CACHE BOOL 逻辑。
编译器配置
CC/CXX控制目标编译器;build_CC/build_CXX控制原生构建工具(如native_capnp、native_qt)的编译器,默认在 Linux 上为gcc/g++,在 macOS/FreeBSD/OpenBSD 上为clang/clang++(见 depends/builders/ 下各*.mk)。
在默认构建编译器不可用的系统上(例如没有 gcc/g++ 的 Linux),可以让所有包都用 clang 构建:
make -C depends build_CC=clang build_CXX=clang++ CC=clang CXX=clang++
编译器变化会被缓存机制感知:build_id 与 host id 分别通过 depends/gen_id 对编译器 -v 输出等做哈希,换编译器后全部缓存自动失效重建。
交叉编译
基本用法
构建其他架构 + 操作系统的目标时,只需指定 HOST:
make HOST=host-platform-triplet
例如:
make HOST=x86_64-w64-mingw32 -j4
常用 host-platform-triplet 一览:
| Triplet | 目标 |
|---|---|
i686-linux-gnu |
Linux x86 32 位 |
x86_64-linux-gnu |
Linux x86 64 位 |
x86_64-w64-mingw32 |
Windows(MSVCRT) |
x86_64-w64-mingw32ucrt |
Windows(UCRT) |
x86_64-apple-darwin |
Intel macOS |
arm64-apple-darwin |
ARM macOS |
arm-linux-gnueabihf |
Linux ARM 32 位 |
aarch64-linux-gnu |
Linux ARM 64 位 |
powerpc64-linux-gnu |
Linux POWER 64 位(大端) |
powerpc64le-linux-gnu |
Linux POWER 64 位(小端) |
riscv32-linux-gnu |
Linux RISC-V 32 位 |
riscv64-linux-gnu |
Linux RISC-V 64 位 |
s390x-linux-gnu |
Linux S390X |
路径会自动配置好,无需其他选项。Makefile 通过 config.guess/config.sub 规范化 BUILD 与 HOST(见 depends/Makefile),并据此 include 对应的 hosts/*.mk、builders/*.mk 定义工具链与编译参数。
macOS 交叉编译
apt install clang lld llvm zip
要求 Clang 18 或更新版本。开始交叉编译前必须先获得 macOS SDK:在 depends 目录下创建名为 SDKs 的子目录,并把解压后的 SDK 放入其中。解压方法见 contrib/macdeploy/README.md 的 “SDK Extraction” 一节。
从 depends/hosts/darwin.mk 可以看到具体消费方式:SDK 路径为 $(SDK_PATH)/Xcode-<版本>-<build_id>-extracted-SDK-with-libcxx-headers,编译命令带 -isysroot$(OSX_SDK) -nostdlibinc 等参数,最低支持版本为 OSX_MIN_VERSION=14.0;跨平台构建(构建机不是 darwin)时还会附加 -fuse-ld=lld 与 -no_adhoc_codesign 以保证链接的确定性。
Windows 交叉编译
MSVCRT:
apt install g++-mingw-w64-x86-64-posix
UCRT:
apt install g++-mingw-w64-ucrt64
某些 Ubuntu/Debian 版本可能不提供可用的软件包。此时可以安装 nix-bin,并从仓库根目录使用 Nix shell:
apt install nix-bin
NIX_BUILD_SHELL=bash HOST=x86_64-w64-mingw32 nix-shell contrib/devtools/shell-win64-cross.nix # MSVCRT
NIX_BUILD_SHELL=bash HOST=x86_64-w64-mingw32ucrt nix-shell contrib/devtools/shell-win64-cross.nix # UCRT
Linux 交叉编译
注意:软件包可用性可能取决于你所使用的架构 + 操作系统。
Linux x86 32 位:
sudo apt-get install g++-i686-linux-gnu binutils-i686-linux-gnu
Linux x86 64 位:
sudo apt-get install g++-x86-64-linux-gnu binutils-x86-64-linux-gnu
Linux ARM 32 位:
sudo apt-get install g++-arm-linux-gnueabihf binutils-arm-linux-gnueabihf
Linux ARM 64 位:
sudo apt-get install g++-aarch64-linux-gnu binutils-aarch64-linux-gnu
Linux POWER 64 位(无 32 位软件包):
sudo apt-get install g++-powerpc64-linux-gnu binutils-powerpc64-linux-gnu g++-powerpc64le-linux-gnu binutils-powerpc64le-linux-gnu
Linux RISC-V 64 位(无 32 位软件包):
sudo apt-get install g++-riscv64-linux-gnu binutils-riscv64-linux-gnu
Linux S390X:
sudo apt-get install g++-s390x-linux-gnu binutils-s390x-linux-gnu
Linux 目标的编译参数定义在 depends/hosts/linux.mk:release 模式为 -O2,debug 模式为 -O1 -g 并追加 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC 与 libc++ 加固宏;LTO 开启时 AR/NM/RANLIB 会切换为 gcc-ar/gcc-nm/gcc-ranlib 以满足 LTO 归档要求。
附加目标(预下载源码)
| 目标 | 说明 |
|---|---|
download |
执行 make download,抓取全部源码但不构建 |
download-osx |
抓取 macOS 构建所需的全部源码 |
download-win |
抓取 Windows 构建所需的全部源码 |
download-linux |
抓取 Linux 构建所需的全部源码 |
从 depends/Makefile 可见,download 实际是依次以 HOST=x86_64-apple-darwin、HOST=x86_64-unknown-linux-gnu、HOST=x86_64-w64-mingw32 调用 download-one 的组合目标。下载与校验逻辑在 depends/funcs.mk 的 fetch_file 中:先按包定义的源地址下载并用 SHA256 校验,失败则回落到 FALLBACK_DOWNLOAD_PATH 重试;源码下载完成后在 SOURCES_PATH/download-stamps/ 留下 .hash 印章文件,后续构建据此判断是否需要重新下载(对应设计文档中“不依赖时间戳”的原则)。
小结
Bitcoin Core 的 depends 系统把“依赖获取、校验、编译、缓存、toolchain 生成”整合进单一 Make 流程:本机构建只需两条命令,交叉构建只需加一个 HOST,功能裁剪由一组 NO_* 开关完成,且缓存失效完全由内容哈希驱动、可被 CI 无状态复用。深入其实现(depends/Makefile、depends/funcs.mk、depends/gen_id、depends/toolchain.cmake.in)即可理解它如何保证每个包的构建环境与缓存 id 严格一致,这是 Bitcoin Core 能在任意构建机上可复现地生产多平台二进制的核心基础。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00