Skip to content

Commit

Permalink
Revert "Remove Native submodule" (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielbosio authored Jan 10, 2025
1 parent 4e351bf commit 3086d54
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 0 deletions.
69 changes: 69 additions & 0 deletions crates/blockifier/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#[cfg(feature = "cairo_native")]
fn compile_cairo_native_aot_runtime() {
use std::path::PathBuf;
use std::process::Command;

use infra_utils::compile_time_cargo_manifest_dir;
use infra_utils::path::current_dir;

let cairo_native_dir =
PathBuf::from(compile_time_cargo_manifest_dir!()).join(PathBuf::from("cairo_native"));

if !cairo_native_dir.exists() || !cairo_native_dir.join(".git").exists() {
panic!(
"It seems git submodule at {} doesn't exist or it is not initialized, please \
run:\n\ngit submodule update --init --recursive\n",
cairo_native_dir.to_str().unwrap()
);
}

let runtime_target_dir = cairo_native_dir.join(PathBuf::from("target"));
let status = Command::new("cargo")
.args([
"build",
"--release",
"-p",
"cairo-native-runtime",
"--message-format=json",
"--target-dir",
runtime_target_dir.to_str().unwrap(),
])
.current_dir(cairo_native_dir)
.status()
.expect("Failed to execute cargo");
if !status.success() {
panic!("Building cairo native runtime failed: {status}")
}

let runtime_target_path =
runtime_target_dir.join(PathBuf::from("release/libcairo_native_runtime.a"));

const RUNTIME_LIBRARY: &str = "CAIRO_NATIVE_RUNTIME_LIBRARY";
let runtime_expected_path = {
let expected_path_env =
std::env::var(RUNTIME_LIBRARY).expect("Cairo Native runtime path variable is not set");
let expected_path = PathBuf::from(&expected_path_env);

if expected_path.is_absolute() {
expected_path
} else {
current_dir().expect("Failed to get current directory").join(expected_path)
}
};

std::fs::copy(&runtime_target_path, &runtime_expected_path)
.expect("Failed to copy native runtime");

println!("cargo::rerun-if-changed=./cairo_native/runtime/");
// todo(rodrigo): this directive seems to cause the build script to trigger everytime on
// Linux based machines. Investigate the issue further.
println!("cargo::rerun-if-changed={}", runtime_expected_path.to_str().unwrap());
println!("cargo::rerun-if-env-changed={RUNTIME_LIBRARY}");
}

fn main() {
// Build instructions are defined behind this condition since they are only relevant when using
// Cairo Native.
#[cfg(feature = "cairo_native")]
compile_cairo_native_aot_runtime();
}
1 change: 1 addition & 0 deletions crates/blockifier/cairo_native
Submodule cairo_native added at 6a4efa
118 changes: 118 additions & 0 deletions crates/starknet_sierra_compile/build.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,119 @@
use std::process::Command;

use tempfile::TempDir;

include!("src/constants.rs");
include!("src/paths.rs");

fn main() {
println!("cargo:rerun-if-changed=../../Cargo.lock");
println!("cargo:rerun-if-changed=build.rs");

set_run_time_out_dir_env_var();
install_starknet_sierra_compile();
#[cfg(feature = "cairo_native")]
install_starknet_native_compile();
}

const REQUIRED_CAIRO_LANG_VERSION: &str = "2.7.1";
#[cfg(feature = "cairo_native")]
const REQUIRED_CAIRO_NATIVE_VERSION: &str = "0.2.4";

/// Downloads the Cairo crate from StarkWare's release page and extracts its contents into the
/// `target` directory. This crate includes the `starknet-sierra-compile` binary, which is used to
/// compile Sierra to Casm. The binary is executed as a subprocess whenever Sierra compilation is
/// required.
fn install_starknet_sierra_compile() {
let binary_name = CAIRO_LANG_BINARY_NAME;
let required_version = REQUIRED_CAIRO_LANG_VERSION;

let cargo_install_args = &[binary_name, "--version", required_version];
install_compiler_binary(binary_name, required_version, cargo_install_args);
}

/// Installs the `starknet-native-compile` crate from the current repository and moves the binary
/// to the shared executables folder. This crate includes the `starknet-native-compile` binary,
/// which is used to compile Sierra to 0x86. The binary is executed as a subprocess whenever Sierra
/// compilation is required.
#[cfg(feature = "cairo_native")]
fn install_starknet_native_compile() {
let binary_name = CAIRO_NATIVE_BINARY_NAME;
let required_version = REQUIRED_CAIRO_NATIVE_VERSION;

let repo_root_dir =
infra_utils::path::project_path().expect("Should be able to get the project path");

// Set the runtime library path. This is required for Cairo native compilation.
let runtime_library_path = repo_root_dir
.join("crates/blockifier/cairo_native/target/release/libcairo_native_runtime.a");
println!("cargo:rustc-env=CAIRO_NATIVE_RUNTIME_LIBRARY={}", runtime_library_path.display());
println!("cargo:rerun-if-env-changed=CAIRO_NATIVE_RUNTIME_LIBRARY");

let starknet_native_compile_crate_path = repo_root_dir.join("crates/bin").join(binary_name);
let starknet_native_compile_crate_path_str = starknet_native_compile_crate_path
.to_str()
.expect("Failed to convert the crate path to str");
println!("cargo:rerun-if-changed={}", starknet_native_compile_crate_path_str);

let cargo_install_args = &["--path", starknet_native_compile_crate_path_str];
install_compiler_binary(binary_name, required_version, cargo_install_args);
}

fn install_compiler_binary(binary_name: &str, required_version: &str, cargo_install_args: &[&str]) {
let binary_path = binary_path(out_dir(), binary_name);
println!("cargo:rerun-if-changed={}", binary_path.to_str().unwrap());

match Command::new(&binary_path).args(["--version"]).output() {
Ok(binary_version) => {
let binary_version = String::from_utf8(binary_version.stdout)
.expect("Failed to convert the binary version to a string.");
if binary_version.contains(required_version) {
println!("The {binary_name} binary is up to date.");
return;
} else {
println!(
"The {binary_name} binary is not up to date. Installing the required version."
);
std::fs::remove_file(&binary_path).expect("Failed to remove the old binary.");
}
}
Err(_) => {
println!("The {binary_name} binary is not installed. Installing the required version.");
}
}

let temp_cargo_path = TempDir::new().expect("Failed to create a temporary directory.");
let post_install_file_path = temp_cargo_path.path().join("bin").join(binary_name);

let install_command_status = Command::new("cargo")
.args([
"install",
"--root",
temp_cargo_path.path().to_str().expect("Failed to convert cargo_path to str"),
])
.args(cargo_install_args)
.status()
.unwrap_or_else(|_| panic!("Failed to install {binary_name}"));

if !install_command_status.success() {
panic!("Failed to install {}", binary_name);
}

// Move the '{binary_name}' executable to a shared location.
std::fs::create_dir_all(shared_folder_dir(out_dir()))
.expect("Failed to create shared executables folder");
let move_command_status = Command::new("mv")
.args([post_install_file_path.as_os_str(), binary_path.as_os_str()])
.status()
.expect("Failed to perform mv command.");

if !move_command_status.success() {
panic!("Failed to move the {} binary to the shared folder.", binary_name);
}

std::fs::remove_dir_all(temp_cargo_path).expect("Failed to remove the cargo directory.");

println!("Successfully set executable file: {:?}", binary_path.display());
}

// Sets the `RUNTIME_ACCESSIBLE_OUT_DIR` environment variable to the `OUT_DIR` value, which will be
Expand All @@ -11,3 +122,10 @@ fn set_run_time_out_dir_env_var() {
let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR is not set");
println!("cargo:rustc-env=RUNTIME_ACCESSIBLE_OUT_DIR={}", out_dir);
}

// Returns the OUT_DIR. This function is only operable at build time.
fn out_dir() -> std::path::PathBuf {
std::env::var("OUT_DIR")
.expect("Failed to get the build time OUT_DIR environment variable")
.into()
}

0 comments on commit 3086d54

Please sign in to comment.