Move NoLlvmMetadataLoader to rustc_trans_traits
This commit is contained in:
parent
44c184382f
commit
9eeaba18bd
7 changed files with 171 additions and 213 deletions
4
src/Cargo.lock
generated
4
src/Cargo.lock
generated
|
@ -1781,10 +1781,14 @@ dependencies = [
|
|||
name = "rustc_trans_traits"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"ar 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc 0.0.0",
|
||||
"rustc_back 0.0.0",
|
||||
"rustc_incremental 0.0.0",
|
||||
"rustc_trans_utils 0.0.0",
|
||||
"syntax 0.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -159,10 +159,6 @@ fn main() {
|
|||
cmd.arg("-C").arg("panic=abort");
|
||||
}
|
||||
|
||||
if env::var("RUSTC_LLVM_ENABLED") == Ok("0".to_string()) && stage != "0" {
|
||||
cmd.arg("-Zno-trans");
|
||||
}
|
||||
|
||||
// Set various options from config.toml to configure how we're building
|
||||
// code.
|
||||
if env::var("RUSTC_DEBUGINFO") == Ok("true".to_string()) {
|
||||
|
|
|
@ -531,6 +531,9 @@ impl<'a> Builder<'a> {
|
|||
// For other crates, however, we know that we've already got a standard
|
||||
// library up and running, so we can use the normal compiler to compile
|
||||
// build scripts in that situation.
|
||||
//
|
||||
// If LLVM support is disabled we need to use the snapshot compiler to compile
|
||||
// build scripts, as the new compiler doesnt support executables.
|
||||
if mode == Mode::Libstd || !self.build.config.llvm_enabled {
|
||||
cargo.env("RUSTC_SNAPSHOT", &self.initial_rustc)
|
||||
.env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir());
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![cfg_attr(not(feature="llvm"), allow(dead_code))]
|
||||
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::hir::{self, map as hir_map};
|
||||
use rustc::hir::lowering::lower_crate;
|
||||
|
@ -96,10 +94,6 @@ pub fn compile_input(sess: &Session,
|
|||
}
|
||||
|
||||
if cfg!(not(feature="llvm")) {
|
||||
if !sess.opts.debugging_opts.no_trans && sess.opts.output_types.should_trans() {
|
||||
sess.err("LLVM is not supported by this rustc. Please use -Z no-trans to compile")
|
||||
}
|
||||
|
||||
for cty in sess.opts.crate_types.iter() {
|
||||
match *cty {
|
||||
CrateType::CrateTypeRlib | CrateType::CrateTypeDylib |
|
||||
|
@ -269,48 +263,36 @@ pub fn compile_input(sess: &Session,
|
|||
})??
|
||||
};
|
||||
|
||||
if cfg!(not(feature="llvm")) {
|
||||
let (_, _) = (outputs, trans);
|
||||
|
||||
if sess.opts.crate_types.contains(&CrateType::CrateTypeRlib)
|
||||
|| sess.opts.crate_types.contains(&CrateType::CrateTypeDylib) {
|
||||
return Ok(())
|
||||
}
|
||||
sess.fatal("LLVM is not supported by this rustc");
|
||||
if sess.opts.debugging_opts.print_type_sizes {
|
||||
sess.code_stats.borrow().print_type_sizes();
|
||||
}
|
||||
|
||||
let (phase5_result, trans) = phase_5_run_llvm_passes::<DefaultTransCrate>(sess, &dep_graph, trans);
|
||||
|
||||
controller_entry_point!(after_llvm,
|
||||
sess,
|
||||
CompileState::state_after_llvm(input, sess, outdir, output, &trans),
|
||||
phase5_result);
|
||||
phase5_result?;
|
||||
|
||||
phase_6_link_output::<DefaultTransCrate>(sess, &trans, &outputs);
|
||||
|
||||
// Now that we won't touch anything in the incremental compilation directory
|
||||
// any more, we can finalize it (which involves renaming it)
|
||||
#[cfg(feature="llvm")]
|
||||
{
|
||||
if sess.opts.debugging_opts.print_type_sizes {
|
||||
sess.code_stats.borrow().print_type_sizes();
|
||||
}
|
||||
rustc_incremental::finalize_session_directory(sess, trans.link.crate_hash);
|
||||
|
||||
let (phase5_result, trans) = phase_5_run_llvm_passes::<DefaultTransCrate>(sess, &dep_graph, trans);
|
||||
|
||||
controller_entry_point!(after_llvm,
|
||||
sess,
|
||||
CompileState::state_after_llvm(input, sess, outdir, output, &trans),
|
||||
phase5_result);
|
||||
phase5_result?;
|
||||
|
||||
phase_6_link_output::<DefaultTransCrate>(sess, &trans, &outputs);
|
||||
|
||||
// Now that we won't touch anything in the incremental compilation directory
|
||||
// any more, we can finalize it (which involves renaming it)
|
||||
rustc_incremental::finalize_session_directory(sess, trans.link.crate_hash);
|
||||
|
||||
if sess.opts.debugging_opts.perf_stats {
|
||||
sess.print_perf_stats();
|
||||
}
|
||||
|
||||
controller_entry_point!(
|
||||
compilation_done,
|
||||
sess,
|
||||
CompileState::state_when_compilation_done(input, sess, outdir, output),
|
||||
Ok(())
|
||||
);
|
||||
if sess.opts.debugging_opts.perf_stats {
|
||||
sess.print_perf_stats();
|
||||
}
|
||||
|
||||
controller_entry_point!(
|
||||
compilation_done,
|
||||
sess,
|
||||
CompileState::state_when_compilation_done(input, sess, outdir, output),
|
||||
Ok(())
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1171,7 +1153,6 @@ pub fn phase_5_run_llvm_passes<T: TransCrate>(sess: &Session,
|
|||
|
||||
/// Run the linker on any artifacts that resulted from the LLVM run.
|
||||
/// This should produce either a finished executable or library.
|
||||
#[cfg(feature="llvm")]
|
||||
pub fn phase_6_link_output<T: TransCrate>(sess: &Session,
|
||||
trans: &<T as TransCrate>::TranslatedCrate,
|
||||
outputs: &OutputFilenames) {
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(set_stdio)]
|
||||
|
||||
extern crate ar;
|
||||
extern crate flate2;
|
||||
extern crate arena;
|
||||
extern crate getopts;
|
||||
extern crate graphviz;
|
||||
|
@ -155,173 +153,17 @@ pub fn run<F>(run_compiler: F) -> isize
|
|||
}
|
||||
|
||||
#[cfg(not(feature="llvm"))]
|
||||
pub use trans_metadata_only::MetadataOnlyTransCrate as DefaultTransCrate;
|
||||
pub use rustc_trans_traits::MetadataOnlyTransCrate as DefaultTransCrate;
|
||||
#[cfg(feature="llvm")]
|
||||
pub use rustc_trans::LlvmTransCrate as DefaultTransCrate;
|
||||
|
||||
mod no_llvm_metadata_loader {
|
||||
extern crate owning_ref;
|
||||
|
||||
use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait;
|
||||
use rustc_back::target::Target;
|
||||
use std::io;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
|
||||
use ar::Archive;
|
||||
use self::owning_ref::{OwningRef, ErasedBoxRef};
|
||||
|
||||
pub struct NoLlvmMetadataLoader;
|
||||
|
||||
impl MetadataLoaderTrait for NoLlvmMetadataLoader {
|
||||
fn get_rlib_metadata(
|
||||
&self,
|
||||
_: &Target,
|
||||
filename: &Path
|
||||
) -> Result<ErasedBoxRef<[u8]>, String> {
|
||||
let file = File::open(filename).map_err(|e| {
|
||||
format!("metadata file open err: {:?}", e)
|
||||
})?;
|
||||
let mut archive = Archive::new(file);
|
||||
|
||||
while let Some(entry_result) = archive.next_entry() {
|
||||
let mut entry = entry_result.map_err(|e| {
|
||||
format!("metadata section read err: {:?}", e)
|
||||
})?;
|
||||
if entry.header().identifier() == "rust.metadata.bin" {
|
||||
let mut buf = Vec::new();
|
||||
io::copy(&mut entry, &mut buf).unwrap();
|
||||
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
|
||||
return Ok(buf.map_owner_box().erase_owner());
|
||||
}
|
||||
}
|
||||
|
||||
Err("Couldnt find metadata section".to_string())
|
||||
}
|
||||
|
||||
fn get_dylib_metadata(&self,
|
||||
_target: &Target,
|
||||
_filename: &Path)
|
||||
-> Result<ErasedBoxRef<[u8]>, String> {
|
||||
// FIXME: Support reading dylibs from llvm enabled rustc
|
||||
self.get_rlib_metadata(_target, _filename)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod trans_metadata_only {
|
||||
use std::io::prelude::*;
|
||||
use std::io::Cursor;
|
||||
use std::fs::File;
|
||||
|
||||
use ar::{Builder, Header};
|
||||
use flate2::Compression;
|
||||
use flate2::write::DeflateEncoder;
|
||||
|
||||
use syntax::symbol::Symbol;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::{OutputFilenames, CrateType};
|
||||
use rustc::ty::{TyCtxt, CrateAnalysis};
|
||||
use rustc::ty::maps::Providers;
|
||||
use rustc::middle::cstore::{MetadataLoader, EncodedMetadata};
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc_incremental::IncrementalHashesMap;
|
||||
use rustc_trans_utils::find_exported_symbols;
|
||||
use rustc_trans_utils::link::{out_filename, build_link_meta};
|
||||
use rustc_trans_traits::TransCrate;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct MetadataOnlyTransCrate;
|
||||
pub struct OngoingCrateTranslation {
|
||||
metadata: EncodedMetadata,
|
||||
metadata_version: Vec<u8>,
|
||||
crate_name: Symbol,
|
||||
}
|
||||
pub struct TranslatedCrate(OngoingCrateTranslation);
|
||||
|
||||
impl MetadataOnlyTransCrate {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(/*_sess: &Session*/) -> Self {
|
||||
MetadataOnlyTransCrate
|
||||
}
|
||||
}
|
||||
|
||||
impl TransCrate for MetadataOnlyTransCrate {
|
||||
type MetadataLoader = ::no_llvm_metadata_loader::NoLlvmMetadataLoader;
|
||||
type OngoingCrateTranslation = OngoingCrateTranslation;
|
||||
type TranslatedCrate = TranslatedCrate;
|
||||
|
||||
fn metadata_loader() -> Box<MetadataLoader> {
|
||||
box ::no_llvm_metadata_loader::NoLlvmMetadataLoader
|
||||
}
|
||||
|
||||
fn provide(_providers: &mut Providers) {}
|
||||
|
||||
fn trans_crate<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
analysis: CrateAnalysis,
|
||||
incr_hashes_map: IncrementalHashesMap,
|
||||
_output_filenames: &OutputFilenames
|
||||
) -> Self::OngoingCrateTranslation {
|
||||
let link_meta = build_link_meta(&incr_hashes_map);
|
||||
let exported_symbols = find_exported_symbols(tcx, &analysis.reachable);
|
||||
let (metadata, _hashes) = tcx.encode_metadata(&link_meta, &exported_symbols);
|
||||
|
||||
OngoingCrateTranslation {
|
||||
metadata: metadata,
|
||||
metadata_version: tcx.metadata_encoding_version().to_vec(),
|
||||
crate_name: tcx.crate_name(LOCAL_CRATE),
|
||||
}
|
||||
}
|
||||
|
||||
fn join_trans(
|
||||
trans: Self::OngoingCrateTranslation,
|
||||
_sess: &Session,
|
||||
_dep_graph: &DepGraph,
|
||||
) -> Self::TranslatedCrate {
|
||||
TranslatedCrate(trans)
|
||||
}
|
||||
|
||||
fn link_binary(sess: &Session,
|
||||
trans: &Self::TranslatedCrate,
|
||||
outputs: &OutputFilenames) {
|
||||
for &crate_type in sess.opts.crate_types.iter() {
|
||||
if crate_type != CrateType::CrateTypeRlib &&
|
||||
crate_type != CrateType::CrateTypeDylib {
|
||||
continue;
|
||||
}
|
||||
let output_name =
|
||||
out_filename(sess, crate_type, &outputs, &trans.0.crate_name.as_str());
|
||||
let mut compressed = trans.0.metadata_version.clone();
|
||||
let metadata = if crate_type == CrateType::CrateTypeDylib {
|
||||
DeflateEncoder::new(&mut compressed, Compression::Fast)
|
||||
.write_all(&trans.0.metadata.raw_data).unwrap();
|
||||
&compressed
|
||||
} else {
|
||||
&trans.0.metadata.raw_data
|
||||
};
|
||||
let mut builder = Builder::new(File::create(&output_name).unwrap());
|
||||
let header = Header::new(
|
||||
"rust.metadata.bin".to_string(),
|
||||
metadata.len() as u64
|
||||
);
|
||||
builder
|
||||
.append(&header, Cursor::new(metadata))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn dump_incremental_data(_trans: &Self::TranslatedCrate) {}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature="llvm"))]
|
||||
mod rustc_trans {
|
||||
use syntax_pos::symbol::Symbol;
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::PrintRequest;
|
||||
pub use trans_metadata_only::MetadataOnlyTransCrate as LlvmTransCrate;
|
||||
pub use rustc_trans_traits::MetadataOnlyTransCrate as LlvmTransCrate;
|
||||
pub use rustc_trans_traits::TranslatedCrate as CrateTranslation;
|
||||
|
||||
pub fn init(_sess: &Session) {}
|
||||
pub fn enable_llvm_debug() {}
|
||||
|
@ -330,8 +172,6 @@ mod rustc_trans {
|
|||
pub fn print(_req: PrintRequest, _sess: &Session) {}
|
||||
pub fn target_features(_sess: &Session) -> Vec<Symbol> { vec![] }
|
||||
|
||||
pub struct CrateTranslation(());
|
||||
|
||||
pub mod back {
|
||||
pub mod write {
|
||||
pub const RELOC_MODEL_ARGS: [(&'static str, ()); 0] = [];
|
||||
|
|
|
@ -10,8 +10,12 @@ crate-type = ["dylib"]
|
|||
test = false
|
||||
|
||||
[dependencies]
|
||||
ar = "0.3.0"
|
||||
flate2 = "0.2"
|
||||
owning_ref = "0.3.3"
|
||||
|
||||
syntax = { path = "../libsyntax" }
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_back = { path = "../librustc_back" }
|
||||
rustc_incremental = { path = "../librustc_incremental" }
|
||||
rustc_trans_utils = { path = "../librustc_trans_utils" }
|
||||
|
|
|
@ -21,24 +21,40 @@
|
|||
|
||||
#![feature(box_syntax)]
|
||||
|
||||
extern crate ar;
|
||||
extern crate flate2;
|
||||
extern crate owning_ref;
|
||||
|
||||
extern crate syntax;
|
||||
#[macro_use]
|
||||
extern crate rustc;
|
||||
extern crate rustc_back;
|
||||
extern crate rustc_incremental;
|
||||
extern crate rustc_trans_utils;
|
||||
|
||||
use std::io::prelude::*;
|
||||
use std::io::{self, Cursor};
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use owning_ref::ErasedBoxRef;
|
||||
|
||||
use owning_ref::{ErasedBoxRef, OwningRef};
|
||||
use ar::{Archive, Builder, Header};
|
||||
use flate2::Compression;
|
||||
use flate2::write::DeflateEncoder;
|
||||
|
||||
use syntax::symbol::Symbol;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::OutputFilenames;
|
||||
use rustc::ty::{TyCtxt, CrateAnalysis};
|
||||
use rustc::session::config::{CrateType, OutputFilenames};
|
||||
use rustc::ty::{CrateAnalysis, TyCtxt};
|
||||
use rustc::ty::maps::Providers;
|
||||
use rustc::middle::cstore::EncodedMetadata;
|
||||
use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait;
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc_back::target::Target;
|
||||
use rustc_incremental::IncrementalHashesMap;
|
||||
use rustc_trans_utils::find_exported_symbols;
|
||||
use rustc_trans_utils::link::{build_link_meta, out_filename};
|
||||
|
||||
pub trait TransCrate {
|
||||
type MetadataLoader: MetadataLoaderTrait;
|
||||
|
@ -114,3 +130,117 @@ impl MetadataLoaderTrait for DummyMetadataLoader {
|
|||
bug!("DummyMetadataLoader::get_dylib_metadata");
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NoLlvmMetadataLoader;
|
||||
|
||||
impl MetadataLoaderTrait for NoLlvmMetadataLoader {
|
||||
fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> {
|
||||
let file = File::open(filename)
|
||||
.map_err(|e| format!("metadata file open err: {:?}", e))?;
|
||||
let mut archive = Archive::new(file);
|
||||
|
||||
while let Some(entry_result) = archive.next_entry() {
|
||||
let mut entry = entry_result
|
||||
.map_err(|e| format!("metadata section read err: {:?}", e))?;
|
||||
if entry.header().identifier() == "rust.metadata.bin" {
|
||||
let mut buf = Vec::new();
|
||||
io::copy(&mut entry, &mut buf).unwrap();
|
||||
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
|
||||
return Ok(buf.map_owner_box().erase_owner());
|
||||
}
|
||||
}
|
||||
|
||||
Err("Couldnt find metadata section".to_string())
|
||||
}
|
||||
|
||||
fn get_dylib_metadata(
|
||||
&self,
|
||||
_target: &Target,
|
||||
_filename: &Path,
|
||||
) -> Result<ErasedBoxRef<[u8]>, String> {
|
||||
// FIXME: Support reading dylibs from llvm enabled rustc
|
||||
self.get_rlib_metadata(_target, _filename)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct MetadataOnlyTransCrate;
|
||||
pub struct OngoingCrateTranslation {
|
||||
metadata: EncodedMetadata,
|
||||
metadata_version: Vec<u8>,
|
||||
crate_name: Symbol,
|
||||
}
|
||||
pub struct TranslatedCrate(OngoingCrateTranslation);
|
||||
|
||||
impl MetadataOnlyTransCrate {
|
||||
#[allow(dead_code)]
|
||||
pub fn new() -> Self {
|
||||
MetadataOnlyTransCrate
|
||||
}
|
||||
}
|
||||
|
||||
impl TransCrate for MetadataOnlyTransCrate {
|
||||
type MetadataLoader = NoLlvmMetadataLoader;
|
||||
type OngoingCrateTranslation = OngoingCrateTranslation;
|
||||
type TranslatedCrate = TranslatedCrate;
|
||||
|
||||
fn metadata_loader() -> Box<MetadataLoaderTrait> {
|
||||
box NoLlvmMetadataLoader
|
||||
}
|
||||
|
||||
fn provide(_providers: &mut Providers) {}
|
||||
|
||||
fn trans_crate<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
analysis: CrateAnalysis,
|
||||
incr_hashes_map: IncrementalHashesMap,
|
||||
_output_filenames: &OutputFilenames,
|
||||
) -> Self::OngoingCrateTranslation {
|
||||
let link_meta = build_link_meta(&incr_hashes_map);
|
||||
let exported_symbols = find_exported_symbols(tcx, &analysis.reachable);
|
||||
let (metadata, _hashes) = tcx.encode_metadata(&link_meta, &exported_symbols);
|
||||
|
||||
OngoingCrateTranslation {
|
||||
metadata: metadata,
|
||||
metadata_version: tcx.metadata_encoding_version().to_vec(),
|
||||
crate_name: tcx.crate_name(LOCAL_CRATE),
|
||||
}
|
||||
}
|
||||
|
||||
fn join_trans(
|
||||
trans: Self::OngoingCrateTranslation,
|
||||
_sess: &Session,
|
||||
_dep_graph: &DepGraph,
|
||||
) -> Self::TranslatedCrate {
|
||||
TranslatedCrate(trans)
|
||||
}
|
||||
|
||||
fn link_binary(sess: &Session, trans: &Self::TranslatedCrate, outputs: &OutputFilenames) {
|
||||
for &crate_type in sess.opts.crate_types.iter() {
|
||||
if crate_type != CrateType::CrateTypeRlib && crate_type != CrateType::CrateTypeDylib {
|
||||
continue;
|
||||
}
|
||||
let output_name =
|
||||
out_filename(sess, crate_type, &outputs, &trans.0.crate_name.as_str());
|
||||
let mut compressed = trans.0.metadata_version.clone();
|
||||
let metadata = if crate_type == CrateType::CrateTypeDylib {
|
||||
DeflateEncoder::new(&mut compressed, Compression::Fast)
|
||||
.write_all(&trans.0.metadata.raw_data)
|
||||
.unwrap();
|
||||
&compressed
|
||||
} else {
|
||||
&trans.0.metadata.raw_data
|
||||
};
|
||||
let mut builder = Builder::new(File::create(&output_name).unwrap());
|
||||
let header = Header::new("rust.metadata.bin".to_string(), metadata.len() as u64);
|
||||
builder.append(&header, Cursor::new(metadata)).unwrap();
|
||||
}
|
||||
|
||||
if !sess.opts.crate_types.contains(&CrateType::CrateTypeRlib)
|
||||
&& !sess.opts.crate_types.contains(&CrateType::CrateTypeDylib) {
|
||||
sess.fatal("Executables are not supported by the metadata-only backend.");
|
||||
}
|
||||
}
|
||||
|
||||
fn dump_incremental_data(_trans: &Self::TranslatedCrate) {}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue