Auto merge of #132070 - fmease:rollup-4i4k587, r=fmease
Rollup of 5 pull requests Successful merges: - #131043 (Refactor change detection for rustdoc and download-rustc) - #131181 (Compiletest: Custom differ) - #131487 (Add wasm32v1-none target (compiler-team/#791)) - #132054 (do not remove `.cargo` directory) - #132058 (CI: rfl: use rust-next temporary commit) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
4f2f477fde
@ -1803,6 +1803,7 @@ fn $module() {
|
|||||||
|
|
||||||
("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
|
("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
|
||||||
("wasm32-unknown-unknown", wasm32_unknown_unknown),
|
("wasm32-unknown-unknown", wasm32_unknown_unknown),
|
||||||
|
("wasm32v1-none", wasm32v1_none),
|
||||||
("wasm32-wasi", wasm32_wasi),
|
("wasm32-wasi", wasm32_wasi),
|
||||||
("wasm32-wasip1", wasm32_wasip1),
|
("wasm32-wasip1", wasm32_wasip1),
|
||||||
("wasm32-wasip2", wasm32_wasip2),
|
("wasm32-wasip2", wasm32_wasip2),
|
||||||
|
51
compiler/rustc_target/src/spec/targets/wasm32v1_none.rs
Normal file
51
compiler/rustc_target/src/spec/targets/wasm32v1_none.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//! A "bare wasm" target representing a WebAssembly output that does not import
|
||||||
|
//! anything from its environment and also specifies an _upper_ bound on the set
|
||||||
|
//! of WebAssembly proposals that are supported.
|
||||||
|
//!
|
||||||
|
//! It's equivalent to the `wasm32-unknown-unknown` target with the additional
|
||||||
|
//! flags `-Ctarget-cpu=mvp` and `-Ctarget-feature=+mutable-globals`. This
|
||||||
|
//! enables just the features specified in <https://www.w3.org/TR/wasm-core-1/>
|
||||||
|
//!
|
||||||
|
//! This is a _separate target_ because using `wasm32-unknown-unknown` with
|
||||||
|
//! those target flags doesn't automatically rebuild libcore / liballoc with
|
||||||
|
//! them, and in order to get those libraries rebuilt you need to use the
|
||||||
|
//! nightly Rust feature `-Zbuild-std`. This target is for people who want to
|
||||||
|
//! use stable Rust, and target a stable set pf WebAssembly features.
|
||||||
|
|
||||||
|
use crate::spec::{Cc, LinkerFlavor, Target, base};
|
||||||
|
|
||||||
|
pub(crate) fn target() -> Target {
|
||||||
|
let mut options = base::wasm::options();
|
||||||
|
options.os = "none".into();
|
||||||
|
|
||||||
|
// WebAssembly 1.0 shipped in 2019 and included exactly one proposal
|
||||||
|
// after the initial "MVP" feature set: "mutable-globals".
|
||||||
|
options.cpu = "mvp".into();
|
||||||
|
options.features = "+mutable-globals".into();
|
||||||
|
|
||||||
|
options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::No), &[
|
||||||
|
// For now this target just never has an entry symbol no matter the output
|
||||||
|
// type, so unconditionally pass this.
|
||||||
|
"--no-entry",
|
||||||
|
]);
|
||||||
|
options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &[
|
||||||
|
// Make sure clang uses LLD as its linker and is configured appropriately
|
||||||
|
// otherwise
|
||||||
|
"--target=wasm32-unknown-unknown",
|
||||||
|
"-Wl,--no-entry",
|
||||||
|
]);
|
||||||
|
|
||||||
|
Target {
|
||||||
|
llvm_target: "wasm32-unknown-unknown".into(),
|
||||||
|
metadata: crate::spec::TargetMetadata {
|
||||||
|
description: Some("WebAssembly".into()),
|
||||||
|
tier: Some(2),
|
||||||
|
host_tools: Some(false),
|
||||||
|
std: Some(false),
|
||||||
|
},
|
||||||
|
pointer_width: 32,
|
||||||
|
data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20".into(),
|
||||||
|
arch: "wasm32".into(),
|
||||||
|
options,
|
||||||
|
}
|
||||||
|
}
|
@ -121,7 +121,13 @@ fn check_consistency(&self) {
|
|||||||
// Check dynamic linking stuff
|
// Check dynamic linking stuff
|
||||||
// BPF: when targeting user space vms (like rbpf), those can load dynamic libraries.
|
// BPF: when targeting user space vms (like rbpf), those can load dynamic libraries.
|
||||||
// hexagon: when targeting QuRT, that OS can load dynamic libraries.
|
// hexagon: when targeting QuRT, that OS can load dynamic libraries.
|
||||||
if self.os == "none" && (self.arch != "bpf" && self.arch != "hexagon") {
|
// wasm{32,64}: dynamic linking is inherent in the definition of the VM.
|
||||||
|
if self.os == "none"
|
||||||
|
&& (self.arch != "bpf"
|
||||||
|
&& self.arch != "hexagon"
|
||||||
|
&& self.arch != "wasm32"
|
||||||
|
&& self.arch != "wasm64")
|
||||||
|
{
|
||||||
assert!(!self.dynamic_linking);
|
assert!(!self.dynamic_linking);
|
||||||
}
|
}
|
||||||
if self.only_cdylib
|
if self.only_cdylib
|
||||||
|
@ -419,6 +419,9 @@
|
|||||||
# passed to cargo invocations.
|
# passed to cargo invocations.
|
||||||
#jobs = 0
|
#jobs = 0
|
||||||
|
|
||||||
|
# What custom diff tool to use for displaying compiletest tests.
|
||||||
|
#compiletest-diff-tool = <none>
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# General install configuration options
|
# General install configuration options
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
@ -1092,9 +1092,6 @@ class RustBuild(object):
|
|||||||
if not os.path.exists(cargo_dir):
|
if not os.path.exists(cargo_dir):
|
||||||
eprint('ERROR: vendoring required, but .cargo/config does not exist.')
|
eprint('ERROR: vendoring required, but .cargo/config does not exist.')
|
||||||
raise Exception("{} not found".format(cargo_dir))
|
raise Exception("{} not found".format(cargo_dir))
|
||||||
else:
|
|
||||||
if os.path.exists(cargo_dir):
|
|
||||||
shutil.rmtree(cargo_dir)
|
|
||||||
|
|
||||||
def parse_args(args):
|
def parse_args(args):
|
||||||
"""Parse the command line arguments that the python script needs."""
|
"""Parse the command line arguments that the python script needs."""
|
||||||
|
@ -1836,6 +1836,9 @@ fn run(self, builder: &Builder<'_>) {
|
|||||||
if builder.config.cmd.only_modified() {
|
if builder.config.cmd.only_modified() {
|
||||||
cmd.arg("--only-modified");
|
cmd.arg("--only-modified");
|
||||||
}
|
}
|
||||||
|
if let Some(compiletest_diff_tool) = &builder.config.compiletest_diff_tool {
|
||||||
|
cmd.arg("--compiletest-diff-tool").arg(compiletest_diff_tool);
|
||||||
|
}
|
||||||
|
|
||||||
let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
|
let mut flags = if is_rustdoc { Vec::new() } else { vec!["-Crpath".to_string()] };
|
||||||
flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
|
flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::{env, fs};
|
use std::{env, fs};
|
||||||
|
|
||||||
use build_helper::git::get_closest_merge_commit;
|
|
||||||
|
|
||||||
use crate::core::build_steps::compile;
|
use crate::core::build_steps::compile;
|
||||||
use crate::core::build_steps::toolstate::ToolState;
|
use crate::core::build_steps::toolstate::ToolState;
|
||||||
use crate::core::builder;
|
use crate::core::builder;
|
||||||
@ -10,7 +8,7 @@
|
|||||||
use crate::core::config::TargetSelection;
|
use crate::core::config::TargetSelection;
|
||||||
use crate::utils::channel::GitInfo;
|
use crate::utils::channel::GitInfo;
|
||||||
use crate::utils::exec::{BootstrapCommand, command};
|
use crate::utils::exec::{BootstrapCommand, command};
|
||||||
use crate::utils::helpers::{add_dylib_path, exe, git, t};
|
use crate::utils::helpers::{add_dylib_path, exe, t};
|
||||||
use crate::{Compiler, Kind, Mode, gha};
|
use crate::{Compiler, Kind, Mode, gha};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||||
@ -596,28 +594,11 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
|
|||||||
&& target_compiler.stage > 0
|
&& target_compiler.stage > 0
|
||||||
&& builder.rust_info().is_managed_git_subrepository()
|
&& builder.rust_info().is_managed_git_subrepository()
|
||||||
{
|
{
|
||||||
let commit = get_closest_merge_commit(
|
let files_to_track = &["src/librustdoc", "src/tools/rustdoc"];
|
||||||
Some(&builder.config.src),
|
|
||||||
&builder.config.git_config(),
|
|
||||||
&[],
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let librustdoc_src = builder.config.src.join("src/librustdoc");
|
// Check if unchanged
|
||||||
let rustdoc_src = builder.config.src.join("src/tools/rustdoc");
|
if builder.config.last_modified_commit(files_to_track, "download-rustc", true).is_some()
|
||||||
|
{
|
||||||
// FIXME: The change detection logic here is quite similar to `Config::download_ci_rustc_commit`.
|
|
||||||
// It would be better to unify them.
|
|
||||||
let has_changes = !git(Some(&builder.config.src))
|
|
||||||
.allow_failure()
|
|
||||||
.run_always()
|
|
||||||
.args(["diff-index", "--quiet", &commit])
|
|
||||||
.arg("--")
|
|
||||||
.arg(librustdoc_src)
|
|
||||||
.arg(rustdoc_src)
|
|
||||||
.run(builder);
|
|
||||||
|
|
||||||
if !has_changes {
|
|
||||||
let precompiled_rustdoc = builder
|
let precompiled_rustdoc = builder
|
||||||
.config
|
.config
|
||||||
.ci_rustc_dir()
|
.ci_rustc_dir()
|
||||||
|
@ -368,6 +368,9 @@ pub struct Config {
|
|||||||
/// The paths to work with. For example: with `./x check foo bar` we get
|
/// The paths to work with. For example: with `./x check foo bar` we get
|
||||||
/// `paths=["foo", "bar"]`.
|
/// `paths=["foo", "bar"]`.
|
||||||
pub paths: Vec<PathBuf>,
|
pub paths: Vec<PathBuf>,
|
||||||
|
|
||||||
|
/// Command for visual diff display, e.g. `diff-tool --color=always`.
|
||||||
|
pub compiletest_diff_tool: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
@ -892,6 +895,7 @@ struct Build {
|
|||||||
android_ndk: Option<PathBuf> = "android-ndk",
|
android_ndk: Option<PathBuf> = "android-ndk",
|
||||||
optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
|
optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins",
|
||||||
jobs: Option<u32> = "jobs",
|
jobs: Option<u32> = "jobs",
|
||||||
|
compiletest_diff_tool: Option<String> = "compiletest-diff-tool",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1512,6 +1516,7 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
|
|||||||
android_ndk,
|
android_ndk,
|
||||||
optimized_compiler_builtins,
|
optimized_compiler_builtins,
|
||||||
jobs,
|
jobs,
|
||||||
|
compiletest_diff_tool,
|
||||||
} = toml.build.unwrap_or_default();
|
} = toml.build.unwrap_or_default();
|
||||||
|
|
||||||
config.jobs = Some(threads_from_config(flags.jobs.unwrap_or(jobs.unwrap_or(0))));
|
config.jobs = Some(threads_from_config(flags.jobs.unwrap_or(jobs.unwrap_or(0))));
|
||||||
@ -2158,6 +2163,7 @@ fn get_table(option: &str) -> Result<TomlConfig, toml::de::Error> {
|
|||||||
config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(DebuginfoLevel::None);
|
config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(DebuginfoLevel::None);
|
||||||
config.optimized_compiler_builtins =
|
config.optimized_compiler_builtins =
|
||||||
optimized_compiler_builtins.unwrap_or(config.channel != "dev");
|
optimized_compiler_builtins.unwrap_or(config.channel != "dev");
|
||||||
|
config.compiletest_diff_tool = compiletest_diff_tool;
|
||||||
|
|
||||||
let download_rustc = config.download_rustc_commit.is_some();
|
let download_rustc = config.download_rustc_commit.is_some();
|
||||||
// See https://github.com/rust-lang/compiler-team/issues/326
|
// See https://github.com/rust-lang/compiler-team/issues/326
|
||||||
@ -2754,25 +2760,25 @@ fn download_ci_rustc_commit(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let files_to_track = &[
|
let files_to_track =
|
||||||
self.src.join("compiler"),
|
&["compiler", "library", "src/version", "src/stage0", "src/ci/channel"];
|
||||||
self.src.join("library"),
|
|
||||||
self.src.join("src/version"),
|
|
||||||
self.src.join("src/stage0"),
|
|
||||||
self.src.join("src/ci/channel"),
|
|
||||||
];
|
|
||||||
|
|
||||||
// Look for a version to compare to based on the current commit.
|
// Look for a version to compare to based on the current commit.
|
||||||
// Only commits merged by bors will have CI artifacts.
|
// Only commits merged by bors will have CI artifacts.
|
||||||
let commit =
|
let commit = match self.last_modified_commit(files_to_track, "download-rustc", if_unchanged)
|
||||||
get_closest_merge_commit(Some(&self.src), &self.git_config(), files_to_track).unwrap();
|
{
|
||||||
if commit.is_empty() {
|
Some(commit) => commit,
|
||||||
println!("ERROR: could not find commit hash for downloading rustc");
|
None => {
|
||||||
println!("HELP: maybe your repository history is too shallow?");
|
if if_unchanged {
|
||||||
println!("HELP: consider disabling `download-rustc`");
|
return None;
|
||||||
println!("HELP: or fetch enough history to include one upstream commit");
|
}
|
||||||
crate::exit!(1);
|
println!("ERROR: could not find commit hash for downloading rustc");
|
||||||
}
|
println!("HELP: maybe your repository history is too shallow?");
|
||||||
|
println!("HELP: consider disabling `download-rustc`");
|
||||||
|
println!("HELP: or fetch enough history to include one upstream commit");
|
||||||
|
crate::exit!(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if CiEnv::is_ci() && {
|
if CiEnv::is_ci() && {
|
||||||
let head_sha =
|
let head_sha =
|
||||||
@ -2787,31 +2793,7 @@ fn download_ci_rustc_commit(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warn if there were changes to the compiler or standard library since the ancestor commit.
|
Some(commit)
|
||||||
let has_changes = !t!(helpers::git(Some(&self.src))
|
|
||||||
.args(["diff-index", "--quiet", &commit])
|
|
||||||
.arg("--")
|
|
||||||
.args(files_to_track)
|
|
||||||
.as_command_mut()
|
|
||||||
.status())
|
|
||||||
.success();
|
|
||||||
if has_changes {
|
|
||||||
if if_unchanged {
|
|
||||||
if self.is_verbose() {
|
|
||||||
println!(
|
|
||||||
"WARNING: saw changes to compiler/ or library/ since {commit}; \
|
|
||||||
ignoring `download-rustc`"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
println!(
|
|
||||||
"WARNING: `download-rustc` is enabled, but there are changes to \
|
|
||||||
compiler/ or library/"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(commit.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_download_ci_llvm(
|
fn parse_download_ci_llvm(
|
||||||
|
@ -280,4 +280,9 @@ pub fn human_readable_changes(changes: &[ChangeInfo]) -> String {
|
|||||||
severity: ChangeSeverity::Info,
|
severity: ChangeSeverity::Info,
|
||||||
summary: "Allow setting `--jobs` in config.toml with `build.jobs`.",
|
summary: "Allow setting `--jobs` in config.toml with `build.jobs`.",
|
||||||
},
|
},
|
||||||
|
ChangeInfo {
|
||||||
|
change_id: 131181,
|
||||||
|
severity: ChangeSeverity::Info,
|
||||||
|
summary: "New option `build.compiletest-diff-tool` that adds support for a custom differ for compiletest",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
@ -118,6 +118,7 @@ ENV TARGETS=$TARGETS,wasm32-wasi
|
|||||||
ENV TARGETS=$TARGETS,wasm32-wasip1
|
ENV TARGETS=$TARGETS,wasm32-wasip1
|
||||||
ENV TARGETS=$TARGETS,wasm32-wasip1-threads
|
ENV TARGETS=$TARGETS,wasm32-wasip1-threads
|
||||||
ENV TARGETS=$TARGETS,wasm32-wasip2
|
ENV TARGETS=$TARGETS,wasm32-wasip2
|
||||||
|
ENV TARGETS=$TARGETS,wasm32v1-none
|
||||||
ENV TARGETS=$TARGETS,sparcv9-sun-solaris
|
ENV TARGETS=$TARGETS,sparcv9-sun-solaris
|
||||||
ENV TARGETS=$TARGETS,x86_64-pc-solaris
|
ENV TARGETS=$TARGETS,x86_64-pc-solaris
|
||||||
ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32
|
ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
LINUX_VERSION=v6.12-rc2
|
LINUX_VERSION=28e848386b92645f93b9f2fdba5882c3ca7fb3e2
|
||||||
|
|
||||||
# Build rustc, rustdoc, cargo, clippy-driver and rustfmt
|
# Build rustc, rustdoc, cargo, clippy-driver and rustfmt
|
||||||
../x.py build --stage 2 library rustdoc clippy rustfmt
|
../x.py build --stage 2 library rustdoc clippy rustfmt
|
||||||
|
@ -86,6 +86,7 @@
|
|||||||
- [wasm32-wasip2](platform-support/wasm32-wasip2.md)
|
- [wasm32-wasip2](platform-support/wasm32-wasip2.md)
|
||||||
- [wasm32-unknown-emscripten](platform-support/wasm32-unknown-emscripten.md)
|
- [wasm32-unknown-emscripten](platform-support/wasm32-unknown-emscripten.md)
|
||||||
- [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md)
|
- [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md)
|
||||||
|
- [wasm32v1-none](platform-support/wasm32v1-none.md)
|
||||||
- [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
|
- [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
|
||||||
- [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md)
|
- [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md)
|
||||||
- [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md)
|
- [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md)
|
||||||
|
@ -195,6 +195,7 @@ target | std | notes
|
|||||||
`wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename])
|
`wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename])
|
||||||
[`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI
|
[`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI
|
||||||
[`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads
|
[`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads
|
||||||
|
[`wasm32v1-none`](platform-support/wasm32v1-none.md) | * | WebAssembly limited to 1.0 features and no imports
|
||||||
[`x86_64-apple-ios`](platform-support/apple-ios.md) | ✓ | 64-bit x86 iOS
|
[`x86_64-apple-ios`](platform-support/apple-ios.md) | ✓ | 64-bit x86 iOS
|
||||||
[`x86_64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on x86_64
|
[`x86_64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on x86_64
|
||||||
[`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX
|
[`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX
|
||||||
|
@ -132,10 +132,20 @@ As of the time of this writing the proposals that are enabled by default (the
|
|||||||
|
|
||||||
If you're compiling WebAssembly code for an engine that does not support a
|
If you're compiling WebAssembly code for an engine that does not support a
|
||||||
feature in LLVM's default feature set then the feature must be disabled at
|
feature in LLVM's default feature set then the feature must be disabled at
|
||||||
compile time. Note, though, that enabled features may be used in the standard
|
compile time. There are two approaches to choose from:
|
||||||
library or precompiled libraries shipped via rustup. This means that not only
|
|
||||||
does your own code need to be compiled with the correct set of flags but the
|
- If you are targeting a feature set no smaller than the W3C WebAssembly Core
|
||||||
Rust standard library additionally must be recompiled.
|
1.0 recommendation -- which is equivalent to the WebAssembly MVP plus the
|
||||||
|
`mutable-globals` feature -- and you are building `no_std`, then you can
|
||||||
|
simply use the [`wasm32v1-none` target](./wasm32v1-none.md) instead of
|
||||||
|
`wasm32-unknown-unknown`, which uses only those minimal features and
|
||||||
|
includes a core and alloc library built with only those minimal features.
|
||||||
|
|
||||||
|
- Otherwise -- if you need std, or if you need to target the ultra-minimal
|
||||||
|
"MVP" feature set, excluding `mutable-globals` -- you will need to manually
|
||||||
|
specify `-Ctarget-cpu=mvp` and also rebuild the stdlib using that target to
|
||||||
|
ensure no features are used in the stdlib. This in turn requires use of a
|
||||||
|
nightly compiler.
|
||||||
|
|
||||||
Compiling all code for the initial release of WebAssembly looks like:
|
Compiling all code for the initial release of WebAssembly looks like:
|
||||||
|
|
||||||
@ -150,9 +160,9 @@ then used to recompile the standard library in addition to your own code. This
|
|||||||
will produce a binary that uses only the original WebAssembly features by
|
will produce a binary that uses only the original WebAssembly features by
|
||||||
default and no proposals since its inception.
|
default and no proposals since its inception.
|
||||||
|
|
||||||
To enable individual features it can be done with `-Ctarget-feature=+foo`.
|
To enable individual features on either this target or `wasm32v1-none`, pass
|
||||||
Available features for Rust code itself are documented in the [reference] and
|
arguments of the form `-Ctarget-feature=+foo`. Available features for Rust code
|
||||||
can also be found through:
|
itself are documented in the [reference] and can also be found through:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ rustc -Ctarget-feature=help --target wasm32-unknown-unknown
|
$ rustc -Ctarget-feature=help --target wasm32-unknown-unknown
|
||||||
|
109
src/doc/rustc/src/platform-support/wasm32v1-none.md
Normal file
109
src/doc/rustc/src/platform-support/wasm32v1-none.md
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
# `wasm32v1-none`
|
||||||
|
|
||||||
|
**Tier: 2**
|
||||||
|
|
||||||
|
The `wasm32v1-none` target is a WebAssembly compilation target that:
|
||||||
|
|
||||||
|
- Imports nothing from its host environment
|
||||||
|
- Enables no proposals / features past the [W3C WebAssembly Core 1.0 spec]
|
||||||
|
|
||||||
|
[W3C WebAssembly Core 1.0 spec]: https://www.w3.org/TR/wasm-core-1/
|
||||||
|
|
||||||
|
The target is very similar to [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md) and similarly uses LLVM's `wasm32-unknown-unknown` backend target. It contains only three minor differences:
|
||||||
|
|
||||||
|
* Setting the `target-cpu` to `mvp` rather than the default `generic`. Requesting `mvp` disables _all_ WebAssembly proposals / LLVM target feature flags.
|
||||||
|
* Enabling the [Import/Export of Mutable Globals] proposal (i.e. the `+mutable-globals` LLVM target feature flag)
|
||||||
|
* Not compiling the `std` library at all, rather than compiling it with stubs.
|
||||||
|
|
||||||
|
[Import/Export of Mutable Globals]: https://github.com/WebAssembly/mutable-global
|
||||||
|
|
||||||
|
## Target maintainers
|
||||||
|
|
||||||
|
- Alex Crichton, https://github.com/alexcrichton
|
||||||
|
- Graydon Hoare, https://github.com/graydon
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
This target is cross-compiled. It does not support `std`, only `core` and `alloc`. Since it imports nothing from its environment, any `std` parts that use OS facilities would be stubbed out with functions-that-fail anyways, and the experience of working with the stub `std` in the `wasm32-unknown-unknown` target was deemed not something worth repeating here.
|
||||||
|
|
||||||
|
Everything else about this target's requirements, building, usage and testing is the same as what's described in the [`wasm32-unknown-unknown` document](./wasm32-unknown-unknown.md), just using the target string `wasm32v1-none` in place of `wasm32-unknown-unknown`.
|
||||||
|
|
||||||
|
## Conditionally compiling code
|
||||||
|
|
||||||
|
It's recommended to conditionally compile code for this target with:
|
||||||
|
|
||||||
|
```text
|
||||||
|
#[cfg(all(target_family = "wasm", target_os = "none"))]
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that there is no way to tell via `#[cfg]` whether code will be running on
|
||||||
|
the web or not.
|
||||||
|
|
||||||
|
## Enabled WebAssembly features
|
||||||
|
|
||||||
|
As noted above, _no WebAssembly proposals past 1.0_ are enabled on this target by default. Indeed, the entire point of this target is to have a way to compile for a stable "no post-1.0 proposals" subset of WebAssembly _on stable Rust_.
|
||||||
|
|
||||||
|
The [W3C WebAssembly Core 1.0 spec] was adopted as a W3C recommendation in December 2019, and includes exactly one "post-MVP" proposal: the [Import/Export of Mutable Globals] proposal.
|
||||||
|
|
||||||
|
All subsequent proposals are _disabled_ on this target by default, though they can be individually enabled by passing LLVM target-feature flags.
|
||||||
|
|
||||||
|
For reference sake, the set of proposals that LLVM supports at the time of writing, that this target _does not enable by default_, are listed here along with their LLVM target-feature flags:
|
||||||
|
|
||||||
|
* Post-1.0 proposals (integrated into the WebAssembly core 2.0 spec):
|
||||||
|
* [Bulk memory] - `+bulk-memory`
|
||||||
|
* [Sign-extending operations] - `+sign-ext`
|
||||||
|
* [Non-trapping fp-to-int operations] - `+nontrapping-fptoint`
|
||||||
|
* [Multi-value] - `+multivalue`
|
||||||
|
* [Reference Types] - `+reference-types`
|
||||||
|
* [Fixed-width SIMD] - `+simd128`
|
||||||
|
* Post-2.0 proposals:
|
||||||
|
* [Threads] (supported by atomics) - `+atomics`
|
||||||
|
* [Exception handling] - `+exception-handling`
|
||||||
|
* [Extended Constant Expressions] - `+extended-const`
|
||||||
|
* [Half Precision] - `+half-precision`
|
||||||
|
* [Multiple memories]- `+multimemory`
|
||||||
|
* [Relaxed SIMD] - `+relaxed-simd`
|
||||||
|
* [Tail call] - `+tail-call`
|
||||||
|
|
||||||
|
[Bulk memory]: https://github.com/WebAssembly/spec/blob/main/proposals/bulk-memory-operations/Overview.md
|
||||||
|
[Sign-extending operations]: https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md
|
||||||
|
[Non-trapping fp-to-int operations]: https://github.com/WebAssembly/spec/blob/main/proposals/nontrapping-float-to-int-conversion/Overview.md
|
||||||
|
[Multi-value]: https://github.com/WebAssembly/spec/blob/main/proposals/multi-value/Overview.md
|
||||||
|
[Reference Types]: https://github.com/WebAssembly/spec/blob/main/proposals/reference-types/Overview.md
|
||||||
|
[Fixed-width SIMD]: https://github.com/WebAssembly/spec/blob/main/proposals/simd/SIMD.md
|
||||||
|
[Threads]: https://github.com/webassembly/threads
|
||||||
|
[Exception handling]: https://github.com/WebAssembly/exception-handling
|
||||||
|
[Extended Constant Expressions]: https://github.com/WebAssembly/extended-const
|
||||||
|
[Half Precision]: https://github.com/WebAssembly/half-precision
|
||||||
|
[Multiple memories]: https://github.com/WebAssembly/multi-memory
|
||||||
|
[Relaxed SIMD]: https://github.com/WebAssembly/relaxed-simd
|
||||||
|
[Tail call]: https://github.com/WebAssembly/tail-call
|
||||||
|
|
||||||
|
Additional proposals in the future are, of course, also not enabled by default.
|
||||||
|
|
||||||
|
## Rationale relative to wasm32-unknown-unknown
|
||||||
|
|
||||||
|
As noted in the [`wasm32-unknown-unknown` document](./wasm32-unknown-unknown.md), it is possible to compile with `--target wasm32-unknown-unknown` and disable all WebAssembly proposals "by hand", by passing `-Ctarget-cpu=mvp`. Furthermore one can enable proposals one by one by passing LLVM target feature flags, such as `-Ctarget-feature=+mutable-globals`.
|
||||||
|
|
||||||
|
Is it therefore reasonable to wonder what the difference is between building with this:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ rustc --target wasm32-unknown-unknown -Ctarget-cpu=mvp -Ctarget-feature=+mutable-globals
|
||||||
|
```
|
||||||
|
|
||||||
|
and building with this:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ rustc --target wasm32v1-none
|
||||||
|
```
|
||||||
|
|
||||||
|
The difference is in how the `core` and `alloc` crates are compiled for distribution with the toolchain, and whether it works on _stable_ Rust toolchains or requires _nightly_ ones. Again referring back to the [`wasm32-unknown-unknown` document](./wasm32-unknown-unknown.md), note that to disable all post-MVP proposals on that target one _actually_ has to compile with this:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ export RUSTFLAGS="-Ctarget-cpu=mvp -Ctarget-feature=+mutable-globals"
|
||||||
|
$ cargo +nightly build -Zbuild-std=panic_abort,std --target wasm32-unknown-unknown
|
||||||
|
```
|
||||||
|
|
||||||
|
Which not only rebuilds `std`, `core` and `alloc` (which is somewhat costly and annoying) but more importantly requires the use of nightly Rust toolchains (for the `-Zbuild-std` flag). This is very undesirable for the target audience, which consists of people targeting WebAssembly implementations that prioritize stability, simplicity and/or security over feature support.
|
||||||
|
|
||||||
|
This `wasm32v1-none` target exists as an alternative option that works on stable Rust toolchains, without rebuilding the stdlib.
|
@ -161,6 +161,7 @@
|
|||||||
"wasm32-wasip1",
|
"wasm32-wasip1",
|
||||||
"wasm32-wasip1-threads",
|
"wasm32-wasip1-threads",
|
||||||
"wasm32-wasip2",
|
"wasm32-wasip2",
|
||||||
|
"wasm32v1-none",
|
||||||
"x86_64-apple-darwin",
|
"x86_64-apple-darwin",
|
||||||
"x86_64-apple-ios",
|
"x86_64-apple-ios",
|
||||||
"x86_64-apple-ios-macabi",
|
"x86_64-apple-ios-macabi",
|
||||||
|
@ -387,6 +387,9 @@ pub struct Config {
|
|||||||
/// True if the profiler runtime is enabled for this target.
|
/// True if the profiler runtime is enabled for this target.
|
||||||
/// Used by the "needs-profiler-runtime" directive in test files.
|
/// Used by the "needs-profiler-runtime" directive in test files.
|
||||||
pub profiler_runtime: bool,
|
pub profiler_runtime: bool,
|
||||||
|
|
||||||
|
/// Command for visual diff display, e.g. `diff-tool --color=always`.
|
||||||
|
pub diff_command: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
@ -175,6 +175,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||||||
"git-merge-commit-email",
|
"git-merge-commit-email",
|
||||||
"email address used for finding merge commits",
|
"email address used for finding merge commits",
|
||||||
"EMAIL",
|
"EMAIL",
|
||||||
|
)
|
||||||
|
.optopt(
|
||||||
|
"",
|
||||||
|
"compiletest-diff-tool",
|
||||||
|
"What custom diff tool to use for displaying compiletest tests.",
|
||||||
|
"COMMAND",
|
||||||
);
|
);
|
||||||
|
|
||||||
let (argv0, args_) = args.split_first().unwrap();
|
let (argv0, args_) = args.split_first().unwrap();
|
||||||
@ -364,6 +370,7 @@ fn make_absolute(path: PathBuf) -> PathBuf {
|
|||||||
git_merge_commit_email: matches.opt_str("git-merge-commit-email").unwrap(),
|
git_merge_commit_email: matches.opt_str("git-merge-commit-email").unwrap(),
|
||||||
|
|
||||||
profiler_runtime: matches.opt_present("profiler-runtime"),
|
profiler_runtime: matches.opt_present("profiler-runtime"),
|
||||||
|
diff_command: matches.opt_str("compiletest-diff-tool"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2459,7 +2459,7 @@ fn delete_file(&self, file: &PathBuf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize {
|
fn compare_output(&self, stream: &str, actual: &str, expected: &str) -> usize {
|
||||||
let are_different = match (self.force_color_svg(), expected.find('\n'), actual.find('\n')) {
|
let are_different = match (self.force_color_svg(), expected.find('\n'), actual.find('\n')) {
|
||||||
// FIXME: We ignore the first line of SVG files
|
// FIXME: We ignore the first line of SVG files
|
||||||
// because the width parameter is non-deterministic.
|
// because the width parameter is non-deterministic.
|
||||||
@ -2499,56 +2499,66 @@ fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize {
|
|||||||
(expected, actual)
|
(expected, actual)
|
||||||
};
|
};
|
||||||
|
|
||||||
if !self.config.bless {
|
// Write the actual output to a file in build/
|
||||||
if expected.is_empty() {
|
let test_name = self.config.compare_mode.as_ref().map_or("", |m| m.to_str());
|
||||||
println!("normalized {}:\n{}\n", kind, actual);
|
let actual_path = self
|
||||||
} else {
|
|
||||||
println!("diff of {}:\n", kind);
|
|
||||||
print!("{}", write_diff(expected, actual, 3));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mode = self.config.compare_mode.as_ref().map_or("", |m| m.to_str());
|
|
||||||
let output_file = self
|
|
||||||
.output_base_name()
|
.output_base_name()
|
||||||
.with_extra_extension(self.revision.unwrap_or(""))
|
.with_extra_extension(self.revision.unwrap_or(""))
|
||||||
.with_extra_extension(mode)
|
.with_extra_extension(test_name)
|
||||||
.with_extra_extension(kind);
|
.with_extra_extension(stream);
|
||||||
|
|
||||||
let mut files = vec![output_file];
|
if let Err(err) = fs::write(&actual_path, &actual) {
|
||||||
if self.config.bless {
|
self.fatal(&format!("failed to write {stream} to `{actual_path:?}`: {err}",));
|
||||||
|
}
|
||||||
|
println!("Saved the actual {stream} to {actual_path:?}");
|
||||||
|
|
||||||
|
let expected_path =
|
||||||
|
expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream);
|
||||||
|
|
||||||
|
if !self.config.bless {
|
||||||
|
if expected.is_empty() {
|
||||||
|
println!("normalized {}:\n{}\n", stream, actual);
|
||||||
|
} else {
|
||||||
|
println!("diff of {stream}:\n");
|
||||||
|
if let Some(diff_command) = self.config.diff_command.as_deref() {
|
||||||
|
let mut args = diff_command.split_whitespace();
|
||||||
|
let name = args.next().unwrap();
|
||||||
|
match Command::new(name)
|
||||||
|
.args(args)
|
||||||
|
.args([&expected_path, &actual_path])
|
||||||
|
.output()
|
||||||
|
{
|
||||||
|
Err(err) => {
|
||||||
|
self.fatal(&format!(
|
||||||
|
"failed to call custom diff command `{diff_command}`: {err}"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(output) => {
|
||||||
|
let output = String::from_utf8_lossy(&output.stdout);
|
||||||
|
print!("{output}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print!("{}", write_diff(expected, actual, 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// Delete non-revision .stderr/.stdout file if revisions are used.
|
// Delete non-revision .stderr/.stdout file if revisions are used.
|
||||||
// Without this, we'd just generate the new files and leave the old files around.
|
// Without this, we'd just generate the new files and leave the old files around.
|
||||||
if self.revision.is_some() {
|
if self.revision.is_some() {
|
||||||
let old =
|
let old =
|
||||||
expected_output_path(self.testpaths, None, &self.config.compare_mode, kind);
|
expected_output_path(self.testpaths, None, &self.config.compare_mode, stream);
|
||||||
self.delete_file(&old);
|
self.delete_file(&old);
|
||||||
}
|
}
|
||||||
files.push(expected_output_path(
|
|
||||||
self.testpaths,
|
|
||||||
self.revision,
|
|
||||||
&self.config.compare_mode,
|
|
||||||
kind,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
for output_file in &files {
|
if let Err(err) = fs::write(&expected_path, &actual) {
|
||||||
if actual.is_empty() {
|
self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}"));
|
||||||
self.delete_file(output_file);
|
|
||||||
} else if let Err(err) = fs::write(&output_file, &actual) {
|
|
||||||
self.fatal(&format!(
|
|
||||||
"failed to write {} to `{}`: {}",
|
|
||||||
kind,
|
|
||||||
output_file.display(),
|
|
||||||
err,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
println!("Blessing the {stream} of {test_name} in {expected_path:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("\nThe actual {0} differed from the expected {0}.", kind);
|
println!("\nThe actual {0} differed from the expected {0}.", stream);
|
||||||
for output_file in files {
|
|
||||||
println!("Actual {} saved to {}", kind, output_file.display());
|
|
||||||
}
|
|
||||||
if self.config.bless { 0 } else { 1 }
|
if self.config.bless { 0 } else { 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,6 +522,9 @@
|
|||||||
//@ revisions: wasm32_unknown_unknown
|
//@ revisions: wasm32_unknown_unknown
|
||||||
//@ [wasm32_unknown_unknown] compile-flags: --target wasm32-unknown-unknown
|
//@ [wasm32_unknown_unknown] compile-flags: --target wasm32-unknown-unknown
|
||||||
//@ [wasm32_unknown_unknown] needs-llvm-components: webassembly
|
//@ [wasm32_unknown_unknown] needs-llvm-components: webassembly
|
||||||
|
//@ revisions: wasm32v1_none
|
||||||
|
//@ [wasm32v1_none] compile-flags: --target wasm32v1-none
|
||||||
|
//@ [wasm32v1_none] needs-llvm-components: webassembly
|
||||||
//@ revisions: wasm32_wasi
|
//@ revisions: wasm32_wasi
|
||||||
//@ [wasm32_wasi] compile-flags: --target wasm32-wasi
|
//@ [wasm32_wasi] compile-flags: --target wasm32-wasi
|
||||||
//@ [wasm32_wasi] needs-llvm-components: webassembly
|
//@ [wasm32_wasi] needs-llvm-components: webassembly
|
||||||
|
Loading…
Reference in New Issue
Block a user