6.5 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
仓库性质
本仓库只包含构建与打包基础设施,不含 mond 源码。源码在编译时从外部仓库克隆(见 docker/Dockerfile):
- 源码仓库:
github.com/monero-project/monero.git(Monero 官方仓库,非换名仓库) - 发布仓库:Gitea
gitea.bcde.io下wangdefa/mond的 Generic / Debian 包仓库
mond 是 Monero 守护进程 monerod 的定制换名构建。换名通过 init.sh 在编译期对源码做 sed 改写完成:project(monero)→project(mond)、二进制 OUTPUT_NAME monerod→mond、MONERO_VERSION_* 宏 → MOND_VERSION_*、用户可见字符串 Monero→Mond。改动版本宏或显示字符串相关逻辑时,改 init.sh 而非源码(源码每次构建都重新克隆)。init.sh 末尾还含 musl 纯静态所需的 CMakeLists patch(见下「为何 patch」)。
与同目录
gitea-xxxig/gitea-xxxig-proxy的关键差异:那两个项目源码来自wangdefaa(双 a)换名仓库;mond 直接克隆 Monero 官方仓库,靠 init.sh 现场改名。三者共享同一套 CI / build-deb / debian 打包骨架,且均为 musl fully-static 构建;mond 的版本号格式为四段0.18.5.0。
整体架构:单二进制
编译产出单个可执行文件 mond:Monero 全节点守护进程,负责 P2P 同步区块链、提供 RPC。配置来自 conf/params.example.conf。
构建与发布流程(CI)
.gitea/workflows/ci.yaml 是 Gitea Actions 流水线:
- build-and-test(矩阵
arch=[amd64,arm64],跑在对应架构原生 runner):用docker buildx按 docker/Dockerfile 原生编译 → 打成 tar.gz → 解包冒烟测试(mond --version+ldd纯静态校验)→ 调debian/build-deb.sh打 .deb → 上传 artifact。 - release(仅 tag 触发):下载 artifact,上传 tar.gz 到 Generic Package Registry、上传 .deb 到 Debian Registry(stable/main),并用
jq生成描述创建 Gitea Release。
关键点:
- musl fully-static(Alpine 构建,勿改回 glibc):docker/Dockerfile 在
alpine:3.23下手动源码编译 5 个静态库(OpenSSL 3.0.16 / libsodium / libzmq / expat / unbound——Alpine 仓库只有.so/缺.a,须--disable-shared自编),编出 static-pie 纯静态二进制:ldd=statically linked、零外部依赖,glibc/musl 任意发行版直接运行(实测 musl 产物在 Debian 13 上正常运行)。make daemon约 7 分钟/架构(5 库命中 Docker 层缓存后),远快于原 glibc depends 系统的 30–60 分钟。 - 为何用 musl 而非 glibc 全静态:glibc 的
getaddrinfo依赖运行时dlopenNSS 模块,-static全静态后无法加载 → DNS 解析失败(DNS error: resource busy or locked);musl 的getaddrinfo自带实现,全静态也能正常解析。与gitea-xxxig/gitea-xxxig-proxy一致。曾用的 glibc(ubuntu) depends 构建线已删除。 - 为何 patch monero 源码(init.sh 末尾,勿删):monero 官方明确「不支持 fully static」——
CMakeLists.txt中STATIC=ON在 Linux 只加-static-libgcc -static-libstdc++(非真-static),且强制追加-pie安全加固,会让链接结果带 musl interpreter、退化成动态。故 init.sh 用sed去掉-pie、把 Linux 的STATIC_FLAGS改成真-static。Alpine gcc 默认 PIE,-static自动产出 static-pie(零外部依赖)。 - 版本号约定:包版本硬编码在 ci.yaml 的
PACKAGE_VERSION: "0.18.5.0"(纯数字、无 v,符合 Debian 版本规范)。关键分界:上游 Monero git tag 带v,故 build job 用MONERO_VERSION=v${PACKAGE_VERSION}补回 v 传给 Dockerfilegit clone --branch;tar.gz / deb / registry 路径 / Release 标题等包版本一律直接用${PACKAGE_VERSION};release job 用VERSION="${TAG#v}"归一(tag 带不带 v 都兼容)。CI 触发条件为tags: ['*'],发版改PACKAGE_VERSION并打对应 tag(纯数字,如0.18.5.0)。 - 依赖精简:5 个静态库 + libstdc++/libgcc 全部静态链入(真
-static),故 debian/control.template 无Depends字段(纯静态,连 libc6 都不需要)。 - 架构映射:Dockerfile 内
arm64→ARCH=armv8-a / BUILD_TAG=linux-armv8、amd64→ARCH=x86-64 / BUILD_TAG=linux-x64(传给 monero cmake);OpenSSL targetaarch64→linux-aarch64、x86_64→linux-x86_64。 - tar.gz 下载 URL 形如
https://gitea.bcde.io/api/packages/wangdefa/generic/mond/{version}/mond-{arch}-linux-static-{version}.tar.gz(version 为纯数字)。
本地常用命令
# 本地编译某架构的二进制(输出到 ./output/linux_<arch>/mond)
docker buildx build --platform linux/amd64 \
--build-arg MONERO_VERSION=v0.18.5.0 \
--output type=local,dest=./output \
-f docker/Dockerfile .
# 用已有 tar.gz 打 .deb 包(注意第三个参数是 tar.gz,不是目录)
./debian/build-deb.sh amd64 0.18.5.0 mond-amd64-linux-static-0.18.5.0.tar.gz
# 改 shell 脚本后做静态检查(需自行安装 shellcheck)
shellcheck debian/*.sh
无单元测试;CI 中唯一的冒烟测试是解包后跑 mond --version(musl 纯静态二进制可在 glibc 的 CI runner 直接运行),并用 ldd 校验为 statically linked(纯静态、无任何动态依赖)。
Debian 包布局与服务
- 二进制装到
/opt/mond/mond,systemd 服务文件 debian/mond.service,维护脚本debian/{postinst,prerm,postrm}。 - 配置流转(单一数据源):
conf/params.example.conf是唯一配置源 → build-deb.sh 复制进包内/opt/mond/params.conf→ postinst 首次安装时cp到/etc/mond/params.conf(升级不覆盖用户已有配置;旧版本位于/var/lib/mond/params.conf时 postinst 会自动迁移到/etc/mond/)。service 的ExecStart用--config-file=/etc/mond/params.conf。改默认配置改 conf/params.example.conf 一处即可(不要再在 postinst 内联)。 - 数据目录
/var/lib/mond/data、日志目录/var/log/mond,均归mond系统用户。 - postinst 创建
mond系统用户/组。服务不自动启用/启动(首次同步需用户确认配置),升级时若服务原为 enabled 则重启以加载新二进制。.deb 安装后手动systemctl enable --now mond。