mirror of
https://github.com/logos-blockchain/logos-blockchain-rust-rapidsnark.git
synced 2026-06-13 22:59:27 +00:00
fix: host -fPIC Linux archives from the fork instead of building from source
Building rapidsnark from source in build.rs required cmake/nasm/gmp on every runner, which the self-hosted CI hosts lack. Instead, host pre-built -fPIC static archives as a fork GitHub release and download them like before. - build.rs: reverted to the download-based approach (the PIC archives are built on glibc 2.35 so they carry no __isoc23 references; no compat shim needed). - download_rapidsnark.sh: Linux x86_64/arm64 now download the -fPIC rebuilds from this fork's `rapidsnark-pic-*` release; macOS/iOS/Android keep using the upstream iden3 archives (which work fine). - Add .github/workflows/build-pic-archives.yml: builds the -fPIC archives (rapidsnark + GMP) inside a glibc-2.35 container and publishes/updates the release. Trigger by pushing a `rapidsnark-pic-*` tag or via workflow_dispatch. Verified locally (glibc-2.35 container): the produced archives link into a -shared cdylib with rust-lld. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
384513f9c9
commit
632ef6f643
108
.github/workflows/build-pic-archives.yml
vendored
Normal file
108
.github/workflows/build-pic-archives.yml
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
name: Build PIC archives
|
||||
|
||||
# Builds position-independent (-fPIC) static archives of rapidsnark + GMP for
|
||||
# glibc-Linux and publishes them as a GitHub release. The upstream iden3 Linux
|
||||
# archives are non-PIC and built against a newer glibc, so they cannot be linked
|
||||
# into a shared library (e.g. a downstream cdylib). crates/download_rapidsnark.sh
|
||||
# consumes the release produced here for the Linux targets.
|
||||
#
|
||||
# Trigger by pushing a tag like `rapidsnark-pic-v0.0.8`, or manually via the
|
||||
# "Run workflow" button (workflow_dispatch).
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
rapidsnark_version:
|
||||
description: "iden3 rapidsnark tag to build"
|
||||
default: "v0.0.8"
|
||||
push:
|
||||
tags:
|
||||
- "rapidsnark-pic-*"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
RAPIDSNARK_VERSION: ${{ github.event.inputs.rapidsnark_version || 'v0.0.8' }}
|
||||
GMP_VERSION: "6.3.0"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: x86_64
|
||||
slug: rapidsnark-linux-x86_64-pic
|
||||
# Build inside a glibc-2.35 image so the archives stay compatible with older
|
||||
# glibc hosts (avoids the __isoc23_* / newer-GLIBCXX symbol requirements).
|
||||
runs-on: ubuntu-latest
|
||||
container: ubuntu:22.04
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y build-essential cmake nasm m4 xz-utils zip git curl ca-certificates libgmp-dev
|
||||
|
||||
- name: Build GMP (static, -fPIC)
|
||||
run: |
|
||||
curl -fsSL -o gmp.tar.xz "https://ftpmirror.gnu.org/gmp/gmp-${GMP_VERSION}.tar.xz"
|
||||
tar xf gmp.tar.xz
|
||||
cd "gmp-${GMP_VERSION}"
|
||||
./configure --enable-static --disable-shared --with-pic --prefix="$PWD/../gmp-install"
|
||||
make -j"$(nproc)"
|
||||
make install
|
||||
|
||||
- name: Build rapidsnark (static, -fPIC)
|
||||
run: |
|
||||
git clone --depth 1 --branch "$RAPIDSNARK_VERSION" https://github.com/iden3/rapidsnark.git rs
|
||||
cd rs
|
||||
git submodule update --init --depth 1 depends/ffiasm depends/json
|
||||
mkdir bp && cd bp
|
||||
cmake .. \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
|
||||
-DUSE_ASM=ON \
|
||||
-DUSE_OPENMP=OFF \
|
||||
-DUSE_LOGGER=ON
|
||||
make -j"$(nproc)" rapidsnarkStatic fr fq
|
||||
|
||||
- name: Package archives
|
||||
run: |
|
||||
NAME="${{ matrix.slug }}-${RAPIDSNARK_VERSION}"
|
||||
mkdir -p "pkg/$NAME/lib"
|
||||
cp rs/bp/src/librapidsnark.a rs/bp/src/libfr.a rs/bp/src/libfq.a \
|
||||
gmp-install/lib/libgmp.a "pkg/$NAME/lib/"
|
||||
(cd pkg && zip -r "../$NAME.zip" "$NAME")
|
||||
echo "--- contents ---"
|
||||
unzip -l "$NAME.zip"
|
||||
echo "isoc23 refs (expect 0): $(nm "pkg/$NAME/lib/librapidsnark.a" | grep -c isoc23 || true)"
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.slug }}
|
||||
path: ${{ matrix.slug }}-*.zip
|
||||
if-no-files-found: error
|
||||
|
||||
publish:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: dist
|
||||
merge-multiple: true
|
||||
|
||||
- name: Publish / update release
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
TAG="rapidsnark-pic-${RAPIDSNARK_VERSION}"
|
||||
ls -la dist/
|
||||
gh release create "$TAG" --repo "$GITHUB_REPOSITORY" \
|
||||
--title "rapidsnark ${RAPIDSNARK_VERSION} (-fPIC Linux archives)" \
|
||||
--notes "Position-independent static archives of rapidsnark ${RAPIDSNARK_VERSION} and GMP ${GMP_VERSION}, built on glibc 2.35 for Linux. Consumed by crates/download_rapidsnark.sh for the Linux targets." \
|
||||
|| echo "Release $TAG already exists; updating assets."
|
||||
gh release upload "$TAG" dist/*.zip --repo "$GITHUB_REPOSITORY" --clobber
|
||||
@ -4,8 +4,6 @@ use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
const RAPIDSNARK_DOWNLOAD_SCRIPT: &str = include_str!("./download_rapidsnark.sh");
|
||||
const RAPIDSNARK_GIT: &str = "https://github.com/iden3/rapidsnark.git";
|
||||
const RAPIDSNARK_TAG: &str = "v0.0.8";
|
||||
|
||||
fn main() {
|
||||
let target = env::var("TARGET").unwrap();
|
||||
@ -15,16 +13,6 @@ fn main() {
|
||||
// See: https://github.com/zkmopro/chkstk_stub
|
||||
chkstk_stub::build();
|
||||
|
||||
// On glibc-Linux with static linking the prebuilt iden3 archives don't work:
|
||||
// they are non-PIC (cannot be linked into a downstream cdylib such as the
|
||||
// node's C bindings) and are built against a newer glibc (undefined
|
||||
// __isoc23_strtoll/ull on older hosts). Build rapidsnark from source with
|
||||
// -fPIC against the host toolchain instead, which resolves both problems.
|
||||
if build_from_source_applies() {
|
||||
build_rapidsnark_from_source(&out_dir);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to list contents of the target directory
|
||||
let rapidsnark_path = Path::new(&out_dir).join(Path::new("rapidsnark"));
|
||||
// If the rapidsnark repo is not downloaded, download it
|
||||
@ -85,86 +73,6 @@ fn main() {
|
||||
println!("cargo:rustc-link-lib={thread_lib}");
|
||||
}
|
||||
|
||||
fn build_from_source_applies() -> bool {
|
||||
is_static_rapidsnark()
|
||||
&& env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("linux")
|
||||
&& env::var("CARGO_CFG_TARGET_ENV").as_deref() == Ok("gnu")
|
||||
}
|
||||
|
||||
/// Build rapidsnark's static archives from source with position-independent code.
|
||||
///
|
||||
/// Requires `git`, `cmake`, `make`, `nasm`, a C++ compiler, and the GMP/libsodium
|
||||
/// development headers to be available on the build host. GMP is linked from the
|
||||
/// system as a (PIC) shared library.
|
||||
fn build_rapidsnark_from_source(out_dir: &str) {
|
||||
let src = Path::new(out_dir).join("rapidsnark-src");
|
||||
if !src.join("CMakeLists.txt").exists() {
|
||||
// Clean any partial checkout so the clone can succeed.
|
||||
let _ = fs::remove_dir_all(&src);
|
||||
run(Command::new("git").args([
|
||||
"clone",
|
||||
"--depth",
|
||||
"1",
|
||||
"--branch",
|
||||
RAPIDSNARK_TAG,
|
||||
RAPIDSNARK_GIT,
|
||||
src.to_str().unwrap(),
|
||||
]));
|
||||
}
|
||||
// Only the field-element codegen (ffiasm) and JSON header are needed to build
|
||||
// the prover/verifier static libraries.
|
||||
run(Command::new("git").current_dir(&src).args([
|
||||
"submodule",
|
||||
"update",
|
||||
"--init",
|
||||
"--depth",
|
||||
"1",
|
||||
"depends/ffiasm",
|
||||
"depends/json",
|
||||
]));
|
||||
|
||||
let build = src.join("build_pic");
|
||||
fs::create_dir_all(&build).expect("Failed to create rapidsnark build dir");
|
||||
run(Command::new("cmake").current_dir(&build).args([
|
||||
"..",
|
||||
"-DCMAKE_BUILD_TYPE=Release",
|
||||
"-DCMAKE_POSITION_INDEPENDENT_CODE=ON",
|
||||
"-DUSE_ASM=ON",
|
||||
"-DUSE_OPENMP=OFF",
|
||||
"-DUSE_LOGGER=ON",
|
||||
]));
|
||||
|
||||
let jobs = std::thread::available_parallelism()
|
||||
.map(|n| n.get())
|
||||
.unwrap_or(4)
|
||||
.to_string();
|
||||
run(Command::new("make").current_dir(&build).args([
|
||||
"-j",
|
||||
&jobs,
|
||||
"rapidsnarkStatic",
|
||||
"fr",
|
||||
"fq",
|
||||
]));
|
||||
|
||||
let lib_dir = build.join("src");
|
||||
println!("cargo:rustc-link-search=native={}", lib_dir.display());
|
||||
println!("cargo:rustc-link-lib=static=rapidsnark");
|
||||
println!("cargo:rustc-link-lib=static=fr");
|
||||
println!("cargo:rustc-link-lib=static=fq");
|
||||
// GMP is provided by the system as a PIC shared library.
|
||||
println!("cargo:rustc-link-lib=dylib=gmp");
|
||||
println!("cargo:rustc-link-lib=stdc++");
|
||||
println!("cargo:rustc-link-lib=pthread");
|
||||
}
|
||||
|
||||
fn run(cmd: &mut Command) {
|
||||
eprintln!("rapidsnark build: running {cmd:?}");
|
||||
let status = cmd
|
||||
.status()
|
||||
.unwrap_or_else(|e| panic!("Failed to spawn {cmd:?}: {e}"));
|
||||
assert!(status.success(), "Command failed ({status}): {cmd:?}");
|
||||
}
|
||||
|
||||
fn is_static_rapidsnark() -> bool {
|
||||
env::var_os("CARGO_FEATURE_STATIC_RAPIDSNARK").is_some()
|
||||
}
|
||||
|
||||
@ -14,27 +14,32 @@ if [ -z "$TARGET" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Pinned iden3 rapidsnark release. Bump this to update the prebuilt artifacts.
|
||||
# Pinned rapidsnark release. Bump this to update the prebuilt artifacts.
|
||||
VERSION="v0.0.8"
|
||||
BASE_URL="https://github.com/iden3/rapidsnark/releases/download/$VERSION"
|
||||
# Upstream iden3 prebuilt archives (used for macOS / iOS / Android).
|
||||
IDEN3_BASE="https://github.com/iden3/rapidsnark/releases/download/$VERSION"
|
||||
# The iden3 Linux archives are non-PIC and built against a newer glibc, so they
|
||||
# cannot be linked into a shared library (e.g. a downstream cdylib) on the build
|
||||
# hosts. The Logos fork hosts -fPIC rebuilds of the Linux archives instead.
|
||||
FORK_BASE="https://github.com/logos-blockchain/logos-blockchain-rust-rapidsnark/releases/download/rapidsnark-pic-$VERSION"
|
||||
|
||||
BUILD_DIR="$OUT_DIR/rapidsnark"
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
arch=$(echo "$TARGET" | cut -d'-' -f1)
|
||||
|
||||
# Map the rust target triple to the iden3 release asset slug.
|
||||
# Map the rust target triple to the release asset slug and its hosting base URL.
|
||||
case "$TARGET" in
|
||||
x86_64-*-linux-*) asset="rapidsnark-linux-x86_64-$VERSION" ;;
|
||||
aarch64-*-linux-gnu*) asset="rapidsnark-linux-arm64-$VERSION" ;;
|
||||
aarch64-linux-android) asset="rapidsnark-android-arm64-$VERSION" ;;
|
||||
x86_64-linux-android) asset="rapidsnark-android-x86_64-$VERSION" ;;
|
||||
aarch64-apple-darwin) asset="rapidsnark-macOS-arm64-$VERSION" ;;
|
||||
x86_64-apple-darwin) asset="rapidsnark-macOS-x86_64-$VERSION" ;;
|
||||
aarch64-apple-ios-sim|x86_64-apple-ios) asset="rapidsnark-iOS-Simulator-$VERSION" ;;
|
||||
aarch64-apple-ios) asset="rapidsnark-iOS-$VERSION" ;;
|
||||
x86_64-*-linux-*) asset="rapidsnark-linux-x86_64-pic-$VERSION"; base_url="$FORK_BASE" ;;
|
||||
aarch64-*-linux-gnu*) asset="rapidsnark-linux-arm64-pic-$VERSION"; base_url="$FORK_BASE" ;;
|
||||
aarch64-linux-android) asset="rapidsnark-android-arm64-$VERSION"; base_url="$IDEN3_BASE" ;;
|
||||
x86_64-linux-android) asset="rapidsnark-android-x86_64-$VERSION"; base_url="$IDEN3_BASE" ;;
|
||||
aarch64-apple-darwin) asset="rapidsnark-macOS-arm64-$VERSION"; base_url="$IDEN3_BASE" ;;
|
||||
x86_64-apple-darwin) asset="rapidsnark-macOS-x86_64-$VERSION"; base_url="$IDEN3_BASE" ;;
|
||||
aarch64-apple-ios-sim|x86_64-apple-ios) asset="rapidsnark-iOS-Simulator-$VERSION"; base_url="$IDEN3_BASE" ;;
|
||||
aarch64-apple-ios) asset="rapidsnark-iOS-$VERSION"; base_url="$IDEN3_BASE" ;;
|
||||
*)
|
||||
echo "Unsupported TARGET: $TARGET (no iden3 rapidsnark $VERSION asset mapping)"
|
||||
echo "Unsupported TARGET: $TARGET (no rapidsnark $VERSION asset mapping)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@ -42,8 +47,8 @@ esac
|
||||
zip_file="$BUILD_DIR/$asset.zip"
|
||||
|
||||
echo "Downloading $asset.zip ..."
|
||||
if ! curl -fL -o "$zip_file" "$BASE_URL/$asset.zip"; then
|
||||
echo "Failed to download $BASE_URL/$asset.zip"
|
||||
if ! curl -fL -o "$zip_file" "$base_url/$asset.zip"; then
|
||||
echo "Failed to download $base_url/$asset.zip"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user