From 4ef16d7466cca262c682fb3a9441a88a61a089df Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 4 Jan 2018 18:15:40 +0100 Subject: [PATCH] Fix hotplug backend and add test --- src/librustc_driver/lib.rs | 8 +++ .../run-make/hotplug_codegen_backend/Makefile | 10 +++ .../hotplug_codegen_backend/some_crate.rs | 3 + .../hotplug_codegen_backend/the_backend.rs | 72 +++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 src/test/run-make/hotplug_codegen_backend/Makefile create mode 100644 src/test/run-make/hotplug_codegen_backend/some_crate.rs create mode 100644 src/test/run-make/hotplug_codegen_backend/the_backend.rs diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 14d14ab591e3..e9535ba63964 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -204,6 +204,14 @@ fn load_backend_from_dylib(sess: &Session, backend_name: &str) -> Box, } + + impl Drop for ExternTransCrate { + fn drop(&mut self) { + // Make sure trans gets dropped before _lib as bad things happen otherwise + self.trans = Box::new(::rustc_trans_utils::trans_crate::DummyTransCrate) + } + } + impl TransCrate for ExternTransCrate { fn print(&self, req: PrintRequest, sess: &Session) { self.trans.print(req, sess); diff --git a/src/test/run-make/hotplug_codegen_backend/Makefile b/src/test/run-make/hotplug_codegen_backend/Makefile new file mode 100644 index 000000000000..1916983a9e79 --- /dev/null +++ b/src/test/run-make/hotplug_codegen_backend/Makefile @@ -0,0 +1,10 @@ +include ../tools.mk + +all: + /bin/echo || exit 0 # This test requires /bin/echo to exist + $(RUSTC) the_backend.rs --crate-name the_backend --crate-type dylib \ + -o $(TMPDIR)/the_backend.dylib + sleep 10 + $(RUSTC) some_crate.rs --crate-name some_crate --crate-type bin -o $(TMPDIR)/some_crate \ + -Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options + grep -x "This has been \"compiled\" succesfully." $(TMPDIR)/some_crate diff --git a/src/test/run-make/hotplug_codegen_backend/some_crate.rs b/src/test/run-make/hotplug_codegen_backend/some_crate.rs new file mode 100644 index 000000000000..7d01978dcee9 --- /dev/null +++ b/src/test/run-make/hotplug_codegen_backend/some_crate.rs @@ -0,0 +1,3 @@ +fn main() { + ::std::process::exit(1); +} diff --git a/src/test/run-make/hotplug_codegen_backend/the_backend.rs b/src/test/run-make/hotplug_codegen_backend/the_backend.rs new file mode 100644 index 000000000000..8200658b1f1c --- /dev/null +++ b/src/test/run-make/hotplug_codegen_backend/the_backend.rs @@ -0,0 +1,72 @@ +#![feature(rustc_private)] + +extern crate syntax; +extern crate rustc; +extern crate rustc_trans_utils; + +use std::any::Any; +use std::sync::mpsc; +use syntax::symbol::Symbol; +use rustc::session::{Session, CompileIncomplete}; +use rustc::session::config::OutputFilenames; +use rustc::ty::TyCtxt; +use rustc::ty::maps::Providers; +use rustc::middle::cstore::MetadataLoader; +use rustc::dep_graph::DepGraph; +use rustc_trans_utils::trans_crate::{TransCrate, MetadataOnlyTransCrate}; + +struct TheBackend(Box); + +impl TransCrate for TheBackend { + fn metadata_loader(&self) -> Box { + self.0.metadata_loader() + } + + fn provide(&self, providers: &mut Providers) { + self.0.provide(providers); + } + + fn provide_extern(&self, providers: &mut Providers) { + self.0.provide_extern(providers); + } + + fn trans_crate<'a, 'tcx>( + &self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + _rx: mpsc::Receiver> + ) -> Box { + use rustc::hir::def_id::LOCAL_CRATE; + + Box::new(tcx.crate_name(LOCAL_CRATE) as Symbol) + } + + fn join_trans_and_link( + &self, + trans: Box, + sess: &Session, + _dep_graph: &DepGraph, + outputs: &OutputFilenames, + ) -> Result<(), CompileIncomplete> { + use std::io::Write; + use rustc::session::config::CrateType; + use rustc_trans_utils::link::out_filename; + let crate_name = trans.downcast::() + .expect("in join_trans_and_link: trans is not a Symbol"); + for &crate_type in sess.opts.crate_types.iter() { + if crate_type != CrateType::CrateTypeExecutable { + sess.fatal(&format!("Crate type is {:?}", crate_type)); + } + let output_name = + out_filename(sess, crate_type, &outputs, &*crate_name.as_str()); + let mut out_file = ::std::fs::File::create(output_name).unwrap(); + write!(out_file, "This has been \"compiled\" succesfully.").unwrap(); + } + Ok(()) + } +} + +/// This is the entrypoint for a hot plugged rustc_trans +#[no_mangle] +pub extern "C" fn __rustc_codegen_backend(sess: &Session) -> Box { + Box::new(TheBackend(MetadataOnlyTransCrate::new(sess))) +}