Add support for using cg_clif to bootstrap rustc
This commit is contained in:
parent
596b0d5027
commit
cf798c1ec6
12 changed files with 432 additions and 39 deletions
|
@ -31,6 +31,7 @@ members = [
|
||||||
]
|
]
|
||||||
exclude = [
|
exclude = [
|
||||||
"build",
|
"build",
|
||||||
|
"compiler/rustc_codegen_cranelift",
|
||||||
# HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`.
|
# HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`.
|
||||||
"obj",
|
"obj",
|
||||||
]
|
]
|
||||||
|
|
|
@ -22,7 +22,7 @@ use rustc_errors::registry::{InvalidErrorCode, Registry};
|
||||||
use rustc_errors::{ErrorReported, PResult};
|
use rustc_errors::{ErrorReported, PResult};
|
||||||
use rustc_feature::{find_gated_cfg, UnstableFeatures};
|
use rustc_feature::{find_gated_cfg, UnstableFeatures};
|
||||||
use rustc_hir::def_id::LOCAL_CRATE;
|
use rustc_hir::def_id::LOCAL_CRATE;
|
||||||
use rustc_interface::util::{collect_crate_types, get_builtin_codegen_backend};
|
use rustc_interface::util::{self, collect_crate_types, get_builtin_codegen_backend};
|
||||||
use rustc_interface::{interface, Queries};
|
use rustc_interface::{interface, Queries};
|
||||||
use rustc_lint::LintStore;
|
use rustc_lint::LintStore;
|
||||||
use rustc_metadata::locator;
|
use rustc_metadata::locator;
|
||||||
|
@ -793,38 +793,25 @@ impl RustcDefaultCalls {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a version string such as "0.12.0-dev".
|
|
||||||
fn release_str() -> Option<&'static str> {
|
|
||||||
option_env!("CFG_RELEASE")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the full SHA1 hash of HEAD of the Git repo from which rustc was built.
|
|
||||||
fn commit_hash_str() -> Option<&'static str> {
|
|
||||||
option_env!("CFG_VER_HASH")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the "commit date" of HEAD of the Git repo from which rustc was built as a static string.
|
|
||||||
fn commit_date_str() -> Option<&'static str> {
|
|
||||||
option_env!("CFG_VER_DATE")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Prints version information
|
/// Prints version information
|
||||||
pub fn version(binary: &str, matches: &getopts::Matches) {
|
pub fn version(binary: &str, matches: &getopts::Matches) {
|
||||||
let verbose = matches.opt_present("verbose");
|
let verbose = matches.opt_present("verbose");
|
||||||
|
|
||||||
println!("{} {}", binary, option_env!("CFG_VERSION").unwrap_or("unknown version"));
|
println!("{} {}", binary, util::version_str().unwrap_or("unknown version"));
|
||||||
|
|
||||||
if verbose {
|
if verbose {
|
||||||
fn unw(x: Option<&str>) -> &str {
|
fn unw(x: Option<&str>) -> &str {
|
||||||
x.unwrap_or("unknown")
|
x.unwrap_or("unknown")
|
||||||
}
|
}
|
||||||
println!("binary: {}", binary);
|
println!("binary: {}", binary);
|
||||||
println!("commit-hash: {}", unw(commit_hash_str()));
|
println!("commit-hash: {}", unw(util::commit_hash_str()));
|
||||||
println!("commit-date: {}", unw(commit_date_str()));
|
println!("commit-date: {}", unw(util::commit_date_str()));
|
||||||
println!("host: {}", config::host_triple());
|
println!("host: {}", config::host_triple());
|
||||||
println!("release: {}", unw(release_str()));
|
println!("release: {}", unw(util::release_str()));
|
||||||
|
if cfg!(llvm) {
|
||||||
get_builtin_codegen_backend("llvm")().print_version();
|
get_builtin_codegen_backend("llvm")().print_version();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(verbose: bool, include_unstable_options: bool) {
|
fn usage(verbose: bool, include_unstable_options: bool) {
|
||||||
|
@ -1109,7 +1096,9 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if cg_flags.iter().any(|x| *x == "passes=list") {
|
if cg_flags.iter().any(|x| *x == "passes=list") {
|
||||||
|
if cfg!(llvm) {
|
||||||
get_builtin_codegen_backend("llvm")().print_passes();
|
get_builtin_codegen_backend("llvm")().print_passes();
|
||||||
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,7 +1226,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
|
||||||
format!("we would appreciate a bug report: {}", bug_report_url).into(),
|
format!("we would appreciate a bug report: {}", bug_report_url).into(),
|
||||||
format!(
|
format!(
|
||||||
"rustc {} running on {}",
|
"rustc {} running on {}",
|
||||||
option_env!("CFG_VERSION").unwrap_or("unknown_version"),
|
util::version_str().unwrap_or("unknown_version"),
|
||||||
config::host_triple()
|
config::host_triple()
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
|
|
|
@ -24,11 +24,13 @@ use rustc_span::source_map::FileLoader;
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::lazy::SyncOnceCell;
|
use std::lazy::SyncOnceCell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Arc, Mutex, Once};
|
use std::sync::{Arc, Mutex, Once};
|
||||||
#[cfg(not(parallel_compiler))]
|
#[cfg(not(parallel_compiler))]
|
||||||
use std::{panic, thread};
|
use std::{panic, thread};
|
||||||
|
@ -238,7 +240,19 @@ pub fn get_codegen_backend(sopts: &config::Options) -> Box<dyn CodegenBackend> {
|
||||||
static mut LOAD: fn() -> Box<dyn CodegenBackend> = || unreachable!();
|
static mut LOAD: fn() -> Box<dyn CodegenBackend> = || unreachable!();
|
||||||
|
|
||||||
INIT.call_once(|| {
|
INIT.call_once(|| {
|
||||||
let codegen_name = sopts.debugging_opts.codegen_backend.as_deref().unwrap_or("llvm");
|
#[cfg(feature = "llvm")]
|
||||||
|
const DEFAULT_CODEGEN_BACKEND: &'static str = "llvm";
|
||||||
|
|
||||||
|
#[cfg(not(feature = "llvm"))]
|
||||||
|
const DEFAULT_CODEGEN_BACKEND: &'static str = "cranelift";
|
||||||
|
|
||||||
|
let codegen_name = sopts
|
||||||
|
.debugging_opts
|
||||||
|
.codegen_backend
|
||||||
|
.as_ref()
|
||||||
|
.map(|name| &name[..])
|
||||||
|
.unwrap_or(DEFAULT_CODEGEN_BACKEND);
|
||||||
|
|
||||||
let backend = match codegen_name {
|
let backend = match codegen_name {
|
||||||
filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()),
|
filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()),
|
||||||
codegen_name => get_builtin_codegen_backend(codegen_name),
|
codegen_name => get_builtin_codegen_backend(codegen_name),
|
||||||
|
@ -367,15 +381,102 @@ fn sysroot_candidates() -> Vec<PathBuf> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_builtin_codegen_backend(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
|
pub fn get_builtin_codegen_backend(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
|
||||||
|
match backend_name {
|
||||||
#[cfg(feature = "llvm")]
|
#[cfg(feature = "llvm")]
|
||||||
{
|
"llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
|
||||||
if backend_name == "llvm" {
|
_ => get_codegen_sysroot(backend_name),
|
||||||
return rustc_codegen_llvm::LlvmCodegenBackend::new;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
|
||||||
|
// For now we only allow this function to be called once as it'll dlopen a
|
||||||
|
// few things, which seems to work best if we only do that once. In
|
||||||
|
// general this assertion never trips due to the once guard in `get_codegen_backend`,
|
||||||
|
// but there's a few manual calls to this function in this file we protect
|
||||||
|
// against.
|
||||||
|
static LOADED: AtomicBool = AtomicBool::new(false);
|
||||||
|
assert!(
|
||||||
|
!LOADED.fetch_or(true, Ordering::SeqCst),
|
||||||
|
"cannot load the default codegen backend twice"
|
||||||
|
);
|
||||||
|
|
||||||
|
let target = session::config::host_triple();
|
||||||
|
let sysroot_candidates = sysroot_candidates();
|
||||||
|
|
||||||
|
let sysroot = sysroot_candidates
|
||||||
|
.iter()
|
||||||
|
.map(|sysroot| {
|
||||||
|
let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
|
||||||
|
sysroot.join(libdir).with_file_name("codegen-backends")
|
||||||
|
})
|
||||||
|
.filter(|f| {
|
||||||
|
info!("codegen backend candidate: {}", f.display());
|
||||||
|
f.exists()
|
||||||
|
})
|
||||||
|
.next();
|
||||||
|
let sysroot = sysroot.unwrap_or_else(|| {
|
||||||
|
let candidates = sysroot_candidates
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.display().to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n* ");
|
||||||
|
let err = format!(
|
||||||
|
"failed to find a `codegen-backends` folder \
|
||||||
|
in the sysroot candidates:\n* {}",
|
||||||
|
candidates
|
||||||
|
);
|
||||||
|
early_error(ErrorOutputType::default(), &err);
|
||||||
|
});
|
||||||
|
info!("probing {} for a codegen backend", sysroot.display());
|
||||||
|
|
||||||
|
let d = sysroot.read_dir().unwrap_or_else(|e| {
|
||||||
|
let err = format!(
|
||||||
|
"failed to load default codegen backend, couldn't \
|
||||||
|
read `{}`: {}",
|
||||||
|
sysroot.display(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
early_error(ErrorOutputType::default(), &err);
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut file: Option<PathBuf> = None;
|
||||||
|
|
||||||
|
let expected_name =
|
||||||
|
format!("rustc_codegen_{}-{}", backend_name, release_str().expect("CFG_RELEASE"));
|
||||||
|
for entry in d.filter_map(|e| e.ok()) {
|
||||||
|
let path = entry.path();
|
||||||
|
let filename = match path.file_name().and_then(|s| s.to_str()) {
|
||||||
|
Some(s) => s,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
if !(filename.starts_with(DLL_PREFIX) && filename.ends_with(DLL_SUFFIX)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let name = &filename[DLL_PREFIX.len()..filename.len() - DLL_SUFFIX.len()];
|
||||||
|
if name != expected_name {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Some(ref prev) = file {
|
||||||
|
let err = format!(
|
||||||
|
"duplicate codegen backends found\n\
|
||||||
|
first: {}\n\
|
||||||
|
second: {}\n\
|
||||||
|
",
|
||||||
|
prev.display(),
|
||||||
|
path.display()
|
||||||
|
);
|
||||||
|
early_error(ErrorOutputType::default(), &err);
|
||||||
|
}
|
||||||
|
file = Some(path.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match file {
|
||||||
|
Some(ref s) => load_backend_from_dylib(s),
|
||||||
|
None => {
|
||||||
let err = format!("unsupported builtin codegen backend `{}`", backend_name);
|
let err = format!("unsupported builtin codegen backend `{}`", backend_name);
|
||||||
early_error(ErrorOutputType::default(), &err);
|
early_error(ErrorOutputType::default(), &err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguator {
|
pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguator {
|
||||||
|
@ -782,3 +883,23 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
|
||||||
noop_visit_mac(mac, self)
|
noop_visit_mac(mac, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a version string such as "rustc 1.46.0 (04488afe3 2020-08-24)"
|
||||||
|
pub fn version_str() -> Option<&'static str> {
|
||||||
|
option_env!("CFG_VERSION")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a version string such as "0.12.0-dev".
|
||||||
|
pub fn release_str() -> Option<&'static str> {
|
||||||
|
option_env!("CFG_RELEASE")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the full SHA1 hash of HEAD of the Git repo from which rustc was built.
|
||||||
|
pub fn commit_hash_str() -> Option<&'static str> {
|
||||||
|
option_env!("CFG_VER_HASH")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the "commit date" of HEAD of the Git repo from which rustc was built as a static string.
|
||||||
|
pub fn commit_date_str() -> Option<&'static str> {
|
||||||
|
option_env!("CFG_VER_DATE")
|
||||||
|
}
|
||||||
|
|
|
@ -478,7 +478,7 @@ changelog-seen = 2
|
||||||
|
|
||||||
# This is an array of the codegen backends that will be compiled for the rustc
|
# This is an array of the codegen backends that will be compiled for the rustc
|
||||||
# that's being compiled. The default is to only build the LLVM codegen backend,
|
# that's being compiled. The default is to only build the LLVM codegen backend,
|
||||||
# and currently the only standard option supported is `"llvm"`
|
# and currently the only standard options supported are `"llvm"` and `"cranelift"`.
|
||||||
#codegen-backends = ["llvm"]
|
#codegen-backends = ["llvm"]
|
||||||
|
|
||||||
# Indicates whether LLD will be compiled and made available in the sysroot for
|
# Indicates whether LLD will be compiled and made available in the sysroot for
|
||||||
|
|
|
@ -16,6 +16,7 @@ ignore = [
|
||||||
# do not format submodules
|
# do not format submodules
|
||||||
"library/backtrace",
|
"library/backtrace",
|
||||||
"library/stdarch",
|
"library/stdarch",
|
||||||
|
"compiler/rustc_codegen_cranelift",
|
||||||
"src/doc/book",
|
"src/doc/book",
|
||||||
"src/doc/edition-guide",
|
"src/doc/edition-guide",
|
||||||
"src/doc/embedded-book",
|
"src/doc/embedded-book",
|
||||||
|
|
|
@ -962,8 +962,12 @@ class RustBuild(object):
|
||||||
# the rust git repository is updated. Normal development usually does
|
# the rust git repository is updated. Normal development usually does
|
||||||
# not use vendoring, so hopefully this isn't too much of a problem.
|
# not use vendoring, so hopefully this isn't too much of a problem.
|
||||||
if self.use_vendored_sources and not os.path.exists(vendor_dir):
|
if self.use_vendored_sources and not os.path.exists(vendor_dir):
|
||||||
run([self.cargo(), "vendor", "--sync=./src/tools/rust-analyzer/Cargo.toml"],
|
run([
|
||||||
verbose=self.verbose, cwd=self.rust_root)
|
self.cargo(),
|
||||||
|
"vendor",
|
||||||
|
"--sync=./src/tools/rust-analyzer/Cargo.toml",
|
||||||
|
"--sync=./compiler/rustc_codegen_cranelift/Cargo.toml",
|
||||||
|
], verbose=self.verbose, cwd=self.rust_root)
|
||||||
|
|
||||||
|
|
||||||
def bootstrap(help_triggered):
|
def bootstrap(help_triggered):
|
||||||
|
|
|
@ -344,6 +344,7 @@ impl<'a> Builder<'a> {
|
||||||
Kind::Build => describe!(
|
Kind::Build => describe!(
|
||||||
compile::Std,
|
compile::Std,
|
||||||
compile::Rustc,
|
compile::Rustc,
|
||||||
|
compile::CodegenBackend,
|
||||||
compile::StartupObjects,
|
compile::StartupObjects,
|
||||||
tool::BuildManifest,
|
tool::BuildManifest,
|
||||||
tool::Rustbook,
|
tool::Rustbook,
|
||||||
|
@ -370,9 +371,14 @@ impl<'a> Builder<'a> {
|
||||||
tool::CargoMiri,
|
tool::CargoMiri,
|
||||||
native::Lld
|
native::Lld
|
||||||
),
|
),
|
||||||
Kind::Check | Kind::Clippy | Kind::Fix | Kind::Format => {
|
Kind::Check | Kind::Clippy | Kind::Fix | Kind::Format => describe!(
|
||||||
describe!(check::Std, check::Rustc, check::Rustdoc, check::Clippy, check::Bootstrap)
|
check::Std,
|
||||||
}
|
check::Rustc,
|
||||||
|
check::Rustdoc,
|
||||||
|
check::CodegenBackend,
|
||||||
|
check::Clippy,
|
||||||
|
check::Bootstrap
|
||||||
|
),
|
||||||
Kind::Test => describe!(
|
Kind::Test => describe!(
|
||||||
crate::toolstate::ToolStateCheck,
|
crate::toolstate::ToolStateCheck,
|
||||||
test::ExpandYamlAnchors,
|
test::ExpandYamlAnchors,
|
||||||
|
@ -630,6 +636,10 @@ impl<'a> Builder<'a> {
|
||||||
self.ensure(Libdir { compiler, target })
|
self.ensure(Libdir { compiler, target })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sysroot_codegen_backends(&self, compiler: Compiler) -> PathBuf {
|
||||||
|
self.sysroot_libdir(compiler, compiler.host).with_file_name("codegen-backends")
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the compiler's libdir where it stores the dynamic libraries that
|
/// Returns the compiler's libdir where it stores the dynamic libraries that
|
||||||
/// it itself links against.
|
/// it itself links against.
|
||||||
///
|
///
|
||||||
|
@ -698,6 +708,15 @@ impl<'a> Builder<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the paths to all of the compiler's codegen backends.
|
||||||
|
fn codegen_backends(&self, compiler: Compiler) -> impl Iterator<Item = PathBuf> {
|
||||||
|
fs::read_dir(self.sysroot_codegen_backends(compiler))
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.filter_map(Result::ok)
|
||||||
|
.map(|entry| entry.path())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rustdoc(&self, compiler: Compiler) -> PathBuf {
|
pub fn rustdoc(&self, compiler: Compiler) -> PathBuf {
|
||||||
self.ensure(tool::Rustdoc { compiler })
|
self.ensure(tool::Rustdoc { compiler })
|
||||||
}
|
}
|
||||||
|
@ -762,6 +781,12 @@ impl<'a> Builder<'a> {
|
||||||
let mut cargo = Command::new(&self.initial_cargo);
|
let mut cargo = Command::new(&self.initial_cargo);
|
||||||
let out_dir = self.stage_out(compiler, mode);
|
let out_dir = self.stage_out(compiler, mode);
|
||||||
|
|
||||||
|
// Codegen backends are not yet tracked by -Zbinary-dep-depinfo,
|
||||||
|
// so we need to explicitly clear out if they've been updated.
|
||||||
|
for backend in self.codegen_backends(compiler) {
|
||||||
|
self.clear_if_dirty(&out_dir, &backend);
|
||||||
|
}
|
||||||
|
|
||||||
if cmd == "doc" || cmd == "rustdoc" {
|
if cmd == "doc" || cmd == "rustdoc" {
|
||||||
let my_out = match mode {
|
let my_out = match mode {
|
||||||
// This is the intended out directory for compiler documentation.
|
// This is the intended out directory for compiler documentation.
|
||||||
|
@ -843,7 +868,7 @@ impl<'a> Builder<'a> {
|
||||||
|
|
||||||
match mode {
|
match mode {
|
||||||
Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {}
|
Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {}
|
||||||
Mode::Rustc | Mode::ToolRustc => {
|
Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
|
||||||
// Build proc macros both for the host and the target
|
// Build proc macros both for the host and the target
|
||||||
if target != compiler.host && cmd != "check" {
|
if target != compiler.host && cmd != "check" {
|
||||||
cargo.arg("-Zdual-proc-macros");
|
cargo.arg("-Zdual-proc-macros");
|
||||||
|
@ -904,6 +929,8 @@ impl<'a> Builder<'a> {
|
||||||
// problem, somehow -- not really clear why -- but we know that this
|
// problem, somehow -- not really clear why -- but we know that this
|
||||||
// fixes things.
|
// fixes things.
|
||||||
Mode::ToolRustc => metadata.push_str("tool-rustc"),
|
Mode::ToolRustc => metadata.push_str("tool-rustc"),
|
||||||
|
// Same for codegen backends.
|
||||||
|
Mode::Codegen => metadata.push_str("codegen"),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata);
|
cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata);
|
||||||
|
@ -1030,7 +1057,7 @@ impl<'a> Builder<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let debuginfo_level = match mode {
|
let debuginfo_level = match mode {
|
||||||
Mode::Rustc => self.config.rust_debuginfo_level_rustc,
|
Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc,
|
||||||
Mode::Std => self.config.rust_debuginfo_level_std,
|
Mode::Std => self.config.rust_debuginfo_level_std,
|
||||||
Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc => {
|
Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc => {
|
||||||
self.config.rust_debuginfo_level_tools
|
self.config.rust_debuginfo_level_tools
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
|
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
|
||||||
|
|
||||||
use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, std_cargo};
|
use crate::cache::Interned;
|
||||||
|
use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo};
|
||||||
use crate::config::TargetSelection;
|
use crate::config::TargetSelection;
|
||||||
use crate::tool::{prepare_tool_cargo, SourceType};
|
use crate::tool::{prepare_tool_cargo, SourceType};
|
||||||
|
use crate::INTERNER;
|
||||||
use crate::{
|
use crate::{
|
||||||
builder::{Builder, Kind, RunConfig, ShouldRun, Step},
|
builder::{Builder, Kind, RunConfig, ShouldRun, Step},
|
||||||
Subcommand,
|
Subcommand,
|
||||||
|
@ -175,6 +177,57 @@ impl Step for Rustc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct CodegenBackend {
|
||||||
|
pub target: TargetSelection,
|
||||||
|
pub backend: Interned<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Step for CodegenBackend {
|
||||||
|
type Output = ();
|
||||||
|
const ONLY_HOSTS: bool = true;
|
||||||
|
const DEFAULT: bool = true;
|
||||||
|
|
||||||
|
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||||
|
run.paths(&["compiler/rustc_codegen_cranelift", "rustc_codegen_cranelift"])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_run(run: RunConfig<'_>) {
|
||||||
|
for &backend in &[INTERNER.intern_str("cranelift")] {
|
||||||
|
run.builder.ensure(CodegenBackend { target: run.target, backend });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(self, builder: &Builder<'_>) {
|
||||||
|
let compiler = builder.compiler(0, builder.config.build);
|
||||||
|
let target = self.target;
|
||||||
|
let backend = self.backend;
|
||||||
|
|
||||||
|
builder.ensure(Rustc { target });
|
||||||
|
|
||||||
|
let mut cargo = builder.cargo(
|
||||||
|
compiler,
|
||||||
|
Mode::Codegen,
|
||||||
|
SourceType::Submodule,
|
||||||
|
target,
|
||||||
|
cargo_subcommand(builder.kind),
|
||||||
|
);
|
||||||
|
cargo
|
||||||
|
.arg("--manifest-path")
|
||||||
|
.arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend)));
|
||||||
|
rustc_cargo_env(builder, &mut cargo, target);
|
||||||
|
|
||||||
|
run_cargo(
|
||||||
|
builder,
|
||||||
|
cargo,
|
||||||
|
args(builder.kind),
|
||||||
|
&codegen_backend_stamp(builder, compiler, target, backend),
|
||||||
|
vec![],
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! tool_check_step {
|
macro_rules! tool_check_step {
|
||||||
($name:ident, $path:expr, $source_type:expr) => {
|
($name:ident, $path:expr, $source_type:expr) => {
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -281,3 +334,16 @@ fn libstd_test_stamp(
|
||||||
fn librustc_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
|
fn librustc_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
|
||||||
builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc-check.stamp")
|
builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc-check.stamp")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
|
||||||
|
/// compiler for the specified target and backend.
|
||||||
|
fn codegen_backend_stamp(
|
||||||
|
builder: &Builder<'_>,
|
||||||
|
compiler: Compiler,
|
||||||
|
target: TargetSelection,
|
||||||
|
backend: Interned<String>,
|
||||||
|
) -> PathBuf {
|
||||||
|
builder
|
||||||
|
.cargo_out(compiler, Mode::Codegen, target)
|
||||||
|
.join(format!(".librustc_codegen_{}-check.stamp", backend))
|
||||||
|
}
|
||||||
|
|
|
@ -640,6 +640,144 @@ impl Step for RustcLink {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct CodegenBackend {
|
||||||
|
pub target: TargetSelection,
|
||||||
|
pub compiler: Compiler,
|
||||||
|
pub backend: Interned<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Step for CodegenBackend {
|
||||||
|
type Output = ();
|
||||||
|
const ONLY_HOSTS: bool = true;
|
||||||
|
// Only the backends specified in the `codegen-backends` entry of `config.toml` are built.
|
||||||
|
const DEFAULT: bool = true;
|
||||||
|
|
||||||
|
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||||
|
run.path("compiler/rustc_codegen_cranelift")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_run(run: RunConfig<'_>) {
|
||||||
|
for &backend in &run.builder.config.rust_codegen_backends {
|
||||||
|
if backend == "llvm" {
|
||||||
|
continue; // Already built as part of rustc
|
||||||
|
}
|
||||||
|
|
||||||
|
run.builder.ensure(CodegenBackend {
|
||||||
|
target: run.target,
|
||||||
|
compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
|
||||||
|
backend,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(self, builder: &Builder<'_>) {
|
||||||
|
let compiler = self.compiler;
|
||||||
|
let target = self.target;
|
||||||
|
let backend = self.backend;
|
||||||
|
|
||||||
|
builder.ensure(Rustc { compiler, target });
|
||||||
|
|
||||||
|
if builder.config.keep_stage.contains(&compiler.stage) {
|
||||||
|
builder.info(
|
||||||
|
"Warning: Using a potentially old codegen backend. \
|
||||||
|
This may not behave well.",
|
||||||
|
);
|
||||||
|
// Codegen backends are linked separately from this step today, so we don't do
|
||||||
|
// anything here.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
|
||||||
|
if compiler_to_use != compiler {
|
||||||
|
builder.ensure(CodegenBackend { compiler: compiler_to_use, target, backend });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let out_dir = builder.cargo_out(compiler, Mode::Codegen, target);
|
||||||
|
|
||||||
|
let mut cargo =
|
||||||
|
builder.cargo(compiler, Mode::Codegen, SourceType::Submodule, target, "build");
|
||||||
|
cargo
|
||||||
|
.arg("--manifest-path")
|
||||||
|
.arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend)));
|
||||||
|
rustc_cargo_env(builder, &mut cargo, target);
|
||||||
|
|
||||||
|
let tmp_stamp = out_dir.join(".tmp.stamp");
|
||||||
|
|
||||||
|
let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false);
|
||||||
|
if builder.config.dry_run {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut files = files.into_iter().filter(|f| {
|
||||||
|
let filename = f.file_name().unwrap().to_str().unwrap();
|
||||||
|
is_dylib(filename) && filename.contains("rustc_codegen_")
|
||||||
|
});
|
||||||
|
let codegen_backend = match files.next() {
|
||||||
|
Some(f) => f,
|
||||||
|
None => panic!("no dylibs built for codegen backend?"),
|
||||||
|
};
|
||||||
|
if let Some(f) = files.next() {
|
||||||
|
panic!(
|
||||||
|
"codegen backend built two dylibs:\n{}\n{}",
|
||||||
|
codegen_backend.display(),
|
||||||
|
f.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let stamp = codegen_backend_stamp(builder, compiler, target, backend);
|
||||||
|
let codegen_backend = codegen_backend.to_str().unwrap();
|
||||||
|
t!(fs::write(&stamp, &codegen_backend));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates the `codegen-backends` folder for a compiler that's about to be
|
||||||
|
/// assembled as a complete compiler.
|
||||||
|
///
|
||||||
|
/// This will take the codegen artifacts produced by `compiler` and link them
|
||||||
|
/// into an appropriate location for `target_compiler` to be a functional
|
||||||
|
/// compiler.
|
||||||
|
fn copy_codegen_backends_to_sysroot(
|
||||||
|
builder: &Builder<'_>,
|
||||||
|
compiler: Compiler,
|
||||||
|
target_compiler: Compiler,
|
||||||
|
) {
|
||||||
|
let target = target_compiler.host;
|
||||||
|
|
||||||
|
// Note that this step is different than all the other `*Link` steps in
|
||||||
|
// that it's not assembling a bunch of libraries but rather is primarily
|
||||||
|
// moving the codegen backend into place. The codegen backend of rustc is
|
||||||
|
// not linked into the main compiler by default but is rather dynamically
|
||||||
|
// selected at runtime for inclusion.
|
||||||
|
//
|
||||||
|
// Here we're looking for the output dylib of the `CodegenBackend` step and
|
||||||
|
// we're copying that into the `codegen-backends` folder.
|
||||||
|
let dst = builder.sysroot_codegen_backends(target_compiler);
|
||||||
|
t!(fs::create_dir_all(&dst));
|
||||||
|
|
||||||
|
if builder.config.dry_run {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for backend in builder.config.rust_codegen_backends.iter() {
|
||||||
|
if backend == "llvm" {
|
||||||
|
continue; // Already built as part of rustc
|
||||||
|
}
|
||||||
|
|
||||||
|
let stamp = codegen_backend_stamp(builder, compiler, target, *backend);
|
||||||
|
let dylib = t!(fs::read_to_string(&stamp));
|
||||||
|
let file = Path::new(&dylib);
|
||||||
|
let filename = file.file_name().unwrap().to_str().unwrap();
|
||||||
|
// change `librustc_codegen_cranelift-xxxxxx.so` to
|
||||||
|
// `librustc_codegen_cranelift-release.so`
|
||||||
|
let target_filename = {
|
||||||
|
let dash = filename.find('-').unwrap();
|
||||||
|
let dot = filename.find('.').unwrap();
|
||||||
|
format!("{}-{}{}", &filename[..dash], builder.rust_release(), &filename[dot..])
|
||||||
|
};
|
||||||
|
builder.copy(&file, &dst.join(target_filename));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Cargo's output path for the standard library in a given stage, compiled
|
/// Cargo's output path for the standard library in a given stage, compiled
|
||||||
/// by a particular compiler for the specified target.
|
/// by a particular compiler for the specified target.
|
||||||
pub fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
|
pub fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
|
||||||
|
@ -656,6 +794,19 @@ pub fn librustc_stamp(
|
||||||
builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc.stamp")
|
builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc.stamp")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
|
||||||
|
/// compiler for the specified target and backend.
|
||||||
|
fn codegen_backend_stamp(
|
||||||
|
builder: &Builder<'_>,
|
||||||
|
compiler: Compiler,
|
||||||
|
target: TargetSelection,
|
||||||
|
backend: Interned<String>,
|
||||||
|
) -> PathBuf {
|
||||||
|
builder
|
||||||
|
.cargo_out(compiler, Mode::Codegen, target)
|
||||||
|
.join(format!(".librustc_codegen_{}.stamp", backend))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn compiler_file(
|
pub fn compiler_file(
|
||||||
builder: &Builder<'_>,
|
builder: &Builder<'_>,
|
||||||
compiler: &Path,
|
compiler: &Path,
|
||||||
|
@ -782,6 +933,18 @@ impl Step for Assemble {
|
||||||
// when not performing a full bootstrap).
|
// when not performing a full bootstrap).
|
||||||
builder.ensure(Rustc { compiler: build_compiler, target: target_compiler.host });
|
builder.ensure(Rustc { compiler: build_compiler, target: target_compiler.host });
|
||||||
|
|
||||||
|
for &backend in builder.config.rust_codegen_backends.iter() {
|
||||||
|
if backend == "llvm" {
|
||||||
|
continue; // Already built as part of rustc
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.ensure(CodegenBackend {
|
||||||
|
compiler: build_compiler,
|
||||||
|
target: target_compiler.host,
|
||||||
|
backend,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let lld_install = if builder.config.lld_enabled {
|
let lld_install = if builder.config.lld_enabled {
|
||||||
Some(builder.ensure(native::Lld { target: target_compiler.host }))
|
Some(builder.ensure(native::Lld { target: target_compiler.host }))
|
||||||
} else {
|
} else {
|
||||||
|
@ -804,6 +967,8 @@ impl Step for Assemble {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler);
|
||||||
|
|
||||||
let libdir = builder.sysroot_libdir(target_compiler, target_compiler.host);
|
let libdir = builder.sysroot_libdir(target_compiler, target_compiler.host);
|
||||||
if let Some(lld_install) = lld_install {
|
if let Some(lld_install) = lld_install {
|
||||||
let src_exe = exe("lld", target_compiler.host);
|
let src_exe = exe("lld", target_compiler.host);
|
||||||
|
|
|
@ -504,6 +504,19 @@ impl Step for Rustc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy over the codegen backends
|
||||||
|
let backends_src = builder.sysroot_codegen_backends(compiler);
|
||||||
|
let backends_rel = backends_src
|
||||||
|
.strip_prefix(&src)
|
||||||
|
.unwrap()
|
||||||
|
.strip_prefix(builder.sysroot_libdir_relative(compiler))
|
||||||
|
.unwrap();
|
||||||
|
// Don't use custom libdir here because ^lib/ will be resolved again with installer
|
||||||
|
let backends_dst = image.join("lib").join(&backends_rel);
|
||||||
|
|
||||||
|
t!(fs::create_dir_all(&backends_dst));
|
||||||
|
builder.cp_r(&backends_src, &backends_dst);
|
||||||
|
|
||||||
// Copy libLLVM.so to the lib dir as well, if needed. While not
|
// Copy libLLVM.so to the lib dir as well, if needed. While not
|
||||||
// technically needed by rustc itself it's needed by lots of other
|
// technically needed by rustc itself it's needed by lots of other
|
||||||
// components like the llvm tools and LLD. LLD is included below and
|
// components like the llvm tools and LLD. LLD is included below and
|
||||||
|
@ -1115,6 +1128,7 @@ impl Step for PlainSourceTarball {
|
||||||
cmd.arg("vendor")
|
cmd.arg("vendor")
|
||||||
.arg("--sync")
|
.arg("--sync")
|
||||||
.arg(builder.src.join("./src/tools/rust-analyzer/Cargo.toml"))
|
.arg(builder.src.join("./src/tools/rust-analyzer/Cargo.toml"))
|
||||||
|
.arg(builder.src.join("./compiler/rustc_codegen_cranelift/Cargo.toml"))
|
||||||
.current_dir(&plain_dst_src);
|
.current_dir(&plain_dst_src);
|
||||||
builder.run(&mut cmd);
|
builder.run(&mut cmd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,6 +307,9 @@ pub enum Mode {
|
||||||
/// Build librustc, and compiler libraries, placing output in the "stageN-rustc" directory.
|
/// Build librustc, and compiler libraries, placing output in the "stageN-rustc" directory.
|
||||||
Rustc,
|
Rustc,
|
||||||
|
|
||||||
|
/// Build a codegen backend for rustc, placing the output in the "stageN-codegen" directory.
|
||||||
|
Codegen,
|
||||||
|
|
||||||
/// Build a tool, placing output in the "stage0-bootstrap-tools"
|
/// Build a tool, placing output in the "stage0-bootstrap-tools"
|
||||||
/// directory. This is for miscellaneous sets of tools that are built
|
/// directory. This is for miscellaneous sets of tools that are built
|
||||||
/// using the bootstrap stage0 compiler in its entirety (target libraries
|
/// using the bootstrap stage0 compiler in its entirety (target libraries
|
||||||
|
@ -594,6 +597,7 @@ impl Build {
|
||||||
let suffix = match mode {
|
let suffix = match mode {
|
||||||
Mode::Std => "-std",
|
Mode::Std => "-std",
|
||||||
Mode::Rustc => "-rustc",
|
Mode::Rustc => "-rustc",
|
||||||
|
Mode::Codegen => "-codegen",
|
||||||
Mode::ToolBootstrap => "-bootstrap-tools",
|
Mode::ToolBootstrap => "-bootstrap-tools",
|
||||||
Mode::ToolStd | Mode::ToolRustc => "-tools",
|
Mode::ToolStd | Mode::ToolRustc => "-tools",
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,6 +50,7 @@ pub mod unstable_book;
|
||||||
|
|
||||||
fn filter_dirs(path: &Path) -> bool {
|
fn filter_dirs(path: &Path) -> bool {
|
||||||
let skip = [
|
let skip = [
|
||||||
|
"compiler/rustc_codegen_cranelift",
|
||||||
"src/llvm-project",
|
"src/llvm-project",
|
||||||
"library/backtrace",
|
"library/backtrace",
|
||||||
"library/stdarch",
|
"library/stdarch",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue