Skip to content

Commit

Permalink
Add "cargo-risc0" tool to manage risc0 toolchain (risc0#198)
Browse files Browse the repository at this point in the history
Add "cargo-risc0" tool to manage the risc0 toolchain. This isn't particularly useful yet by itself, but is one of the few parts of simplifying guest compilation that doesn't depend on other things.
  • Loading branch information
shkoo authored Jul 6, 2022
1 parent 127153f commit a3e5c75
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ members = [
]

exclude = [
"risc0/zkvm/sdk/rust/cargo-risc0",
"risc0/zkvm/sdk/rust/methods",
]

Expand Down
10 changes: 10 additions & 0 deletions risc0/zkvm/sdk/rust/cargo-risc0/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[workspace]

[package]
name = "cargo-risc0"
version = "0.1.0"
edition = "2021"

[dependencies]
clap = { version = "3.2", features = ["derive"] }
home = { version = "0.5" }
5 changes: 5 additions & 0 deletions risc0/zkvm/sdk/rust/cargo-risc0/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Force stable channel here in case a parent directory requests the
# "risc0" toolchain which might not be present if this crate is
# responsible for installing it.
[toolchain]
channel = "stable"
147 changes: 147 additions & 0 deletions risc0/zkvm/sdk/rust/cargo-risc0/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
use clap::Parser;
use std::path::PathBuf;
use std::process::Command;

const DIST_SERVER: &str = "https://storage.googleapis.com/risc0-rust-dist";

#[derive(Parser)]
#[clap(name = "cargo")]
#[clap(bin_name = "cargo")]
enum Cargo {
#[clap(name = "risc0")]
Risc0(Risc0),
}

#[derive(Parser)]
struct Risc0 {
#[clap(short, long, action = clap::ArgAction::Count)]
verbose: u8,

#[clap(subcommand)]
subcommand: Subcommand,
}

#[derive(Debug, Parser)]
enum Subcommand {
/// Install the risc0 toolchain for riscv32im-risc0-zkvm-elf.
Install,

/// Update the risc0 toolchain for riscv32im-risc0-zkvm-elf to the latest version.
Update,

/// Uninstall the risc0 toolchain.
Uninstall,
}

fn rustup_exe() -> PathBuf {
home::cargo_home()
.expect("Unable to determine cargo home directory")
.join("bin")
.join("rustup")
.into()
}
fn risc0_root() -> PathBuf {
home::home_dir().unwrap().join(".risc0").into()
}

fn set_verbose(args: &Risc0, cmd: &mut Command) {
for _ in 0..args.verbose {
cmd.arg("-v");
}
}

fn risc0_rustup(args: &Risc0) -> Command {
let mut cmd = Command::new(rustup_exe());

cmd.env("RUSTUP_HOME", risc0_root().join("rustup"));
cmd.env("RUSTUP_DIST_SERVER", DIST_SERVER);
set_verbose(&args, &mut cmd);

cmd
}

fn install_toolchain() {}

fn cmd_install(args: &Risc0) {
std::fs::create_dir_all(risc0_root().join("rustup")).expect("Could not create risc0 root");

risc0_rustup(&args)
.arg("toolchain")
.arg("install")
.arg("nightly")
.arg("--no-self-update")
.arg("--target")
.arg("riscv32im-risc0-zkvm-elf")
.status()
.expect("Could not use rustup to install riscv32im toolchain");

let toolchains_dir = risc0_root().join("rustup").join("toolchains");

let toolchains: Vec<String> = std::fs::read_dir(&toolchains_dir)
.unwrap_or_else(|err| {
panic!(
"Unable to enumerate risc0 toolchains in {:?}: {:?}",
toolchains_dir, err
)
})
.filter_map(|ent| {
let fname = ent.ok()?.file_name().into_string().ok()?;
if fname.starts_with("nightly-") {
Option::Some(fname)
} else {
Option::None
}
})
.collect();
let toolchain = match toolchains.as_slice() {
[] => panic!("No toolchains downloaded"),
[toolchain] => toolchain,
_ => panic!("Ambiguous toolchains downloaded: {:?}", toolchains),
};

let mut cmd = Command::new(rustup_exe());
set_verbose(&args, &mut cmd);
cmd.arg("toolchain")
.arg("link")
.arg("risc0")
.arg(toolchains_dir.join(toolchain))
.status()
.expect("Unable to alias 'risc0' to point to the risc0 custom toolchain");

install_toolchain();
}

fn cmd_update(args: &Risc0) {
risc0_rustup(&args)
.arg("update")
.arg("--no-self-update")
.status()
.expect("'rustup update' failed");
}

fn cmd_uninstall(args: &Risc0) {
std::fs::remove_dir_all(risc0_root()).unwrap_or_else(|err| {
panic!(
"Unable to remove risc0 directory {}: {}",
risc0_root().display(),
err
);
});

let mut cmd = Command::new(rustup_exe());
set_verbose(&args, &mut cmd);
cmd.arg("toolchain")
.arg("uninstall")
.arg("risc0")
.status()
.expect("Unable to unalias 'risc0' from the risc0 custom toolchain");
}

fn main() {
let Cargo::Risc0(args) = Cargo::parse();
match args.subcommand {
Subcommand::Install => cmd_install(&args),
Subcommand::Update => cmd_update(&args),
Subcommand::Uninstall => cmd_uninstall(&args),
}
}

0 comments on commit a3e5c75

Please sign in to comment.