1. 为什么值得在 Ubuntu 上从源码编译 Bitcoin Core
很多人第一次接触 Bitcoin Core,第一反应是去官网下载现成的二进制包,解压、双击、同步,完事。这当然没问题,日常用钱包、跑全节点、做简单查询,二进制包完全够用。但只要你稍微往深里走一步——比如想调试某个 RPC 接口的行为、想给上游提一个补丁、想验证某个版本在特定编译选项下的性能差异、或者单纯想搞清楚这个软件到底由哪些库拼起来——你就会发现,二进制包是一堵墙,你只能用它,不能改它、不能看它、不能按自己的需求裁剪它。
在 Ubuntu 下从源码编译 Bitcoin Core,解决的正是这个“只能黑盒使用”的问题。编译过程本身不复杂,但它牵扯到的东西比想象中多:依赖库的版本匹配、编译选项的取舍、钱包功能的开关、GUI 与命令行版本的差异、以及编译产物到底放在哪里。这些细节在官方文档里往往一笔带过,但真正动手时,每一个都可能让你卡上半小时。
这篇文章面向的是有一定 Linux 命令行基础、想在 Ubuntu 上把 Bitcoin Core 从源码编译出来的读者。不管你是刚装好 Ubuntu 的新手,还是已经用过几年 Linux 的老手,只要你想搞清楚“编译这件事到底在干什么”,下面的内容都能直接照着做。我会把每一步的意图讲清楚,把踩过的坑标出来,把参数选择的逻辑说明白,而不是甩给你一串命令让你复制粘贴。
需要提前说明的是,本文讨论的是 Bitcoin Core 这个开源全节点软件的编译流程,属于纯粹的软件工程实践,不涉及任何交易、投资或网络访问层面的操作建议。编译出来的程序如何使用,取决于你自己的判断和所在地区的相关规定,这部分不在本文范围内。
2. 编译前的整体思路与环境准备
2.1 为什么选择源码编译而不是二进制包
先把这个“为什么”说透,后面的步骤你才会做得心甘情愿。
二进制包的本质是别人在他的机器上、用他的编译器和依赖版本,把源码编译好之后打包给你。你拿到的是一个已经定型的东西。它的优点是省事,缺点是:第一,你无法确认它到底用了哪些编译选项,比如钱包功能是否开启、GUI 是否包含、是否链接了某些外部库;第二,你无法针对自己的 CPU 做优化,通用二进制包为了兼容性往往牺牲了性能;第三,你无法修改任何一行代码,哪怕只是想加一个日志输出。
源码编译则把这三个限制全部打开。你可以决定要不要钱包、要不要 GUI、要不要启用某些实验性功能,可以用-march=native让编译器针对你的 CPU 生成更高效的指令,也可以随手改代码重新编译验证想法。代价就是你需要自己处理依赖、自己等编译时间、自己解决报错。
对于想认真理解这个软件的人来说,编译一次是值得的。它让你从“使用者”变成“构建者”。
2.2 Ubuntu 版本与硬件的基本要求
Bitcoin Core 的编译对系统版本有一定要求。太老的 Ubuntu(比如 16.04)自带的 GCC 和 Boost 版本可能偏低,会在编译中途报错。比较稳妥的选择是 Ubuntu 20.04 LTS 或 22.04 LTS,这两个版本的软件源里 GCC 版本足够新,Boost 也能满足要求。如果你用的是 24.04,同样没问题,只是部分包名可能有细微变化,遇到时按提示调整即可。
硬件方面,编译本身对 CPU 和内存的要求比运行节点要高。编译过程中会有大量 C++ 模板实例化,内存占用峰值可能到 2GB 以上。建议至少 4GB 内存,2 核 CPU。如果内存只有 2GB,编译时可能会因为 OOM 被系统杀掉进程,这时候需要临时加 swap。磁盘空间方面,源码加上编译产物大概需要 3 到 5GB,留出 10GB 比较从容。
还有一个容易被忽略的点:编译时间。在 4 核机器上,完整编译(含 GUI)大概需要 20 到 40 分钟,取决于 CPU 性能。如果只编译命令行版本(不含 GUI),时间可以缩短三分之一左右。所以如果你只是想跑节点,不打算用图形界面,完全可以跳过 GUI 依赖,省时省力。
2.3 依赖库清单与作用说明
Bitcoin Core 的编译依赖可以分为两类:必需依赖和可选依赖。必需依赖不装就编译不过,可选依赖决定了你能开启哪些功能。
必需依赖包括:build-essential(提供 GCC、make 等基础工具)、libtool、autotools-dev、pkg-config、libssl-dev(用于加密相关功能)、libevent-dev(网络事件循环)、libboost-all-dev(大量使用 Boost 库)。这些是编译的底线。
可选依赖里最重要的是libdb-dev和libdb++-dev,它们提供 Berkeley DB,也就是钱包功能所依赖的数据库。如果你不需要钱包,可以不装,编译时用--disable-wallet关掉。另一个是 GUI 相关的libqt5gui5、libqt5core5a、libqt5dbus5、qttools5-dev、qttools5-dev-tools、libprotobuf-dev、protobuf-compiler,这些是给图形界面用的。还有libzmq3-dev,用于 ZMQ 通知功能,做监控或对接外部程序时会用到。
把这些依赖按需安装,是编译前最重要的一步。装多了不影响,装少了会在 configure 阶段或编译中途报错。
3. 依赖安装与源码获取的实操细节
3.1 一步步安装编译依赖
先更新软件源,确保拿到的是最新版本:
sudo apt update sudo apt upgrade -y然后安装必需依赖:
sudo apt install -y build-essential libtool autotools-dev automake pkg-config libssl-dev libevent-dev bsdmainutils libboost-all-dev这里有几个点值得说明。bsdmainutils提供了一些文本处理工具,虽然不直接参与编译,但某些构建脚本会用到。libboost-all-dev会一次性装齐所有 Boost 组件,体积不小,但省去了逐个挑选的麻烦。如果你磁盘紧张,可以只装libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev,这几个是实际用到的。
接着装钱包依赖(如果不需要钱包可跳过):
sudo apt install -y libdb-dev libdb++-dev再装 GUI 依赖(如果不需要图形界面可跳过):
sudo apt install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler最后装 ZMQ 依赖(可选):
sudo apt install -y libzmq3-dev注意:Ubuntu 22.04 之后,
libdb-dev默认可能指向 Berkeley DB 5.3,而 Bitcoin Core 的钱包功能对 BDB 版本有要求。如果 configure 阶段报 BDB 版本不匹配,需要手动指定 BDB 路径,或者从源码编译一个合适版本的 BDB。这是新手最容易卡住的地方之一。
3.2 获取源码的两种方式与选择逻辑
获取源码有两种方式:下载官方发布的源码压缩包,或者用 git 克隆仓库。
下载压缩包的好处是快、稳定,适合只想编译某个特定版本的场景。你从发布页面下载bitcoin-x.x.x.tar.gz,解压即可。缺点是如果你后续想切换版本或查看提交历史,得重新下载。
git 克隆的好处是灵活,可以随时切换分支、拉取更新、查看提交记录。缺点是首次克隆会下载完整历史,体积较大。如果你只关心最新代码,可以用--depth 1做浅克隆,只拉取最近一次提交,速度快很多。
git clone --depth 1 https://github.com/bitcoin/bitcoin.git cd bitcoin如果你要编译特定版本,比如某个稳定版,可以这样:
git fetch --tags git checkout v25.0提示:浅克隆之后无法直接 checkout 历史标签,需要先
git fetch --unshallow补全历史,或者重新完整克隆。这一点在你想切换版本时很容易踩坑。
3.3 源码目录结构速览
进入源码目录后,花两分钟看一下结构,对后面理解编译流程有帮助。
src/是核心代码所在,所有 C++ 源文件都在这里。src/qt/是图形界面相关代码。depends/是一个特殊的依赖构建系统,它允许你在不污染系统环境的前提下,自己编译一套依赖,适合做交叉编译或需要特定版本依赖的场景。doc/里是各种文档,其中build-unix.md是 Unix 系统编译的官方说明,值得一读。configure.ac和Makefile.am是 autotools 的配置文件,configure脚本就是从这里生成的。
理解这个结构的意义在于:当编译报错时,你能快速定位是核心代码问题、依赖问题还是构建脚本问题。
4. 配置与编译的核心环节拆解
4.1 configure 阶段到底在做什么
很多人把./configure当成一个黑盒,敲完等它跑完就行。其实它做的事情很明确:检查你的系统环境,确认依赖库是否存在、版本是否满足要求,然后根据你给的选项生成Makefile。Makefile就是后续make命令的“施工图纸”。
在源码根目录下,先执行:
./autogen.sh这一步会根据configure.ac生成configure脚本。如果你下载的是官方发布的压缩包,里面通常已经包含了configure,可以跳过这步。但如果是 git 克隆的,必须先跑autogen.sh,否则没有configure可用。
然后执行 configure,带上你需要的选项:
./configure --with-gui=qt5 --enable-wallet --with-zmq如果你不需要 GUI 和钱包,可以简化为:
./configure --without-gui --disable-walletconfigure 跑完后,它会输出一个总结,列出哪些功能被启用、哪些被禁用。这个总结非常重要,一定要看一眼。比如它告诉你with wallet: no,那说明钱包没启用,如果你本来想要钱包,就得回头检查依赖。
4.2 关键编译选项的取舍与参数说明
configure 的选项很多,但常用的就那么几个。我把它们列出来,说明每个的作用和适用场景。
| 选项 | 作用 | 建议 |
|---|---|---|
--with-gui=qt5 | 启用 Qt5 图形界面 | 需要桌面环境时使用 |
--without-gui | 禁用图形界面 | 只跑节点或服务器环境推荐 |
--enable-wallet | 启用钱包功能 | 需要管理地址和交易时使用 |
--disable-wallet | 禁用钱包功能 | 只做验证节点时推荐,省依赖 |
--with-zmq | 启用 ZMQ 通知 | 需要外部程序订阅事件时使用 |
--enable-debug | 启用调试符号 | 开发调试时使用,会增大体积 |
--disable-tests | 跳过测试编译 | 只想快速拿到可执行文件时使用 |
--prefix=/usr/local | 指定安装路径 | 默认即可,需要自定义时修改 |
还有一个隐藏但很有用的选项:--enable-reduce-exports。它会减少导出符号,加快链接速度,对最终功能没影响。如果你编译时觉得链接阶段特别慢,可以加上这个。
注意:
--enable-debug会让编译产物变大很多,而且运行速度会下降。除非你要用 gdb 调试,否则不要开。很多人以为开了 debug 更“完整”,其实只是徒增体积。
4.3 make 编译过程中的资源控制与加速技巧
configure 成功后,就可以 make 了。直接敲make会用单线程编译,速度慢。用-j参数指定并行任务数,可以大幅加速:
make -j$(nproc)$(nproc)会自动获取 CPU 核心数。比如 4 核机器就是make -j4。但要注意,并行数不是越大越好。如果内存不足,开太多并行任务会导致 OOM。经验法则是:每核至少 1GB 内存。4 核 4GB 内存可以开-j4,4 核 2GB 内存建议只开-j2。
编译过程中会刷大量输出,如果只想看有没有报错,可以把输出重定向到文件:
make -j$(nproc) > build.log 2>&1然后另开一个终端tail -f build.log观察进度。这样即使编译中断,日志也保留着,方便排查。
编译时间方面,前面说过,4 核机器含 GUI 大概 20 到 40 分钟。如果只编译命令行版本,15 到 25 分钟。第一次编译会慢一些,因为所有对象文件都要从头生成。后续如果只改了一小部分代码,make 会增量编译,只重新编译改动的部分,快很多。
4.4 编译产物的位置与验证方法
编译完成后,可执行文件在src/目录下。主要的有这几个:
src/bitcoind:核心守护进程,命令行节点src/bitcoin-cli:命令行交互工具src/bitcoin-tx:交易操作工具src/bitcoin-qt:图形界面版本(如果启用了 GUI)src/bitcoin-wallet:钱包工具
验证编译是否成功,最简单的方法是运行:
./src/bitcoind --version如果输出了版本号,说明编译成功。再运行:
./src/bitcoin-cli --version同样应该输出版本信息。
如果你想安装到系统路径,可以执行:
sudo make install这样bitcoind和bitcoin-cli就会被安装到/usr/local/bin,可以直接在终端里调用,不用每次都进源码目录。但如果你同时有多个版本,建议不要 install,而是用完整路径调用,避免版本混淆。
5. 常见报错与排查技巧实录
5.1 configure 阶段的典型报错
报错一:configure: error: libdb_cxx headers missing
这是钱包依赖没装好。解决方法是安装libdb++-dev。如果装了还报错,可能是 BDB 版本不对。Bitcoin Core 需要 Berkeley DB 4.8 或更高版本,但某些 Ubuntu 版本默认装的是 5.3,理论上兼容,但 configure 脚本可能检测不到。这时候可以手动指定:
./configure --with-incompatible-bdb这个选项会跳过版本检查,强制使用已安装的 BDB。但要注意,用不兼容版本编译出来的钱包,可能无法被其他版本的 Bitcoin Core 读取,存在数据兼容风险。所以更稳妥的做法是从源码编译一个 BDB 4.8,然后用--with-bdb=/path/to/bdb指定路径。
报错二:configure: error: Qt5 dependencies not found
GUI 依赖没装全。检查是否装了libqt5gui5、libqt5core5a、libqt5dbus5、qttools5-dev、qttools5-dev-tools、libprotobuf-dev、protobuf-compiler。如果都装了还报错,可能是 Qt5 的 pkg-config 路径问题,可以尝试export PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig。
报错三:configure: error: Boost headers missing
Boost 没装或版本太低。安装libboost-all-dev即可。如果系统源里的 Boost 版本低于 1.58,需要手动编译新版 Boost,或者升级系统。
5.2 编译阶段的典型报错
报错一:virtual memory exhausted: Cannot allocate memory
这是内存不足。编译 C++ 模板时内存占用会飙升。解决办法有两个:一是加 swap,二是减少并行任务数。加 swap 的方法:
sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile然后重新 make,用-j2或-j1。编译完可以关掉 swap:sudo swapoff /swapfile。
报错二:fatal error: openssl/ssl.h: No such file or directory
OpenSSL 头文件缺失。安装libssl-dev即可。如果装了还报错,可能是 OpenSSL 版本问题。Bitcoin Core 对 OpenSSL 的依赖在较新版本中已经减少,但如果你的版本较老,可能需要 OpenSSL 1.0 或 1.1。Ubuntu 22.04 默认是 OpenSSL 3.0,某些老版本 Bitcoin Core 可能不兼容,需要升级 Bitcoin Core 版本或手动编译 OpenSSL。
报错三:链接阶段undefined reference to ...
这类错误通常是某个库没链接上。检查 configure 输出,确认相关功能是否启用。如果是 ZMQ 相关,确认libzmq3-dev已安装且 configure 时带了--with-zmq。如果是钱包相关,确认 BDB 路径正确。
5.3 编译成功后的运行问题
问题一:bitcoind启动后立即退出
查看日志,通常在~/.bitcoin/debug.log。常见原因是数据目录权限问题,或者配置文件有误。确保~/.bitcoin目录存在且当前用户有读写权限。
问题二:bitcoin-cli连接不上bitcoind
确认bitcoind正在运行,且bitcoin-cli使用的配置文件和bitcoind一致。如果bitcoind用了自定义数据目录,bitcoin-cli也要用-datadir指定同样的目录。另外,如果启用了 RPC 认证,bitcoin-cli需要能读到bitcoin.conf里的rpcuser和rpcpassword。
问题三:GUI 版本启动报 Qt 平台插件错误
这是 Qt 环境变量问题。尝试:
export QT_QPA_PLATFORM=xcb ./src/bitcoin-qt如果是在无桌面环境的服务器上跑 GUI,需要先配置 X11 转发或 VNC,否则 Qt 无法创建窗口。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| configure 报 BDB 缺失 | 未装 libdb++-dev | 安装 libdb++-dev 或指定 BDB 路径 |
| configure 报 Qt5 缺失 | GUI 依赖不全 | 安装全部 Qt5 相关包 |
| 编译中 OOM | 内存不足 | 加 swap 或降低 -j 并行数 |
| 链接报 undefined reference | 库未链接 | 检查 configure 选项和依赖安装 |
| bitcoind 启动即退出 | 数据目录权限或配置错误 | 检查 debug.log 和目录权限 |
| bitcoin-cli 连不上 | 数据目录或 RPC 配置不一致 | 统一 datadir 和配置文件 |
实操心得:编译报错时,第一件事是看 configure 的总结输出,确认你想要的功能够不够启用。第二件事是看完整报错信息的第一行,往往那里才是根因,后面的报错都是连锁反应。第三件事是善用搜索引擎,把报错关键词加上“bitcoin core”搜索,大概率有人遇到过同样的问题。
6. 编译后的扩展与个人经验
编译出可执行文件只是起点。如果你想让这套东西真正好用,还有几件事可以做。
第一,把src/bitcoind和src/bitcoin-cli加到 PATH 里,或者做个软链接到/usr/local/bin,这样在任何目录都能直接调用。第二,写一个简单的 systemd 服务文件,让bitcoind开机自启、崩溃自动重启。第三,如果你编译时没开钱包,后来又想用钱包,不用重新编译整个项目,只需要重新 configure 时加上--enable-wallet,然后 make 会增量编译,只重新编译受影响的部分,比从头来快得多。
我自己在编译时踩过最深的坑是 BDB 版本问题。当时系统默认装的是 5.3,configure 报错说需要 4.8,我图省事用了--with-incompatible-bdb,结果编译出来的钱包文件在另一台机器上读不了,折腾了很久才搞清楚是 BDB 版本不兼容。后来老老实实从源码编译了一个 BDB 4.8,指定路径重新编译,问题才彻底解决。所以如果你要用钱包功能,BDB 版本这件事千万别将就。
另一个经验是关于并行编译的。我有一次在 2GB 内存的虚拟机上用make -j4,编译到一半进程被系统杀掉,日志里只留下一句Killed,没有任何其他信息。后来查系统日志才知道是 OOM。从那以后,我在内存不足的机器上都会先加 swap,或者直接用-j1慢慢编。慢是慢点,但至少不会白等一场。
最后说一个容易被忽略的点:编译完成后,源码目录里的src/bitcoind是动态链接的,依赖系统里的共享库。如果你想把编译产物拷到另一台机器上运行,那台机器也需要有相同的共享库,否则会报error while loading shared libraries。解决办法是静态编译,configure 时加上--enable-static和相关的 LDFLAGS。但静态编译会更复杂,依赖也需要静态版本,适合有明确分发需求的场景。日常自己用,动态链接就够了。