rustc: Add a flag for specifying dependencies

This comit implements a new flag, --extern, which is used to specify where a
crate is located. The purpose of this flag is to bypass the normal crate
loading/matching of the compiler to point it directly at the right file.

This flag takes the form `--extern foo=bar` where `foo` is the name of a crate
and `bar` is the location at which to find the crate. Multiple `--extern`
directives are allowed with the same crate name to specify the rlib/dylib pair
for a crate. It is invalid to specify more than one rlib or more than one dylib,
and it's required that the crates are valid rust crates.

I have also added some extensive documentation to metadata::loader about how
crate loading should work.

RFC: 0035-remove-crate-id
This commit is contained in:
Alex Crichton 2014-07-01 08:37:54 -07:00
parent df4ea9c39a
commit cc3c8bbfaf
17 changed files with 444 additions and 15 deletions

View file

@ -0,0 +1,24 @@
-include ../tools.mk
# Attempt to build this dependency tree:
#
# A.1 A.2
# |\ |
# | \ |
# B \ C
# \ | /
# \|/
# D
#
# Note that A.1 and A.2 are crates with the same name.
all:
$(RUSTC) -C metadata=1 -C extra-filename=-1 a.rs
$(RUSTC) -C metadata=2 -C extra-filename=-2 a.rs
$(RUSTC) b.rs --extern a=$(TMPDIR)/liba-1.rlib
$(RUSTC) c.rs --extern a=$(TMPDIR)/liba-2.rlib
$(RUSTC) --cfg before d.rs --extern a=$(TMPDIR)/liba-1.rlib
$(call RUN,d)
$(RUSTC) --cfg after d.rs --extern a=$(TMPDIR)/liba-1.rlib
$(call RUN,d)

View file

@ -0,0 +1,6 @@
#![crate_name = "a"]
#![crate_type = "rlib"]
static FOO: uint = 3;
pub fn token() -> &'static uint { &FOO }

View file

@ -0,0 +1,9 @@
#![crate_name = "b"]
#![crate_type = "rlib"]
extern crate a;
static FOO: uint = 3;
pub fn token() -> &'static uint { &FOO }
pub fn a_token() -> &'static uint { a::token() }

View file

@ -0,0 +1,9 @@
#![crate_name = "c"]
#![crate_type = "rlib"]
extern crate a;
static FOO: uint = 3;
pub fn token() -> &'static uint { &FOO }
pub fn a_token() -> &'static uint { a::token() }

View file

@ -0,0 +1,11 @@
#[cfg(before)] extern crate a;
extern crate b;
extern crate c;
#[cfg(after)] extern crate a;
fn t(a: &'static uint) -> uint { a as *const _ as uint }
fn main() {
assert!(t(a::token()) == t(b::a_token()));
assert!(t(a::token()) != t(c::a_token()));
}

View file

@ -0,0 +1,16 @@
-include ../tools.mk
all:
$(RUSTC) bar.rs --crate-type=rlib
$(RUSTC) bar.rs --crate-type=rlib -C extra-filename=-a
$(RUSTC) foo.rs --extern hello && exit 1 || exit 0
$(RUSTC) foo.rs --extern bar=no-exist && exit 1 || exit 0
$(RUSTC) foo.rs --extern bar=foo.rs && exit 1 || exit 0
$(RUSTC) foo.rs \
--extern bar=$(TMPDIR)/libbar.rlib \
--extern bar=$(TMPDIR)/libbar-a.rlib \
&& exit 1 || exit 0
$(RUSTC) foo.rs \
--extern bar=$(TMPDIR)/libbar.rlib \
--extern bar=$(TMPDIR)/libbar.rlib
$(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib

View file

View file

@ -0,0 +1,3 @@
extern crate bar;
fn main() {}

View file

@ -0,0 +1,10 @@
-include ../tools.mk
all:
$(RUSTC) foo.rs -C metadata=a -C extra-filename=-a
$(RUSTC) foo.rs -C metadata=b -C extra-filename=-b
$(RUSTC) bar.rs \
--extern foo1=$(TMPDIR)/libfoo-a.rlib \
--extern foo2=$(TMPDIR)/libfoo-b.rlib \
-Z print-link-args
$(call RUN,bar)

View file

@ -0,0 +1,8 @@
extern crate foo1;
extern crate foo2;
fn main() {
let a = foo1::foo();
let b = foo2::foo();
assert!(a as *const _ != b as *const _);
}

View file

@ -0,0 +1,6 @@
#![crate_name = "foo"]
#![crate_type = "rlib"]
static FOO: uint = 3;
pub fn foo() -> &'static uint { &FOO }