diff options
| author | bjorn3 <bjorn3@users.noreply.github.com> | 2020-10-15 14:23:43 +0200 |
|---|---|---|
| committer | bjorn3 <bjorn3@users.noreply.github.com> | 2020-10-26 09:52:59 +0100 |
| commit | cf798c1ec65a5ec3491846777f9003fabb881b4a (patch) | |
| tree | 7b1729074a6a93415c55000d1b992ed350258474 /compiler/rustc_interface/src | |
| parent | 596b0d5027bfb1b5835e17a25f56b00a1f6ff95f (diff) | |
| download | rust-cf798c1ec65a5ec3491846777f9003fabb881b4a.tar.gz rust-cf798c1ec65a5ec3491846777f9003fabb881b4a.zip | |
Add support for using cg_clif to bootstrap rustc
Diffstat (limited to 'compiler/rustc_interface/src')
| -rw-r--r-- | compiler/rustc_interface/src/util.rs | 135 |
1 files changed, 128 insertions, 7 deletions
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index c1b359c7d0d..7658ffb0e3d 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -24,11 +24,13 @@ use rustc_span::source_map::FileLoader; use rustc_span::symbol::{sym, Symbol}; use smallvec::SmallVec; use std::env; +use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; use std::io::{self, Write}; use std::lazy::SyncOnceCell; use std::mem; use std::ops::DerefMut; use std::path::{Path, PathBuf}; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex, Once}; #[cfg(not(parallel_compiler))] 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!(); 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 { filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()), 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> { - #[cfg(feature = "llvm")] - { - if backend_name == "llvm" { - return rustc_codegen_llvm::LlvmCodegenBackend::new; + match backend_name { + #[cfg(feature = "llvm")] + "llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new, + _ => get_codegen_sysroot(backend_name), + } +} + +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()); } - let err = format!("unsupported builtin codegen backend `{}`", backend_name); - early_error(ErrorOutputType::default(), &err); + match file { + Some(ref s) => load_backend_from_dylib(s), + None => { + let err = format!("unsupported builtin codegen backend `{}`", backend_name); + early_error(ErrorOutputType::default(), &err); + } + } } pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguator { @@ -782,3 +883,23 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { 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") +} |
