Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(wasm-builder): allow building with stable toolchain #3459

Merged
merged 31 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
eaa20f3
fix(wasm-builder): remove build scripts environment variables
StackOverflowExcept1on Oct 30, 2023
cf92679
add simple test in check action
StackOverflowExcept1on Oct 30, 2023
89fc899
remove wrappers
StackOverflowExcept1on Oct 30, 2023
27ac13e
ci(time-consuming-tests): build & tests on two toolchains
StackOverflowExcept1on Oct 30, 2023
9345f9c
try this to fix ci
StackOverflowExcept1on Oct 30, 2023
04899da
install stable but w/o as default toolchain
StackOverflowExcept1on Oct 30, 2023
af137e6
back to old code
StackOverflowExcept1on Oct 30, 2023
c18a745
experiment with RUSTC RUSTC_BOOTSTRAP
StackOverflowExcept1on Oct 30, 2023
03bd5c7
add some comments
StackOverflowExcept1on Oct 31, 2023
8908cf2
revert RUSTC_BOOTSTRAP & pin version
StackOverflowExcept1on Oct 31, 2023
11bf2d6
pin specific toolchain and provide error handling
StackOverflowExcept1on Oct 31, 2023
b0246e8
use ensure!
StackOverflowExcept1on Oct 31, 2023
c258f69
extract lists into const slices
StackOverflowExcept1on Nov 10, 2023
65efa62
read toolchain from workspace dir
StackOverflowExcept1on Nov 10, 2023
e53233e
apply suggestion
StackOverflowExcept1on Nov 10, 2023
0e85180
Merge remote-tracking branch 'origin/master' into av/wasm-builder-cle…
StackOverflowExcept1on Dec 26, 2023
c4e2e56
remove concept of pinned toolchain
StackOverflowExcept1on Dec 26, 2023
77f1f29
small fix
StackOverflowExcept1on Dec 26, 2023
0f77875
Merge remote-tracking branch 'origin/master' into av/wasm-builder-cle…
StackOverflowExcept1on Jan 10, 2024
1d56886
ws
StackOverflowExcept1on Jan 10, 2024
254fad6
add recommended toolchain to wasm-builder
StackOverflowExcept1on Jan 12, 2024
68906f2
Merge remote-tracking branch 'origin/master' into av/wasm-builder-cle…
StackOverflowExcept1on Jan 12, 2024
eaa92fc
add check on ci
StackOverflowExcept1on Jan 12, 2024
603e2fd
resolve conversations
StackOverflowExcept1on Jan 15, 2024
1f8d2bc
use with_forced_recommended_toolchain in out-of-memory demo
StackOverflowExcept1on Jan 16, 2024
95ad91b
Merge remote-tracking branch 'origin/master' into av/wasm-builder-cle…
StackOverflowExcept1on Jan 16, 2024
6cdbc09
[skip-ci] add docs about internal use
StackOverflowExcept1on Jan 16, 2024
9e5b362
[skip-ci] add better error msg
StackOverflowExcept1on Jan 16, 2024
5e95541
[skip-ci] fix comment
StackOverflowExcept1on Jan 16, 2024
beb4d72
more comments
StackOverflowExcept1on Jan 17, 2024
19800ad
Merge remote-tracking branch 'origin/master' into av/wasm-builder-cle…
StackOverflowExcept1on Jan 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,12 @@ jobs:
fi

- name: "Install: Rust stable toolchain"
uses: dtolnay/rust-toolchain@stable
run: rustup toolchain install stable --component llvm-tools-preview --target wasm32-unknown-unknown
StackOverflowExcept1on marked this conversation as resolved.
Show resolved Hide resolved

- name: "Check: Compiling gstd on stable"
run: cargo +stable check -p gstd
run: |
cargo +stable check -p gstd
cargo +stable check --manifest-path utils/wasm-builder/test-program/Cargo.toml

- run: sccache --show-stats

Expand Down
6 changes: 6 additions & 0 deletions utils/wasm-builder/src/builder_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,10 @@ pub enum BuilderError {

#[error("cargo toolchain is invalid `{0}`")]
CargoToolchainInvalid(String),

#[error(
"recommended toolchain `{0}` not found, install it using the command:\n\
rustup toolchain install {0} --component llvm-tools-preview --target wasm32-unknown-unknown"
)]
RecommendedToolchainNotFound(String),
}
45 changes: 36 additions & 9 deletions utils/wasm-builder/src/cargo_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

