]> git.lizzy.rs Git - rust.git/commitdiff
Make -Z gen-crate-map usable for I/O
authorAlex Crichton <alex@alexcrichton.com>
Tue, 12 Nov 2013 09:29:09 +0000 (01:29 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Sat, 30 Nov 2013 02:36:14 +0000 (18:36 -0800)
In #10422, I didn't actually test to make sure that the '-Z gen-crate-map'
option was usable before I implemented it. The crate map was indeed generated
when '-Z gen-crate-map' was specified, but the I/O factory slot was empty
because of an extra check in trans about filling in that location.

This commit both fixes that location, and checks in a "fancy test" which does
lots of fun stuff. The test will use the rustc library to compile a rust crate,
and then compile a C program to link against that crate and run the C program.
To my knowledge this is the first test of its kind, so it's a little ad-hoc, but
it seems to get the job done. We could perhaps generalize running tests like
this, but for now I think it's fine to have this sort of functionality tucked
away in a test.

src/librustc/middle/trans/base.rs
src/test/run-make/bootstrap-from-c-with-uvio/Makefile [new file with mode: 0644]
src/test/run-make/bootstrap-from-c-with-uvio/lib.rs [new file with mode: 0644]
src/test/run-make/bootstrap-from-c-with-uvio/main.c [new file with mode: 0644]

index f14fc265b82b0d979369c8555fb813ff2010615b..deb4f00d7a02fb425249a1f658d0d43408545ac0 100644 (file)
@@ -77,7 +77,7 @@
 use extra::sort;
 use syntax::ast::Name;
 use syntax::ast_map::{path, path_elt_to_str, path_name, path_pretty_name};
-use syntax::ast_util::{local_def};
+use syntax::ast_util::{local_def, is_local};
 use syntax::attr;
 use syntax::codemap::Span;
 use syntax::parse::token;
@@ -2996,7 +2996,7 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
     return map;
 }
 
-pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) {
+pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
     let mut subcrates: ~[ValueRef] = ~[];
     let mut i = 1;
     let cstore = ccx.sess.cstore;
@@ -3014,19 +3014,20 @@ pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) {
         subcrates.push(p2i(ccx, cr));
         i += 1;
     }
-    let event_loop_factory = if !*ccx.sess.building_library {
-        match ccx.tcx.lang_items.event_loop_factory() {
-            Some(did) => unsafe {
+    let event_loop_factory = match ccx.tcx.lang_items.event_loop_factory() {
+        Some(did) => unsafe {
+            if is_local(did) {
+                llvm::LLVMConstPointerCast(get_item_val(ccx, did.node),
+                                           ccx.int_type.ptr_to().to_ref())
+            } else {
                 let name = csearch::get_symbol(ccx.sess.cstore, did);
                 let global = name.with_c_str(|buf| {
                     llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
                 });
                 global
-            },
-            None => C_null(ccx.int_type.ptr_to())
-        }
-    } else {
-        C_null(ccx.int_type.ptr_to())
+            }
+        },
+        None => C_null(ccx.int_type.ptr_to())
     };
     unsafe {
         let maptype = Type::array(&ccx.int_type, subcrates.len() as u64);
diff --git a/src/test/run-make/bootstrap-from-c-with-uvio/Makefile b/src/test/run-make/bootstrap-from-c-with-uvio/Makefile
new file mode 100644 (file)
index 0000000..7f46657
--- /dev/null
@@ -0,0 +1,9 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) lib.rs -Z gen-crate-map
+       ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
+       $(CC) main.c -o $(call RUN,main) -lboot -Wl,-rpath,$(TMPDIR)
+       $(call RUN,main)
+       rm $(call DYLIB,boot)
+       $(call FAIL,main)
diff --git a/src/test/run-make/bootstrap-from-c-with-uvio/lib.rs b/src/test/run-make/bootstrap-from-c-with-uvio/lib.rs
new file mode 100644 (file)
index 0000000..85941ec
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[link(package_id = "boot", name = "boot", vers = "0.1")];
+#[crate_type = "lib"];
+
+extern mod rustuv; // pull in uvio
+
+use std::rt;
+
+#[no_mangle] // this needs to get called from C
+pub extern "C" fn foo(argc: int, argv: **u8) -> int {
+    do rt::start(argc, argv) {
+        do spawn {
+            println!("hello");
+        }
+    }
+}
diff --git a/src/test/run-make/bootstrap-from-c-with-uvio/main.c b/src/test/run-make/bootstrap-from-c-with-uvio/main.c
new file mode 100644 (file)
index 0000000..1872c1e
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// this is the rust entry point that we're going to call.
+int foo(int argc, char *argv[]);
+
+int main(int argc, char *argv[]) {
+  return foo(argc, argv);
+}