diff --git a/src/Cargo.lock b/src/Cargo.lock index 38897993d43..2e3b54f00bc 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -65,6 +65,11 @@ name = "ansi_term" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ar" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arena" version = "0.0.0" @@ -1333,6 +1338,7 @@ dependencies = [ name = "rustc_driver" version = "0.0.0" dependencies = [ + "ar 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "arena 0.0.0", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", @@ -2141,6 +2147,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" +"checksum ar 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b24e4eef8e3fa7e2ca75b157e6039cdf8d9d3a68213ddc19d0fd9d576b9717c9" "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" "checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76" "checksum backtrace-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "afccc5772ba333abccdf60d55200fa3406f8c59dcf54d5f7998c9107d3799c7c" diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index f1bdf0b2c3d..c8ea09f4687 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -29,9 +29,14 @@ rustc_plugin = { path = "../librustc_plugin" } rustc_privacy = { path = "../librustc_privacy" } rustc_resolve = { path = "../librustc_resolve" } rustc_save_analysis = { path = "../librustc_save_analysis" } -rustc_trans = { path = "../librustc_trans" } +rustc_trans = { path = "../librustc_trans", optional = true } rustc_typeck = { path = "../librustc_typeck" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } + +ar = "0.3.0" + +[features] +llvm = ["rustc_trans"] diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 6f0a50180d7..2a3da956468 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -28,6 +28,9 @@ #![feature(rustc_diagnostic_macros)] #![feature(set_stdio)] +#[cfg(not(feature="llvm"))] +extern crate ar; + extern crate arena; extern crate getopts; extern crate graphviz; @@ -49,6 +52,7 @@ extern crate rustc_metadata; extern crate rustc_mir; extern crate rustc_resolve; extern crate rustc_save_analysis; +#[cfg(feature="llvm")] extern crate rustc_trans; extern crate rustc_typeck; extern crate serialize; @@ -74,6 +78,8 @@ use rustc::session::config::nightly_options; use rustc::session::{early_error, early_warn}; use rustc::lint::Lint; use rustc::lint; +#[cfg(not(feature="llvm"))] +use rustc::middle::cstore::MetadataLoader; use rustc_metadata::locator; use rustc_metadata::cstore::CStore; use rustc::util::common::{time, ErrorReported}; @@ -151,6 +157,45 @@ pub fn run(run_compiler: F) -> isize 0 } +#[cfg(not(feature="llvm"))] +pub struct NoLLvmMetadataLoader; + +#[cfg(not(feature="llvm"))] +pub use NoLLvmMetadataLoader as MetadataLoader; +#[cfg(feature="llvm")] +pub use rustc_trans::LlvmMetadataLoader as MetadataLoader; + +#[cfg(not(feature="llvm"))] +impl MetadataLoader for NoLLvmMetadataLoader { + fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result, String> { + use std::fs::File; + use std::io; + use self::ar::Archive; + + 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() == METADATA_FILENAME { + let mut buf = Vec::new(); + io::copy(&mut entry, &mut buf).unwrap(); + let buf: OwningRef, [u8]> = OwningRef::new(buf).into(); + return Ok(buf.erase_owner()); + } + } + + Err("Couldnt find metadata section".to_string()) + } + + fn get_dylib_metadata(&self, + target: &Target, + filename: &Path) + -> Result, String> { + panic!("Dylib metadata loading not supported without LLVM") + } +} + // Parse args and run the compiler. This is the primary entry point for rustc. // See comments on CompilerCalls below for details about the callbacks argument. // The FileLoader provides a way to load files from sources other than the file system. @@ -197,7 +242,7 @@ pub fn run_compiler<'a>(args: &[String], }; let dep_graph = DepGraph::new(sopts.build_dep_graph()); - let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); + let cstore = Rc::new(CStore::new(&dep_graph, box ::MetadataLoader)); let loader = file_loader.unwrap_or(box RealFileLoader); let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping())); @@ -477,7 +522,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { return None; } let dep_graph = DepGraph::new(sopts.build_dep_graph()); - let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); + let cstore = Rc::new(CStore::new(&dep_graph, box ::MetadataLoader)); let mut sess = build_session(sopts.clone(), &dep_graph, None, diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 8668ab30154..b187cdaa480 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -106,7 +106,7 @@ fn test_env(source_string: &str, let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); - let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); + let cstore = Rc::new(CStore::new(&dep_graph, box ::MetadataLoader)); let sess = session::build_session_(options, &dep_graph, None, diff --git a/src/rustc/Cargo.toml b/src/rustc/Cargo.toml index 4452f4a2f44..d185c061d5b 100644 --- a/src/rustc/Cargo.toml +++ b/src/rustc/Cargo.toml @@ -15,3 +15,4 @@ rustc_driver = { path = "../librustc_driver" } [features] jemalloc = ["rustc_back/jemalloc"] +llvm = ["rustc_driver/llvm"]