about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-11-16 17:07:32 -0800
committerAlex Crichton <alex@alexcrichton.com>2013-11-29 18:36:14 -0800
commit6d6ccb75ff2240ed294fcf6aa57e96c72316954c (patch)
treeae07356d883d3d076460b5a0a821e2b93f554e2f
parent9fbba7b2eeabd073f9518f2dbd50f4eabb621c67 (diff)
downloadrust-6d6ccb75ff2240ed294fcf6aa57e96c72316954c.tar.gz
rust-6d6ccb75ff2240ed294fcf6aa57e96c72316954c.zip
Add a new run-make test directory
This infrastructure is meant to support runnings tests that involve various
interesting interdependencies about the types of crates being linked or possibly
interacting with C libraries. The goal of these make tests is to not restrict
them to a particular test runner, but allow each test to run its own tests.

To this end, there is a new src/test/run-make directory which has sub-folders of
tests. Each test requires a `Makefile`, and running the tests constitues simply
running `make` inside the directory. The new target is `check-stageN-rmake`.

These tests will have the destination directory (as TMPDIR) and the local rust
compiler (as RUSTC) passed along to them. There is also some helpful
cross-platform utilities included in src/test/run-make/tools.mk to aid with
compiling C programs and running them.

The impetus for adding this new test suite is to allow various interesting forms
of testing rust linkage. All of the tests initially added are various flavors of
compiling Rust and C with one another as well as just making sure that rust
linkage works in general.

Closes #10434
-rw-r--r--mk/tests.mk39
-rw-r--r--src/etc/maketest.py26
-rw-r--r--src/test/run-make/c-dynamic-dylib/Makefile14
-rw-r--r--src/test/run-make/c-dynamic-dylib/bar.rs5
-rw-r--r--src/test/run-make/c-dynamic-dylib/cfoo.c1
-rw-r--r--src/test/run-make/c-dynamic-dylib/foo.rs10
-rw-r--r--src/test/run-make/c-dynamic-rlib/Makefile14
-rw-r--r--src/test/run-make/c-dynamic-rlib/bar.rs5
-rw-r--r--src/test/run-make/c-dynamic-rlib/cfoo.c1
-rw-r--r--src/test/run-make/c-dynamic-rlib/foo.rs10
-rw-r--r--src/test/run-make/c-link-to-rust-dylib/Makefile9
-rw-r--r--src/test/run-make/c-link-to-rust-dylib/bar.c6
-rw-r--r--src/test/run-make/c-link-to-rust-dylib/foo.rs4
-rw-r--r--src/test/run-make/c-link-to-rust-staticlib/Makefile13
-rw-r--r--src/test/run-make/c-link-to-rust-staticlib/bar.c6
-rw-r--r--src/test/run-make/c-link-to-rust-staticlib/foo.rs4
-rw-r--r--src/test/run-make/c-static-dylib/Makefile9
-rw-r--r--src/test/run-make/c-static-dylib/bar.rs5
-rw-r--r--src/test/run-make/c-static-dylib/cfoo.c1
-rw-r--r--src/test/run-make/c-static-dylib/foo.rs10
-rw-r--r--src/test/run-make/c-static-rlib/Makefile8
-rw-r--r--src/test/run-make/c-static-rlib/bar.rs5
-rw-r--r--src/test/run-make/c-static-rlib/cfoo.c1
-rw-r--r--src/test/run-make/c-static-rlib/foo.rs10
-rw-r--r--src/test/run-make/dylib-chain/Makefile12
-rw-r--r--src/test/run-make/dylib-chain/m1.rs2
-rw-r--r--src/test/run-make/dylib-chain/m2.rs4
-rw-r--r--src/test/run-make/dylib-chain/m3.rs4
-rw-r--r--src/test/run-make/dylib-chain/m4.rs3
-rw-r--r--src/test/run-make/mixing-deps/Makefile7
-rw-r--r--src/test/run-make/mixing-deps/both.rs4
-rw-r--r--src/test/run-make/mixing-deps/dylib.rs6
-rw-r--r--src/test/run-make/mixing-deps/prog.rs9
-rw-r--r--src/test/run-make/mixing-libs/Makefile9
-rw-r--r--src/test/run-make/mixing-libs/dylib.rs4
-rw-r--r--src/test/run-make/mixing-libs/prog.rs7
-rw-r--r--src/test/run-make/mixing-libs/rlib.rs2
-rw-r--r--src/test/run-make/prefer-dylib/Makefile8
-rw-r--r--src/test/run-make/prefer-dylib/bar.rs1
-rw-r--r--src/test/run-make/prefer-dylib/foo.rs5
-rw-r--r--src/test/run-make/prefer-rlib/Makefile8
-rw-r--r--src/test/run-make/prefer-rlib/bar.rs1
-rw-r--r--src/test/run-make/prefer-rlib/foo.rs5
-rw-r--r--src/test/run-make/rlib-chain/Makefile10
-rw-r--r--src/test/run-make/rlib-chain/m1.rs2
-rw-r--r--src/test/run-make/rlib-chain/m2.rs4
-rw-r--r--src/test/run-make/rlib-chain/m3.rs4
-rw-r--r--src/test/run-make/rlib-chain/m4.rs3
-rw-r--r--src/test/run-make/simple-dylib/Makefile5
-rw-r--r--src/test/run-make/simple-dylib/bar.rs1
-rw-r--r--src/test/run-make/simple-dylib/foo.rs5
-rw-r--r--src/test/run-make/simple-rlib/Makefile5
-rw-r--r--src/test/run-make/simple-rlib/bar.rs1
-rw-r--r--src/test/run-make/simple-rlib/foo.rs5
-rw-r--r--src/test/run-make/static-unwinding/Makefile6
-rw-r--r--src/test/run-make/static-unwinding/lib.rs15
-rw-r--r--src/test/run-make/static-unwinding/main.rs25
-rw-r--r--src/test/run-make/tools.mk27
58 files changed, 433 insertions, 2 deletions
diff --git a/mk/tests.mk b/mk/tests.mk
index c3614cbcc6b..5b021eb48f1 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -193,7 +193,7 @@ check-lite: cleantestlibs cleantmptestlogs \
 	check-stage2-std check-stage2-extra check-stage2-rpass \
 	check-stage2-rustuv \
 	check-stage2-rustpkg \
