Merge branch 'main' into philsippl/init_path
This commit is contained in:
commit
77050626e2
|
@ -65,6 +65,10 @@ tempfile = "3.0"
|
|||
tiny-keccak = "2.0.2"
|
||||
tracing-test = "0.2"
|
||||
|
||||
[build-dependencies]
|
||||
color-eyre = "0.5"
|
||||
enumset = "1.0.8"
|
||||
wasmer = { version = "2.0", features = [ "dylib" ] }
|
||||
wasmer-engine-dylib = "2.2.1"
|
||||
wasmer-compiler-cranelift = "2.2.1"
|
||||
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
use color_eyre::eyre::{eyre, Result};
|
||||
use std::{
|
||||
path::{Component, Path, PathBuf},
|
||||
process::Command,
|
||||
str::FromStr, env,
|
||||
};
|
||||
use wasmer::{Module, Store, Target, Triple};
|
||||
use wasmer_compiler_cranelift::Cranelift;
|
||||
use wasmer_engine_dylib::Dylib;
|
||||
use enumset::enum_set;
|
||||
|
||||
const ZKEY_FILE: &str = "./semaphore/build/snark/semaphore_final.zkey";
|
||||
const WASM_FILE: &str = "./semaphore/build/snark/semaphore.wasm";
|
||||
|
||||
// See <https://internals.rust-lang.org/t/path-to-lexical-absolute/14940>
|
||||
fn absolute(path: &str) -> Result<PathBuf> {
|
||||
let path = Path::new(path);
|
||||
let mut absolute = if path.is_absolute() {
|
||||
PathBuf::new()
|
||||
} else {
|
||||
std::env::current_dir()?
|
||||
};
|
||||
for component in path.components() {
|
||||
match component {
|
||||
Component::CurDir => {}
|
||||
Component::ParentDir => {
|
||||
absolute.pop();
|
||||
}
|
||||
component @ _ => absolute.push(component.as_os_str()),
|
||||
}
|
||||
}
|
||||
Ok(absolute)
|
||||
}
|
||||
|
||||
fn build_circuit() -> Result<()> {
|
||||
println!("cargo:rerun-if-changed=./semaphore");
|
||||
let run = |cmd: &[&str]| -> Result<()> {
|
||||
// TODO: Use ExitCode::exit_ok() when stable.
|
||||
Command::new(cmd[0])
|
||||
.args(cmd[1..].iter())
|
||||
.current_dir("./semaphore")
|
||||
.status()?
|
||||
.success()
|
||||
.then(|| ())
|
||||
.ok_or(eyre!("procees returned failure"))?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
// Compute absolute paths
|
||||
let zkey_file = absolute(ZKEY_FILE)?;
|
||||
let wasm_file = absolute(WASM_FILE)?;
|
||||
|
||||
// Build circuits if not exists
|
||||
// TODO: This does not rebuild if the semaphore submodule is changed.
|
||||
// NOTE: This requires npm / nodejs to be installed.
|
||||
if !(zkey_file.exists() && wasm_file.exists()) {
|
||||
run(&["npm", "install"])?;
|
||||
run(&["npm", "exec", "ts-node", "./scripts/compile-circuits.ts"])?;
|
||||
}
|
||||
assert!(zkey_file.exists());
|
||||
assert!(wasm_file.exists());
|
||||
|
||||
// Export generated paths
|
||||
println!("cargo:rustc-env=BUILD_RS_ZKEY_FILE={}", zkey_file.display());
|
||||
println!("cargo:rustc-env=BUILD_RS_WASM_FILE={}", wasm_file.display());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_dylib() -> Result<()> {
|
||||
let wasm_file = absolute(WASM_FILE)?;
|
||||
assert!(wasm_file.exists());
|
||||
|
||||
let out_dir = env::var("OUT_DIR")?;
|
||||
let out_dir = Path::new(&out_dir).to_path_buf();
|
||||
let dylib_file = out_dir.join("semaphore.dylib");
|
||||
println!("cargo:rustc-env=BUILD_DYLIB_FILE={}", dylib_file.display());
|
||||
|
||||
if dylib_file.exists() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Create a WASM engine for the target that can compile
|
||||
let triple = Triple::from_str(&env::var("TARGET")?).map_err(|e| eyre!(e))?;
|
||||
let cpu_features = enum_set!();
|
||||
let target = Target::new(triple, cpu_features);
|
||||
let compiler_config = Cranelift::default();
|
||||
let engine = Dylib::new(compiler_config)
|
||||
.target(target)
|
||||
.engine();
|
||||
|
||||
// Compile the WASM module
|
||||
let store = Store::new(&engine);
|
||||
let module = Module::from_file(&store, &wasm_file)?;
|
||||
module.serialize_to_file(&dylib_file)?;
|
||||
assert!(dylib_file.exists());
|
||||
println!("cargo:warning=Circuit dylib is in {}", dylib_file.display());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
build_circuit()?;
|
||||
build_dylib()?;
|
||||
Ok(())
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
use wasmer::{Module, Store};
|
||||
use wasmer_compiler_cranelift::Cranelift;
|
||||
use wasmer_engine_dylib::Dylib;
|
||||
|
||||
const PATH: &str = "../semaphore/build/snark/semaphore.wasm";
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Define a compiler configuration.
|
||||
//
|
||||
// In this situation, the compiler is
|
||||
// `wasmer_compiler_cranelift`. The compiler is responsible to
|
||||
// compile the Wasm module into executable code.
|
||||
let compiler_config = Cranelift::default();
|
||||
|
||||
println!("Creating Dylib engine...");
|
||||
// Define the engine that will drive everything.
|
||||
//
|
||||
// In this case, the engine is `wasmer_engine_dylib` which means
|
||||
// that a shared object is going to be generated.
|
||||
let engine = Dylib::new(compiler_config).engine();
|
||||
|
||||
// Create a store, that holds the engine.
|
||||
let store = Store::new(&engine);
|
||||
|
||||
println!("Compiling module...");
|
||||
// Here we go.
|
||||
//
|
||||
// Let's compile the Wasm module. It is at this step that the Wasm
|
||||
// text is transformed into Wasm bytes (if necessary), and then
|
||||
// compiled to executable code by the compiler, which is then
|
||||
// stored into a shared object by the engine.
|
||||
let module = Module::from_file(&store, "../semaphore/build/snark/semaphore.wasm")?;
|
||||
|
||||
println!("Storing as \"{}\"", PATH);
|
||||
module.serialize_to_file(PATH)?;
|
||||
|
||||
println!("Done! you can now compile with CIRCUIT_WASM_DYLIB=\"{}\"", PATH);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
//! This builds the wasm file into a dylib for a given target platform.
|
||||
//!
|
||||
//! ```shell
|
||||
//! cargo run --example dylib_ios aarch64-apple-ios semaphore/build/snark/semaphore.wasm semaphore/build/snark/semaphore.dylib
|
||||
//! ```
|
||||
//!
|
||||
//! Ready?
|
||||
|
||||
|
||||
use std::{str::FromStr};
|
||||
|
||||
use wasmer::{Module, Store, Triple, RuntimeError, CpuFeature, Target};
|
||||
use wasmer_compiler_cranelift::Cranelift;
|
||||
use wasmer_engine_dylib::Dylib;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// to build for ios: aarch64-apple-ios, aarch64-apple-ios-sim, x86_64-apple-ios
|
||||
let target_os = std::env::args().nth(1).expect("no target given");
|
||||
let wasm_path = std::env::args().nth(2).expect("no wasm path given");
|
||||
let dylib_path = std::env::args().nth(3).expect("no dylib path given");
|
||||
|
||||
// Define a compiler configuration.
|
||||
//
|
||||
// In this situation, the compiler is
|
||||
// `wasmer_compiler_cranelift`. The compiler is responsible to
|
||||
// compile the Wasm module into executable code.
|
||||
let compiler_config = Cranelift::default();
|
||||
|
||||
let triple = Triple::from_str(&target_os)
|
||||
.map_err(|error| RuntimeError::new(error.to_string()))?;
|
||||
|
||||
// Let's build the target.
|
||||
let mut cpu_feature = CpuFeature::set();
|
||||
cpu_feature.insert(CpuFeature::from_str("sse2")?);
|
||||
let target = Target::new(triple, cpu_feature);
|
||||
println!("Chosen target: {:?}", target);
|
||||
|
||||
println!("Creating Dylib engine...");
|
||||
// Define the engine that will drive everything.
|
||||
//
|
||||
// In this case, the engine is `wasmer_engine_dylib` which means
|
||||
// that a shared object is going to be generated.
|
||||
let engine = Dylib::new(compiler_config).target(target).engine();
|
||||
|
||||
// Create a store, that holds the engine.
|
||||
let store = Store::new(&engine);
|
||||
|
||||
println!("Compiling module...");
|
||||
// Here we go.
|
||||
//
|
||||
// Let's compile the Wasm module. It is at this step that the Wasm
|
||||
// text is transformed into Wasm bytes (if necessary), and then
|
||||
// compiled to executable code by the compiler, which is then
|
||||
// stored into a shared object by the engine.
|
||||
let module = Module::from_file(&store, &wasm_path)?;
|
||||
|
||||
module.serialize_to_file(&dylib_path)?;
|
||||
|
||||
println!("Done! you can now compile with CIRCUIT_WASM_DYLIB=\"{}\"", &dylib_path);
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -8,14 +8,14 @@ use std::{io::Cursor, sync::Mutex};
|
|||
use wasmer::{Module, Store};
|
||||
|
||||
#[cfg(feature = "dylib")]
|
||||
use std::{path::Path, env};
|
||||
use std::{env, path::Path};
|
||||
#[cfg(feature = "dylib")]
|
||||
use wasmer::{Dylib};
|
||||
use wasmer::Dylib;
|
||||
|
||||
const ZKEY_BYTES: &[u8] = include_bytes!("../semaphore/build/snark/semaphore_final.zkey");
|
||||
const ZKEY_BYTES: &[u8] = include_bytes!(env!("BUILD_RS_ZKEY_FILE"));
|
||||
|
||||
#[cfg(not(feature = "dylib"))]
|
||||
const WASM: &[u8] = include_bytes!("../semaphore/build/snark/semaphore.wasm");
|
||||
const WASM: &[u8] = include_bytes!(env!("BUILD_RS_WASM_FILE"));
|
||||
|
||||
static ZKEY: Lazy<(ProvingKey<Bn254>, ConstraintMatrices<Fr>)> = Lazy::new(|| {
|
||||
let mut reader = Cursor::new(ZKEY_BYTES);
|
||||
|
@ -55,7 +55,11 @@ pub fn zkey() -> &'static (ProvingKey<Bn254>, ConstraintMatrices<Fr>) {
|
|||
#[must_use]
|
||||
pub fn witness_calculator() -> &'static Mutex<WitnessCalculator> {
|
||||
WITNESS_CALCULATOR.get_or_init(|| {
|
||||
let path = env::var("CIRCUIT_WASM_DYLIB").expect("Semaphore-rs is not initialized. The library needs to be initialized before use when build with the `cdylib` feature. You can initialize by calling `initialize` or seting the `CIRCUIT_WASM_DYLIB` environment variable.");
|
||||
let path = env::var("CIRCUIT_WASM_DYLIB").expect(
|
||||
"Semaphore-rs is not initialized. The library needs to be initialized before use when \
|
||||
build with the `cdylib` feature. You can initialize by calling `initialize` or \
|
||||
seting the `CIRCUIT_WASM_DYLIB` environment variable.",
|
||||
);
|
||||
from_dylib(&Path::new(&path))
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue