diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 779a20c..beb17ae 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -151,6 +151,15 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "logos-blockchain-circuits-build" +version = "0.4.2" +dependencies = [ + "flate2", + "tar", + "ureq", +] + [[package]] name = "logos-blockchain-circuits-common" version = "0.4.2" @@ -162,44 +171,36 @@ dependencies = [ name = "logos-blockchain-circuits-poc-sys" version = "0.4.2" dependencies = [ - "flate2", + "logos-blockchain-circuits-build", "logos-blockchain-circuits-common", "logos-blockchain-circuits-types", - "tar", - "ureq", ] [[package]] name = "logos-blockchain-circuits-pol-sys" version = "0.4.2" dependencies = [ - "flate2", + "logos-blockchain-circuits-build", "logos-blockchain-circuits-common", "logos-blockchain-circuits-types", - "tar", - "ureq", ] [[package]] name = "logos-blockchain-circuits-poq-sys" version = "0.4.2" dependencies = [ - "flate2", + "logos-blockchain-circuits-build", "logos-blockchain-circuits-common", "logos-blockchain-circuits-types", - "tar", - "ureq", ] [[package]] name = "logos-blockchain-circuits-signature-sys" version = "0.4.2" dependencies = [ - "flate2", + "logos-blockchain-circuits-build", "logos-blockchain-circuits-common", "logos-blockchain-circuits-types", - "tar", - "ureq", ] [[package]] diff --git a/rust/Cargo.toml b/rust/Cargo.toml index df0632f..1f48855 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -10,6 +10,7 @@ version = "0.4.2" [workspace] members = [ + "logos-blockchain-circuits-build", "logos-blockchain-circuits-poc-sys", "logos-blockchain-circuits-pol-sys", "logos-blockchain-circuits-poq-sys", @@ -19,6 +20,22 @@ members = [ ] resolver = "3" +[workspace.dependencies] +# Internal +lbc-common = { default-features = false, package = "logos-blockchain-circuits-common", path = "./logos-blockchain-circuits-common" } +lbc-build = { package = "logos-blockchain-circuits-build", path = "./logos-blockchain-circuits-build" } +lbc-poc-sys = { default-features = false, package = "logos-blockchain-circuits-poc-sys", path = "./logos-blockchain-circuits-poc-sys" } +lbc-pol-sys = { default-features = false, package = "logos-blockchain-circuits-pol-sys", path = "./logos-blockchain-circuits-pol-sys" } +lbc-poq-sys = { default-features = false, package = "logos-blockchain-circuits-poq-sys", path = "./logos-blockchain-circuits-poq-sys" } +lbc-signature-sys = { default-features = false, package = "logos-blockchain-circuits-signature-sys", path = "./logos-blockchain-circuits-signature-sys" } +lbc-types = { default-features = false, package = "logos-blockchain-circuits-types", path = "./logos-blockchain-circuits-types" } + +# External +flate2 = "^1" +libc = "^0.2" +tar = "^0.4" +ureq = "^3.3" + # Sourced from https://github.com/logos-co/nomos/blob/main/Cargo.toml [workspace.lints.clippy] @@ -170,18 +187,3 @@ trivial_casts = { level = "allow" } unreachable_pub = { level = "allow" } unsafe_code = { level = "allow" } variant_size_differences = { level = "allow" } - -[workspace.dependencies] -# Internal -lbc-poc-sys = { default-features = false, package = "logos-blockchain-circuits-poc-sys", path = "./logos-blockchain-circuits-poc-sys" } -lbc-pol-sys = { default-features = false, package = "logos-blockchain-circuits-pol-sys", path = "./logos-blockchain-circuits-pol-sys" } -lbc-poq-sys = { default-features = false, package = "logos-blockchain-circuits-poq-sys", path = "./logos-blockchain-circuits-poq-sys" } -lbc-signature-sys = { default-features = false, package = "logos-blockchain-circuits-signature-sys", path = "./logos-blockchain-circuits-signature-sys" } -lbc-types = { default-features = false, package = "logos-blockchain-circuits-types", path = "./logos-blockchain-circuits-types" } -lbc-common = { default-features = false, package = "logos-blockchain-circuits-common", path = "./logos-blockchain-circuits-common" } - -# External -flate2 = "^1" -libc = "^0.2" -tar = "^0.4" -ureq = "^3.3" diff --git a/rust/logos-blockchain-circuits-build/Cargo.toml b/rust/logos-blockchain-circuits-build/Cargo.toml new file mode 100644 index 0000000..fff522c --- /dev/null +++ b/rust/logos-blockchain-circuits-build/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "logos-blockchain-circuits-build" +categories.workspace = true +description = "Shared build script logic for Logos Blockchain Circuits sys crates." +edition.workspace = true +keywords.workspace = true +license.workspace = true +readme.workspace = true +repository.workspace = true +version.workspace = true + +[lints] +workspace = true + +[dependencies] +flate2 = { workspace = true } +tar = { workspace = true } +ureq = { workspace = true } diff --git a/rust/logos-blockchain-circuits-build/src/lib.rs b/rust/logos-blockchain-circuits-build/src/lib.rs new file mode 100644 index 0000000..0c6d85f --- /dev/null +++ b/rust/logos-blockchain-circuits-build/src/lib.rs @@ -0,0 +1,108 @@ +use std::path::{Path, PathBuf}; + +use ureq::Body; +use ureq::http::Response; + +static REPO: &str = "logos-blockchain/logos-blockchain-circuits"; +static ARTIFACT_PREFIX: &str = "logos-blockchain-circuits"; + +fn get_artifact_name(version: &str, os: &str, arch: &str) -> String { + format!("{ARTIFACT_PREFIX}-v{version}-{os}-{arch}") +} + +fn get_artifact_url(version: &str, os: &str, arch: &str) -> String { + let artifact = get_artifact_name(version, os, arch); + let artifact_tar_gz = format!("{artifact}.tar.gz"); + format!("https://github.com/{REPO}/releases/download/v{version}/{artifact_tar_gz}") +} + +fn fetch_library(version: &str, os: &str, arch: &str, lib_var_name: &str) -> Response { + let url = get_artifact_url(version, os, arch); + // We skip checksum verification intentionally. + // Hardcoded hashes would protect against a silently replaced release asset, but require a + // two-step release (build → hash → commit → tag) which feels overkill for a first-party + // library. + ureq::get(&url).call().unwrap_or_else(|error| { + panic!( + "Failed to download a prebuilt library for {os}-{arch} v{version}: {error}. \ + Set {lib_var_name} to point to a local build instead." + ) + }) +} + +fn unpack_library( + response: Response, + circuit_name: &str, + version: &str, + os: &str, + arch: &str, + output_dir: &Path, +) -> PathBuf { + let gz_decoder = flate2::read::GzDecoder::new(response.into_body().into_reader()); + let mut archive = tar::Archive::new(gz_decoder); + archive + .unpack(output_dir) + .expect("Failed to unpack the downloaded archive."); + + let unpacked_artifact_path = output_dir.join(get_artifact_name(version, os, arch)); + let unpacked_library_directory = unpacked_artifact_path.join(circuit_name); + + assert!( + unpacked_library_directory.is_dir(), + "Failed to find the unpacked library at {}", + unpacked_library_directory.display() + ); + + unpacked_library_directory +} + +fn provision_library(circuit_name: &str, lib_var_name: &str) -> PathBuf { + let version = env!("CARGO_PKG_VERSION"); + let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); + let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap()); + + let expected_library_directory = out_dir + .join(get_artifact_name(version, &os, &arch)) + .join(circuit_name); + if expected_library_directory.is_dir() { + println!( + "Found an existing library at {}. Reusing it.", + expected_library_directory.display() + ); + return expected_library_directory; + } + + let response = fetch_library(version, &os, &arch, lib_var_name); + unpack_library(response, circuit_name, version, &os, &arch, &out_dir) +} + +pub fn build(circuit_name: &str, lib_var_name: &str) { + println!("cargo:rerun-if-env-changed={lib_var_name}"); + println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION"); + println!("cargo:rerun-if-changed=Cargo.toml"); + println!("cargo:rerun-if-changed=build.rs"); + + let lib_dir = std::env::var(lib_var_name).map_or_else( + |_| provision_library(circuit_name, lib_var_name), + |lib_dir| { + println!("Using a library directory from {lib_var_name}: {lib_dir}"); + let lib_dir_path = PathBuf::from(lib_dir); + assert!( + lib_dir_path.is_dir(), + "The library directory specified in {lib_var_name} at {} does not exist.", + lib_dir_path.display() + ); + lib_dir_path + }, + ); + + let lib_dir = lib_dir + .to_str() + .expect("Failed to convert the library directory path to a string"); + println!("cargo:rustc-env={lib_var_name}={lib_dir}"); + println!("cargo:rustc-link-search=native={lib_dir}"); + println!("cargo:rustc-link-lib=static={circuit_name}"); + println!("cargo:rustc-link-lib=stdc++"); + println!("cargo:rustc-link-lib=gmp"); +} diff --git a/rust/logos-blockchain-circuits-poc-sys/Cargo.toml b/rust/logos-blockchain-circuits-poc-sys/Cargo.toml index 4302dd5..01fa797 100644 --- a/rust/logos-blockchain-circuits-poc-sys/Cargo.toml +++ b/rust/logos-blockchain-circuits-poc-sys/Cargo.toml @@ -17,6 +17,4 @@ lbc-types = { workspace = true } lbc-common = { workspace = true } [build-dependencies] -flate2 = { workspace = true } -tar = { workspace = true } -ureq = { workspace = true } +lbc-build = { workspace = true } diff --git a/rust/logos-blockchain-circuits-poc-sys/build.rs b/rust/logos-blockchain-circuits-poc-sys/build.rs index 89f319d..33ca513 100644 --- a/rust/logos-blockchain-circuits-poc-sys/build.rs +++ b/rust/logos-blockchain-circuits-poc-sys/build.rs @@ -1,107 +1,3 @@ -use std::path::{Path, PathBuf}; -use ureq::Body; -use ureq::http::Response; - -static CIRCUIT_NAME: &str = "poc"; -static LIB_VAR_NAME: &str = "LBC_POC_LIB_DIR"; - -fn get_artifact_name(version: &str, os: &str, arch: &str) -> String { - format!("logos-blockchain-circuits-v{version}-{os}-{arch}") -} - -fn get_artifact_url(version: &str, os: &str, arch: &str) -> String { - let artifact = get_artifact_name(version, os, arch); - let artifact_tar_gz = format!("{artifact}.tar.gz"); - format!( - "https://github.com/logos-blockchain/logos-blockchain-circuits/releases/download/v{version}/{artifact_tar_gz}" - ) -} - -fn fetch_library(version: &str, os: &str, arch: &str) -> Response { - let url = get_artifact_url(version, os, arch); - // We skip checksum verification intentionally. Hardcoded hashes would protect against a - // silently replaced release asset, but require a two-step release (build → hash → commit → - // tag) which we consider too costly for now. - ureq::get(&url).call().unwrap_or_else(|error| { - panic!( - "Failed to download a prebuilt library for {os}-{arch} v{version}: {error}. \ - Set {LIB_VAR_NAME} to point to a local build instead." - ) - }) -} - -fn unpack_library( - response: Response, - version: &str, - os: &str, - arch: &str, - output_dir: &Path, -) -> PathBuf { - let gz_decoder = flate2::read::GzDecoder::new(response.into_body().into_reader()); - let mut archive = tar::Archive::new(gz_decoder); - archive - .unpack(output_dir) - .expect("Failed to unpack the downloaded archive."); - - let unpacked_artifact_path = output_dir.join(get_artifact_name(version, os, arch)); - let unpacked_library_directory = unpacked_artifact_path.join(CIRCUIT_NAME); - - assert!( - unpacked_library_directory.is_dir(), - "Failed to find the unpacked library at {}", - unpacked_library_directory.display() - ); - - unpacked_library_directory -} - -fn provision_library() -> PathBuf { - let version = env!("CARGO_PKG_VERSION"); - let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); - let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap()); - - let expected_library_directory = out_dir - .join(get_artifact_name(version, &os, &arch)) - .join(CIRCUIT_NAME); - if expected_library_directory.exists() { - println!( - "Found an existing library at {}. Reusing it.", - expected_library_directory.display() - ); - return expected_library_directory; - } - - let response = fetch_library(version, &os, &arch); - unpack_library(response, version, &os, &arch, &out_dir) -} - fn main() { - println!("cargo:rerun-if-env-changed={LIB_VAR_NAME}"); - println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION"); - println!("cargo:rerun-if-changed=Cargo.toml"); - println!("cargo:rerun-if-changed=build.rs"); - - let lib_dir = std::env::var(LIB_VAR_NAME).map_or_else( - |_| provision_library(), - |lib_dir| { - println!("Using a library directory from {LIB_VAR_NAME}: {lib_dir}"); - let lib_dir_path = PathBuf::from(lib_dir); - assert!( - lib_dir_path.is_dir(), - "The library directory specified in {LIB_VAR_NAME} at {} does not exist.", - lib_dir_path.display() - ); - lib_dir_path - }, - ); - - let lib_dir = lib_dir - .to_str() - .expect("Failed to convert the library directory path to a string"); - println!("cargo:rustc-env={LIB_VAR_NAME}={lib_dir}"); - println!("cargo:rustc-link-search=native={lib_dir}"); - println!("cargo:rustc-link-lib=static={CIRCUIT_NAME}"); - println!("cargo:rustc-link-lib=stdc++"); - println!("cargo:rustc-link-lib=gmp"); + lbc_build::build("poc", "LBC_POC_LIB_DIR"); } diff --git a/rust/logos-blockchain-circuits-pol-sys/Cargo.toml b/rust/logos-blockchain-circuits-pol-sys/Cargo.toml index 99d9de2..7bb520e 100644 --- a/rust/logos-blockchain-circuits-pol-sys/Cargo.toml +++ b/rust/logos-blockchain-circuits-pol-sys/Cargo.toml @@ -17,6 +17,4 @@ lbc-types = { workspace = true } lbc-common = { workspace = true } [build-dependencies] -flate2 = { workspace = true } -tar = { workspace = true } -ureq = { workspace = true } +lbc-build = { workspace = true } diff --git a/rust/logos-blockchain-circuits-pol-sys/build.rs b/rust/logos-blockchain-circuits-pol-sys/build.rs index 9d0735e..8966f3f 100644 --- a/rust/logos-blockchain-circuits-pol-sys/build.rs +++ b/rust/logos-blockchain-circuits-pol-sys/build.rs @@ -1,107 +1,3 @@ -use std::path::{Path, PathBuf}; -use ureq::Body; -use ureq::http::Response; - -static CIRCUIT_NAME: &str = "pol"; -static LIB_VAR_NAME: &str = "LBC_POL_LIB_DIR"; - -fn get_artifact_name(version: &str, os: &str, arch: &str) -> String { - format!("logos-blockchain-circuits-v{version}-{os}-{arch}") -} - -fn get_artifact_url(version: &str, os: &str, arch: &str) -> String { - let artifact = get_artifact_name(version, os, arch); - let artifact_tar_gz = format!("{artifact}.tar.gz"); - format!( - "https://github.com/logos-blockchain/logos-blockchain-circuits/releases/download/v{version}/{artifact_tar_gz}" - ) -} - -fn fetch_library(version: &str, os: &str, arch: &str) -> Response { - let url = get_artifact_url(version, os, arch); - // We skip checksum verification intentionally. Hardcoded hashes would protect against a - // silently replaced release asset, but require a two-step release (build → hash → commit → - // tag) which we consider too costly for now. - ureq::get(&url).call().unwrap_or_else(|error| { - panic!( - "Failed to download a prebuilt library for {os}-{arch} v{version}: {error}. \ - Set {LIB_VAR_NAME} to point to a local build instead." - ) - }) -} - -fn unpack_library( - response: Response, - version: &str, - os: &str, - arch: &str, - output_dir: &Path, -) -> PathBuf { - let gz_decoder = flate2::read::GzDecoder::new(response.into_body().into_reader()); - let mut archive = tar::Archive::new(gz_decoder); - archive - .unpack(output_dir) - .expect("Failed to unpack the downloaded archive."); - - let unpacked_artifact_path = output_dir.join(get_artifact_name(version, os, arch)); - let unpacked_library_directory = unpacked_artifact_path.join(CIRCUIT_NAME); - - assert!( - unpacked_library_directory.is_dir(), - "Failed to find the unpacked library at {}", - unpacked_library_directory.display() - ); - - unpacked_library_directory -} - -fn provision_library() -> PathBuf { - let version = env!("CARGO_PKG_VERSION"); - let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); - let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap()); - - let expected_library_directory = out_dir - .join(get_artifact_name(version, &os, &arch)) - .join(CIRCUIT_NAME); - if expected_library_directory.exists() { - println!( - "Found an existing library at {}. Reusing it.", - expected_library_directory.display() - ); - return expected_library_directory; - } - - let response = fetch_library(version, &os, &arch); - unpack_library(response, version, &os, &arch, &out_dir) -} - fn main() { - println!("cargo:rerun-if-env-changed={LIB_VAR_NAME}"); - println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION"); - println!("cargo:rerun-if-changed=Cargo.toml"); - println!("cargo:rerun-if-changed=build.rs"); - - let lib_dir = std::env::var(LIB_VAR_NAME).map_or_else( - |_| provision_library(), - |lib_dir| { - println!("Using a library directory from {LIB_VAR_NAME}: {lib_dir}"); - let lib_dir_path = PathBuf::from(lib_dir); - assert!( - lib_dir_path.is_dir(), - "The library directory specified in {LIB_VAR_NAME} at {} does not exist.", - lib_dir_path.display() - ); - lib_dir_path - }, - ); - - let lib_dir = lib_dir - .to_str() - .expect("Failed to convert the library directory path to a string"); - println!("cargo:rustc-env={LIB_VAR_NAME}={lib_dir}"); - println!("cargo:rustc-link-search=native={lib_dir}"); - println!("cargo:rustc-link-lib=static={CIRCUIT_NAME}"); - println!("cargo:rustc-link-lib=stdc++"); - println!("cargo:rustc-link-lib=gmp"); + lbc_build::build("pol", "LBC_POL_LIB_DIR"); } diff --git a/rust/logos-blockchain-circuits-poq-sys/Cargo.toml b/rust/logos-blockchain-circuits-poq-sys/Cargo.toml index a9cdc2a..d3b8324 100644 --- a/rust/logos-blockchain-circuits-poq-sys/Cargo.toml +++ b/rust/logos-blockchain-circuits-poq-sys/Cargo.toml @@ -17,6 +17,4 @@ lbc-types = { workspace = true } lbc-common = { workspace = true } [build-dependencies] -flate2 = { workspace = true } -tar = { workspace = true } -ureq = { workspace = true } +lbc-build = { workspace = true } diff --git a/rust/logos-blockchain-circuits-poq-sys/build.rs b/rust/logos-blockchain-circuits-poq-sys/build.rs index 68d607d..305cc4b 100644 --- a/rust/logos-blockchain-circuits-poq-sys/build.rs +++ b/rust/logos-blockchain-circuits-poq-sys/build.rs @@ -1,118 +1,3 @@ -use std::path::{Path, PathBuf}; -use ureq::Body; -use ureq::http::Response; - -static CIRCUIT_NAME: &str = "poq"; -static LIB_VAR_NAME: &str = "LBC_POQ_LIB_DIR"; - -fn get_artifact_name(version: &str, os: &str, arch: &str) -> String { - format!("logos-blockchain-circuits-v{version}-{os}-{arch}") -} - -fn get_artifact_url(version: &str, os: &str, arch: &str) -> String { - let artifact = get_artifact_name(version, os, arch); - let artifact_tar_gz = format!("{artifact}.tar.gz"); - format!( - "https://github.com/logos-blockchain/logos-blockchain-circuits/releases/download/v{version}/{artifact_tar_gz}" - ) -} - -fn fetch_library(version: &str, os: &str, arch: &str) -> Response { - let url = get_artifact_url(version, os, arch); - // We skip checksum verification intentionally. Hardcoded hashes would protect against a - // silently replaced release asset, but require a two-step release (build → hash → commit → - // tag) which we consider too costly for now. - ureq::get(&url).call().unwrap_or_else(|error| { - panic!( - "Failed to download a prebuilt library for {os}-{arch} v{version}: {error}. \ - Set {LIB_VAR_NAME} to point to a local build instead." - ) - }) -} - -fn unpack_library( - response: Response, - version: &str, - os: &str, - arch: &str, - output_dir: &Path, -) -> PathBuf { - let gz_decoder = flate2::read::GzDecoder::new(response.into_body().into_reader()); - let mut archive = tar::Archive::new(gz_decoder); - archive - .unpack(output_dir) - .expect("Failed to unpack the downloaded archive."); - - let unpacked_artifact_path = output_dir.join(get_artifact_name(version, os, arch)); - let unpacked_library_directory = unpacked_artifact_path.join(CIRCUIT_NAME); - - assert!( - unpacked_library_directory.is_dir(), - "Failed to find the unpacked library at {}", - unpacked_library_directory.display() - ); - - unpacked_library_directory -} - -fn provision_library() -> PathBuf { - let version = env!("CARGO_PKG_VERSION"); - let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); - let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap()); - - let expected_library_directory = out_dir - .join(get_artifact_name(version, &os, &arch)) - .join(CIRCUIT_NAME); - if expected_library_directory.exists() { - println!( - "Found an existing library at {}. Reusing it.", - expected_library_directory.display() - ); - return expected_library_directory; - } - - let response = fetch_library(version, &os, &arch); - unpack_library(response, version, &os, &arch, &out_dir) -} - -/// Configures the corresponding witness generator library. -/// -/// # Arguments -/// -/// - `LIB_VAR_NAME` is the name of the environment variable that points to the directory -/// containing the library. If it is not set, the library will be downloaded from GitHub. -/// -/// # Output -/// -/// - `LIB_VAR_NAME` is always emitted so internals can refer to it regardless of whether the -/// library was downloaded or provided by the user. fn main() { - println!("cargo:rerun-if-env-changed={LIB_VAR_NAME}"); - println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION"); - println!("cargo:rerun-if-changed=Cargo.toml"); - println!("cargo:rerun-if-changed=build.rs"); - - let lib_dir = std::env::var(LIB_VAR_NAME).map_or_else( - |_| provision_library(), - |lib_dir| { - println!("Using a library directory from {LIB_VAR_NAME}: {lib_dir}"); - let lib_dir_path = PathBuf::from(lib_dir); - assert!( - lib_dir_path.is_dir(), - "The library directory specified in {LIB_VAR_NAME} at {} does not exist.", - lib_dir_path.display() - ); - lib_dir_path - }, - ); - - let lib_dir = lib_dir - .to_str() - .expect("Failed to convert the library directory path to a string"); - println!("cargo:rustc-env={LIB_VAR_NAME}={lib_dir}"); - println!("cargo:rustc-link-search=native={lib_dir}"); - println!("cargo:rustc-link-lib=static={CIRCUIT_NAME}"); - println!("cargo:rustc-link-lib=stdc++"); - println!("cargo:rustc-link-lib=gmp"); + lbc_build::build("poq", "LBC_POQ_LIB_DIR"); } diff --git a/rust/logos-blockchain-circuits-signature-sys/Cargo.toml b/rust/logos-blockchain-circuits-signature-sys/Cargo.toml index d055ba6..0a4ec14 100644 --- a/rust/logos-blockchain-circuits-signature-sys/Cargo.toml +++ b/rust/logos-blockchain-circuits-signature-sys/Cargo.toml @@ -17,6 +17,4 @@ lbc-types = { workspace = true } lbc-common = { workspace = true } [build-dependencies] -flate2 = { workspace = true } -tar = { workspace = true } -ureq = { workspace = true } +lbc-build = { workspace = true } diff --git a/rust/logos-blockchain-circuits-signature-sys/build.rs b/rust/logos-blockchain-circuits-signature-sys/build.rs index 05b675f..74bd5b2 100644 --- a/rust/logos-blockchain-circuits-signature-sys/build.rs +++ b/rust/logos-blockchain-circuits-signature-sys/build.rs @@ -1,107 +1,3 @@ -use std::path::{Path, PathBuf}; -use ureq::Body; -use ureq::http::Response; - -static CIRCUIT_NAME: &str = "signature"; -static LIB_VAR_NAME: &str = "LBC_SIGNATURE_LIB_DIR"; - -fn get_artifact_name(version: &str, os: &str, arch: &str) -> String { - format!("logos-blockchain-circuits-v{version}-{os}-{arch}") -} - -fn get_artifact_url(version: &str, os: &str, arch: &str) -> String { - let artifact = get_artifact_name(version, os, arch); - let artifact_tar_gz = format!("{artifact}.tar.gz"); - format!( - "https://github.com/logos-blockchain/logos-blockchain-circuits/releases/download/v{version}/{artifact_tar_gz}" - ) -} - -fn fetch_library(version: &str, os: &str, arch: &str) -> Response { - let url = get_artifact_url(version, os, arch); - // We skip checksum verification intentionally. Hardcoded hashes would protect against a - // silently replaced release asset, but require a two-step release (build → hash → commit → - // tag) which we consider too costly for now. - ureq::get(&url).call().unwrap_or_else(|error| { - panic!( - "Failed to download a prebuilt library for {os}-{arch} v{version}: {error}. \ - Set {LIB_VAR_NAME} to point to a local build instead." - ) - }) -} - -fn unpack_library( - response: Response, - version: &str, - os: &str, - arch: &str, - output_dir: &Path, -) -> PathBuf { - let gz_decoder = flate2::read::GzDecoder::new(response.into_body().into_reader()); - let mut archive = tar::Archive::new(gz_decoder); - archive - .unpack(output_dir) - .expect("Failed to unpack the downloaded archive."); - - let unpacked_artifact_path = output_dir.join(get_artifact_name(version, os, arch)); - let unpacked_library_directory = unpacked_artifact_path.join(CIRCUIT_NAME); - - assert!( - unpacked_library_directory.is_dir(), - "Failed to find the unpacked library at {}", - unpacked_library_directory.display() - ); - - unpacked_library_directory -} - -fn provision_library() -> PathBuf { - let version = env!("CARGO_PKG_VERSION"); - let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); - let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap()); - - let expected_library_directory = out_dir - .join(get_artifact_name(version, &os, &arch)) - .join(CIRCUIT_NAME); - if expected_library_directory.exists() { - println!( - "Found an existing library at {}. Reusing it.", - expected_library_directory.display() - ); - return expected_library_directory; - } - - let response = fetch_library(version, &os, &arch); - unpack_library(response, version, &os, &arch, &out_dir) -} - fn main() { - println!("cargo:rerun-if-env-changed={LIB_VAR_NAME}"); - println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION"); - println!("cargo:rerun-if-changed=Cargo.toml"); - println!("cargo:rerun-if-changed=build.rs"); - - let lib_dir = std::env::var(LIB_VAR_NAME).map_or_else( - |_| provision_library(), - |lib_dir| { - println!("Using a library directory from {LIB_VAR_NAME}: {lib_dir}"); - let lib_dir_path = PathBuf::from(lib_dir); - assert!( - lib_dir_path.is_dir(), - "The library directory specified in {LIB_VAR_NAME} at {} does not exist.", - lib_dir_path.display() - ); - lib_dir_path - }, - ); - - let lib_dir = lib_dir - .to_str() - .expect("Failed to convert the library directory path to a string"); - println!("cargo:rustc-env={LIB_VAR_NAME}={lib_dir}"); - println!("cargo:rustc-link-search=native={lib_dir}"); - println!("cargo:rustc-link-lib=static={CIRCUIT_NAME}"); - println!("cargo:rustc-link-lib=stdc++"); - println!("cargo:rustc-link-lib=gmp"); + lbc_build::build("signature", "LBC_SIGNATURE_LIB_DIR"); }