-	check-stage2-rfail check-stage2-cfail
+	check-stage2-rfail check-stage2-cfail check-stage2-rmake
 	$(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
 
 .PHONY: cleantmptestlogs cleantestlibs
@@ -284,7 +284,8 @@ check-stage$(1)-T-$(2)-H-$(3)-exec:     				\
 	check-stage$(1)-T-$(2)-H-$(3)-rfail-exec			\
 	check-stage$(1)-T-$(2)-H-$(3)-cfail-exec			\
 	check-stage$(1)-T-$(2)-H-$(3)-rpass-full-exec			\
-        check-stage$(1)-T-$(2)-H-$(3)-crates-exec                      \
+	check-stage$(1)-T-$(2)-H-$(3)-rmake-exec			\
+        check-stage$(1)-T-$(2)-H-$(3)-crates-exec                       \
 	check-stage$(1)-T-$(2)-H-$(3)-bench-exec			\
 	check-stage$(1)-T-$(2)-H-$(3)-debuginfo-exec \
 	check-stage$(1)-T-$(2)-H-$(3)-codegen-exec \
@@ -770,6 +771,7 @@ TEST_GROUPS = \
 	cfail \
 	bench \
 	perf \
+	rmake \
 	debuginfo \
 	codegen \
 	doc \
@@ -900,3 +902,36 @@ endef
 
 $(foreach host,$(CFG_HOST),			\
  $(eval $(call DEF_CHECK_FAST_FOR_H,$(host))))
+
+RMAKE_TESTS := $(shell ls -d $(S)src/test/run-make/*/)
+RMAKE_TESTS := $(RMAKE_TESTS:$(S)src/test/run-make/%/=%)
+
+define DEF_RMAKE_FOR_T_H
+# $(1) the stage
+# $(2) target triple
+# $(3) host triple
+
+check-stage$(1)-T-$(2)-H-$(3)-rmake-exec: \
+		$$(call TEST_OK_FILE,$(1),$(2),$(3),rmake)
+
+$$(call TEST_OK_FILE,$(1),$(2),$(3),rmake): \
+		$$(RMAKE_TESTS:%=$(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok)
+	@touch $$@
+
+$(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \
+		$(S)src/test/run-make/%/Makefile \
+		$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3))
+	@rm -rf $(3)/test/run-make/$$*
+	@mkdir -p $(3)/test/run-make/$$*
+	@echo maketest: $$*
+	@python $(S)src/etc/maketest.py $$(dir $$<) \
+	    $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
+	    $(3)/test/run-make/$$*
+	@touch $$@
+
+endef
+
+$(foreach stage,$(STAGES), \
+ $(foreach target,$(CFG_TARGET), \
+  $(foreach host,$(CFG_HOST), \
+   $(eval $(call DEF_RMAKE_FOR_T_H,$(stage),$(target),$(host))))))
diff --git a/src/etc/maketest.py b/src/etc/maketest.py
new file mode 100644
index 00000000000..d42bf065657
--- /dev/null
+++ b/src/etc/maketest.py
@@ -0,0 +1,26 @@
+# xfail-license
+
+import subprocess
+import os
+import sys
+
+os.putenv('RUSTC', os.path.abspath(sys.argv[2]))
+os.putenv('TMPDIR', os.path.abspath(sys.argv[3]))
+
+proc = subprocess.Popen(['make', '-C', sys.argv[1]],
+                        stdout = subprocess.PIPE,
+                        stderr = subprocess.PIPE)
+out, err = proc.communicate()
+i = proc.wait()
+
+if i != 0:
+
+    print '----- ' + sys.argv[1] + """ --------------------
+------ stdout ---------------------------------------------
+""" + out + """
+------ stderr ---------------------------------------------
+""" + err + """
+------        ---------------------------------------------
+"""
+    sys.exit(i)
+
diff --git a/src/test/run-make/c-dynamic-dylib/Makefile b/src/test/run-make/c-dynamic-dylib/Makefile
new file mode 100644
index 00000000000..2b2e5d56e92
--- /dev/null
+++ b/src/test/run-make/c-dynamic-dylib/Makefile
@@ -0,0 +1,14 @@
+-include ../tools.mk
+
+# This hits an assertion in the linker on older versions of osx apparently
+ifeq ($(shell uname),Darwin)
+all:
+	echo ignored
+else
+all: $(call DYLIB,cfoo)
+	$(RUSTC) foo.rs
+	$(RUSTC) bar.rs
+	$(call RUN,bar)
+	rm $(TMPDIR)/$(call DYLIB_GLOB,cfoo)
+	$(call FAIL,bar)
+endif
diff --git a/src/test/run-make/c-dynamic-dylib/bar.rs b/src/test/run-make/c-dynamic-dylib/bar.rs
new file mode 100644
index 00000000000..7c4aca1e028
--- /dev/null
+++ b/src/test/run-make/c-dynamic-dylib/bar.rs
@@ -0,0 +1,5 @@
+extern mod foo;
+
+fn main() {
+    foo::rsfoo();
+}
diff --git a/src/test/run-make/c-dynamic-dylib/cfoo.c b/src/test/run-make/c-dynamic-dylib/cfoo.c
new file mode 100644
index 00000000000..9fe07f82f9e
--- /dev/null
+++ b/src/test/run-make/c-dynamic-dylib/cfoo.c
@@ -0,0 +1 @@
+int foo() { return 0; }
diff --git a/src/test/run-make/c-dynamic-dylib/foo.rs b/src/test/run-make/c-dynamic-dylib/foo.rs
new file mode 100644
index 00000000000..0c4a6f7df4b
--- /dev/null
+++ b/src/test/run-make/c-dynamic-dylib/foo.rs
@@ -0,0 +1,10 @@
+#[crate_type = "dylib"];
+
+#[link(name = "cfoo")]
+extern {
+    fn foo();
+}
+
+pub fn rsfoo() {
+    unsafe { foo() }
+}
diff --git a/src/test/run-make/c-dynamic-rlib/Makefile b/src/test/run-make/c-dynamic-rlib/Makefile
new file mode 100644
index 00000000000..18992703b2c
--- /dev/null
+++ b/src/test/run-make/c-dynamic-rlib/Makefile
@@ -0,0 +1,14 @@
+-include ../tools.mk
+
+# This hits an assertion in the linker on older versions of osx apparently
+ifeq ($(shell uname),Darwin)
+all:
+	echo ignored
+else
+all: $(call DYLIB,cfoo)
+	$(RUSTC) foo.rs
+	$(RUSTC) bar.rs
+	LD_LIBRARY_PATH=$(TMPDIR) $(call RUN,bar)
+	rm $(TMPDIR)/$(call DYLIB_GLOB,cfoo)
+	$(call FAIL,bar)
+endif
diff --git a/src/test/run-make/c-dynamic-rlib/bar.rs b/src/test/run-make/c-dynamic-rlib/bar.rs
new file mode 100644
index 00000000000..7c4aca1e028
--- /dev/null
+++ b/src/test/run-make/c-dynamic-rlib/bar.rs
@@ -0,0 +1,5 @@
+extern mod foo;
+
+fn main() {
+    foo::rsfoo();
+}
diff --git a/src/test/run-make/c-dynamic-rlib/cfoo.c b/src/test/run-make/c-dynamic-rlib/cfoo.c
new file mode 100644
index 00000000000..9fe07f82f9e
--- /dev/null
+++ b/src/test/run-make/c-dynamic-rlib/cfoo.c
@@ -0,0 +1 @@
+int foo() { return 0; }
diff --git a/src/test/run-make/c-dynamic-rlib/foo.rs b/src/test/run-make/c-dynamic-rlib/foo.rs
new file mode 100644
index 00000000000..e64811af9c7
--- /dev/null
+++ b/src/test/run-make/c-dynamic-rlib/foo.rs
@@ -0,0 +1,10 @@
+#[crate_type = "rlib"];
+
+#[link(name = "cfoo")]
+extern {
+    fn foo();
+}
+
+pub fn rsfoo() {
+    unsafe { foo() }
+}
diff --git a/src/test/run-make/c-link-to-rust-dylib/Makefile b/src/test/run-make/c-link-to-rust-dylib/Makefile
new file mode 100644
index 00000000000..fb57a08a826
--- /dev/null
+++ b/src/test/run-make/c-link-to-rust-dylib/Makefile
@@ -0,0 +1,9 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) foo.rs
+	ln -s $(call DYLIB,foo-*) $(call DYLIB,foo)
+	$(CC) bar.c -lfoo -o $(call RUN,bar) -Wl,-rpath,$(TMPDIR)
+	$(call RUN,bar)
+	rm $(call DYLIB,foo)
+	$(call FAIL,bar)
diff --git a/src/test/run-make/c-link-to-rust-dylib/bar.c b/src/test/run-make/c-link-to-rust-dylib/bar.c
new file mode 100644
index 00000000000..bb4036b06e1
--- /dev/null
+++ b/src/test/run-make/c-link-to-rust-dylib/bar.c
@@ -0,0 +1,6 @@
+void foo();
+
+int main() {
+    foo();
+    return 0;
+}
diff --git a/src/test/run-make/c-link-to-rust-dylib/foo.rs b/src/test/run-make/c-link-to-rust-dylib/foo.rs
new file mode 100644
index 00000000000..6b6a786ef54
--- /dev/null
+++ b/src/test/run-make/c-link-to-rust-dylib/foo.rs
@@ -0,0 +1,4 @@
+#[crate_type = "dylib"];
+
+#[no_mangle]
+pub extern "C" fn foo() {}
diff --git a/src/test/run-make/c-link-to-rust-staticlib/Makefile b/src/test/run-make/c-link-to-rust-staticlib/Makefile
new file mode 100644
index 00000000000..a81f19d6eb3
--- /dev/null
+++ b/src/test/run-make/c-link-to-rust-staticlib/Makefile
@@ -0,0 +1,13 @@
+-include ../tools.mk
+
+ifneq ($(shell uname),Darwin)
+	EXTRAFLAGS := -lm -lrt -ldl -lpthread
+endif
+
+all:
+	$(RUSTC) foo.rs -Z gen-crate-map
+	ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
+	$(CC) bar.c -lfoo -o $(call RUN,bar) $(EXTRAFLAGS) -lstdc++ 
+	$(call RUN,bar)
+	rm $(call STATICLIB,foo*)
+	$(call RUN,bar)
diff --git a/src/test/run-make/c-link-to-rust-staticlib/bar.c b/src/test/run-make/c-link-to-rust-staticlib/bar.c
new file mode 100644
index 00000000000..bb4036b06e1
--- /dev/null
+++ b/src/test/run-make/c-link-to-rust-staticlib/bar.c
@@ -0,0 +1,6 @@
+void foo();
+
+int main() {
+    foo();
+    return 0;
+}
diff --git a/src/test/run-make/c-link-to-rust-staticlib/foo.rs b/src/test/run-make/c-link-to-rust-staticlib/foo.rs
new file mode 100644
index 00000000000..3da09eb6bb6
--- /dev/null
+++ b/src/test/run-make/c-link-to-rust-staticlib/foo.rs
@@ -0,0 +1,4 @@
+#[crate_type = "staticlib"];
+
+#[no_mangle]
+pub extern "C" fn foo() {}
diff --git a/src/test/run-make/c-static-dylib/Makefile b/src/test/run-make/c-static-dylib/Makefile
new file mode 100644
index 00000000000..62d9c8e90f2
--- /dev/null
+++ b/src/test/run-make/c-static-dylib/Makefile
@@ -0,0 +1,9 @@
+-include ../tools.mk
+
+all: $(call STATICLIB,cfoo)
+	$(RUSTC) foo.rs
+	$(RUSTC) bar.rs
+	rm $(TMPDIR)/$(call STATICLIB_GLOB,cfoo)
+	$(call RUN,bar)
+	rm $(TMPDIR)/$(call DYLIB_GLOB,foo)
+	$(call FAIL,bar)
diff --git a/src/test/run-make/c-static-dylib/bar.rs b/src/test/run-make/c-static-dylib/bar.rs
new file mode 100644
index 00000000000..7c4aca1e028
--- /dev/null
+++ b/src/test/run-make/c-static-dylib/bar.rs
@@ -0,0 +1,5 @@
+extern mod foo;
+
+fn main() {
+    foo::rsfoo();
+}
diff --git a/src/test/run-make/c-static-dylib/cfoo.c b/src/test/run-make/c-static-dylib/cfoo.c
new file mode 100644
index 00000000000..9fe07f82f9e
--- /dev/null
+++ b/src/test/run-make/c-static-dylib/cfoo.c
@@ -0,0 +1 @@
+int foo() { return 0; }
diff --git a/src/test/run-make/c-static-dylib/foo.rs b/src/test/run-make/c-static-dylib/foo.rs
new file mode 100644
index 00000000000..0c4a6f7df4b
--- /dev/null
+++ b/src/test/run-make/c-static-dylib/foo.rs
@@ -0,0 +1,10 @@
+#[crate_type = "dylib"];
+
+#[link(name = "cfoo")]
+extern {
+    fn foo();
+}
+
+pub fn rsfoo() {
+    unsafe { foo() }
+}
diff --git a/src/test/run-make/c-static-rlib/Makefile b/src/test/run-make/c-static-rlib/Makefile
new file mode 100644
index 00000000000..09eb4b1249e
--- /dev/null
+++ b/src/test/run-make/c-static-rlib/Makefile
@@ -0,0 +1,8 @@
+-include ../tools.mk
+
+all: $(call STATICLIB,cfoo)
+	$(RUSTC) foo.rs
+	$(RUSTC) bar.rs
+	rm $(TMPDIR)/$(call RLIB_GLOB,foo)
+	rm $(TMPDIR)/$(call STATICLIB_GLOB,cfoo)
+	$(call RUN,bar)
diff --git a/src/test/run-make/c-static-rlib/bar.rs b/src/test/run-make/c-static-rlib/bar.rs
new file mode 100644
index 00000000000..7c4aca1e028
--- /dev/null
+++ b/src/test/run-make/c-static-rlib/bar.rs
@@ -0,0 +1,5 @@
+extern mod foo;
+
+fn main() {
+    foo::rsfoo();
+}
diff --git a/src/test/run-make/c-static-rlib/cfoo.c b/src/test/run-make/c-static-rlib/cfoo.c
new file mode 100644
index 00000000000..9fe07f82f9e
--- /dev/null
+++ b/src/test/run-make/c-static-rlib/cfoo.c
@@ -0,0 +1 @@
+int foo() { return 0; }
diff --git a/src/test/run-make/c-static-rlib/foo.rs b/src/test/run-make/c-static-rlib/foo.rs
new file mode 100644
index 00000000000..e64811af9c7
--- /dev/null
+++ b/src/test/run-make/c-static-rlib/foo.rs
@@ -0,0 +1,10 @@
+#[crate_type = "rlib"];
+
+#[link(name = "cfoo")]
+extern {
+    fn foo();
+}
+
+pub fn rsfoo() {
+    unsafe { foo() }
+}
diff --git a/src/test/run-make/dylib-chain/Makefile b/src/test/run-make/dylib-chain/Makefile
new file mode 100644
index 00000000000..e60e904240d
--- /dev/null
+++ b/src/test/run-make/dylib-chain/Makefile
@@ -0,0 +1,12 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) m1.rs
+	$(RUSTC) m2.rs
+	$(RUSTC) m3.rs
+	$(RUSTC) m4.rs
+	$(call RUN,m4)
+	rm $(TMPDIR)/$(call DYLIB_GLOB,m1)
+	rm $(TMPDIR)/$(call DYLIB_GLOB,m2)
+	rm $(TMPDIR)/$(call DYLIB_GLOB,m3)
+	$(call FAIL,m4)
diff --git a/src/test/run-make/dylib-chain/m1.rs b/src/test/run-make/dylib-chain/m1.rs
new file mode 100644
index 00000000000..69ea8dcecfc
--- /dev/null
+++ b/src/test/run-make/dylib-chain/m1.rs
@@ -0,0 +1,2 @@
+#[crate_type = "dylib"];
+pub fn m1() {}
diff --git a/src/test/run-make/dylib-chain/m2.rs b/src/test/run-make/dylib-chain/m2.rs
new file mode 100644
index 00000000000..2f5d75a3872
--- /dev/null
+++ b/src/test/run-make/dylib-chain/m2.rs
@@ -0,0 +1,4 @@
+#[crate_type = "dylib"];
+extern mod m1;
+
+pub fn m2() { m1::m1() }
diff --git a/src/test/run-make/dylib-chain/m3.rs b/src/test/run-make/dylib-chain/m3.rs
new file mode 100644
index 00000000000..cc4ff2cff74
--- /dev/null
+++ b/src/test/run-make/dylib-chain/m3.rs
@@ -0,0 +1,4 @@
+#[crate_type = "dylib"];
+extern mod m2;
+
+pub fn m3() { m2::m2() }
diff --git a/src/test/run-make/dylib-chain/m4.rs b/src/test/run-make/dylib-chain/m4.rs
new file mode 100644
index 00000000000..c52d1f7fcbc
--- /dev/null
+++ b/src/test/run-make/dylib-chain/m4.rs
@@ -0,0 +1,3 @@
+extern mod m3;
+
+fn main() { m3::m3() }
diff --git a/src/test/run-make/mixing-deps/Makefile b/src/test/run-make/mixing-deps/Makefile
new file mode 100644
index 00000000000..9ab2abca729
--- /dev/null
+++ b/src/test/run-make/mixing-deps/Makefile
@@ -0,0 +1,7 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) both.rs
+	$(RUSTC) dylib.rs -Z prefer-dynamic
+	$(RUSTC) prog.rs
+	$(call RUN,prog)
diff --git a/src/test/run-make/mixing-deps/both.rs b/src/test/run-make/mixing-deps/both.rs
new file mode 100644
index 00000000000..89d7b6452c9
--- /dev/null
+++ b/src/test/run-make/mixing-deps/both.rs
@@ -0,0 +1,4 @@
+#[crate_type = "rlib"];
+#[crate_type = "dylib"];
+
+pub static foo: int = 4;
diff --git a/src/test/run-make/mixing-deps/dylib.rs b/src/test/run-make/mixing-deps/dylib.rs
new file mode 100644
index 00000000000..130bc2fe803
--- /dev/null
+++ b/src/test/run-make/mixing-deps/dylib.rs
@@ -0,0 +1,6 @@
+#[crate_type = "dylib"];
+extern mod both;
+
+use std::cast;
+
+pub fn addr() -> uint { unsafe { cast::transmute(&both::foo) } }
diff --git a/src/test/run-make/mixing-deps/prog.rs b/src/test/run-make/mixing-deps/prog.rs
new file mode 100644
index 00000000000..da90f8731f4
--- /dev/null
+++ b/src/test/run-make/mixing-deps/prog.rs
@@ -0,0 +1,9 @@
+extern mod dylib;
+extern mod both;
+
+use std::cast;
+
+fn main() {
+    assert_eq!(unsafe { cast::transmute::<&int, uint>(&both::foo) },
+               dylib::addr());
+}
diff --git a/src/test/run-make/mixing-libs/Makefile b/src/test/run-make/mixing-libs/Makefile
new file mode 100644
index 00000000000..eb00c801390
--- /dev/null
+++ b/src/test/run-make/mixing-libs/Makefile
@@ -0,0 +1,9 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) rlib.rs
+	$(RUSTC) dylib.rs && exit 1 || exit 0
+	$(RUSTC) rlib.rs --dylib
+	$(RUSTC) dylib.rs
+	rm $(call DYLIB,rlib-*)
+	$(RUSTC) prog.rs && exit 1 || exit 0
diff --git a/src/test/run-make/mixing-libs/dylib.rs b/src/test/run-make/mixing-libs/dylib.rs
new file mode 100644
index 00000000000..9652cb27641
--- /dev/null
+++ b/src/test/run-make/mixing-libs/dylib.rs
@@ -0,0 +1,4 @@
+#[crate_type = "dylib"];
+extern mod rlib;
+
+pub fn dylib() { rlib::rlib() }
diff --git a/src/test/run-make/mixing-libs/prog.rs b/src/test/run-make/mixing-libs/prog.rs
new file mode 100644
index 00000000000..ec67dea0ab0
--- /dev/null
+++ b/src/test/run-make/mixing-libs/prog.rs
@@ -0,0 +1,7 @@
+extern mod dylib;
+extern mod rlib;
+
+fn main() {
+    dylib::dylib();
+    rlib::rlib();
+}
diff --git a/src/test/run-make/mixing-libs/rlib.rs b/src/test/run-make/mixing-libs/rlib.rs
new file mode 100644
index 00000000000..32c322f3f59
--- /dev/null
+++ b/src/test/run-make/mixing-libs/rlib.rs
@@ -0,0 +1,2 @@
+#[crate_type = "rlib"];
+pub fn rlib() {}
diff --git a/src/test/run-make/prefer-dylib/Makefile b/src/test/run-make/prefer-dylib/Makefile
new file mode 100644
index 00000000000..8229547176a
--- /dev/null
+++ b/src/test/run-make/prefer-dylib/Makefile
@@ -0,0 +1,8 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) bar.rs --dylib --rlib
+	$(RUSTC) foo.rs -Z prefer-dynamic
+	$(call RUN,foo)
+	rm $(TMPDIR)/*bar*
+	$(call FAILS,foo)
diff --git a/src/test/run-make/prefer-dylib/bar.rs b/src/test/run-make/prefer-dylib/bar.rs
new file mode 100644
index 00000000000..c5c0bc606cd
--- /dev/null
+++ b/src/test/run-make/prefer-dylib/bar.rs
@@ -0,0 +1 @@
+pub fn bar() {}
diff --git a/src/test/run-make/prefer-dylib/foo.rs b/src/test/run-make/prefer-dylib/foo.rs
new file mode 100644
index 00000000000..f86ef62a9fe
--- /dev/null
+++ b/src/test/run-make/prefer-dylib/foo.rs
@@ -0,0 +1,5 @@
+extern mod bar;
+
+fn main() {
+    bar::bar();
+}
diff --git a/src/test/run-make/prefer-rlib/Makefile b/src/test/run-make/prefer-rlib/Makefile
new file mode 100644
index 00000000000..eedb70c4efd
--- /dev/null
+++ b/src/test/run-make/prefer-rlib/Makefile
@@ -0,0 +1,8 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) bar.rs --dylib --rlib
+	ls $(TMPDIR)/$(call RLIB_GLOB,bar)
+	$(RUSTC) foo.rs
+	rm $(TMPDIR)/*bar*
+	$(call RUN,foo)
diff --git a/src/test/run-make/prefer-rlib/bar.rs b/src/test/run-make/prefer-rlib/bar.rs
new file mode 100644
index 00000000000..c5c0bc606cd
--- /dev/null
+++ b/src/test/run-make/prefer-rlib/bar.rs
@@ -0,0 +1 @@
+pub fn bar() {}
diff --git a/src/test/run-make/prefer-rlib/foo.rs b/src/test/run-make/prefer-rlib/foo.rs
new file mode 100644
index 00000000000..f86ef62a9fe
--- /dev/null
+++ b/src/test/run-make/prefer-rlib/foo.rs
@@ -0,0 +1,5 @@
+extern mod bar;
+
+fn main() {
+    bar::bar();
+}
diff --git a/src/test/run-make/rlib-chain/Makefile b/src/test/run-make/rlib-chain/Makefile
new file mode 100644
index 00000000000..30b6811a388
--- /dev/null
+++ b/src/test/run-make/rlib-chain/Makefile
@@ -0,0 +1,10 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) m1.rs
+	$(RUSTC) m2.rs
+	$(RUSTC) m3.rs
+	$(RUSTC) m4.rs
+	$(call RUN,m4)
+	rm $(TMPDIR)/*lib
+	$(call RUN,m4)
diff --git a/src/test/run-make/rlib-chain/m1.rs b/src/test/run-make/rlib-chain/m1.rs
new file mode 100644
index 00000000000..1a244efd4dd
--- /dev/null
+++ b/src/test/run-make/rlib-chain/m1.rs
@@ -0,0 +1,2 @@
+#[crate_type = "rlib"];
+pub fn m1() {}
diff --git a/src/test/run-make/rlib-chain/m2.rs b/src/test/run-make/rlib-chain/m2.rs
new file mode 100644
index 00000000000..96f77122083
--- /dev/null
+++ b/src/test/run-make/rlib-chain/m2.rs
@@ -0,0 +1,4 @@
+#[crate_type = "rlib"];
+extern mod m1;
+
+pub fn m2() { m1::m1() }
diff --git a/src/test/run-make/rlib-chain/m3.rs b/src/test/run-make/rlib-chain/m3.rs
new file mode 100644
index 00000000000..cb8d7529160
--- /dev/null
+++ b/src/test/run-make/rlib-chain/m3.rs
@@ -0,0 +1,4 @@
+#[crate_type = "rlib"];
+extern mod m2;
+
+pub fn m3() { m2::m2() }
diff --git a/src/test/run-make/rlib-chain/m4.rs b/src/test/run-make/rlib-chain/m4.rs
new file mode 100644
index 00000000000..c52d1f7fcbc
--- /dev/null
+++ b/src/test/run-make/rlib-chain/m4.rs
@@ -0,0 +1,3 @@
+extern mod m3;
+
+fn main() { m3::m3() }
diff --git a/src/test/run-make/simple-dylib/Makefile b/src/test/run-make/simple-dylib/Makefile
new file mode 100644
index 00000000000..d4f215c69f0
--- /dev/null
+++ b/src/test/run-make/simple-dylib/Makefile
@@ -0,0 +1,5 @@
+-include ../tools.mk
+all:
+	$(RUSTC) bar.rs --dylib
+	$(RUSTC) foo.rs
+	$(call RUN,foo)
diff --git a/src/test/run-make/simple-dylib/bar.rs b/src/test/run-make/simple-dylib/bar.rs
new file mode 100644
index 00000000000..c5c0bc606cd
--- /dev/null
+++ b/src/test/run-make/simple-dylib/bar.rs
@@ -0,0 +1 @@
+pub fn bar() {}
diff --git a/src/test/run-make/simple-dylib/foo.rs b/src/test/run-make/simple-dylib/foo.rs
new file mode 100644
index 00000000000..f86ef62a9fe
--- /dev/null
+++ b/src/test/run-make/simple-dylib/foo.rs
@@ -0,0 +1,5 @@
+extern mod bar;
+
+fn main() {
+    bar::bar();
+}
diff --git a/src/test/run-make/simple-rlib/Makefile b/src/test/run-make/simple-rlib/Makefile
new file mode 100644
index 00000000000..e8909ef134b
--- /dev/null
+++ b/src/test/run-make/simple-rlib/Makefile
@@ -0,0 +1,5 @@
+-include ../tools.mk
+all:
+	$(RUSTC) bar.rs --rlib
+	$(RUSTC) foo.rs
+	$(call RUN,foo)
diff --git a/src/test/run-make/simple-rlib/bar.rs b/src/test/run-make/simple-rlib/bar.rs
new file mode 100644
index 00000000000..c5c0bc606cd
--- /dev/null
+++ b/src/test/run-make/simple-rlib/bar.rs
@@ -0,0 +1 @@
+pub fn bar() {}
diff --git a/src/test/run-make/simple-rlib/foo.rs b/src/test/run-make/simple-rlib/foo.rs
new file mode 100644
index 00000000000..f86ef62a9fe
--- /dev/null
+++ b/src/test/run-make/simple-rlib/foo.rs
@@ -0,0 +1,5 @@
+extern mod bar;
+
+fn main() {
+    bar::bar();
+}
diff --git a/src/test/run-make/static-unwinding/Makefile b/src/test/run-make/static-unwinding/Makefile
new file mode 100644
index 00000000000..cb039744265
--- /dev/null
+++ b/src/test/run-make/static-unwinding/Makefile
@@ -0,0 +1,6 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) lib.rs
+	$(RUSTC) main.rs
+	$(call RUN,main)
diff --git a/src/test/run-make/static-unwinding/lib.rs b/src/test/run-make/static-unwinding/lib.rs
new file mode 100644
index 00000000000..4e2cdb6c222
--- /dev/null
+++ b/src/test/run-make/static-unwinding/lib.rs
@@ -0,0 +1,15 @@
+#[crate_type = "rlib"];
+
+pub static mut statik: int = 0;
+
+struct A;
+impl Drop for A {
+    fn drop(&mut self) {
+        unsafe { statik = 1; }
+    }
+}
+
+pub fn callback(f: ||) {
+    let _a = A;
+    f();
+}
diff --git a/src/test/run-make/static-unwinding/main.rs b/src/test/run-make/static-unwinding/main.rs
new file mode 100644
index 00000000000..029933a819c
--- /dev/null
+++ b/src/test/run-make/static-unwinding/main.rs
@@ -0,0 +1,25 @@
+extern mod lib;
+
+use std::task;
+
+static mut statik: int = 0;
+
+struct A;
+impl Drop for A {
+    fn drop(&mut self) {
+        unsafe { statik = 1; }
+    }
+}
+
+fn main() {
+    do task::try {
+        let _a = A;
+        lib::callback(|| fail!());
+        1
+    };
+
+    unsafe {
+        assert!(lib::statik == 1);
+        assert!(statik == 1);
+    }
+}
diff --git a/src/test/run-make/tools.mk b/src/test/run-make/tools.mk
new file mode 100644
index 00000000000..9c7af7f52c1
--- /dev/null
+++ b/src/test/run-make/tools.mk
@@ -0,0 +1,27 @@
+RUSTC := $(RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR)
+CC := $(CC) -L $(TMPDIR)
+
+RUN = $(TMPDIR)/$(1)
+FAILS = $(TMPDIR)/$(1) && exit 1 || exit 0
+
+RLIB_GLOB = lib$(1)*.rlib
+STATICLIB = $(TMPDIR)/lib$(1).a
+STATICLIB_GLOB = lib$(1)*.a
+
+ifeq ($(shell uname),Darwin)
+DYLIB_GLOB = lib$(1)*.dylib
+DYLIB = $(TMPDIR)/lib$(1).dylib
+else
+DYLIB_GLOB = lib$(1)*.so
+DYLIB = $(TMPDIR)/lib$(1).so
+endif
+
+%.a: %.o
+	ar crus $@ $<
+%.dylib: %.o
+	ld -o $@ $< -dylib
+%.so: %.o
+	ld -o $@ $< -shared
+$(TMPDIR)/lib%.o: %.c
+	$(CC) -c -o $@ $<
+