Skip to content

Commit

Permalink
Use blst crate for Rust blst dep (#351)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelsproul authored Aug 24, 2023
1 parent fa3c629 commit 4c0d477
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 100 deletions.
42 changes: 42 additions & 0 deletions bindings/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bindings/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ no-threads = []
hex = "0.4.2"
libc = "0.2"
serde = { version = "1.0", features = ["derive"] }
blst = "0.3.11"

[dev-dependencies]
criterion = "0.5.1"
Expand Down
100 changes: 2 additions & 98 deletions bindings/rust/build.rs
Original file line number Diff line number Diff line change
@@ -1,100 +1,9 @@
use std::env;
use std::path::{Path, PathBuf};
use std::path::PathBuf;

const MAINNET_FIELD_ELEMENTS_PER_BLOB: usize = 4096;
const MINIMAL_FIELD_ELEMENTS_PER_BLOB: usize = 4;

/// Compiles blst.
//
// NOTE: This code is taken from https://github.com/supranational/blst `build.rs` `main`. The crate
// is not used as a dependency to avoid double link issues on dependants.
fn compile_blst(blst_base_dir: PathBuf) {
// account for cross-compilation [by examining environment variables]
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();

if target_os.ne("none") && !env::var("BLST_TEST_NO_STD").is_ok() {
println!("cargo:rustc-cfg=feature=\"std\"");
if target_arch.eq("wasm32") {
println!("cargo:rustc-cfg=feature=\"no-threads\"");
}
}
println!("cargo:rerun-if-env-changed=BLST_TEST_NO_STD");

println!("Using blst source directory {}", blst_base_dir.display());

// Set CC environment variable to choose alternative C compiler.
// Optimization level depends on whether or not --release is passed
// or implied.

#[cfg(target_env = "msvc")]
if env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap().eq("32") && !env::var("CC").is_ok() {
match std::process::Command::new("clang-cl")
.arg("--version")
.output()
{
Ok(out) => {
if String::from_utf8(out.stdout)
.unwrap_or("unintelligible".to_string())
.contains("Target: i686-")
{
env::set_var("CC", "clang-cl");
}
}
Err(_) => { /* no clang-cl in sight, just ignore the error */ }
}
}

let mut cc = cc::Build::new();

let c_src_dir = blst_base_dir.join("src");
println!("cargo:rerun-if-changed={}", c_src_dir.display());
let mut file_vec = vec![c_src_dir.join("server.c")];

if target_arch.eq("x86_64") || target_arch.eq("aarch64") {
let asm_dir = blst_base_dir.join("build");
println!("cargo:rerun-if-changed={}", asm_dir.display());
blst_assembly(&mut file_vec, &asm_dir, &target_arch);
} else {
cc.define("__BLST_NO_ASM__", None);
}
cc.define("__BLST_PORTABLE__", None);
if env::var("CARGO_CFG_TARGET_ENV").unwrap().eq("msvc") {
cc.flag("-Zl");
}
cc.flag_if_supported("-mno-avx") // avoid costly transitions
.flag_if_supported("-fno-builtin")
.flag_if_supported("-Wno-unused-function")
.flag_if_supported("-Wno-unused-command-line-argument");
if target_arch.eq("wasm32") {
cc.flag_if_supported("-ffreestanding");
}
if !cfg!(debug_assertions) {
cc.opt_level(2);
}
cc.files(&file_vec).compile("blst");
}

/// Adds assembly files for blst compilation.
fn blst_assembly(file_vec: &mut Vec<PathBuf>, base_dir: &Path, _arch: &String) {
#[cfg(target_env = "msvc")]
if env::var("CARGO_CFG_TARGET_ENV").unwrap().eq("msvc") {
let sfx = match _arch.as_str() {
"x86_64" => "x86_64",
"aarch64" => "armv8",
_ => "unknown",
};
let files = glob::glob(&format!("{}/win64/*-{}.asm", base_dir.display(), sfx))
.expect("unable to collect assembly files");
for file in files {
file_vec.push(file.unwrap());
}
return;
}

file_vec.push(base_dir.join("assembly.S"));
}

fn main() {
let cargo_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let root_dir = cargo_dir
Expand All @@ -112,10 +21,8 @@ fn main() {
eprintln!("Using LIB_PREFIX={lib_name}");
eprintln!("Using FIELD_ELEMENTS_PER_BLOB={field_elements_per_blob}");

let blst_base_dir = root_dir.join("blst");
compile_blst(blst_base_dir.clone());

// Obtain the header files of blst
let blst_base_dir = root_dir.join("blst");
let blst_headers_dir = blst_base_dir.join("bindings");

let c_src_dir = root_dir.join("src");
Expand All @@ -133,9 +40,6 @@ fn main() {

cc.try_compile(lib_name).expect("Failed to compile ckzg");

// Tell cargo to search for the static blst exposed by the blst-bindings' crate.
println!("cargo:rustc-link-lib=static=blst");

let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let bindings_out_path = out_dir.join("generated.rs");
let header_file_path = c_src_dir.join("c_kzg_4844.h");
Expand Down
9 changes: 7 additions & 2 deletions bindings/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// This `extern crate` invocation tells `rustc` that we actually need the symbols from `blst`.
// Without it, the compiler won't link to `blst` when compiling this crate.
// See: https://kornel.ski/rust-sys-crate#linking
extern crate blst;

mod bindings;

// Expose relevant types with idiomatic names.
Expand All @@ -7,8 +12,8 @@ pub use bindings::{
};
// Expose the constants.
pub use bindings::{
BYTES_PER_BLOB, BYTES_PER_COMMITMENT, BYTES_PER_FIELD_ELEMENT, BYTES_PER_PROOF,
FIELD_ELEMENTS_PER_BLOB, BYTES_PER_G1_POINT, BYTES_PER_G2_POINT
BYTES_PER_BLOB, BYTES_PER_COMMITMENT, BYTES_PER_FIELD_ELEMENT, BYTES_PER_G1_POINT,
BYTES_PER_G2_POINT, BYTES_PER_PROOF, FIELD_ELEMENTS_PER_BLOB,
};
// Expose the remaining relevant types.
pub use bindings::{Blob, Bytes32, Bytes48, Error};

0 comments on commit 4c0d477

Please sign in to comment.