diff --git a/.gitignore b/.gitignore index b54bab177d0..309fbd95345 100644 --- a/.gitignore +++ b/.gitignore @@ -103,3 +103,6 @@ version.texi .cargo !src/vendor/** /src/target/ + +no_llvm_build + diff --git a/src/Cargo.lock b/src/Cargo.lock index 807375e00af..94810329854 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1778,7 +1778,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 335e1690a2e..2e368ddf43f 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 ce4ab2c8a1d..1520fc7def8 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -77,6 +77,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; @@ -94,7 +96,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") } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 044f4a5eaf5..2e0193fc8a1 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -25,6 +25,8 @@ #![feature(rustc_diagnostic_macros)] #![feature(set_stdio)] +#[cfg(not(feature="llvm"))] +extern crate ar; extern crate arena; extern crate getopts; extern crate graphviz; @@ -157,7 +159,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; @@ -166,7 +167,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 9d13d4ce15b..e6ab46fa931 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -89,15 +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(crate_hash: Fingerprint) -> LinkMeta { - let r = LinkMeta { - crate_hash: Svh::new(crate_hash.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 bfa18d84d27..91852630fa4 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -938,6 +938,8 @@ pub fn find_exported_symbols(tcx: TyCtxt) -> NodeSet { pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver>) -> OngoingCrateTranslation { + use back::link::rustc_trans_utils::find_exported_symbols; + check_for_rustc_errors_attr(tcx); diff --git a/src/librustc_trans_utils/Cargo.toml b/src/librustc_trans_utils/Cargo.toml index f026d4fcbc2..b91a3977111 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 5e8abe59ad9..44f0f62d708 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -29,8 +29,68 @@ #![cfg_attr(stage0, feature(const_fn))] +#[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() +} diff --git a/src/librustc_trans_utils/link.rs b/src/librustc_trans_utils/link.rs index aa8637fabe8..36c3ddc178b 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 {