Skip to content

Commit 4ef16d7

Browse files
committed
Fix hotplug backend and add test
1 parent ace502a commit 4ef16d7

File tree

4 files changed

+93
-0
lines changed

4 files changed

+93
-0
lines changed

src/librustc_driver/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,14 @@ fn load_backend_from_dylib(sess: &Session, backend_name: &str) -> Box<TransCrate
204204
_lib: DynamicLibrary,
205205
trans: Box<TransCrate>,
206206
}
207+
208+
impl Drop for ExternTransCrate {
209+
fn drop(&mut self) {
210+
// Make sure trans gets dropped before _lib as bad things happen otherwise
211+
self.trans = Box::new(::rustc_trans_utils::trans_crate::DummyTransCrate)
212+
}
213+
}
214+
207215
impl TransCrate for ExternTransCrate {
208216
fn print(&self, req: PrintRequest, sess: &Session) {
209217
self.trans.print(req, sess);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
include ../tools.mk
2+
3+
all:
4+
/bin/echo || exit 0 # This test requires /bin/echo to exist
5+
$(RUSTC) the_backend.rs --crate-name the_backend --crate-type dylib \
6+
-o $(TMPDIR)/the_backend.dylib
7+
sleep 10
8+
$(RUSTC) some_crate.rs --crate-name some_crate --crate-type bin -o $(TMPDIR)/some_crate \
9+
-Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options
10+
grep -x "This has been \"compiled\" succesfully." $(TMPDIR)/some_crate
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
::std::process::exit(1);
3+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#![feature(rustc_private)]
2+
3+
extern crate syntax;
4+
extern crate rustc;
5+
extern crate rustc_trans_utils;
6+
7+
use std::any::Any;
8+
use std::sync::mpsc;
9+
use syntax::symbol::Symbol;
10+
use rustc::session::{Session, CompileIncomplete};
11+
use rustc::session::config::OutputFilenames;
12+
use rustc::ty::TyCtxt;
13+
use rustc::ty::maps::Providers;
14+
use rustc::middle::cstore::MetadataLoader;
15+
use rustc::dep_graph::DepGraph;
16+
use rustc_trans_utils::trans_crate::{TransCrate, MetadataOnlyTransCrate};
17+
18+
struct TheBackend(Box<TransCrate>);
19+
20+
impl TransCrate for TheBackend {
21+
fn metadata_loader(&self) -> Box<MetadataLoader> {
22+
self.0.metadata_loader()
23+
}
24+
25+
fn provide(&self, providers: &mut Providers) {
26+
self.0.provide(providers);
27+
}
28+
29+
fn provide_extern(&self, providers: &mut Providers) {
30+
self.0.provide_extern(providers);
31+
}
32+
33+
fn trans_crate<'a, 'tcx>(
34+
&self,
35+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
36+
_rx: mpsc::Receiver<Box<Any + Send>>
37+
) -> Box<Any> {
38+
use rustc::hir::def_id::LOCAL_CRATE;
39+
40+
Box::new(tcx.crate_name(LOCAL_CRATE) as Symbol)
41+
}
42+
43+
fn join_trans_and_link(
44+
&self,
45+
trans: Box<Any>,
46+
sess: &Session,
47+
_dep_graph: &DepGraph,
48+
outputs: &OutputFilenames,
49+
) -> Result<(), CompileIncomplete> {
50+
use std::io::Write;
51+
use rustc::session::config::CrateType;
52+
use rustc_trans_utils::link::out_filename;
53+
let crate_name = trans.downcast::<Symbol>()
54+
.expect("in join_trans_and_link: trans is not a Symbol");
55+
for &crate_type in sess.opts.crate_types.iter() {
56+
if crate_type != CrateType::CrateTypeExecutable {
57+
sess.fatal(&format!("Crate type is {:?}", crate_type));
58+
}
59+
let output_name =
60+
out_filename(sess, crate_type, &outputs, &*crate_name.as_str());
61+
let mut out_file = ::std::fs::File::create(output_name).unwrap();
62+
write!(out_file, "This has been \"compiled\" succesfully.").unwrap();
63+
}
64+
Ok(())
65+
}
66+
}
67+
68+
/// This is the entrypoint for a hot plugged rustc_trans
69+
#[no_mangle]
70+
pub extern "C" fn __rustc_codegen_backend(sess: &Session) -> Box<TransCrate> {
71+
Box::new(TheBackend(MetadataOnlyTransCrate::new(sess)))
72+
}

0 commit comments

Comments
 (0)