Skip to content

Commit dd253c1

Browse files
committed
Allow writing metadata without llvm
1 parent a4d1149 commit dd253c1

File tree

9 files changed

+110
-65
lines changed

9 files changed

+110
-65
lines changed

src/Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bootstrap/compile.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,11 @@ impl Step for Std {
104104

105105
let out_dir = build.cargo_out(compiler, Mode::Libstd, target);
106106
build.clear_if_dirty(&out_dir, &builder.rustc(compiler));
107-
let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build");
107+
let mut cargo = if compiler.stage == 0 {
108+
builder.cargo(compiler, Mode::Libstd, target, "build")
109+
}else{
110+
builder.cargo(compiler, Mode::Libstd, target, "check")
111+
};
108112
std_cargo(build, &compiler, target, &mut cargo);
109113
run_cargo(build,
110114
&mut cargo,
@@ -161,6 +165,7 @@ pub fn std_cargo(build: &Build,
161165
// missing
162166
// We also only build the runtimes when --enable-sanitizers (or its
163167
// config.toml equivalent) is used
168+
//cargo.env("RUST_FLAGS", "-Zno-trans");
164169
cargo.env("LLVM_CONFIG", build.llvm_config(target));
165170
}
166171

src/librustc_driver/driver.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ pub fn compile_input(sess: &Session,
7474
addl_plugins: Option<Vec<String>>,
7575
control: &CompileController) -> CompileResult {
7676
use rustc_trans::back::write::OngoingCrateTranslation;
77+
use rustc::session::config::CrateType;
78+
7779
macro_rules! controller_entry_point {
7880
($point: ident, $tsess: expr, $make_state: expr, $phase_result: expr) => {{
7981
let state = &mut $make_state;
@@ -91,7 +93,6 @@ pub fn compile_input(sess: &Session,
9193
}
9294

9395
if cfg!(not(feature="llvm")) {
94-
use rustc::session::config::CrateType;
9596
if !sess.opts.debugging_opts.no_trans && sess.opts.output_types.should_trans() {
9697
sess.err("LLVM is not supported by this rustc. Please use -Z no-trans to compile")
9798
}
@@ -234,6 +235,26 @@ pub fn compile_input(sess: &Session,
234235
tcx.print_debug_stats();
235236
}
236237

238+
#[cfg(not(feature="llvm"))]
239+
{
240+
use ar::{Builder, Header};
241+
use std::fs::File;
242+
use std::io::Cursor;
243+
if sess.opts.crate_types == vec![CrateType::CrateTypeRlib] {
244+
let cstore = &tcx.sess.cstore;
245+
let link_meta =
246+
::rustc_trans_utils::link::build_link_meta(&incremental_hashes_map);
247+
let exported_symbols =
248+
::rustc_trans_utils::find_exported_symbols(tcx, &analysis.reachable);
249+
let (metadata, _hashes) =
250+
cstore.encode_metadata(tcx, &link_meta, &exported_symbols);
251+
let mut builder = Builder::new(File::create("abc.rlib").unwrap());
252+
builder
253+
.append(&Header::new("rust.metadata.bin".to_string(), metadata.raw_data.len() as u64), Cursor::new(metadata.raw_data))
254+
.unwrap();
255+
}
256+
}
257+
237258
let trans = phase_4_translate_to_llvm(tcx, analysis, incremental_hashes_map,
238259
&outputs);
239260

src/librustc_driver/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#![feature(rustc_diagnostic_macros)]
2929
#![feature(set_stdio)]
3030

31+
#[cfg(not(feature="llvm"))]
32+
extern crate ar;
3133
extern crate arena;
3234
extern crate getopts;
3335
extern crate graphviz;
@@ -159,7 +161,6 @@ pub use rustc_trans::LlvmMetadataLoader as MetadataLoader;
159161

160162
#[cfg(not(feature="llvm"))]
161163
mod no_llvm_metadata_loader {
162-
extern crate ar;
163164
extern crate owning_ref;
164165

165166
use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait;
@@ -168,7 +169,7 @@ mod no_llvm_metadata_loader {
168169
use std::fs::File;
169170
use std::path::Path;
170171

171-
use self::ar::Archive;
172+
use ar::Archive;
172173
use self::owning_ref::{OwningRef, ErasedBoxRef};
173174

174175
pub struct NoLLvmMetadataLoader;

src/librustc_trans/back/link.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,8 @@ pub const RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: usize =
8989
RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET + 8;
9090

9191
pub use self::rustc_trans_utils::link::{find_crate_name, filename_for_input,
92-
default_output_for_target, invalid_output_for_target};
93-
94-
pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMeta {
95-
let krate_dep_node = &DepNode::new_no_params(DepKind::Krate);
96-
let r = LinkMeta {
97-
crate_hash: Svh::new(incremental_hashes_map[krate_dep_node].to_smaller_hash()),
98-
};
99-
info!("{:?}", r);
100-
return r;
101-
}
92+
default_output_for_target, invalid_output_for_target,
93+
build_link_meta};
10294

10395
// The third parameter is for env vars, used on windows to set up the
10496
// path for MSVC to find its DLLs, and gcc to find its bundled

src/librustc_trans/base.rs

-50
Original file line numberDiff line numberDiff line change
@@ -878,56 +878,6 @@ fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter {
878878
}
879879
}
880880

881-
/// The context provided lists a set of reachable ids as calculated by
882-
/// middle::reachable, but this contains far more ids and symbols than we're
883-
/// actually exposing from the object file. This function will filter the set in
884-
/// the context to the set of ids which correspond to symbols that are exposed
885-
/// from the object file being generated.
886-
///
887-
/// This list is later used by linkers to determine the set of symbols needed to
888-
/// be exposed from a dynamic library and it's also encoded into the metadata.
889-
pub fn find_exported_symbols(tcx: TyCtxt, reachable: &NodeSet) -> NodeSet {
890-
reachable.iter().cloned().filter(|&id| {
891-
// Next, we want to ignore some FFI functions that are not exposed from
892-
// this crate. Reachable FFI functions can be lumped into two
893-
// categories:
894-
//
895-
// 1. Those that are included statically via a static library
896-
// 2. Those included otherwise (e.g. dynamically or via a framework)
897-
//
898-
// Although our LLVM module is not literally emitting code for the
899-
// statically included symbols, it's an export of our library which
900-
// needs to be passed on to the linker and encoded in the metadata.
901-
//
902-
// As a result, if this id is an FFI item (foreign item) then we only
903-
// let it through if it's included statically.
904-
match tcx.hir.get(id) {
905-
hir_map::NodeForeignItem(..) => {
906-
let def_id = tcx.hir.local_def_id(id);
907-
tcx.sess.cstore.is_statically_included_foreign_item(def_id)
908-
}
909-
910-
// Only consider nodes that actually have exported symbols.
911-
hir_map::NodeItem(&hir::Item {
912-
node: hir::ItemStatic(..), .. }) |
913-
hir_map::NodeItem(&hir::Item {
914-
node: hir::ItemFn(..), .. }) |
915-
hir_map::NodeImplItem(&hir::ImplItem {
916-
node: hir::ImplItemKind::Method(..), .. }) => {
917-
let def_id = tcx.hir.local_def_id(id);
918-
let generics = tcx.generics_of(def_id);
919-
let attributes = tcx.get_attrs(def_id);
920-
(generics.parent_types == 0 && generics.types.is_empty()) &&
921-
// Functions marked with #[inline] are only ever translated
922-
// with "internal" linkage and are never exported.
923-
!attr::requests_inline(&attributes)
924-
}
925-
926-
_ => false
927-
}
928-
}).collect()
929-
}
930-
931881
pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
932882
analysis: ty::CrateAnalysis,
933883
incremental_hashes_map: IncrementalHashesMap,

src/librustc_trans_utils/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ crate-type = ["dylib"]
1010
test = false
1111

1212
[dependencies]
13+
log = "0.3"
1314
rustc = { path = "../librustc" }
15+
rustc_incremental = { path = "../librustc_incremental" }
1416
syntax = { path = "../libsyntax" }
1517
syntax_pos = { path = "../libsyntax_pos" }

src/librustc_trans_utils/lib.rs

+60
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,68 @@
3131
#![feature(slice_patterns)]
3232
#![feature(conservative_impl_trait)]
3333

34+
#[macro_use]
35+
extern crate log;
3436
extern crate rustc;
37+
extern crate rustc_incremental;
3538
extern crate syntax;
3639
extern crate syntax_pos;
3740

41+
use rustc::ty::TyCtxt;
42+
use rustc::hir;
43+
use rustc::hir::map as hir_map;
44+
use rustc::util::nodemap::NodeSet;
45+
46+
use syntax::attr;
47+
3848
pub mod link;
49+
50+
/// The context provided lists a set of reachable ids as calculated by
51+
/// middle::reachable, but this contains far more ids and symbols than we're
52+
/// actually exposing from the object file. This function will filter the set in
53+
/// the context to the set of ids which correspond to symbols that are exposed
54+
/// from the object file being generated.
55+
///
56+
/// This list is later used by linkers to determine the set of symbols needed to
57+
/// be exposed from a dynamic library and it's also encoded into the metadata.
58+
pub fn find_exported_symbols(tcx: TyCtxt, reachable: &NodeSet) -> NodeSet {
59+
reachable.iter().cloned().filter(|&id| {
60+
// Next, we want to ignore some FFI functions that are not exposed from
61+
// this crate. Reachable FFI functions can be lumped into two
62+
// categories:
63+
//
64+
// 1. Those that are included statically via a static library
65+
// 2. Those included otherwise (e.g. dynamically or via a framework)
66+
//
67+
// Although our LLVM module is not literally emitting code for the
68+
// statically included symbols, it's an export of our library which
69+
// needs to be passed on to the linker and encoded in the metadata.
70+
//
71+
// As a result, if this id is an FFI item (foreign item) then we only
72+
// let it through if it's included statically.
73+
match tcx.hir.get(id) {
74+
hir_map::NodeForeignItem(..) => {
75+
let def_id = tcx.hir.local_def_id(id);
76+
tcx.sess.cstore.is_statically_included_foreign_item(def_id)
77+
}
78+
79+
// Only consider nodes that actually have exported symbols.
80+
hir_map::NodeItem(&hir::Item {
81+
node: hir::ItemStatic(..), .. }) |
82+
hir_map::NodeItem(&hir::Item {
83+
node: hir::ItemFn(..), .. }) |
84+
hir_map::NodeImplItem(&hir::ImplItem {
85+
node: hir::ImplItemKind::Method(..), .. }) => {
86+
let def_id = tcx.hir.local_def_id(id);
87+
let generics = tcx.generics_of(def_id);
88+
let attributes = tcx.get_attrs(def_id);
89+
(generics.parent_types == 0 && generics.types.is_empty()) &&
90+
// Functions marked with #[inline] are only ever translated
91+
// with "internal" linkage and are never exported.
92+
!attr::requests_inline(&attributes)
93+
}
94+
95+
_ => false
96+
}
97+
}).collect()
98+
}

src/librustc_trans_utils/link.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,23 @@
1010

1111
use rustc::session::config::{self, OutputFilenames, Input, OutputType};
1212
use rustc::session::Session;
13-
use rustc::middle::cstore;
13+
use rustc::middle::cstore::{self, LinkMeta};
14+
use rustc::dep_graph::{DepKind, DepNode};
15+
use rustc::hir::svh::Svh;
16+
use rustc_incremental::IncrementalHashesMap;
1417
use std::path::PathBuf;
1518
use syntax::ast;
1619
use syntax_pos::Span;
1720

21+
pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMeta {
22+
let krate_dep_node = &DepNode::new_no_params(DepKind::Krate);
23+
let r = LinkMeta {
24+
crate_hash: Svh::new(incremental_hashes_map[krate_dep_node].to_smaller_hash()),
25+
};
26+
info!("{:?}", r);
27+
return r;
28+
}
29+
1830
pub fn find_crate_name(sess: Option<&Session>,
1931
attrs: &[ast::Attribute],
2032
input: &Input) -> String {

0 commit comments

Comments
 (0)