mirror of
https://github.com/rust-lang/rust
synced 2024-10-06 08:40:35 +00:00
Use a better set of targets for blessing mir-opt tests
This commit is contained in:
parent
586893c7b0
commit
4451bf4d67
|
@ -97,6 +97,20 @@ pub fn new_with_extra_rust_args(
|
|||
is_for_mir_opt_tests: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_extra_objects(
|
||||
&self,
|
||||
builder: &Builder<'_>,
|
||||
compiler: &Compiler,
|
||||
target: TargetSelection,
|
||||
) -> Vec<(PathBuf, DependencyType)> {
|
||||
let mut deps = Vec::new();
|
||||
if !self.is_for_mir_opt_tests {
|
||||
deps.extend(copy_third_party_objects(builder, &compiler, target));
|
||||
deps.extend(copy_self_contained_objects(builder, &compiler, target));
|
||||
}
|
||||
deps
|
||||
}
|
||||
}
|
||||
|
||||
impl Step for Std {
|
||||
|
@ -159,8 +173,7 @@ fn run(self, builder: &Builder<'_>) {
|
|||
{
|
||||
builder.info("WARNING: Using a potentially old libstd. This may not behave well.");
|
||||
|
||||
copy_third_party_objects(builder, &compiler, target);
|
||||
copy_self_contained_objects(builder, &compiler, target);
|
||||
self.copy_extra_objects(builder, &compiler, target);
|
||||
|
||||
builder.ensure(StdLink::from_std(self, compiler));
|
||||
return;
|
||||
|
@ -193,15 +206,13 @@ fn run(self, builder: &Builder<'_>) {
|
|||
|
||||
// Even if we're not building std this stage, the new sysroot must
|
||||
// still contain the third party objects needed by various targets.
|
||||
copy_third_party_objects(builder, &compiler, target);
|
||||
copy_self_contained_objects(builder, &compiler, target);
|
||||
self.copy_extra_objects(builder, &compiler, target);
|
||||
|
||||
builder.ensure(StdLink::from_std(self, compiler_to_use));
|
||||
return;
|
||||
}
|
||||
|
||||
target_deps.extend(copy_third_party_objects(builder, &compiler, target));
|
||||
target_deps.extend(copy_self_contained_objects(builder, &compiler, target));
|
||||
target_deps.extend(self.copy_extra_objects(builder, &compiler, target));
|
||||
|
||||
// The LLD wrappers and `rust-lld` are self-contained linking components that can be
|
||||
// necessary to link the stdlib on some targets. We'll also need to copy these binaries to
|
||||
|
@ -222,9 +233,12 @@ fn run(self, builder: &Builder<'_>) {
|
|||
}
|
||||
}
|
||||
|
||||
// We build a sysroot for mir-opt tests using the same trick that Miri does: A check build
|
||||
// with -Zalways-encode-mir. This frees us from the need to have a target linker, and the
|
||||
// fact that this is a check build integrates nicely with run_cargo.
|
||||
let mut cargo = if self.is_for_mir_opt_tests {
|
||||
let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustc");
|
||||
cargo.arg("-p").arg("std").arg("--crate-type=lib");
|
||||
let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "check");
|
||||
cargo.rustflag("-Zalways-encode-mir");
|
||||
std_cargo(builder, target, compiler.stage, &mut cargo);
|
||||
cargo
|
||||
} else {
|
||||
|
@ -257,7 +271,7 @@ fn run(self, builder: &Builder<'_>) {
|
|||
vec![],
|
||||
&libstd_stamp(builder, compiler, target),
|
||||
target_deps,
|
||||
false,
|
||||
self.is_for_mir_opt_tests, // is_check
|
||||
false,
|
||||
);
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
use crate::core::config::flags::get_completion;
|
||||
use crate::core::config::flags::Subcommand;
|
||||
use crate::core::config::TargetSelection;
|
||||
use crate::utils;
|
||||
use crate::utils::cache::{Interned, INTERNER};
|
||||
use crate::utils::exec::BootstrapCommand;
|
||||
use crate::utils::helpers::{
|
||||
|
@ -38,23 +37,6 @@
|
|||
|
||||
const ADB_TEST_DIR: &str = "/data/local/tmp/work";
|
||||
|
||||
// mir-opt tests have different variants depending on whether a target is 32bit or 64bit, and
|
||||
// blessing them requires blessing with each target. To aid developers, when blessing the mir-opt
|
||||
// test suite the corresponding target of the opposite pointer size is also blessed.
|
||||
//
|
||||
// This array serves as the known mappings between 32bit and 64bit targets. If you're developing on
|
||||
// a target where a target with the opposite pointer size exists, feel free to add it here.
|
||||
const MIR_OPT_BLESS_TARGET_MAPPING: &[(&str, &str)] = &[
|
||||
// (32bit, 64bit)
|
||||
("i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu"),
|
||||
("i686-unknown-linux-musl", "x86_64-unknown-linux-musl"),
|
||||
("i686-pc-windows-msvc", "x86_64-pc-windows-msvc"),
|
||||
("i686-pc-windows-gnu", "x86_64-pc-windows-gnu"),
|
||||
// ARM Macs don't have a corresponding 32-bit target that they can (easily)
|
||||
// build for, so there is no entry for "aarch64-apple-darwin" here.
|
||||
// Likewise, i686 for macOS is no longer possible to build.
|
||||
];
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct CrateBootstrap {
|
||||
path: Interned<PathBuf>,
|
||||
|
@ -1487,46 +1469,19 @@ fn run(self, builder: &Builder<'_>) {
|
|||
})
|
||||
};
|
||||
|
||||
// We use custom logic to bless the mir-opt suite: mir-opt tests have multiple variants
|
||||
// (32bit vs 64bit, and panic=abort vs panic=unwind), and all of them needs to be blessed.
|
||||
// When blessing, we try best-effort to also bless the other variants, to aid developers.
|
||||
if builder.config.cmd.bless() {
|
||||
let targets = MIR_OPT_BLESS_TARGET_MAPPING
|
||||
.iter()
|
||||
.filter(|(target_32bit, target_64bit)| {
|
||||
*target_32bit == &*self.target.triple || *target_64bit == &*self.target.triple
|
||||
})
|
||||
.next()
|
||||
.map(|(target_32bit, target_64bit)| {
|
||||
let target_32bit = TargetSelection::from_user(target_32bit);
|
||||
let target_64bit = TargetSelection::from_user(target_64bit);
|
||||
crate::utils::cc_detect::find_target(builder, self.compiler.host);
|
||||
// All that we really need to do is cover all combinations of 32/64-bit and unwind/abort,
|
||||
// but while we're at it we might as well flex our cross-compilation support. This
|
||||
// selection covers all our tier 1 operating systems and architectures using only tier
|
||||
// 1 targets.
|
||||
|
||||
// Running compiletest requires a C compiler to be available, but it might not
|
||||
// have been detected by bootstrap if the target we're testing wasn't in the
|
||||
// --target flags.
|
||||
if !builder.cc.borrow().contains_key(&target_32bit) {
|
||||
utils::cc_detect::find_target(builder, target_32bit);
|
||||
}
|
||||
if !builder.cc.borrow().contains_key(&target_64bit) {
|
||||
utils::cc_detect::find_target(builder, target_64bit);
|
||||
}
|
||||
|
||||
vec![target_32bit, target_64bit]
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
eprintln!(
|
||||
"\
|
||||
Note that not all variants of mir-opt tests are going to be blessed, as no mapping between
|
||||
a 32bit and a 64bit target was found for {target}.
|
||||
You can add that mapping by changing MIR_OPT_BLESS_TARGET_MAPPING in src/bootstrap/test.rs",
|
||||
target = self.target,
|
||||
);
|
||||
vec![self.target]
|
||||
});
|
||||
|
||||
for target in targets {
|
||||
run(target);
|
||||
for target in ["aarch64-unknown-linux-gnu", "i686-pc-windows-msvc"] {
|
||||
run(TargetSelection::from_user(target));
|
||||
}
|
||||
|
||||
for target in ["x86_64-apple-darwin", "i686-unknown-linux-musl"] {
|
||||
let target = TargetSelection::from_user(target);
|
||||
let panic_abort_target = builder.ensure(MirOptPanicAbortSyntheticTarget {
|
||||
compiler: self.compiler,
|
||||
base: target,
|
||||
|
@ -1616,27 +1571,27 @@ fn run(self, builder: &Builder<'_>) {
|
|||
.ensure(dist::DebuggerScripts { sysroot: builder.sysroot(compiler), host: target });
|
||||
}
|
||||
|
||||
if suite == "mir-opt" {
|
||||
builder.ensure(compile::Std::new_for_mir_opt_tests(compiler, target));
|
||||
} else {
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
}
|
||||
// Also provide `rust_test_helpers` for the host.
|
||||
builder.ensure(TestHelpers { target: compiler.host });
|
||||
|
||||
// ensure that `libproc_macro` is available on the host.
|
||||
builder.ensure(compile::Std::new(compiler, compiler.host));
|
||||
|
||||
// Also provide `rust_test_helpers` for the host.
|
||||
builder.ensure(TestHelpers { target: compiler.host });
|
||||
|
||||
// As well as the target, except for plain wasm32, which can't build it
|
||||
if suite != "mir-opt" && !target.contains("wasm") && !target.contains("emscripten") {
|
||||
builder.ensure(TestHelpers { target });
|
||||
}
|
||||
|
||||
builder.ensure(RemoteCopyLibs { compiler, target });
|
||||
|
||||
let mut cmd = builder.tool_cmd(Tool::Compiletest);
|
||||
|
||||
if suite == "mir-opt" {
|
||||
builder.ensure(compile::Std::new_for_mir_opt_tests(compiler, target));
|
||||
} else {
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
}
|
||||
|
||||
builder.ensure(RemoteCopyLibs { compiler, target });
|
||||
|
||||
// compiletest currently has... a lot of arguments, so let's just pass all
|
||||
// of them!
|
||||
|
||||
|
@ -1745,11 +1700,13 @@ fn run(self, builder: &Builder<'_>) {
|
|||
flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
|
||||
flags.extend(builder.config.cmd.rustc_args().iter().map(|s| s.to_string()));
|
||||
|
||||
if let Some(linker) = builder.linker(target) {
|
||||
cmd.arg("--target-linker").arg(linker);
|
||||
}
|
||||
if let Some(linker) = builder.linker(compiler.host) {
|
||||
cmd.arg("--host-linker").arg(linker);
|
||||
if suite != "mir-opt" {
|
||||
if let Some(linker) = builder.linker(target) {
|
||||
cmd.arg("--target-linker").arg(linker);
|
||||
}
|
||||
if let Some(linker) = builder.linker(compiler.host) {
|
||||
cmd.arg("--host-linker").arg(linker);
|
||||
}
|
||||
}
|
||||
|
||||
let mut hostflags = flags.clone();
|
||||
|
@ -1936,15 +1893,17 @@ fn run(self, builder: &Builder<'_>) {
|
|||
cmd.arg("--remote-test-client").arg(builder.tool_exe(Tool::RemoteTestClient));
|
||||
}
|
||||
|
||||
// Running a C compiler on MSVC requires a few env vars to be set, to be
|
||||
// sure to set them here.
|
||||
//
|
||||
// Note that if we encounter `PATH` we make sure to append to our own `PATH`
|
||||
// rather than stomp over it.
|
||||
if !builder.config.dry_run() && target.is_msvc() {
|
||||
for &(ref k, ref v) in builder.cc.borrow()[&target].env() {
|
||||
if k != "PATH" {
|
||||
cmd.env(k, v);
|
||||
if suite != "mir-opt" {
|
||||
// Running a C compiler on MSVC requires a few env vars to be set, to be
|
||||
// sure to set them here.
|
||||
//
|
||||
// Note that if we encounter `PATH` we make sure to append to our own `PATH`
|
||||
// rather than stomp over it.
|
||||
if !builder.config.dry_run() && target.is_msvc() {
|
||||
for &(ref k, ref v) in builder.cc.borrow()[&target].env() {
|
||||
if k != "PATH" {
|
||||
cmd.env(k, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1646,76 +1646,12 @@ pub fn cargo(
|
|||
cargo.env("RUSTC_WRAPPER_REAL", existing_wrapper);
|
||||
}
|
||||
|
||||
// Dealing with rpath here is a little special, so let's go into some
|
||||
// detail. First off, `-rpath` is a linker option on Unix platforms
|
||||
// which adds to the runtime dynamic loader path when looking for
|
||||
// dynamic libraries. We use this by default on Unix platforms to ensure
|
||||
// that our nightlies behave the same on Windows, that is they work out
|
||||
// of the box. This can be disabled by setting `rpath = false` in `[rust]`
|
||||
// table of `config.toml`
|
||||
//
|
||||
// Ok, so the astute might be wondering "why isn't `-C rpath` used
|
||||
// here?" and that is indeed a good question to ask. This codegen
|
||||
// option is the compiler's current interface to generating an rpath.
|
||||
// Unfortunately it doesn't quite suffice for us. The flag currently
|
||||
// takes no value as an argument, so the compiler calculates what it
|
||||
// should pass to the linker as `-rpath`. This unfortunately is based on
|
||||
// the **compile time** directory structure which when building with
|
||||
// Cargo will be very different than the runtime directory structure.
|
||||
//
|
||||
// All that's a really long winded way of saying that if we use
|
||||
// `-Crpath` then the executables generated have the wrong rpath of
|
||||
// something like `$ORIGIN/deps` when in fact the way we distribute
|
||||
// rustc requires the rpath to be `$ORIGIN/../lib`.
|
||||
//
|
||||
// So, all in all, to set up the correct rpath we pass the linker
|
||||
// argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
|
||||
// fun to pass a flag to a tool to pass a flag to pass a flag to a tool
|
||||
// to change a flag in a binary?
|
||||
if self.config.rpath_enabled(target) && helpers::use_host_linker(target) {
|
||||
let libdir = self.sysroot_libdir_relative(compiler).to_str().unwrap();
|
||||
let rpath = if target.contains("apple") {
|
||||
// Note that we need to take one extra step on macOS to also pass
|
||||
// `-Wl,-instal_name,@rpath/...` to get things to work right. To
|
||||
// do that we pass a weird flag to the compiler to get it to do
|
||||
// so. Note that this is definitely a hack, and we should likely
|
||||
// flesh out rpath support more fully in the future.
|
||||
rustflags.arg("-Zosx-rpath-install-name");
|
||||
Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
|
||||
} else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
|
||||
rustflags.arg("-Clink-args=-Wl,-z,origin");
|
||||
Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(rpath) = rpath {
|
||||
rustflags.arg(&format!("-Clink-args={rpath}"));
|
||||
}
|
||||
}
|
||||
|
||||
cargo.env(profile_var("STRIP"), self.config.rust_strip.to_string());
|
||||
|
||||
if let Some(stack_protector) = &self.config.rust_stack_protector {
|
||||
rustflags.arg(&format!("-Zstack-protector={stack_protector}"));
|
||||
}
|
||||
|
||||
for arg in linker_args(self, compiler.host, LldThreads::Yes) {
|
||||
hostflags.arg(&arg);
|
||||
}
|
||||
|
||||
if let Some(target_linker) = self.linker(target) {
|
||||
let target = crate::envify(&target.triple);
|
||||
cargo.env(&format!("CARGO_TARGET_{target}_LINKER"), target_linker);
|
||||
}
|
||||
// We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
|
||||
// `linker_args` here.
|
||||
for flag in linker_flags(self, target, LldThreads::Yes) {
|
||||
rustflags.arg(&flag);
|
||||
}
|
||||
for arg in linker_args(self, target, LldThreads::Yes) {
|
||||
rustdocflags.arg(&arg);
|
||||
}
|
||||
|
||||
if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
|
||||
cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
|
||||
}
|
||||
|
@ -1731,10 +1667,6 @@ pub fn cargo(
|
|||
if let Some(opt_level) = &self.config.rust_optimize.get_opt_level() {
|
||||
cargo.env(profile_var("OPT_LEVEL"), opt_level);
|
||||
}
|
||||
if !self.config.dry_run() && self.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz")
|
||||
{
|
||||
rustflags.arg("-Clink-arg=-gz");
|
||||
}
|
||||
cargo.env(
|
||||
profile_var("DEBUG_ASSERTIONS"),
|
||||
if mode == Mode::Std {
|
||||
|
@ -1940,55 +1872,15 @@ pub fn cargo(
|
|||
rustflags.arg("-Wrustc::internal");
|
||||
}
|
||||
|
||||
// Throughout the build Cargo can execute a number of build scripts
|
||||
// compiling C/C++ code and we need to pass compilers, archivers, flags, etc
|
||||
// obtained previously to those build scripts.
|
||||
// Build scripts use either the `cc` crate or `configure/make` so we pass
|
||||
// the options through environment variables that are fetched and understood by both.
|
||||
//
|
||||
// FIXME: the guard against msvc shouldn't need to be here
|
||||
if target.is_msvc() {
|
||||
if let Some(ref cl) = self.config.llvm_clang_cl {
|
||||
cargo.env("CC", cl).env("CXX", cl);
|
||||
}
|
||||
} else {
|
||||
let ccache = self.config.ccache.as_ref();
|
||||
let ccacheify = |s: &Path| {
|
||||
let ccache = match ccache {
|
||||
Some(ref s) => s,
|
||||
None => return s.display().to_string(),
|
||||
};
|
||||
// FIXME: the cc-rs crate only recognizes the literal strings
|
||||
// `ccache` and `sccache` when doing caching compilations, so we
|
||||
// mirror that here. It should probably be fixed upstream to
|
||||
// accept a new env var or otherwise work with custom ccache
|
||||
// vars.
|
||||
match &ccache[..] {
|
||||
"ccache" | "sccache" => format!("{} {}", ccache, s.display()),
|
||||
_ => s.display().to_string(),
|
||||
}
|
||||
};
|
||||
let triple_underscored = target.triple.replace("-", "_");
|
||||
let cc = ccacheify(&self.cc(target));
|
||||
cargo.env(format!("CC_{triple_underscored}"), &cc);
|
||||
|
||||
let cflags = self.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
|
||||
cargo.env(format!("CFLAGS_{triple_underscored}"), &cflags);
|
||||
|
||||
if let Some(ar) = self.ar(target) {
|
||||
let ranlib = format!("{} s", ar.display());
|
||||
cargo
|
||||
.env(format!("AR_{triple_underscored}"), ar)
|
||||
.env(format!("RANLIB_{triple_underscored}"), ranlib);
|
||||
}
|
||||
|
||||
if let Ok(cxx) = self.cxx(target) {
|
||||
let cxx = ccacheify(&cxx);
|
||||
let cxxflags = self.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
|
||||
cargo
|
||||
.env(format!("CXX_{triple_underscored}"), &cxx)
|
||||
.env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);
|
||||
}
|
||||
if cmd != "check" {
|
||||
self.configure_linker(
|
||||
compiler,
|
||||
target,
|
||||
&mut cargo,
|
||||
&mut rustflags,
|
||||
&mut rustdocflags,
|
||||
&mut hostflags,
|
||||
);
|
||||
}
|
||||
|
||||
// If Control Flow Guard is enabled, pass the `control-flow-guard` flag to rustc
|
||||
|
@ -2142,6 +2034,136 @@ pub fn cargo(
|
|||
Cargo { command: cargo, rustflags, rustdocflags, hostflags, allow_features }
|
||||
}
|
||||
|
||||
fn configure_linker(
|
||||
&self,
|
||||
compiler: Compiler,
|
||||
target: TargetSelection,
|
||||
cargo: &mut Command,
|
||||
rustflags: &mut Rustflags,
|
||||
rustdocflags: &mut Rustflags,
|
||||
hostflags: &mut HostFlags,
|
||||
) {
|
||||
// Dealing with rpath here is a little special, so let's go into some
|
||||
// detail. First off, `-rpath` is a linker option on Unix platforms
|
||||
// which adds to the runtime dynamic loader path when looking for
|
||||
// dynamic libraries. We use this by default on Unix platforms to ensure
|
||||
// that our nightlies behave the same on Windows, that is they work out
|
||||
// of the box. This can be disabled by setting `rpath = false` in `[rust]`
|
||||
// table of `config.toml`
|
||||
//
|
||||
// Ok, so the astute might be wondering "why isn't `-C rpath` used
|
||||
// here?" and that is indeed a good question to ask. This codegen
|
||||
// option is the compiler's current interface to generating an rpath.
|
||||
// Unfortunately it doesn't quite suffice for us. The flag currently
|
||||
// takes no value as an argument, so the compiler calculates what it
|
||||
// should pass to the linker as `-rpath`. This unfortunately is based on
|
||||
// the **compile time** directory structure which when building with
|
||||
// Cargo will be very different than the runtime directory structure.
|
||||
//
|
||||
// All that's a really long winded way of saying that if we use
|
||||
// `-Crpath` then the executables generated have the wrong rpath of
|
||||
// something like `$ORIGIN/deps` when in fact the way we distribute
|
||||
// rustc requires the rpath to be `$ORIGIN/../lib`.
|
||||
//
|
||||
// So, all in all, to set up the correct rpath we pass the linker
|
||||
// argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
|
||||
// fun to pass a flag to a tool to pass a flag to pass a flag to a tool
|
||||
// to change a flag in a binary?
|
||||
if self.config.rpath_enabled(target) && helpers::use_host_linker(target) {
|
||||
let libdir = self.sysroot_libdir_relative(compiler).to_str().unwrap();
|
||||
let rpath = if target.contains("apple") {
|
||||
// Note that we need to take one extra step on macOS to also pass
|
||||
// `-Wl,-instal_name,@rpath/...` to get things to work right. To
|
||||
// do that we pass a weird flag to the compiler to get it to do
|
||||
// so. Note that this is definitely a hack, and we should likely
|
||||
// flesh out rpath support more fully in the future.
|
||||
rustflags.arg("-Zosx-rpath-install-name");
|
||||
Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
|
||||
} else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
|
||||
rustflags.arg("-Clink-args=-Wl,-z,origin");
|
||||
Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(rpath) = rpath {
|
||||
rustflags.arg(&format!("-Clink-args={rpath}"));
|
||||
}
|
||||
}
|
||||
|
||||
for arg in linker_args(self, compiler.host, LldThreads::Yes) {
|
||||
hostflags.arg(&arg);
|
||||
}
|
||||
|
||||
if let Some(target_linker) = self.linker(target) {
|
||||
let target = crate::envify(&target.triple);
|
||||
cargo.env(&format!("CARGO_TARGET_{target}_LINKER"), target_linker);
|
||||
}
|
||||
// We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
|
||||
// `linker_args` here.
|
||||
for flag in linker_flags(self, target, LldThreads::Yes) {
|
||||
rustflags.arg(&flag);
|
||||
}
|
||||
for arg in linker_args(self, target, LldThreads::Yes) {
|
||||
rustdocflags.arg(&arg);
|
||||
}
|
||||
|
||||
if !self.config.dry_run() && self.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz")
|
||||
{
|
||||
rustflags.arg("-Clink-arg=-gz");
|
||||
}
|
||||
|
||||
// Throughout the build Cargo can execute a number of build scripts
|
||||
// compiling C/C++ code and we need to pass compilers, archivers, flags, etc
|
||||
// obtained previously to those build scripts.
|
||||
// Build scripts use either the `cc` crate or `configure/make` so we pass
|
||||
// the options through environment variables that are fetched and understood by both.
|
||||
//
|
||||
// FIXME: the guard against msvc shouldn't need to be here
|
||||
if target.is_msvc() {
|
||||
if let Some(ref cl) = self.config.llvm_clang_cl {
|
||||
cargo.env("CC", cl).env("CXX", cl);
|
||||
}
|
||||
} else {
|
||||
let ccache = self.config.ccache.as_ref();
|
||||
let ccacheify = |s: &Path| {
|
||||
let ccache = match ccache {
|
||||
Some(ref s) => s,
|
||||
None => return s.display().to_string(),
|
||||
};
|
||||
// FIXME: the cc-rs crate only recognizes the literal strings
|
||||
// `ccache` and `sccache` when doing caching compilations, so we
|
||||
// mirror that here. It should probably be fixed upstream to
|
||||
// accept a new env var or otherwise work with custom ccache
|
||||
// vars.
|
||||
match &ccache[..] {
|
||||
"ccache" | "sccache" => format!("{} {}", ccache, s.display()),
|
||||
_ => s.display().to_string(),
|
||||
}
|
||||
};
|
||||
let triple_underscored = target.triple.replace("-", "_");
|
||||
let cc = ccacheify(&self.cc(target));
|
||||
cargo.env(format!("CC_{triple_underscored}"), &cc);
|
||||
|
||||
let cflags = self.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
|
||||
cargo.env(format!("CFLAGS_{triple_underscored}"), &cflags);
|
||||
|
||||
if let Some(ar) = self.ar(target) {
|
||||
let ranlib = format!("{} s", ar.display());
|
||||
cargo
|
||||
.env(format!("AR_{triple_underscored}"), ar)
|
||||
.env(format!("RANLIB_{triple_underscored}"), ranlib);
|
||||
}
|
||||
|
||||
if let Ok(cxx) = self.cxx(target) {
|
||||
let cxx = ccacheify(&cxx);
|
||||
let cxxflags = self.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
|
||||
cargo
|
||||
.env(format!("CXX_{triple_underscored}"), &cxx)
|
||||
.env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure that a given step is built, returning its output. This will
|
||||
/// cache the step, so it is safe (and good!) to call this as often as
|
||||
/// needed to ensure that all dependencies are built.
|
||||
|
|
|
@ -2467,6 +2467,8 @@ fn make_compile_args(
|
|||
"-Zvalidate-mir",
|
||||
"-Zlint-mir",
|
||||
"-Zdump-mir-exclude-pass-number",
|
||||
"--crate-type=rlib",
|
||||
"-Clink-dead-code",
|
||||
]);
|
||||
if let Some(pass) = &self.props.mir_unit_test {
|
||||
rustc.args(&["-Zmir-opt-level=0", &format!("-Zmir-enable-passes=+{}", pass)]);
|
||||
|
|
|
@ -4,35 +4,16 @@
|
|||
fn g() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
+ let mut _2: fn() {main};
|
||||
+ scope 1 (inlined f::<fn() {main}>) {
|
||||
+ debug g => _2;
|
||||
+ let mut _3: &fn() {main};
|
||||
+ let _4: ();
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = f::<fn() {main}>(main) -> [return: bb1, unwind unreachable];
|
||||
+ StorageLive(_2);
|
||||
+ _2 = main;
|
||||
+ StorageLive(_4);
|
||||
+ StorageLive(_3);
|
||||
+ _3 = &_2;
|
||||
+ _4 = <fn() {main} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind unreachable];
|
||||
_1 = f::<fn() {main}>(main) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
+ StorageDead(_4);
|
||||
+ StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
_0 = const ();
|
||||
return;
|
||||
+ }
|
||||
+
|
||||
+ bb2: {
|
||||
+ StorageDead(_3);
|
||||
+ drop(_2) -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,43 +4,16 @@
|
|||
fn g() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
+ let mut _2: fn() {main};
|
||||
+ scope 1 (inlined f::<fn() {main}>) {
|
||||
+ debug g => _2;
|
||||
+ let mut _3: &fn() {main};
|
||||
+ let _4: ();
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = f::<fn() {main}>(main) -> [return: bb1, unwind continue];
|
||||
+ StorageLive(_2);
|
||||
+ _2 = main;
|
||||
+ StorageLive(_4);
|
||||
+ StorageLive(_3);
|
||||
+ _3 = &_2;
|
||||
+ _4 = <fn() {main} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind: bb3];
|
||||
_1 = f::<fn() {main}>(main) -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
+ StorageDead(_4);
|
||||
+ StorageDead(_2);
|
||||
StorageDead(_1);
|
||||
_0 = const ();
|
||||
return;
|
||||
+ }
|
||||
+
|
||||
+ bb2: {
|
||||
+ StorageDead(_3);
|
||||
+ drop(_2) -> [return: bb1, unwind continue];
|
||||
+ }
|
||||
+
|
||||
+ bb3 (cleanup): {
|
||||
+ drop(_2) -> [return: bb4, unwind terminate(cleanup)];
|
||||
+ }
|
||||
+
|
||||
+ bb4 (cleanup): {
|
||||
+ resume;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,7 @@ fn f(g: impl Fn()) {
|
|||
#[inline(always)]
|
||||
fn g() {
|
||||
// CHECK-LABEL: fn g(
|
||||
// CHECK-NOT: inlined
|
||||
// CHECK: (inlined f::<fn() {main}>)
|
||||
// CHECK-NOT: inlined
|
||||
// CHECK-NOT: (inlined f::<fn() {main}>)
|
||||
f(main);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
+ scope 1 (inlined <C as Call>::call) {
|
||||
+ scope 2 (inlined <B<A> as Call>::call) {
|
||||
+ scope 3 (inlined <A as Call>::call) {
|
||||
+ scope 4 (inlined <B<C> as Call>::call) {
|
||||
+ scope 5 (inlined <C as Call>::call) {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
|
@ -14,7 +18,7 @@
|
|||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = <C as Call>::call() -> [return: bb1, unwind unreachable];
|
||||
+ _1 = <B<C> as Call>::call() -> [return: bb1, unwind unreachable];
|
||||
+ _1 = <B<A> as Call>::call() -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
+ scope 1 (inlined <C as Call>::call) {
|
||||
+ scope 2 (inlined <B<A> as Call>::call) {
|
||||
+ scope 3 (inlined <A as Call>::call) {
|
||||
+ scope 4 (inlined <B<C> as Call>::call) {
|
||||
+ scope 5 (inlined <C as Call>::call) {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
|
@ -14,7 +18,7 @@
|
|||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = <C as Call>::call() -> [return: bb1, unwind continue];
|
||||
+ _1 = <B<C> as Call>::call() -> [return: bb1, unwind continue];
|
||||
+ _1 = <B<A> as Call>::call() -> [return: bb1, unwind continue];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// MIR for `main` after built
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
|
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// MIR for `main` after built
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
|
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
|
|
Loading…
Reference in a new issue