mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 09:23:05 +00:00
Auto merge of #67077 - Aaron1011:build-llvm-in-binary, r=alexcrichton
rustc: Link LLVM directly into rustc again (take two) This is a continuation of PR https://github.com/rust-lang/rust/pull/65703
This commit is contained in:
commit
3964a55ba5
22
Cargo.lock
22
Cargo.lock
@ -3435,7 +3435,27 @@ dependencies = [
|
||||
name = "rustc_codegen_llvm"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"flate2",
|
||||
"libc",
|
||||
"log",
|
||||
"rustc",
|
||||
"rustc-demangle",
|
||||
"rustc_codegen_ssa",
|
||||
"rustc_codegen_utils",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_feature",
|
||||
"rustc_fs_util",
|
||||
"rustc_incremental",
|
||||
"rustc_index",
|
||||
"rustc_llvm",
|
||||
"rustc_session",
|
||||
"rustc_target",
|
||||
"smallvec 0.6.10",
|
||||
"syntax",
|
||||
"syntax_expand",
|
||||
"syntax_pos",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3597,6 +3617,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"rustc",
|
||||
"rustc-rayon",
|
||||
"rustc_codegen_llvm",
|
||||
"rustc_codegen_ssa",
|
||||
"rustc_codegen_utils",
|
||||
"rustc_data_structures",
|
||||
@ -3651,6 +3672,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"build_helper",
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -379,9 +379,6 @@
|
||||
# and currently the only standard option supported is `"llvm"`
|
||||
#codegen-backends = ["llvm"]
|
||||
|
||||
# This is the name of the directory in which codegen backends will get installed
|
||||
#codegen-backends-dir = "codegen-backends"
|
||||
|
||||
# Indicates whether LLD will be compiled and made available in the sysroot for
|
||||
# rustc to execute.
|
||||
#lld = false
|
||||
|
@ -339,7 +339,6 @@ impl<'a> Builder<'a> {
|
||||
Kind::Build => describe!(
|
||||
compile::Std,
|
||||
compile::Rustc,
|
||||
compile::CodegenBackend,
|
||||
compile::StartupObjects,
|
||||
tool::BuildManifest,
|
||||
tool::Rustbook,
|
||||
@ -364,7 +363,6 @@ impl<'a> Builder<'a> {
|
||||
Kind::Check | Kind::Clippy | Kind::Fix => describe!(
|
||||
check::Std,
|
||||
check::Rustc,
|
||||
check::CodegenBackend,
|
||||
check::Rustdoc
|
||||
),
|
||||
Kind::Test => describe!(
|
||||
@ -632,11 +630,6 @@ impl<'a> Builder<'a> {
|
||||
self.ensure(Libdir { compiler, target })
|
||||
}
|
||||
|
||||
pub fn sysroot_codegen_backends(&self, compiler: Compiler) -> PathBuf {
|
||||
self.sysroot_libdir(compiler, compiler.host)
|
||||
.with_file_name(self.config.rust_codegen_backends_dir.clone())
|
||||
}
|
||||
|
||||
/// Returns the compiler's libdir where it stores the dynamic libraries that
|
||||
/// it itself links against.
|
||||
///
|
||||
@ -707,15 +700,6 @@ 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 {
|
||||
self.ensure(tool::Rustdoc { compiler })
|
||||
}
|
||||
@ -759,12 +743,6 @@ impl<'a> Builder<'a> {
|
||||
let mut cargo = Command::new(&self.initial_cargo);
|
||||
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" {
|
||||
let my_out = match mode {
|
||||
// This is the intended out directory for compiler documentation.
|
||||
|
@ -363,6 +363,10 @@ fn dist_with_same_targets_and_hosts() {
|
||||
compiler: Compiler { host: a, stage: 1 },
|
||||
target: b,
|
||||
},
|
||||
compile::Std {
|
||||
compiler: Compiler { host: a, stage: 2 },
|
||||
target: b,
|
||||
},
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -1,11 +1,10 @@
|
||||
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
|
||||
|
||||
use crate::compile::{run_cargo, std_cargo, rustc_cargo, rustc_cargo_env,
|
||||
add_to_sysroot};
|
||||
use crate::compile::{run_cargo, std_cargo, rustc_cargo, add_to_sysroot};
|
||||
use crate::builder::{RunConfig, Builder, Kind, ShouldRun, Step};
|
||||
use crate::tool::{prepare_tool_cargo, SourceType};
|
||||
use crate::{Compiler, Mode};
|
||||
use crate::cache::{INTERNER, Interned};
|
||||
use crate::cache::Interned;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
@ -97,7 +96,7 @@ impl Step for Rustc {
|
||||
|
||||
let mut cargo = builder.cargo(compiler, Mode::Rustc, target,
|
||||
cargo_subcommand(builder.kind));
|
||||
rustc_cargo(builder, &mut cargo);
|
||||
rustc_cargo(builder, &mut cargo, target);
|
||||
|
||||
builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
|
||||
run_cargo(builder,
|
||||
@ -113,55 +112,6 @@ impl Step for Rustc {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct CodegenBackend {
|
||||
pub target: Interned<String>,
|
||||
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.all_krates("rustc_codegen_llvm")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
let backend = run.builder.config.rust_codegen_backends.get(0);
|
||||
let backend = backend.cloned().unwrap_or_else(|| {
|
||||
INTERNER.intern_str("llvm")
|
||||
});
|
||||
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, target,
|
||||
cargo_subcommand(builder.kind));
|
||||
cargo.arg("--manifest-path").arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
|
||||
rustc_cargo_env(builder, &mut cargo);
|
||||
|
||||
// We won't build LLVM if it's not available, as it shouldn't affect `check`.
|
||||
|
||||
run_cargo(builder,
|
||||
cargo,
|
||||
args(builder.kind),
|
||||
&codegen_backend_stamp(builder, compiler, target, backend),
|
||||
vec![],
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Rustdoc {
|
||||
pub target: Interned<String>,
|
||||
@ -231,16 +181,6 @@ pub fn librustc_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: Interned<String>,
|
||||
backend: Interned<String>) -> PathBuf {
|
||||
builder.cargo_out(compiler, Mode::Codegen, target)
|
||||
.join(format!(".librustc_codegen_llvm-{}-check.stamp", backend))
|
||||
}
|
||||
|
||||
/// Cargo's output path for rustdoc in a given stage, compiled by a particular
|
||||
/// compiler for the specified target.
|
||||
pub fn rustdoc_stamp(
|
||||
|
@ -27,7 +27,7 @@ use crate::{Compiler, Mode, GitRepo};
|
||||
use crate::native;
|
||||
|
||||
use crate::cache::{INTERNER, Interned};
|
||||
use crate::builder::{Step, RunConfig, ShouldRun, Builder};
|
||||
use crate::builder::{Step, RunConfig, ShouldRun, Builder, Kind};
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Std {
|
||||
@ -445,7 +445,7 @@ impl Step for Rustc {
|
||||
});
|
||||
|
||||
let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "build");
|
||||
rustc_cargo(builder, &mut cargo);
|
||||
rustc_cargo(builder, &mut cargo, target);
|
||||
|
||||
builder.info(&format!("Building stage{} compiler artifacts ({} -> {})",
|
||||
compiler.stage, &compiler.host, target));
|
||||
@ -456,6 +456,44 @@ impl Step for Rustc {
|
||||
vec![],
|
||||
false);
|
||||
|
||||
// We used to build librustc_codegen_llvm as a separate step,
|
||||
// which produced a dylib that the compiler would dlopen() at runtime.
|
||||
// This meant that we only needed to make sure that libLLVM.so was
|
||||
// installed by the time we went to run a tool using it - since
|
||||
// librustc_codegen_llvm was effectively a standalone artifact,
|
||||
// other crates were completely oblivious to its dependency
|
||||
// on `libLLVM.so` during build time.
|
||||
//
|
||||
// However, librustc_codegen_llvm is now built as an ordinary
|
||||
// crate during the same step as the rest of the compiler crates.
|
||||
// This means that any crates depending on it will see the fact
|
||||
// that it uses `libLLVM.so` as a native library, and will
|
||||
// cause us to pass `-llibLLVM.so` to the linker when we link
|
||||
// a binary.
|
||||
//
|
||||
// For `rustc` itself, this works out fine.
|
||||
// During the `Assemble` step, we call `dist::maybe_install_llvm_dylib`
|
||||
// to copy libLLVM.so into the `stage` directory. We then link
|
||||
// the compiler binary, which will find `libLLVM.so` in the correct place.
|
||||
//
|
||||
// However, this is insufficient for tools that are build against stage0
|
||||
// (e.g. stage1 rustdoc). Since `Assemble` for stage0 doesn't actually do anything,
|
||||
// we won't have `libLLVM.so` in the stage0 sysroot. In the past, this wasn't
|
||||
// a problem - we would copy the tool binary into its correct stage directory
|
||||
// (e.g. stage1 for a stage1 rustdoc built against a stage0 compiler).
|
||||
// Since libLLVM.so wasn't resolved until runtime, it was fine for it to
|
||||
// not exist while we were building it.
|
||||
//
|
||||
// To ensure that we can still build stage1 tools against a stage0 compiler,
|
||||
// we explicitly copy libLLVM.so into the stage0 sysroot when building
|
||||
// the stage0 compiler. This ensures that tools built against stage0
|
||||
// will see libLLVM.so at build time, making the linker happy.
|
||||
if compiler.stage == 0 {
|
||||
builder.info(&format!("Installing libLLVM.so to stage 0 ({})", compiler.host));
|
||||
let sysroot = builder.sysroot(compiler);
|
||||
dist::maybe_install_llvm_dylib(builder, compiler.host, &sysroot);
|
||||
}
|
||||
|
||||
builder.ensure(RustcLink {
|
||||
compiler: builder.compiler(compiler.stage, builder.config.build),
|
||||
target_compiler: compiler,
|
||||
@ -464,21 +502,20 @@ impl Step for Rustc {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo) {
|
||||
pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: Interned<String>) {
|
||||
cargo.arg("--features").arg(builder.rustc_features())
|
||||
.arg("--manifest-path")
|
||||
.arg(builder.src.join("src/rustc/Cargo.toml"));
|
||||
rustc_cargo_env(builder, cargo);
|
||||
rustc_cargo_env(builder, cargo, target);
|
||||
}
|
||||
|
||||
pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo) {
|
||||
pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: Interned<String>) {
|
||||
// Set some configuration variables picked up by build scripts and
|
||||
// the compiler alike
|
||||
cargo.env("CFG_RELEASE", builder.rust_release())
|
||||
.env("CFG_RELEASE_CHANNEL", &builder.config.channel)
|
||||
.env("CFG_VERSION", builder.rust_version())
|
||||
.env("CFG_PREFIX", builder.config.prefix.clone().unwrap_or_default())
|
||||
.env("CFG_CODEGEN_BACKENDS_DIR", &builder.config.rust_codegen_backends_dir);
|
||||
.env("CFG_PREFIX", builder.config.prefix.clone().unwrap_or_default());
|
||||
|
||||
let libdir_relative = builder.config.libdir_relative().unwrap_or(Path::new("lib"));
|
||||
cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative);
|
||||
@ -501,6 +538,49 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo) {
|
||||
if builder.config.rust_verify_llvm_ir {
|
||||
cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
|
||||
}
|
||||
|
||||
// Pass down configuration from the LLVM build into the build of
|
||||
// librustc_llvm and librustc_codegen_llvm.
|
||||
//
|
||||
// Note that this is disabled if LLVM itself is disabled or we're in a check
|
||||
// build, where if we're in a check build there's no need to build all of
|
||||
// LLVM and such.
|
||||
if builder.config.llvm_enabled() && builder.kind != Kind::Check {
|
||||
if builder.is_rust_llvm(target) {
|
||||
cargo.env("LLVM_RUSTLLVM", "1");
|
||||
}
|
||||
let llvm_config = builder.ensure(native::Llvm { target });
|
||||
cargo.env("LLVM_CONFIG", &llvm_config);
|
||||
let target_config = builder.config.target_config.get(&target);
|
||||
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
|
||||
cargo.env("CFG_LLVM_ROOT", s);
|
||||
}
|
||||
// Some LLVM linker flags (-L and -l) may be needed to link librustc_llvm.
|
||||
if let Some(ref s) = builder.config.llvm_ldflags {
|
||||
cargo.env("LLVM_LINKER_FLAGS", s);
|
||||
}
|
||||
// Building with a static libstdc++ is only supported on linux right now,
|
||||
// not for MSVC or macOS
|
||||
if builder.config.llvm_static_stdcpp &&
|
||||
!target.contains("freebsd") &&
|
||||
!target.contains("windows") &&
|
||||
!target.contains("apple") {
|
||||
let file = compiler_file(builder,
|
||||
builder.cxx(target).unwrap(),
|
||||
target,
|
||||
"libstdc++.a");
|
||||
cargo.env("LLVM_STATIC_STDCPP", file);
|
||||
}
|
||||
if builder.config.llvm_link_shared || builder.config.llvm_thin_lto {
|
||||
cargo.env("LLVM_LINK_SHARED", "1");
|
||||
}
|
||||
if builder.config.llvm_use_libcxx {
|
||||
cargo.env("LLVM_USE_LIBCXX", "1");
|
||||
}
|
||||
if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo {
|
||||
cargo.env("LLVM_NDEBUG", "1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
@ -537,215 +617,6 @@ impl Step for RustcLink {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct CodegenBackend {
|
||||
pub compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
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.all_krates("rustc_codegen_llvm")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
let backend = run.builder.config.rust_codegen_backends.get(0);
|
||||
let backend = backend.cloned().unwrap_or_else(|| {
|
||||
INTERNER.intern_str("llvm")
|
||||
});
|
||||
run.builder.ensure(CodegenBackend {
|
||||
compiler: run.builder.compiler(run.builder.top_stage, run.host),
|
||||
target: run.target,
|
||||
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, target, "build");
|
||||
cargo.arg("--manifest-path")
|
||||
.arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
|
||||
rustc_cargo_env(builder, &mut cargo);
|
||||
|
||||
let features = build_codegen_backend(&builder, &mut cargo, &compiler, target, backend);
|
||||
cargo.arg("--features").arg(features);
|
||||
|
||||
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_llvm-")
|
||||
});
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_codegen_backend(builder: &Builder<'_>,
|
||||
cargo: &mut Cargo,
|
||||
compiler: &Compiler,
|
||||
target: Interned<String>,
|
||||
backend: Interned<String>) -> String {
|
||||
match &*backend {
|
||||
"llvm" => {
|
||||
// Build LLVM for our target. This will implicitly build the
|
||||
// host LLVM if necessary.
|
||||
let llvm_config = builder.ensure(native::Llvm {
|
||||
target,
|
||||
});
|
||||
|
||||
builder.info(&format!("Building stage{} codegen artifacts ({} -> {}, {})",
|
||||
compiler.stage, &compiler.host, target, backend));
|
||||
|
||||
// Pass down configuration from the LLVM build into the build of
|
||||
// librustc_llvm and librustc_codegen_llvm.
|
||||
if builder.is_rust_llvm(target) {
|
||||
cargo.env("LLVM_RUSTLLVM", "1");
|
||||
}
|
||||
|
||||
cargo.env("LLVM_CONFIG", &llvm_config);
|
||||
let target_config = builder.config.target_config.get(&target);
|
||||
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
|
||||
cargo.env("CFG_LLVM_ROOT", s);
|
||||
}
|
||||
// Some LLVM linker flags (-L and -l) may be needed to link librustc_llvm.
|
||||
if let Some(ref s) = builder.config.llvm_ldflags {
|
||||
cargo.env("LLVM_LINKER_FLAGS", s);
|
||||
}
|
||||
// Building with a static libstdc++ is only supported on linux and mingw right now,
|
||||
// not for MSVC or macOS
|
||||
if builder.config.llvm_static_stdcpp &&
|
||||
!target.contains("freebsd") &&
|
||||
!target.contains("msvc") &&
|
||||
!target.contains("apple") {
|
||||
let file = compiler_file(builder,
|
||||
builder.cxx(target).unwrap(),
|
||||
target,
|
||||
"libstdc++.a");
|
||||
cargo.env("LLVM_STATIC_STDCPP", file);
|
||||
}
|
||||
if builder.config.llvm_link_shared || builder.config.llvm_thin_lto {
|
||||
cargo.env("LLVM_LINK_SHARED", "1");
|
||||
}
|
||||
if builder.config.llvm_use_libcxx {
|
||||
cargo.env("LLVM_USE_LIBCXX", "1");
|
||||
}
|
||||
if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo {
|
||||
cargo.env("LLVM_NDEBUG", "1");
|
||||
}
|
||||
}
|
||||
_ => panic!("unknown backend: {}", backend),
|
||||
}
|
||||
String::new()
|
||||
}
|
||||
|
||||
/// 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() {
|
||||
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_llvm-xxxxxx.so` to `librustc_codegen_llvm-llvm.so`
|
||||
let target_filename = {
|
||||
let dash = filename.find('-').unwrap();
|
||||
let dot = filename.find('.').unwrap();
|
||||
format!("{}-{}{}",
|
||||
&filename[..dash],
|
||||
backend,
|
||||
&filename[dot..])
|
||||
};
|
||||
builder.copy(&file, &dst.join(target_filename));
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_lld_to_sysroot(builder: &Builder<'_>,
|
||||
target_compiler: Compiler,
|
||||
lld_install_root: &Path) {
|
||||
let target = target_compiler.host;
|
||||
|
||||
let dst = builder.sysroot_libdir(target_compiler, target)
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("bin");
|
||||
t!(fs::create_dir_all(&dst));
|
||||
|
||||
let src_exe = exe("lld", &target);
|
||||
let dst_exe = exe("rust-lld", &target);
|
||||
// we prepend this bin directory to the user PATH when linking Rust binaries. To
|
||||
// avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`.
|
||||
builder.copy(&lld_install_root.join("bin").join(&src_exe), &dst.join(&dst_exe));
|
||||
}
|
||||
|
||||
/// Cargo's output path for the standard library in a given stage, compiled
|
||||
/// by a particular compiler for the specified target.
|
||||
pub fn libstd_stamp(
|
||||
@ -766,16 +637,6 @@ pub fn 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: Interned<String>,
|
||||
backend: Interned<String>) -> PathBuf {
|
||||
builder.cargo_out(compiler, Mode::Codegen, target)
|
||||
.join(format!(".librustc_codegen_llvm-{}.stamp", backend))
|
||||
}
|
||||
|
||||
pub fn compiler_file(
|
||||
builder: &Builder<'_>,
|
||||
compiler: &Path,
|
||||
@ -879,13 +740,6 @@ impl Step for Assemble {
|
||||
compiler: build_compiler,
|
||||
target: target_compiler.host,
|
||||
});
|
||||
for &backend in builder.config.rust_codegen_backends.iter() {
|
||||
builder.ensure(CodegenBackend {
|
||||
compiler: build_compiler,
|
||||
target: target_compiler.host,
|
||||
backend,
|
||||
});
|
||||
}
|
||||
|
||||
let lld_install = if builder.config.lld_enabled {
|
||||
Some(builder.ensure(native::Lld {
|
||||
@ -911,13 +765,19 @@ impl Step for Assemble {
|
||||
}
|
||||
}
|
||||
|
||||
copy_codegen_backends_to_sysroot(builder,
|
||||
build_compiler,
|
||||
target_compiler);
|
||||
let libdir = builder.sysroot_libdir(target_compiler, target_compiler.host);
|
||||
if let Some(lld_install) = lld_install {
|
||||
copy_lld_to_sysroot(builder, target_compiler, &lld_install);
|
||||
let src_exe = exe("lld", &target_compiler.host);
|
||||
let dst_exe = exe("rust-lld", &target_compiler.host);
|
||||
// we prepend this bin directory to the user PATH when linking Rust binaries. To
|
||||
// avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`.
|
||||
let dst = libdir.parent().unwrap().join("bin");
|
||||
t!(fs::create_dir_all(&dst));
|
||||
builder.copy(&lld_install.join("bin").join(&src_exe), &dst.join(&dst_exe));
|
||||
}
|
||||
|
||||
// Ensure that `libLLVM.so` ends up in the newly build compiler directory,
|
||||
// so that it can be found when the newly built `rustc` is run.
|
||||
dist::maybe_install_llvm_dylib(builder, target_compiler.host, &sysroot);
|
||||
|
||||
// Link the compiler binary itself into place
|
||||
|
@ -105,7 +105,6 @@ pub struct Config {
|
||||
pub rust_optimize_tests: bool,
|
||||
pub rust_dist_src: bool,
|
||||
pub rust_codegen_backends: Vec<Interned<String>>,
|
||||
pub rust_codegen_backends_dir: String,
|
||||
pub rust_verify_llvm_ir: bool,
|
||||
pub rust_remap_debuginfo: bool,
|
||||
|
||||
@ -316,7 +315,6 @@ struct Rust {
|
||||
dist_src: Option<bool>,
|
||||
save_toolstates: Option<String>,
|
||||
codegen_backends: Option<Vec<String>>,
|
||||
codegen_backends_dir: Option<String>,
|
||||
lld: Option<bool>,
|
||||
llvm_tools: Option<bool>,
|
||||
lldb: Option<bool>,
|
||||
@ -372,7 +370,6 @@ impl Config {
|
||||
config.ignore_git = false;
|
||||
config.rust_dist_src = true;
|
||||
config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")];
|
||||
config.rust_codegen_backends_dir = "codegen-backends".to_owned();
|
||||
config.deny_warnings = true;
|
||||
config.missing_tools = false;
|
||||
|
||||
@ -575,8 +572,6 @@ impl Config {
|
||||
.collect();
|
||||
}
|
||||
|
||||
set(&mut config.rust_codegen_backends_dir, rust.codegen_backends_dir.clone());
|
||||
|
||||
config.rust_codegen_units = rust.codegen_units.map(threads_from_config);
|
||||
config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config);
|
||||
}
|
||||
|
@ -498,16 +498,6 @@ 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
|
||||
// technically needed by rustc itself it's needed by lots of other
|
||||
// components like the llvm tools and LLD. LLD is included below and
|
||||
@ -2134,6 +2124,10 @@ impl Step for HashSign {
|
||||
|
||||
// Maybe add libLLVM.so to the lib-dir. It will only have been built if
|
||||
// LLVM tools are linked dynamically.
|
||||
//
|
||||
// We add this to both the libdir of the rustc binary itself (for it to load at
|
||||
// runtime) and also to the target directory so it can find it at link-time.
|
||||
//
|
||||
// Note: This function does no yet support Windows but we also don't support
|
||||
// linking LLVM tools dynamically on Windows yet.
|
||||
pub fn maybe_install_llvm_dylib(builder: &Builder<'_>,
|
||||
@ -2142,13 +2136,19 @@ pub fn maybe_install_llvm_dylib(builder: &Builder<'_>,
|
||||
let src_libdir = builder
|
||||
.llvm_out(target)
|
||||
.join("lib");
|
||||
let dst_libdir = sysroot.join("lib/rustlib").join(&*target).join("lib");
|
||||
t!(fs::create_dir_all(&dst_libdir));
|
||||
let dst_libdir1 = sysroot.join("lib/rustlib").join(&*target).join("lib");
|
||||
let dst_libdir2 = sysroot.join(builder.sysroot_libdir_relative(Compiler {
|
||||
stage: 1,
|
||||
host: target,
|
||||
}));
|
||||
t!(fs::create_dir_all(&dst_libdir1));
|
||||
t!(fs::create_dir_all(&dst_libdir2));
|
||||
|
||||
if target.contains("apple-darwin") {
|
||||
let llvm_dylib_path = src_libdir.join("libLLVM.dylib");
|
||||
if llvm_dylib_path.exists() {
|
||||
builder.install(&llvm_dylib_path, &dst_libdir, 0o644);
|
||||
builder.install(&llvm_dylib_path, &dst_libdir1, 0o644);
|
||||
builder.install(&llvm_dylib_path, &dst_libdir2, 0o644);
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -2164,7 +2164,8 @@ pub fn maybe_install_llvm_dylib(builder: &Builder<'_>,
|
||||
});
|
||||
|
||||
|
||||
builder.install(&llvm_dylib_path, &dst_libdir, 0o644);
|
||||
builder.install(&llvm_dylib_path, &dst_libdir1, 0o644);
|
||||
builder.install(&llvm_dylib_path, &dst_libdir2, 0o644);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -433,7 +433,7 @@ impl Step for Std {
|
||||
builder.info(&format!("Documenting stage{} std ({})", stage, target));
|
||||
let out = builder.doc_out(target);
|
||||
t!(fs::create_dir_all(&out));
|
||||
let compiler = builder.compiler_for(stage, builder.config.build, target);
|
||||
let compiler = builder.compiler(stage, builder.config.build);
|
||||
|
||||
builder.ensure(compile::Std { compiler, target });
|
||||
let out_dir = builder.stage_out(compiler, Mode::Std)
|
||||
@ -541,7 +541,7 @@ impl Step for Rustc {
|
||||
// Build cargo command.
|
||||
let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc");
|
||||
cargo.env("RUSTDOCFLAGS", "--document-private-items --passes strip-hidden");
|
||||
compile::rustc_cargo(builder, &mut cargo);
|
||||
compile::rustc_cargo(builder, &mut cargo, target);
|
||||
|
||||
// Only include compiler crates, no dependencies of those, such as `libc`.
|
||||
cargo.arg("--no-deps");
|
||||
|
@ -500,6 +500,9 @@ impl Build {
|
||||
if self.config.jemalloc {
|
||||
features.push_str("jemalloc");
|
||||
}
|
||||
if self.config.llvm_enabled() {
|
||||
features.push_str(" llvm");
|
||||
}
|
||||
features
|
||||
}
|
||||
|
||||
|
@ -1773,7 +1773,7 @@ impl Step for Crate {
|
||||
}
|
||||
Mode::Rustc => {
|
||||
builder.ensure(compile::Rustc { compiler, target });
|
||||
compile::rustc_cargo(builder, &mut cargo);
|
||||
compile::rustc_cargo(builder, &mut cargo, target);
|
||||
}
|
||||
_ => panic!("can only test libraries"),
|
||||
};
|
||||
|
@ -7,8 +7,28 @@ edition = "2018"
|
||||
[lib]
|
||||
name = "rustc_codegen_llvm"
|
||||
path = "lib.rs"
|
||||
crate-type = ["dylib"]
|
||||
test = false
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
flate2 = "1.0"
|
||||
libc = "0.2"
|
||||
log = "0.4"
|
||||
rustc = { path = "../librustc" }
|
||||
rustc-demangle = "0.1"
|
||||
rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
|
||||
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
rustc_errors = { path = "../librustc_errors" }
|
||||
rustc_feature = { path = "../librustc_feature" }
|
||||
rustc_fs_util = { path = "../librustc_fs_util" }
|
||||
rustc_incremental = { path = "../librustc_incremental" }
|
||||
rustc_index = { path = "../librustc_index" }
|
||||
rustc_llvm = { path = "../librustc_llvm" }
|
||||
rustc_session = { path = "../librustc_session" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_expand = { path = "../libsyntax_expand" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
@ -8,6 +8,7 @@ use crate::value::Value;
|
||||
use rustc_codegen_ssa::MemFlags;
|
||||
use rustc_codegen_ssa::mir::place::PlaceRef;
|
||||
use rustc_codegen_ssa::mir::operand::OperandValue;
|
||||
use rustc::bug;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_target::abi::call::ArgAbi;
|
||||
use rustc_target::abi::{HasDataLayout, LayoutOf};
|
||||
|
@ -4,6 +4,7 @@ use crate::attributes;
|
||||
use libc::c_uint;
|
||||
use rustc::ty::TyCtxt;
|
||||
use syntax::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
|
||||
use rustc::bug;
|
||||
|
||||
use crate::ModuleLlvm;
|
||||
use crate::llvm::{self, False, True};
|
||||
|
@ -12,7 +12,7 @@ use syntax_pos::Span;
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use libc::{c_uint, c_char};
|
||||
|
||||
use log::debug;
|
||||
|
||||
impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
fn codegen_inline_asm(
|
||||
|
@ -12,6 +12,7 @@ use rustc::ty::query::Providers;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_target::abi::call::Conv;
|
||||
use rustc_data_structures::const_cstr;
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
|
||||
|
@ -4,11 +4,12 @@ use crate::back::write::{self, DiagnosticHandlers, with_llvm_pmb, save_temp_bitc
|
||||
use crate::llvm::archive_ro::ArchiveRO;
|
||||
use crate::llvm::{self, True, False};
|
||||
use crate::{ModuleLlvm, LlvmCodegenBackend};
|
||||
use rustc::bug;
|
||||
use rustc_codegen_ssa::back::symbol_export;
|
||||
use rustc_codegen_ssa::back::write::{ModuleConfig, CodegenContext, FatLTOInput};
|
||||
use rustc_codegen_ssa::back::lto::{SerializedModule, LtoModuleCodegen, ThinShared, ThinModule};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use errors::{FatalError, Handler};
|
||||
use rustc_errors::{FatalError, Handler};
|
||||
use rustc::dep_graph::WorkProduct;
|
||||
use rustc_session::cgu_reuse_tracker::CguReuse;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
@ -17,6 +18,7 @@ use rustc::session::config::{self, Lto};
|
||||
use rustc::util::common::time_ext;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_codegen_ssa::{RLIB_BYTECODE_EXTENSION, ModuleCodegen, ModuleKind};
|
||||
use log::{info, debug};
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ptr;
|
||||
|
@ -10,6 +10,7 @@ use crate::type_::Type;
|
||||
use crate::context::{is_pie_binary, get_reloc_model};
|
||||
use crate::common;
|
||||
use crate::LlvmCodegenBackend;
|
||||
use rustc::bug;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use rustc_codegen_ssa::back::write::{CodegenContext, ModuleConfig, run_assembler};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
@ -20,7 +21,8 @@ use rustc_codegen_ssa::{RLIB_BYTECODE_EXTENSION, ModuleCodegen, CompiledModule};
|
||||
use rustc::util::common::time_ext;
|
||||
use rustc_fs_util::{path_to_c_string, link_or_copy};
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use errors::{Handler, FatalError};
|
||||
use rustc_errors::{Handler, FatalError};
|
||||
use log::debug;
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::fs;
|
||||
@ -55,7 +57,7 @@ pub const TLS_MODEL_ARGS : [(&str, llvm::ThreadLocalMode); 4] = [
|
||||
("local-exec", llvm::ThreadLocalMode::LocalExec),
|
||||
];
|
||||
|
||||
pub fn llvm_err(handler: &errors::Handler, msg: &str) -> FatalError {
|
||||
pub fn llvm_err(handler: &rustc_errors::Handler, msg: &str) -> FatalError {
|
||||
match llvm::last_error() {
|
||||
Some(err) => handler.fatal(&format!("{}: {}", msg, err)),
|
||||
None => handler.fatal(&msg),
|
||||
@ -63,7 +65,7 @@ pub fn llvm_err(handler: &errors::Handler, msg: &str) -> FatalError {
|
||||
}
|
||||
|
||||
pub fn write_output_file(
|
||||
handler: &errors::Handler,
|
||||
handler: &rustc_errors::Handler,
|
||||
target: &'ll llvm::TargetMachine,
|
||||
pm: &llvm::PassManager<'ll>,
|
||||
m: &'ll llvm::Module,
|
||||
|
@ -23,6 +23,8 @@ use std::ffi::CStr;
|
||||
use std::ops::{Deref, Range};
|
||||
use std::ptr;
|
||||
use std::iter::TrustedLen;
|
||||
use rustc_data_structures::const_cstr;
|
||||
use log::debug;
|
||||
|
||||
// All Builders must have an llfn associated with them
|
||||
#[must_use]
|
||||
|
@ -10,6 +10,7 @@ use crate::llvm;
|
||||
use crate::context::CodegenCx;
|
||||
use crate::value::Value;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use log::debug;
|
||||
|
||||
use rustc::ty::{TypeFoldable, Instance};
|
||||
use rustc::ty::layout::{FnAbiExt, HasTyCtxt};
|
||||
|
@ -8,6 +8,8 @@ use crate::type_::Type;
|
||||
use crate::type_of::LayoutLlvmExt;
|
||||
use crate::value::Value;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc::bug;
|
||||
use log::debug;
|
||||
|
||||
use crate::consts::const_alloc_to_llvm;
|
||||
use rustc::ty::layout::{HasDataLayout, LayoutOf, self, TyLayout, Size};
|
||||
|
@ -16,6 +16,8 @@ use rustc::ty::{self, Ty, Instance};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use syntax::symbol::{Symbol, sym};
|
||||
use syntax_pos::Span;
|
||||
use rustc::{bug, span_bug};
|
||||
use log::debug;
|
||||
|
||||
use rustc::ty::layout::{self, Size, Align, LayoutOf};
|
||||
|
||||
|
@ -12,6 +12,7 @@ use rustc_codegen_ssa::traits::*;
|
||||
|
||||
use rustc_data_structures::base_n;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc::bug;
|
||||
use rustc::mir::mono::CodegenUnit;
|
||||
use rustc::session::config::{self, DebugInfo};
|
||||
use rustc::session::Session;
|
||||
@ -23,6 +24,7 @@ use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_target::spec::{HasTargetSpec, Target};
|
||||
use rustc_codegen_ssa::base::wants_msvc_seh;
|
||||
use crate::callee::get_fn;
|
||||
use rustc_data_structures::const_cstr;
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
@ -7,6 +7,7 @@ use crate::builder::Builder;
|
||||
use crate::value::Value;
|
||||
use rustc::session::config::DebugInfo;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc::bug;
|
||||
|
||||
use syntax::attr;
|
||||
use syntax::symbol::sym;
|
||||
|
@ -35,10 +35,13 @@ use rustc::session::config::{self, DebugInfo};
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_fs_util::path_to_c_string;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_data_structures::const_cstr;
|
||||
use rustc_target::abi::HasDataLayout;
|
||||
use syntax::ast;
|
||||
use syntax::symbol::{Interner, Symbol};
|
||||
use syntax_pos::{self, Span, FileName};
|
||||
use rustc::{bug, span_bug};
|
||||
use log::debug;
|
||||
|
||||
use libc::{c_uint, c_longlong};
|
||||
use std::collections::hash_map::Entry;
|
||||
|
@ -33,6 +33,7 @@ use rustc_codegen_ssa::mir::debuginfo::{FunctionDebugContext, DebugScope,
|
||||
use libc::c_uint;
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::CString;
|
||||
use log::debug;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use syntax_pos::{self, BytePos, Span, Pos};
|
||||
|
@ -8,6 +8,7 @@ use crate::llvm;
|
||||
use crate::llvm::debuginfo::DIScope;
|
||||
use crate::builder::Builder;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use log::debug;
|
||||
|
||||
use libc::c_uint;
|
||||
use syntax_pos::{Span, Pos};
|
||||
|
@ -22,6 +22,7 @@ use rustc::ty::Ty;
|
||||
use rustc::session::config::Sanitizer;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use log::debug;
|
||||
|
||||
/// Declare a function.
|
||||
///
|
||||
|
@ -19,6 +19,7 @@ use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
|
||||
use rustc::hir;
|
||||
use rustc_target::abi::HasDataLayout;
|
||||
use syntax::ast;
|
||||
use rustc::{bug, span_bug};
|
||||
|
||||
use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
|
@ -24,33 +24,11 @@
|
||||
use back::write::{create_target_machine, create_informational_target_machine};
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
||||
extern crate rustc_demangle;
|
||||
extern crate flate2;
|
||||
#[macro_use] extern crate bitflags;
|
||||
extern crate libc;
|
||||
#[macro_use] extern crate rustc;
|
||||
extern crate rustc_target;
|
||||
#[macro_use] extern crate rustc_data_structures;
|
||||
extern crate rustc_feature;
|
||||
extern crate rustc_index;
|
||||
extern crate rustc_incremental;
|
||||
extern crate rustc_codegen_utils;
|
||||
extern crate rustc_codegen_ssa;
|
||||
extern crate rustc_fs_util;
|
||||
extern crate rustc_driver as _;
|
||||
|
||||
#[macro_use] extern crate log;
|
||||
extern crate smallvec;
|
||||
extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
extern crate rustc_errors as errors;
|
||||
extern crate rustc_session;
|
||||
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_codegen_ssa::back::write::{CodegenContext, ModuleConfig, FatLTOInput};
|
||||
use rustc_codegen_ssa::back::lto::{SerializedModule, LtoModuleCodegen, ThinModule};
|
||||
use rustc_codegen_ssa::CompiledModule;
|
||||
use errors::{FatalError, Handler};
|
||||
use rustc_errors::{FatalError, Handler};
|
||||
use rustc::dep_graph::WorkProduct;
|
||||
use syntax::expand::allocator::AllocatorKind;
|
||||
pub use llvm_util::target_features;
|
||||
@ -339,12 +317,6 @@ impl CodegenBackend for LlvmCodegenBackend {
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the entrypoint for a hot plugged rustc_codegen_llvm
|
||||
#[no_mangle]
|
||||
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
|
||||
LlvmCodegenBackend::new()
|
||||
}
|
||||
|
||||
pub struct ModuleLlvm {
|
||||
llcx: &'static mut llvm::Context,
|
||||
llmod_raw: *const llvm::Module,
|
||||
|
@ -544,6 +544,7 @@ pub type InlineAsmDiagHandler = unsafe extern "C" fn(&SMDiagnostic, *const c_voi
|
||||
|
||||
pub mod debuginfo {
|
||||
use super::{InvariantOpaque, Metadata};
|
||||
use bitflags::bitflags;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DIBuilder<'a>(InvariantOpaque<'a>);
|
||||
|
@ -10,11 +10,11 @@ pub use self::Linkage::*;
|
||||
|
||||
use std::str::FromStr;
|
||||
use std::string::FromUtf8Error;
|
||||
use std::slice;
|
||||
use std::ffi::CStr;
|
||||
use std::cell::RefCell;
|
||||
use libc::{c_uint, c_char, size_t};
|
||||
use libc::c_uint;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_llvm::RustString;
|
||||
|
||||
pub mod archive_ro;
|
||||
pub mod diagnostic;
|
||||
@ -81,21 +81,6 @@ impl FromStr for ArchiveKind {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct RustString {
|
||||
bytes: RefCell<Vec<u8>>,
|
||||
}
|
||||
|
||||
/// Appending to a Rust string -- used by RawRustStringOstream.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: &RustString,
|
||||
ptr: *const c_char,
|
||||
size: size_t) {
|
||||
let slice = slice::from_raw_parts(ptr as *const u8, size as usize);
|
||||
|
||||
sr.bytes.borrow_mut().extend_from_slice(slice);
|
||||
}
|
||||
|
||||
pub fn SetInstructionCallConv(instr: &'a Value, cc: CallConv) {
|
||||
unsafe {
|
||||
LLVMSetInstructionCallConv(instr, cc as c_uint);
|
||||
|
@ -8,6 +8,7 @@ use libc::c_int;
|
||||
use std::ffi::CString;
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use syntax::symbol::sym;
|
||||
use rustc::bug;
|
||||
|
||||
use std::str;
|
||||
use std::slice;
|
||||
|
@ -6,6 +6,8 @@ use rustc_target::spec::Target;
|
||||
|
||||
use rustc_data_structures::owning_ref::OwningRef;
|
||||
use rustc_codegen_ssa::METADATA_FILENAME;
|
||||
use log::debug;
|
||||
use rustc_data_structures::rustc_erase_owner;
|
||||
|
||||
use std::path::Path;
|
||||
use std::slice;
|
||||
|
@ -9,6 +9,7 @@ use rustc::mir::mono::{Linkage, Visibility};
|
||||
use rustc::ty::{TypeFoldable, Instance};
|
||||
use rustc::ty::layout::{FnAbiExt, LayoutOf};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use log::debug;
|
||||
|
||||
pub use rustc::mir::mono::MonoItem;
|
||||
|
||||
|
@ -5,6 +5,7 @@ use crate::llvm::{Bool, False, True};
|
||||
use crate::context::CodegenCx;
|
||||
use crate::value::Value;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc::bug;
|
||||
|
||||
use crate::common;
|
||||
use crate::type_of::LayoutLlvmExt;
|
||||
|
@ -6,6 +6,8 @@ use rustc::ty::layout::{self, Align, LayoutOf, FnAbiExt, PointeeInfo, Size, TyLa
|
||||
use rustc_target::abi::TyLayoutMethods;
|
||||
use rustc::ty::print::obsolete::DefPathBasedNames;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use log::debug;
|
||||
use rustc::bug;
|
||||
|
||||
use std::fmt::Write;
|
||||
|
||||
|
@ -32,3 +32,6 @@ rustc_serialize = { path = "../libserialize", package = "serialize" }
|
||||
rustc_resolve = { path = "../librustc_resolve" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
||||
[features]
|
||||
llvm = ['rustc_interface/llvm']
|
||||
|
@ -42,7 +42,7 @@ use rustc_metadata::locator;
|
||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||
use errors::{PResult, registry::Registry};
|
||||
use rustc_interface::{interface, Queries};
|
||||
use rustc_interface::util::get_codegen_sysroot;
|
||||
use rustc_interface::util::get_builtin_codegen_backend;
|
||||
use rustc_data_structures::sync::SeqCst;
|
||||
use rustc_feature::{find_gated_cfg, UnstableFeatures};
|
||||
use rustc_serialize::json::ToJson;
|
||||
@ -765,7 +765,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) {
|
||||
println!("commit-date: {}", unw(commit_date_str()));
|
||||
println!("host: {}", config::host_triple());
|
||||
println!("release: {}", unw(release_str()));
|
||||
get_codegen_sysroot("llvm")().print_version();
|
||||
get_builtin_codegen_backend("llvm")().print_version();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1059,7 +1059,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
||||
}
|
||||
|
||||
if cg_flags.iter().any(|x| *x == "passes=list") {
|
||||
get_codegen_sysroot("llvm")().print_passes();
|
||||
get_builtin_codegen_backend("llvm")().print_passes();
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ rustc_traits = { path = "../librustc_traits" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
|
||||
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
|
||||
rustc_codegen_llvm = { path = "../librustc_codegen_llvm", optional = true }
|
||||
rustc_metadata = { path = "../librustc_metadata" }
|
||||
rustc_mir = { path = "../librustc_mir" }
|
||||
rustc_passes = { path = "../librustc_passes" }
|
||||
@ -39,3 +40,6 @@ once_cell = "1"
|
||||
|
||||
[dev-dependencies]
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
|
||||
[features]
|
||||
llvm = ['rustc_codegen_llvm']
|
||||
|
@ -16,11 +16,9 @@ use rustc_errors::registry::Registry;
|
||||
use rustc_metadata::dynamic_lib::DynamicLibrary;
|
||||
use rustc_resolve::{self, Resolver};
|
||||
use std::env;
|
||||
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
|
||||
use std::io::{self, Write};
|
||||
use std::mem;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex, Once};
|
||||
use std::ops::DerefMut;
|
||||
use smallvec::SmallVec;
|
||||
@ -249,7 +247,7 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
|
||||
filename if filename.contains(".") => {
|
||||
load_backend_from_dylib(filename.as_ref())
|
||||
}
|
||||
codegen_name => get_codegen_sysroot(codegen_name),
|
||||
codegen_name => get_builtin_codegen_backend(codegen_name),
|
||||
};
|
||||
|
||||
unsafe {
|
||||
@ -384,83 +382,16 @@ fn sysroot_candidates() -> Vec<PathBuf> {
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("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_llvm-{}", backend_name);
|
||||
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) => return load_backend_from_dylib(s),
|
||||
None => {
|
||||
let err = format!("failed to load default codegen backend for `{}`, \
|
||||
no appropriate codegen dylib found in `{}`",
|
||||
backend_name, sysroot.display());
|
||||
early_error(ErrorOutputType::default(), &err);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
let err = format!("unsupported builtin codegen backend `{}`", backend_name);
|
||||
early_error(ErrorOutputType::default(), &err);
|
||||
}
|
||||
|
||||
pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguator {
|
||||
|
@ -13,6 +13,9 @@ path = "lib.rs"
|
||||
static-libstdcpp = []
|
||||
emscripten = []
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
|
||||
[build-dependencies]
|
||||
build_helper = { path = "../build_helper" }
|
||||
cc = "1.0.1"
|
||||
|
@ -5,6 +5,26 @@
|
||||
|
||||
// NOTE: This crate only exists to allow linking on mingw targets.
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::slice;
|
||||
use libc::{c_char, size_t};
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
pub struct RustString {
|
||||
pub bytes: RefCell<Vec<u8>>,
|
||||
}
|
||||
|
||||
/// Appending to a Rust string -- used by RawRustStringOstream.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: &RustString,
|
||||
ptr: *const c_char,
|
||||
size: size_t) {
|
||||
let slice = slice::from_raw_parts(ptr as *const u8, size as usize);
|
||||
|
||||
sr.bytes.borrow_mut().extend_from_slice(slice);
|
||||
}
|
||||
|
||||
/// Initialize targets enabled by the build script via `cfg(llvm_component = "...")`.
|
||||
/// N.B., this function can't be moved to `rustc_codegen_llvm` because of the `cfg`s.
|
||||
pub fn initialize_available_targets() {
|
||||
|
@ -23,3 +23,4 @@ features = ['unprefixed_malloc_on_supported_platforms']
|
||||
|
||||
[features]
|
||||
jemalloc = ['jemalloc-sys']
|
||||
llvm = ['rustc_driver/llvm']
|
||||
|
@ -135,6 +135,7 @@ const WHITELIST: &[Crate<'_>] = &[
|
||||
Crate("polonius-engine"),
|
||||
Crate("ppv-lite86"),
|
||||
Crate("proc-macro2"),
|
||||
Crate("punycode"),
|
||||
Crate("quick-error"),
|
||||
Crate("quote"),
|
||||
Crate("rand"),
|
||||
|
Loading…
Reference in New Issue
Block a user