Allow writing metadata without llvm

This commit is contained in:
bjorn3 2017-08-13 18:53:50 +02:00
parent a6a7dac5cf
commit cba53f0be5
10 changed files with 95 additions and 14 deletions

View file

@ -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" }

View file

@ -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()
}

View file

@ -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 {