diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index 7999fd1..259b620 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -44,13 +44,13 @@ jobs: --platform ${PLATFORM} \ --build-arg MONERO_VERSION=${MONERO_VERSION} \ --output type=local,dest=./output \ - -f docker/Dockerfile.ubuntu . + -f docker/Dockerfile . - name: Package and test run: | DIR="./output/linux_${{ matrix.arch }}" VERSION=${PACKAGE_VERSION} - TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-ubuntu-${VERSION}.tar.gz" + TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-linux-static-${VERSION}.tar.gz" tar -czf "${TARGZ}" -C "$DIR" . @@ -60,11 +60,12 @@ jobs: # 快速验证 mkdir -p test && tar -xzf "${TARGZ}" -C test test/mond --version 2>/dev/null || echo "⚠️ 跳过版本检查" - # 依赖校验:第三方库(boost/ssl/zmq 等)应已被 depends 静态链入, - # 运行时只应依赖 glibc(libc/libm/libpthread/ld-linux) - EXTRA=$(ldd test/mond 2>/dev/null | awk '{print $1}' \ - | grep -vE '(^|/)(linux-vdso|libc\.so|libm\.so|libpthread\.so|libdl\.so|librt\.so|libresolv\.so|libutil\.so|ld-linux)' || true) - [ -z "$EXTRA" ] && echo "✅ 运行时仅依赖 glibc" || echo "⚠️ 检测到非 glibc 动态依赖: ${EXTRA}" + # 依赖校验:musl fully-static,ldd 应为 "statically linked"(零外部依赖,glibc/musl 均可直接运行) + if ldd test/mond 2>&1 | grep -qE 'statically linked|not a dynamic executable'; then + echo "✅ fully-static(无任何动态依赖,跨发行版)" + else + echo "⚠️ 非纯静态,仍有动态依赖:"; ldd test/mond + fi rm -rf test - name: Build Debian package @@ -73,7 +74,7 @@ jobs: sudo apt-get update && sudo apt-get install -y dpkg-dev VERSION=${PACKAGE_VERSION} - TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-ubuntu-${VERSION}.tar.gz" + TARGZ="${PRODUCT_NAME}-${{ matrix.arch }}-linux-static-${VERSION}.tar.gz" echo "📦 Building Debian package for ${{ matrix.arch }}..." chmod +x debian/build-deb.sh diff --git a/CLAUDE.md b/CLAUDE.md index 992274c..3b21db0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,14 +4,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## 仓库性质 -本仓库**只包含构建与打包基础设施**,不含 mond 源码。源码在编译时从外部仓库克隆(见 [docker/Dockerfile.ubuntu](docker/Dockerfile.ubuntu)): +本仓库**只包含构建与打包基础设施**,不含 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 而非源码**(源码每次构建都重新克隆)。 +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 打包骨架,但 mond 的构建方式(官方 depends 系统)和版本号格式(四段 `0.18.5.0`)不同。 +> **与同目录 `gitea-xxxig` / `gitea-xxxig-proxy` 的关键差异**:那两个项目源码来自 `wangdefaa`(双 a)换名仓库;mond 直接克隆 Monero 官方仓库,靠 init.sh 现场改名。三者共享同一套 CI / build-deb / debian 打包骨架,且均为 **musl fully-static** 构建;mond 的版本号格式为四段 `0.18.5.0`。 ## 整体架构:单二进制 @@ -21,15 +21,17 @@ mond 是 Monero 守护进程 `monerod` 的定制换名构建。换名通过 [ini [.gitea/workflows/ci.yaml](.gitea/workflows/ci.yaml) 是 Gitea Actions 流水线: -1. **build-and-test**(矩阵 `arch=[amd64,arm64]`,跑在对应架构原生 runner):用 `docker buildx` 按 [docker/Dockerfile.ubuntu](docker/Dockerfile.ubuntu) 原生编译 → 打成 tar.gz → 解包冒烟测试(`mond --version` + `ldd` 纯静态校验)→ 调 `debian/build-deb.sh` 打 .deb → 上传 artifact。 +1. **build-and-test**(矩阵 `arch=[amd64,arm64]`,跑在对应架构原生 runner):用 `docker buildx` 按 [docker/Dockerfile](docker/Dockerfile) 原生编译 → 打成 tar.gz → 解包冒烟测试(`mond --version` + `ldd` 纯静态校验)→ 调 `debian/build-deb.sh` 打 .deb → 上传 artifact。 2. **release**(仅 tag 触发):下载 artifact,上传 tar.gz 到 Generic Package Registry、上传 .deb 到 Debian Registry(stable/main),并用 `jq` 生成描述创建 Gitea Release。 关键点: -- **只构建 ubuntu,不做 alpine**(刻意取舍):mond 用 Monero **官方 depends 系统**(`make depends target=…`)交叉编译,将 boost/openssl/zmq 等第三方依赖全部静态链入,**运行时仅动态依赖 glibc**(`ldd` 仍列出 libc/libm/libpthread/ld-linux —— 并非纯静态,故 Alpine/musl 系统无法直接运行)。主分发渠道是面向 Debian/Ubuntu 的 .deb(`Depends: libc6 (>= 2.31)`);单次构建耗时 30–60 分钟,加 distro 维度会让 CI 翻倍。若要支持 Alpine 须改用 musl + `-static-pie` 真静态构建(当前未做)。 -- **版本号约定**:包版本硬编码在 ci.yaml 的 `PACKAGE_VERSION: "0.18.5.0"`(**纯数字、无 v**,符合 Debian 版本规范)。**关键分界**:上游 Monero git tag 带 `v`,故 build job 用 `MONERO_VERSION=v${PACKAGE_VERSION}` 补回 v 传给 Dockerfile `git checkout`;tar.gz / deb / registry 路径 / Release 标题等包版本一律直接用 `${PACKAGE_VERSION}`;release job 用 `VERSION="${TAG#v}"` 归一(tag 带不带 v 都兼容)。CI 触发条件为 `tags: ['*']`,发版改 `PACKAGE_VERSION` 并打对应 tag(纯数字,如 `0.18.5.0`)。 -- **依赖精简**:depends 系统已将 boost/openssl/zmq/unbound/sodium/unwind 静态链入,故 [debian/control.template](debian/control.template) 仅 `Depends: libc6`,无需列动态库。 -- 架构名映射:Dockerfile 内 `arm64→aarch64-linux-gnu`、`amd64→x86_64-linux-gnu` 作为 depends target。 -- tar.gz 下载 URL 形如 `https://gitea.bcde.io/api/packages/wangdefa/generic/mond/{version}/mond-{arch}-ubuntu-{version}.tar.gz`(version 为纯数字)。 +- **musl fully-static(Alpine 构建,勿改回 glibc)**:[docker/Dockerfile](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` 依赖运行时 `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(零外部依赖)。 +- **版本号约定**:包版本硬编码在 ci.yaml 的 `PACKAGE_VERSION: "0.18.5.0"`(**纯数字、无 v**,符合 Debian 版本规范)。**关键分界**:上游 Monero git tag 带 `v`,故 build job 用 `MONERO_VERSION=v${PACKAGE_VERSION}` 补回 v 传给 Dockerfile `git 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](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 为纯数字)。 ## 本地常用命令 @@ -38,16 +40,16 @@ mond 是 Monero 守护进程 `monerod` 的定制换名构建。换名通过 [ini docker buildx build --platform linux/amd64 \ --build-arg MONERO_VERSION=v0.18.5.0 \ --output type=local,dest=./output \ - -f docker/Dockerfile.ubuntu . + -f docker/Dockerfile . # 用已有 tar.gz 打 .deb 包(注意第三个参数是 tar.gz,不是目录) -./debian/build-deb.sh amd64 0.18.5.0 mond-amd64-ubuntu-0.18.5.0.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`,并用 `ldd` 校验运行时仅依赖 glibc(无第三方动态库)。 +无单元测试;CI 中唯一的冒烟测试是解包后跑 `mond --version`(musl 纯静态二进制可在 glibc 的 CI runner 直接运行),并用 `ldd` 校验为 `statically linked`(纯静态、无任何动态依赖)。 ## Debian 包布局与服务 diff --git a/README.md b/README.md index a6b49a6..316438e 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ - 🏗️ **多架构支持** - 原生支持 AMD64 和 ARM64 架构 - 📦 **多种安装方式** - 提供 Debian 包和通用二进制包 -- 🐧 **多发行版兼容** - 支持 Ubuntu 和 Debian -- 🔗 **依赖精简** - 第三方库(boost/OpenSSL/ZMQ 等)全部静态链入,运行时仅依赖系统 glibc(libc6 ≥ 2.31) +- 🐧 **跨发行版** - musl 纯静态二进制,glibc/musl 任意发行版(Ubuntu/Debian/CentOS/Alpine)直接运行 +- 🔗 **零依赖** - 所有库(boost/OpenSSL/ZMQ/sodium/unbound 及 libc)全部静态链入,`ldd` 显示 `statically linked`,无任何动态依赖 - 🔒 **隐私优先** - 基于 Monero 的隐私保护技术 - 🔄 **自动更新** - 通过 Debian 仓库轻松安装和更新 @@ -34,10 +34,10 @@ sudo apt-get install mond ```bash # 1. 下载对应架构的包(registry 路径与下载名版本号均不带 v 前缀) -wget https://gitea.bcde.io/api/packages/wangdefa/generic/mond/0.18.5.0/mond-amd64-ubuntu-0.18.5.0.tar.gz +wget https://gitea.bcde.io/api/packages/wangdefa/generic/mond/0.18.5.0/mond-amd64-linux-static-0.18.5.0.tar.gz # 2. 解压 -tar -xzf mond-amd64-ubuntu-0.18.5.0.tar.gz +tar -xzf mond-amd64-linux-static-0.18.5.0.tar.gz # 3. 运行 ./mond --help @@ -144,14 +144,14 @@ sudo systemctl restart mond.service ### Docker 构建(推荐) -本项目使用 Docker 和官方 depends 系统构建,将 boost/OpenSSL/ZMQ 等第三方依赖全部静态链入(运行时仅依赖系统 glibc)。 +本项目使用 Docker + Alpine/musl 构建:手动源码编译 5 个静态库(OpenSSL/libsodium/libzmq/expat/unbound)并 patch monero CMakeLists,产出 static-pie 纯静态二进制(零外部依赖、跨发行版)。 #### 构建多架构二进制文件 ```bash # 构建 amd64 和 arm64 架构 docker buildx build --platform linux/amd64,linux/arm64 \ - -f docker/Dockerfile.ubuntu \ + -f docker/Dockerfile \ --output type=local,dest=./output . ``` @@ -160,54 +160,34 @@ docker buildx build --platform linux/amd64,linux/arm64 \ ```bash # 仅构建 amd64 docker buildx build --platform linux/amd64 \ - -f docker/Dockerfile.ubuntu \ + -f docker/Dockerfile \ --output type=local,dest=./output . # 仅构建 arm64 docker buildx build --platform linux/arm64 \ - -f docker/Dockerfile.ubuntu \ + -f docker/Dockerfile \ --output type=local,dest=./output . ``` #### 验证依赖 ```bash -# 运行时动态依赖应只有 glibc 组件(libc/libm/libpthread/ld-linux),无第三方库 +# 纯静态校验:应输出 "statically linked"(零外部依赖,可在 glibc/musl 任意发行版运行) ldd output/linux_amd64/mond -# 预期: 仅 linux-vdso、libc、libm、libpthread、ld-linux 等 glibc 组件 +# 预期: statically linked ``` ### 本地构建 -如果不使用 Docker,可以手动构建: - -```bash -# 1. 克隆并准备源代码 -git clone https://github.com/monero-project/monero.git .source -cd .source -git checkout v0.18.3.4 -git submodule update --init --force - -# 2. 应用修改 -../init.sh - -# 3. 使用 depends 系统构建(推荐) -make -j$(nproc) depends target=x86_64-linux-gnu -# 二进制文件位于: build/x86_64-linux-gnu/release/bin/mond - -# 或者简单构建(需要手动安装依赖) -mkdir -p build/release && cd build/release -cmake ../.. -DCMAKE_BUILD_TYPE=Release -DBUILD_GUI_DEPS=OFF -make -j$(nproc) daemon -``` +纯静态构建需在 Alpine 下手编 5 个静态库(OpenSSL/libsodium/libzmq/expat/unbound)并 patch monero CMakeLists,步骤已固化在 [docker/Dockerfile](docker/Dockerfile)——**直接用上面的 Docker 构建即可**,无需手动复现。换名 + patch 逻辑见 [init.sh](init.sh)。 ### 构建环境要求 -- **操作系统**: Ubuntu 20.04(推荐)或更新版本 -- **CPU**: 多核 CPU(构建时间约 30-60 分钟) +- **构建镜像**: `alpine:3.23`(Dockerfile 内置,无需本机安装) +- **CPU**: 多核 CPU(`make daemon` 约 7 分钟/架构,5 库命中缓存后) - **内存**: 至少 4GB RAM - **磁盘**: 至少 10GB 可用空间 -- **Docker**: 如使用 Docker 构建,需安装 Docker 和 buildx +- **Docker**: 需安装 Docker 和 buildx ## 📝 许可证 diff --git a/debian/build-deb.sh b/debian/build-deb.sh index e96ee13..3c66210 100755 --- a/debian/build-deb.sh +++ b/debian/build-deb.sh @@ -4,7 +4,7 @@ set -e # 参数检查 if [ $# -ne 3 ]; then echo "Usage: $0 " - echo "Example: $0 amd64 0.18.5.0 mond-amd64-ubuntu-0.18.5.0.tar.gz" + echo "Example: $0 amd64 0.18.5.0 mond-amd64-linux-static-0.18.5.0.tar.gz" exit 1 fi diff --git a/debian/control.template b/debian/control.template index 153fd6b..3940cbf 100644 --- a/debian/control.template +++ b/debian/control.template @@ -3,7 +3,6 @@ Version: {{VERSION}} Section: net Priority: optional Architecture: {{ARCH}} -Depends: libc6 (>= 2.31) Maintainer: Mond Team Homepage: https://github.com/monero-project/monero Description: Mond cryptocurrency daemon diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..3f7533c --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,66 @@ +# musl fully-static 构建 mond(monerod 换名):手编 5 个静态库 + patch CMakeLists + static-pie。 +# 为何 musl 而非 glibc:musl 的 getaddrinfo 自包含,全静态可跨发行版运行;glibc 静态会因 NSS +# 运行时 dlopen 失败(DNS error: resource busy or locked)。详见 CLAUDE.md。 +# 产物为 static-pie(Alpine gcc 默认 PIE),零外部依赖,可在 glibc/musl 任意发行版直接运行。 + +# ---- Stage 1: 静态依赖库(版本固定 → Docker 层缓存,源码不变不重编)---- +FROM alpine:3.23 AS deps +RUN apk add --no-cache g++ gcc make cmake git linux-headers autoconf automake libtool \ + pkgconf perl wget tar xz bzip2 file flex bison boost-static boost-dev rapidjson-dev +ENV CFLAGS="-fPIC -O2" CXXFLAGS="-fPIC -O2" +WORKDIR /deps + +# OpenSSL 3.0.16(Alpine 仓库只有 .so,须源码编静态) +RUN wget -q https://github.com/openssl/openssl/releases/download/openssl-3.0.16/openssl-3.0.16.tar.gz && \ + tar xf openssl-3.0.16.tar.gz && cd openssl-3.0.16 && \ + if [ "$(uname -m)" = aarch64 ]; then OSSL_T=linux-aarch64; else OSSL_T=linux-x86_64; fi && \ + ./Configure no-shared no-tests --prefix=/usr --libdir=lib $OSSL_T && \ + make -j"$(nproc)" && make install_sw && cd / && rm -rf /deps/openssl-3.0.16* + +# libsodium 1.0.20 +RUN wget -q https://download.libsodium.org/libsodium/releases/libsodium-1.0.20.tar.gz && \ + tar xf libsodium-1.0.20.tar.gz && cd libsodium-1.0.20 && \ + ./configure --enable-static --disable-shared --prefix=/usr && \ + make -j"$(nproc)" && make install && cd / && rm -rf /deps/libsodium-1.0.20* + +# libzmq 4.3.5 +RUN wget -q https://github.com/zeromq/libzmq/releases/download/v4.3.5/zeromq-4.3.5.tar.gz && \ + tar xf zeromq-4.3.5.tar.gz && cd zeromq-4.3.5 && \ + ./configure --enable-static --disable-shared --prefix=/usr --without-docs --enable-drafts=no && \ + make -j"$(nproc)" && make install && cd / && rm -rf /deps/zeromq-4.3.5* + +# expat 2.6.4 +RUN wget -q https://github.com/libexpat/libexpat/releases/download/R_2_6_4/expat-2.6.4.tar.bz2 && \ + tar xf expat-2.6.4.tar.bz2 && cd expat-2.6.4 && \ + ./configure --enable-static --disable-shared --prefix=/usr && \ + make -j"$(nproc)" && make install && cd / && rm -rf /deps/expat-2.6.4* + +# unbound 1.22.0(DNSSEC;release archive 需 flex/bison 现生成 lexer) +RUN wget -q https://github.com/NLnetLabs/unbound/archive/refs/tags/release-1.22.0.tar.gz -O unbound.tar.gz && \ + tar xf unbound.tar.gz && cd unbound-release-1.22.0 && \ + ./configure --disable-shared --enable-static --prefix=/usr --with-libexpat=/usr --with-ssl=/usr \ + --with-libevent=no --without-pythonmodule --without-pyunbound --with-libunbound-only --with-pic && \ + make -j"$(nproc)" && make install && cd / && rm -rf /deps/unbound* + +# ---- Stage 2: 换名 + patch + 编译 mond ---- +FROM deps AS build +ARG MONERO_VERSION +ARG TARGETARCH +WORKDIR /src +RUN git clone --recursive --branch "${MONERO_VERSION}" --depth 1 --shallow-submodules \ + https://github.com/monero-project/monero.git monero +WORKDIR /src/monero +# init.sh:monero→mond 换名 + musl fully-static patch(去 -pie、STATIC_FLAGS 改 -static) +COPY ./init.sh ./init.sh +RUN sh ./init.sh +RUN if [ "$TARGETARCH" = "arm64" ]; then MARCH=armv8-a; MTAG=linux-armv8; \ + else MARCH=x86-64; MTAG=linux-x64; fi && \ + cmake -S . -B build/release -DSTATIC=ON -DSTACK_TRACE=OFF -DBUILD_64=ON \ + -DCMAKE_BUILD_TYPE=Release -DARCH="$MARCH" -DBUILD_TAG="$MTAG" -DUSE_DEVICE_TREZOR=OFF && \ + make -j"$(nproc)" -C build/release daemon && \ + mkdir -p /output && cp build/release/bin/mond /output/mond + +# ---- Stage 3: 导出(保持 ci.yaml 期望的 linux_/mond 布局)---- +FROM scratch +ARG TARGETARCH +COPY --from=build /output/mond /linux_${TARGETARCH}/mond diff --git a/docker/Dockerfile.ubuntu b/docker/Dockerfile.ubuntu deleted file mode 100644 index d9a54a4..0000000 --- a/docker/Dockerfile.ubuntu +++ /dev/null @@ -1,70 +0,0 @@ -FROM ubuntu:20.04 AS base - -ARG TARGETARCH -ARG BUILDPLATFORM - -ENV DEBIAN_FRONTEND=noninteractive - -# 仅安装 Monero depends 系统所需的最小工具链: -# depends 会自行交叉编译 boost/openssl/zmq/unbound/sodium 等全部第三方库到 contrib/depends//, -# 故无需任何系统 -dev 库(装了反而可能被动态链接、破坏纯静态)。 -RUN apt-get update && apt-get install -y \ - git \ - wget \ - curl \ - ca-certificates \ - build-essential \ - cmake \ - pkg-config \ - autoconf \ - automake \ - libtool \ - gperf \ - python3 \ - bzip2 \ - xz-utils \ - patch \ - && rm -rf /var/lib/apt/lists/* - -FROM base AS build - -ARG MONERO_VERSION -ARG TARGETARCH -ARG BUILDPLATFORM -ARG TARGETPLATFORM - -# 克隆 Monero 项目 -RUN git clone --recursive https://github.com/monero-project/monero.git && \ - cd monero && \ - git checkout ${MONERO_VERSION} && \ - git submodule update --init --force - -WORKDIR /monero - -# 复制并运行 init.sh 脚本进行修改 -COPY ./init.sh ./init.sh - -RUN chmod +x ./init.sh && ./init.sh - -# 使用官方 depends 系统构建静态依赖(参考 .source/Dockerfile) -RUN if [ "$BUILDPLATFORM" != "$TARGETPLATFORM" ]; then \ - MAKE_JOBS=2; \ - else \ - MAKE_JOBS=$(nproc); \ - fi && \ - if [ "$TARGETARCH" = "arm64" ]; then \ - DEPENDS_TARGET="aarch64-linux-gnu"; \ - else \ - DEPENDS_TARGET="x86_64-linux-gnu"; \ - fi && \ - echo "Building dependencies for $DEPENDS_TARGET with $MAKE_JOBS parallel jobs" && \ - make -j$MAKE_JOBS depends target=$DEPENDS_TARGET && \ - mkdir -p /output && \ - cp build/$DEPENDS_TARGET/release/bin/mond /output/mond - -# 最终阶段 - 只复制静态链接的二进制文件 -FROM scratch - -ARG TARGETARCH - -COPY --from=build /output/mond /linux_${TARGETARCH}/mond diff --git a/init.sh b/init.sh index 741e3f5..37a13b1 100755 --- a/init.sh +++ b/init.sh @@ -50,6 +50,13 @@ find tests -type f -name "*.cpp" -exec sed -i 's/"Monero '"'"'/"Mond '"'"'/g' {} # Uncomment the following lines if you want to remove Monero Project copyright # find . -type f \( -name "*.cpp" -o -name "*.h" \) -exec sed -i '/Copyright.*The Monero Project/d' {} \; +# 8. musl fully-static patch(配合 docker/Dockerfile,产出无 interpreter、零外部依赖的 static-pie) +# monero 官方"不支持 fully static":STATIC=ON 在 Linux 仅给 -static-libgcc/-static-libstdc++,且强制 -pie。 +# 去掉 -pie(否则强制动态 PIE/带 musl interpreter,无法跨发行版) +sed -i 's|add_linker_flag_if_supported("-pie" LD_SECURITY_FLAGS)|# -pie removed for fully-static|' CMakeLists.txt +# Linux STATIC_FLAGS 从 -static-libgcc/-static-libstdc++ 改真 -static +sed -i 's|set(STATIC_FLAGS "-static-libgcc -static-libstdc++")|set(STATIC_FLAGS "-static")|' CMakeLists.txt + echo "Project successfully modified from Monero to Mond!" echo "Binary output name: mond" echo "Project name: mond"