diff --git a/src/Cargo.lock b/src/Cargo.lock index b5db5ce36133f..fff3c9e1f7146 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1564,7 +1564,9 @@ dependencies = [ name = "rustc_trans_utils" version = "0.0.0" dependencies = [ + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", + "rustc_incremental 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 335e1690a2ea0..2e368ddf43f38 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -104,7 +104,11 @@ impl Step for Std { let out_dir = build.cargo_out(compiler, Mode::Libstd, target); build.clear_if_dirty(&out_dir, &builder.rustc(compiler)); - let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build"); + let mut cargo = if compiler.stage == 0 { + builder.cargo(compiler, Mode::Libstd, target, "build") + }else{ + builder.cargo(compiler, Mode::Libstd, target, "check") + }; std_cargo(build, &compiler, target, &mut cargo); run_cargo(build, &mut cargo, @@ -161,6 +165,7 @@ pub fn std_cargo(build: &Build, // missing // We also only build the runtimes when --enable-sanitizers (or its // config.toml equivalent) is used + //cargo.env("RUST_FLAGS", "-Zno-trans"); cargo.env("LLVM_CONFIG", build.llvm_config(target)); } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 163c698e3ff31..53c4c1f6f299f 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -74,6 +74,8 @@ pub fn compile_input(sess: &Session, addl_plugins: Option>, control: &CompileController) -> CompileResult { use rustc_trans::back::write::OngoingCrateTranslation; + use rustc::session::config::CrateType; + macro_rules! controller_entry_point { ($point: ident, $tsess: expr, $make_state: expr, $phase_result: expr) => {{ let state = &mut $make_state; @@ -91,7 +93,6 @@ pub fn compile_input(sess: &Session, } if cfg!(not(feature="llvm")) { - use rustc::session::config::CrateType; 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") } @@ -234,6 +235,26 @@ pub fn compile_input(sess: &Session, tcx.print_debug_stats(); } + #[cfg(not(feature="llvm"))] + { + use ar::{Builder, Header}; + use std::fs::File; + use std::io::Cursor; + if sess.opts.crate_types == vec![CrateType::CrateTypeRlib] { + let cstore = &tcx.sess.cstore; + let link_meta = + ::rustc_trans_utils::link::build_link_meta(&incremental_hashes_map); + let exported_symbols = + ::rustc_trans_utils::find_exported_symbols(tcx, &analysis.reachable); + let (metadata, _hashes) = + cstore.encode_metadata(tcx, &link_meta, &exported_symbols); + let mut builder = Builder::new(File::create("abc.rlib").unwrap()); + builder + .append(&Header::new("rust.metadata.bin".to_string(), metadata.raw_data.len() as u64), Cursor::new(metadata.raw_data)) + .unwrap(); + } + } + let trans = phase_4_translate_to_llvm(tcx, analysis, incremental_hashes_map, &outputs); diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index d7b5d4a6fe3ba..b0abc3b8dc732 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -28,6 +28,8 @@ #![feature(rustc_diagnostic_macros)] #![feature(set_stdio)] +#[cfg(not(feature="llvm"))] +extern crate ar; extern crate arena; extern crate getopts; extern crate graphviz; @@ -159,7 +161,6 @@ pub use rustc_trans::LlvmMetadataLoader as MetadataLoader; #[cfg(not(feature="llvm"))] mod no_llvm_metadata_loader { - extern crate ar; extern crate owning_ref; use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait; @@ -168,7 +169,7 @@ mod no_llvm_metadata_loader { use std::fs::File; use std::path::Path; - use self::ar::Archive; + use ar::Archive; use self::owning_ref::{OwningRef, ErasedBoxRef}; pub struct NoLLvmMetadataLoader; diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 4e211d83cff3e..6ba3d558fe41d 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -89,16 +89,8 @@ pub const RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: usize = RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET + 8; pub use self::rustc_trans_utils::link::{find_crate_name, filename_for_input, - default_output_for_target, invalid_output_for_target}; - -pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMeta { - let krate_dep_node = &DepNode::new_no_params(DepKind::Krate); - let r = LinkMeta { - crate_hash: Svh::new(incremental_hashes_map[krate_dep_node].to_smaller_hash()), - }; - info!("{:?}", r); - return r; -} + default_output_for_target, invalid_output_for_target, + build_link_meta}; // The third parameter is for env vars, used on windows to set up the // path for MSVC to find its DLLs, and gcc to find its bundled diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index e4b090471d75a..2183e5270eefd 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -878,56 +878,6 @@ fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter { } } -/// The context provided lists a set of reachable ids as calculated by -/// middle::reachable, but this contains far more ids and symbols than we're -/// actually exposing from the object file. This function will filter the set in -/// the context to the set of ids which correspond to symbols that are exposed -/// from the object file being generated. -/// -/// This list is later used by linkers to determine the set of symbols needed to -/// be exposed from a dynamic library and it's also encoded into the metadata. -pub fn find_exported_symbols(tcx: TyCtxt, reachable: &NodeSet) -> NodeSet { - reachable.iter().cloned().filter(|&id| { - // Next, we want to ignore some FFI functions that are not exposed from - // this crate. Reachable FFI functions can be lumped into two - // categories: - // - // 1. Those that are included statically via a static library - // 2. Those included otherwise (e.g. dynamically or via a framework) - // - // Although our LLVM module is not literally emitting code for the - // statically included symbols, it's an export of our library which - // needs to be passed on to the linker and encoded in the metadata. - // - // As a result, if this id is an FFI item (foreign item) then we only - // let it through if it's included statically. - match tcx.hir.get(id) { - hir_map::NodeForeignItem(..) => { - let def_id = tcx.hir.local_def_id(id); - tcx.sess.cstore.is_statically_included_foreign_item(def_id) - } - - // Only consider nodes that actually have exported symbols. - hir_map::NodeItem(&hir::Item { - node: hir::ItemStatic(..), .. }) | - hir_map::NodeItem(&hir::Item { - node: hir::ItemFn(..), .. }) | - hir_map::NodeImplItem(&hir::ImplItem { - node: hir::ImplItemKind::Method(..), .. }) => { - let def_id = tcx.hir.local_def_id(id); - let generics = tcx.generics_of(def_id); - let attributes = tcx.get_attrs(def_id); - (generics.parent_types == 0 && generics.types.is_empty()) && - // Functions marked with #[inline] are only ever translated - // with "internal" linkage and are never exported. - !attr::requests_inline(&attributes) - } - - _ => false - } - }).collect() -} - pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, analysis: ty::CrateAnalysis, incremental_hashes_map: IncrementalHashesMap, diff --git a/src/librustc_trans_utils/Cargo.toml b/src/librustc_trans_utils/Cargo.toml index f026d4fcbc280..b91a397711140 100644 --- a/src/librustc_trans_utils/Cargo.toml +++ b/src/librustc_trans_utils/Cargo.toml @@ -10,6 +10,8 @@ crate-type = ["dylib"] test = false [dependencies] +log = "0.3" rustc = { path = "../librustc" } +rustc_incremental = { path = "../librustc_incremental" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 81e83076f8c0c..39cda03369f13 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -31,8 +31,68 @@ #![feature(slice_patterns)] #![feature(conservative_impl_trait)] +#[macro_use] +extern crate log; extern crate rustc; +extern crate rustc_incremental; extern crate syntax; extern crate syntax_pos; +use rustc::ty::TyCtxt; +use rustc::hir; +use rustc::hir::map as hir_map; +use rustc::util::nodemap::NodeSet; + +use syntax::attr; + pub mod link; + +/// The context provided lists a set of reachable ids as calculated by +/// middle::reachable, but this contains far more ids and symbols than we're +/// actually exposing from the object file. This function will filter the set in +/// the context to the set of ids which correspond to symbols that are exposed +/// from the object file being generated. +/// +/// This list is later used by linkers to determine the set of symbols needed to +/// be exposed from a dynamic library and it's also encoded into the metadata. +pub fn find_exported_symbols(tcx: TyCtxt, reachable: &NodeSet) -> NodeSet { + reachable.iter().cloned().filter(|&id| { + // Next, we want to ignore some FFI functions that are not exposed from + // this crate. Reachable FFI functions can be lumped into two + // categories: + // + // 1. Those that are included statically via a static library + // 2. Those included otherwise (e.g. dynamically or via a framework) + // + // Although our LLVM module is not literally emitting code for the + // statically included symbols, it's an export of our library which + // needs to be passed on to the linker and encoded in the metadata. + // + // As a result, if this id is an FFI item (foreign item) then we only + // let it through if it's included statically. + match tcx.hir.get(id) { + hir_map::NodeForeignItem(..) => { + let def_id = tcx.hir.local_def_id(id); + tcx.sess.cstore.is_statically_included_foreign_item(def_id) + } + + // Only consider nodes that actually have exported symbols. + hir_map::NodeItem(&hir::Item { + node: hir::ItemStatic(..), .. }) | + hir_map::NodeItem(&hir::Item { + node: hir::ItemFn(..), .. }) | + hir_map::NodeImplItem(&hir::ImplItem { + node: hir::ImplItemKind::Method(..), .. }) => { + let def_id = tcx.hir.local_def_id(id); + let generics = tcx.generics_of(def_id); + let attributes = tcx.get_attrs(def_id); + (generics.parent_types == 0 && generics.types.is_empty()) && + // Functions marked with #[inline] are only ever translated + // with "internal" linkage and are never exported. + !attr::requests_inline(&attributes) + } + + _ => false + } + }).collect() +} \ No newline at end of file diff --git a/src/librustc_trans_utils/link.rs b/src/librustc_trans_utils/link.rs index aa8637fabe85f..36c3ddc178beb 100644 --- a/src/librustc_trans_utils/link.rs +++ b/src/librustc_trans_utils/link.rs @@ -10,11 +10,23 @@ use rustc::session::config::{self, OutputFilenames, Input, OutputType}; use rustc::session::Session; -use rustc::middle::cstore; +use rustc::middle::cstore::{self, LinkMeta}; +use rustc::dep_graph::{DepKind, DepNode}; +use rustc::hir::svh::Svh; +use rustc_incremental::IncrementalHashesMap; use std::path::PathBuf; use syntax::ast; use syntax_pos::Span; +pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMeta { + let krate_dep_node = &DepNode::new_no_params(DepKind::Krate); + let r = LinkMeta { + crate_hash: Svh::new(incremental_hashes_map[krate_dep_node].to_smaller_hash()), + }; + info!("{:?}", r); + return r; +} + pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input: &Input) -> String {