1 // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! The Rust compiler.
15 //! This API is completely unstable and subject to change.
17 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
18 html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
19 html_root_url = "https://doc.rust-lang.org/nightly/")]
22 #![feature(box_syntax)]
25 use std::io::{self, Write};
28 use std::sync::{mpsc, Arc};
30 use rustc_data_structures::owning_ref::OwningRef;
31 use flate2::Compression;
32 use flate2::write::DeflateEncoder;
34 use syntax::symbol::Symbol;
35 use rustc::hir::def_id::LOCAL_CRATE;
36 use rustc::session::{Session, CompileIncomplete};
37 use rustc::session::config::{CrateType, OutputFilenames, PrintRequest};
38 use rustc::ty::TyCtxt;
39 use rustc::ty::query::Providers;
40 use rustc::middle::cstore::EncodedMetadata;
41 use rustc::middle::cstore::MetadataLoader;
42 use rustc::dep_graph::DepGraph;
43 use rustc_target::spec::Target;
44 use rustc_mir::monomorphize::collector;
45 use link::out_filename;
47 pub use rustc_data_structures::sync::MetadataRef;
49 pub trait CodegenBackend {
50 fn init(&self, _sess: &Session) {}
51 fn print(&self, _req: PrintRequest, _sess: &Session) {}
52 fn target_features(&self, _sess: &Session) -> Vec<Symbol> { vec![] }
53 fn print_passes(&self) {}
54 fn print_version(&self) {}
55 fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] }
57 fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync>;
58 fn provide(&self, _providers: &mut Providers);
59 fn provide_extern(&self, _providers: &mut Providers);
60 fn codegen_crate<'a, 'tcx>(
62 tcx: TyCtxt<'a, 'tcx, 'tcx>,
63 rx: mpsc::Receiver<Box<dyn Any + Send>>
66 /// This is called on the returned `Box<dyn Any>` from `codegen_backend`
70 /// Panics when the passed `Box<dyn Any>` was not returned by `codegen_backend`.
71 fn join_codegen_and_link(
73 ongoing_codegen: Box<dyn Any>,
76 outputs: &OutputFilenames,
77 ) -> Result<(), CompileIncomplete>;
80 pub struct NoLlvmMetadataLoader;
82 impl MetadataLoader for NoLlvmMetadataLoader {
83 fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
84 let mut file = File::open(filename)
85 .map_err(|e| format!("metadata file open err: {:?}", e))?;
87 let mut buf = Vec::new();
88 io::copy(&mut file, &mut buf).unwrap();
89 let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
90 return Ok(rustc_erase_owner!(buf.map_owner_box()));
93 fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String> {
94 self.get_rlib_metadata(target, filename)
98 pub struct MetadataOnlyCodegenBackend(());
99 pub struct OngoingCodegen {
100 metadata: EncodedMetadata,
101 metadata_version: Vec<u8>,
105 impl MetadataOnlyCodegenBackend {
106 pub fn new() -> Box<dyn CodegenBackend> {
107 box MetadataOnlyCodegenBackend(())
111 impl CodegenBackend for MetadataOnlyCodegenBackend {
112 fn init(&self, sess: &Session) {
113 for cty in sess.opts.crate_types.iter() {
115 CrateType::Rlib | CrateType::Dylib | CrateType::Executable => {},
117 sess.diagnostic().warn(
118 &format!("LLVM unsupported, so output type {} is not supported", cty)
125 fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
126 box NoLlvmMetadataLoader
129 fn provide(&self, providers: &mut Providers) {
130 ::symbol_names::provide(providers);
132 providers.target_features_whitelist = |_tcx, _cnum| {
133 Default::default() // Just a dummy
135 providers.is_reachable_non_generic = |_tcx, _defid| true;
136 providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());
138 fn provide_extern(&self, providers: &mut Providers) {
139 providers.is_reachable_non_generic = |_tcx, _defid| true;
142 fn codegen_crate<'a, 'tcx>(
144 tcx: TyCtxt<'a, 'tcx, 'tcx>,
145 _rx: mpsc::Receiver<Box<dyn Any + Send>>
147 use rustc_mir::monomorphize::item::MonoItem;
149 ::check_for_rustc_errors_attr(tcx);
150 ::symbol_names_test::report_symbol_names(tcx);
151 ::rustc_incremental::assert_dep_graph(tcx);
152 ::rustc_incremental::assert_module_sources::assert_module_sources(tcx);
153 ::rustc_mir::monomorphize::assert_symbols_are_distinct(tcx,
154 collector::collect_crate_mono_items(
156 collector::MonoItemCollectionMode::Eager
160 // ::rustc::middle::dependency_format::calculate(tcx);
161 let _ = tcx.link_args(LOCAL_CRATE);
162 let _ = tcx.native_libraries(LOCAL_CRATE);
164 collector::collect_crate_mono_items(
166 collector::MonoItemCollectionMode::Eager
169 MonoItem::Fn(inst) => {
170 let def_id = inst.def_id();
171 if def_id.is_local() {
172 let _ = inst.def.is_inline(tcx);
173 let _ = tcx.codegen_fn_attrs(def_id);
179 tcx.sess.abort_if_errors();
181 let metadata = tcx.encode_metadata();
185 metadata_version: tcx.metadata_encoding_version().to_vec(),
186 crate_name: tcx.crate_name(LOCAL_CRATE),
190 fn join_codegen_and_link(
192 ongoing_codegen: Box<dyn Any>,
194 _dep_graph: &DepGraph,
195 outputs: &OutputFilenames,
196 ) -> Result<(), CompileIncomplete> {
197 let ongoing_codegen = ongoing_codegen.downcast::<OngoingCodegen>()
198 .expect("Expected MetadataOnlyCodegenBackend's OngoingCodegen, found Box<dyn Any>");
199 for &crate_type in sess.opts.crate_types.iter() {
200 if crate_type != CrateType::Rlib &&
201 crate_type != CrateType::Dylib {
205 out_filename(sess, crate_type, &outputs, &ongoing_codegen.crate_name.as_str());
206 let mut compressed = ongoing_codegen.metadata_version.clone();
207 let metadata = if crate_type == CrateType::Dylib {
208 DeflateEncoder::new(&mut compressed, Compression::fast())
209 .write_all(&ongoing_codegen.metadata.raw_data)
213 &ongoing_codegen.metadata.raw_data
215 let mut file = File::create(&output_name).unwrap();
216 file.write_all(metadata).unwrap();
219 sess.abort_if_errors();
220 if !sess.opts.crate_types.contains(&CrateType::Rlib)
221 && !sess.opts.crate_types.contains(&CrateType::Dylib)
223 sess.fatal("Executables are not supported by the metadata-only backend.");