# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## 仓库性质 本仓库**只包含构建与打包基础设施**,不含 mond 源码。源码在编译时从外部仓库克隆(见 [docker/Dockerfile](docker/Dockerfile)): - 源码仓库:`github.com/monero-project/monero.git`(**Monero 官方仓库**,非换名仓库) - 发布仓库:Gitea `gitea.bcde.io` 下 `wangdefa/mond` 的 Generic / Debian 包仓库 mond 是 Monero 守护进程 `monerod` 的定制换名构建。换名通过 [init.sh](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.1`。 ## 整体架构:单二进制 编译产出单个可执行文件 `mond`:Monero 全节点守护进程,负责 P2P 同步区块链、提供 RPC。配置来自 [conf/params.example.conf](conf/params.example.conf)。 ## 构建与发布流程(CI) Gitea Actions 拆成两条独立流水线: 1. [.gitea/workflows/ci.yml](.gitea/workflows/ci.yml) 仅由分支推送触发:先检查版本、配置与 shell 语法,再用 amd64、arm64 原生 runner 并行编译,执行严格冒烟测试并验证 DEB 包内容;不上传 artifact。 2. [.gitea/workflows/release.yml](.gitea/workflows/release.yml) 仅由 tag 推送触发:校验 tag 与 [VERSION](VERSION) 一致,双架构原生构建 → tar.gz → DEB → artifact 汇总 → SHA256SUMS → Generic/Debian Registry → Gitea Release。 关键点: - **musl fully-static(Alpine 构建,勿改回 glibc)**:[docker/Dockerfile](docker/Dockerfile) 在 `alpine:3.23` 下手动源码编译 5 个静态库(OpenSSL 3.0.21 / libsodium 1.0.20 / libzmq 4.3.5 / expat 2.6.4 / unbound 1.25.1),编出 **static-pie 纯静态**二进制:`ldd` = `statically linked`、零外部依赖,**glibc/musl 任意发行版直接运行**(实测 musl 产物在 Debian 13 上正常运行)。`make daemon` 约 7 分钟/架构(5 库命中 Docker 层缓存后),远快于原 glibc depends 系统的 30–60 分钟。 - **为何用 musl 而非 glibc 全静态**:glibc 的 `getaddrinfo` 依赖运行时 `dlopen` NSS 模块,`-static` 全静态后无法加载 → DNS 解析失败(`DNS error: resource busy or locked`);musl 的 `getaddrinfo` 自带实现,全静态也能正常解析。与 `gitea-xxxig`/`gitea-xxxig-proxy` 一致。曾用的 glibc(ubuntu) depends 构建线已删除。 - **为何 patch monero 源码([init.sh](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(零外部依赖)。init.sh 在修改前后都会校验关键锚点,上游结构变化时必须直接失败,不能跳过补丁继续构建。 - **版本号约定**:根目录 [VERSION](VERSION) 是唯一版本来源,内容为不带 `v` 的四段版本号(当前 `0.18.5.1`)。上游 Monero git tag 带 `v`,构建时补回后传给 Dockerfile;tar.gz、DEB 和 Registry 路径使用纯数字版本。发布 tag 可带或不带 `v`,归一后必须与 VERSION 完全一致。 - **依赖精简**:5 个静态库 + libstdc++/libgcc 全部静态链入(真 `-static`),故 [debian/control.template](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 target `aarch64→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 为纯数字)。 ## 本地常用命令 ```bash # 本地编译某架构的二进制(输出到 ./output/linux_/mond) docker buildx build --platform linux/amd64 \ --build-arg MONERO_VERSION="v$(cat VERSION)" \ --output type=local,dest=./output \ -f docker/Dockerfile . # 用已有 tar.gz 打 .deb 包(注意第三个参数是 tar.gz,不是目录) ./debian/build-deb.sh amd64 0.18.5.1 mond-amd64-linux-static-0.18.5.1.tar.gz # 改 shell 脚本后做静态检查(需自行安装 shellcheck) shellcheck debian/*.sh ``` CI 对二进制执行 `mond --version` 和 `mond --help`,用 `ldd` 严格校验为纯静态,并检查 DEB 内的二进制、默认配置和 systemd 服务。 ## Debian 包布局与服务 - 二进制装到 `/opt/mond/mond`,systemd 服务文件 [debian/mond.service](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`。