use crate::cargo_toolchain::Toolchain;
use anyhow::{ensure, Context, Result};
use std::{path::PathBuf, process::Command};
use std::{env, path::PathBuf, process::Command};

use crate::builder_error::BuilderError;

Expand Down Expand Up @@ -86,9 +86,11 @@ impl CargoCommand {
/// Execute the `cargo` command with invoking supplied arguments.
pub fn run(&self) -> Result<()> {
let mut cargo = Command::new(&self.path);
self.clean_up_environment(&mut cargo);

cargo
.arg("run")
.arg(self.toolchain.nightly_toolchain_str().as_ref())
.arg(self.toolchain.try_switch_to_nightly_toolchain()?)
.arg("cargo")
.arg("rustc")
.arg("--target=wasm32-unknown-unknown")
Expand All @@ -108,8 +110,6 @@ impl CargoCommand {
.env("CARGO_TARGET_DIR", &self.target_dir)
.env("__GEAR_WASM_BUILDER_NO_BUILD", "1"); // Don't build the original crate recursively

self.remove_cargo_encoded_rustflags(&mut cargo);

if !self.paths_to_remap.is_empty() {
// `--remap-path-prefix` is used to remove username from panic messages
// https://doc.rust-lang.org/rustc/command-line-arguments.html#--remap-path-prefix-remap-source-names-in-output
Expand All @@ -135,10 +135,37 @@ impl CargoCommand {
Ok(())
}

fn remove_cargo_encoded_rustflags(&self, command: &mut Command) {
// substrate's wasm-builder removes these vars so do we
// check its source for details
command.env_remove("CARGO_ENCODED_RUSTFLAGS");
command.env_remove("RUSTFLAGS");
fn clean_up_environment(&self, command: &mut Command) {
// Inherited build script environment variables must be removed
// so that they cannot change the behavior of the cargo package manager.

// https://doc.rust-lang.org/cargo/reference/environment-variables.html
// `RUSTC_WRAPPER` and `RUSTC_WORKSPACE_WRAPPER` are not removed due to tools like sccache.
for env_var in [
StackOverflowExcept1on marked this conversation as resolved.
Show resolved Hide resolved
"CARGO",
"CARGO_MANIFEST_DIR",
"CARGO_MANIFEST_LINKS",
"CARGO_MAKEFLAGS",
"OUT_DIR",
"TARGET",
"HOST",
"NUM_JOBS",
"OPT_LEVEL",
"PROFILE",
"RUSTC",
"RUSTDOC",
"RUSTC_LINKER",
"CARGO_ENCODED_RUSTFLAGS",
] {
command.env_remove(env_var);
}

for (env_var, _) in env::vars() {
for prefix in ["CARGO_FEATURE_", "CARGO_CFG_", "DEP_", "CARGO_PKG_"] {
if env_var.starts_with(prefix) {
command.env_remove(&env_var);
}
}
}
}
}
50 changes: 19 additions & 31 deletions utils/wasm-builder/src/cargo_toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::builder_error::BuilderError;
use anyhow::{Context, Result};
use once_cell::sync::Lazy;
use regex::Regex;
use std::{borrow::Cow, process::Command};
use std::process::Command;

// The channel patterns we support (borrowed from the rustup code)
static TOOLCHAIN_CHANNELS: &[&str] = &[
Expand All @@ -35,6 +35,9 @@ static TOOLCHAIN_CHANNELS: &[&str] = &[
pub(crate) struct Toolchain(String);

impl Toolchain {
StackOverflowExcept1on marked this conversation as resolved.
Show resolved Hide resolved
/// This is a hardcoded version of nightly toolchain, tested on our CI.
const PINNED_NIGHTLY_TOOLCHAIN: &'static str = "nightly-2023-09-18";
StackOverflowExcept1on marked this conversation as resolved.
Show resolved Hide resolved

/// Returns `Toolchain` representing the most recent nightly version.
pub fn nightly() -> Self {
Self("nightly".into())
Expand Down Expand Up @@ -80,40 +83,25 @@ impl Toolchain {
Ok(Self(toolchain))
}

/// Returns toolchain string specification without target triple
/// as it was passed during initialization.
///
/// `<channel>[-<date>]`
///
/// `<channel> = stable|beta|nightly|<major.minor>|<major.minor.patch>`
///
/// `<date> = YYYY-MM-DD`
pub fn raw_toolchain_str(&'_ self) -> Cow<'_, str> {
self.0.as_str().into()
}

/// Returns toolchain string specification without target triple
/// and with raw `<channel>` substituted by `nightly`.
/// Tries to switch to pinned nightly toolchain and
/// returns toolchain string specification without target triple
/// and with raw `<channel>` substituted by [`Self::PINNED_NIGHTLY_TOOLCHAIN`].
///
/// `nightly[-<date>]`
///
/// `<date> = YYYY-MM-DD`
pub fn nightly_toolchain_str(&'_ self) -> Cow<'_, str> {
if !self.is_nightly() {
let date_start_idx = self
.0
.find('-')
.unwrap_or_else(|| self.raw_toolchain_str().len());
let mut toolchain_str = self.0.clone();
toolchain_str.replace_range(..date_start_idx, "nightly");
toolchain_str.into()
} else {
self.raw_toolchain_str()
}
}
pub fn try_switch_to_nightly_toolchain(&self) -> Result<&str> {
let toolchain = Self::PINNED_NIGHTLY_TOOLCHAIN;
let output = Command::new("rustup")
.args(["run", toolchain, "rustc", "--version"])
.output()
.context("`rustup` command failed")?;

anyhow::ensure!(
output.status.success(),
BuilderError::RecommendedToolchainNotFound(toolchain.into()),
);

// Returns bool representing nightly toolchain.
fn is_nightly(&self) -> bool {
self.0.starts_with("nightly")
Ok(toolchain)
}
}
47 changes: 42 additions & 5 deletions utils/wasm-builder/tests/smoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use gear_wasm_builder::TARGET;
use std::{fs, process::Command};
use std::{fs, process::Command, sync::OnceLock};

struct CargoRunner(Command);

Expand All @@ -26,6 +26,13 @@ impl CargoRunner {
Self(Command::new("cargo"))
}

fn stable() -> Self {
let mut cmd = Command::new("cargo");
cmd.arg("+stable");

Self(cmd)
}

fn args<const SIZE: usize>(mut self, args: [&str; SIZE]) -> Self {
self.0.args(args);
self
Expand All @@ -42,35 +49,65 @@ impl CargoRunner {
}
}

fn install_stable_toolchain() {
static STABLE_TOOLCHAIN: OnceLock<()> = OnceLock::new();

STABLE_TOOLCHAIN.get_or_init(|| {
let status = Command::new("rustup")
.arg("toolchain")
.arg("install")
.arg("stable")
.arg("--component")
.arg("llvm-tools-preview")
.arg("--target")
.arg("wasm32-unknown-unknown")
.status()
.expect("rustup run error");
assert!(status.success());
});
}

#[ignore]
#[test]
fn test_debug() {
install_stable_toolchain();

CargoRunner::new().args(["test"]).run();
CargoRunner::stable().args(["test"]).run();
}

#[ignore]
#[test]
fn build_debug() {
CargoRunner::new().args(["build"]).run()
install_stable_toolchain();

CargoRunner::new().args(["build"]).run();
CargoRunner::stable().args(["build"]).run();
}

#[ignore]
#[test]
fn test_release() {
CargoRunner::new().args(["test", "--release"]).run()
install_stable_toolchain();

CargoRunner::new().args(["test", "--release"]).run();
CargoRunner::stable().args(["test", "--release"]).run();
}

#[ignore]
#[test]
fn build_release() {
CargoRunner::new().args(["build", "--release"]).run()
install_stable_toolchain();

CargoRunner::new().args(["build", "--release"]).run();
CargoRunner::stable().args(["build", "--release"]).run();
}

#[test]
fn build_release_for_target() {
CargoRunner::new()
.args(["build", "--release", "--target", TARGET])
.run()
.run();
}

#[ignore]
Expand Down