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
This commit is contained in:
parent
9fbba7b2ee
commit
6d6ccb75ff
37
mk/tests.mk
37
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,6 +284,7 @@ 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)-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 \
|
||||
|
@ -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))))))
|
||||
|
|
|
@ -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)
|
||||
|
|
@ -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
|
|
@ -0,0 +1,5 @@
|
|||
extern mod foo;
|
||||
|
||||
fn main() {
|
||||
foo::rsfoo();
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
int foo() { return 0; }
|
|
@ -0,0 +1,10 @@
|
|||
#[crate_type = "dylib"];
|
||||
|
||||
#[link(name = "cfoo")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
pub fn rsfoo() {
|
||||
unsafe { foo() }
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,5 @@
|
|||
extern mod foo;
|
||||
|
||||
fn main() {
|
||||
foo::rsfoo();
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
int foo() { return 0; }
|
|
@ -0,0 +1,10 @@
|
|||
#[crate_type = "rlib"];
|
||||
|
||||
#[link(name = "cfoo")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
pub fn rsfoo() {
|
||||
unsafe { foo() }
|
||||
}
|
|
@ -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)
|
|
@ -0,0 +1,6 @@
|
|||
void foo();
|
||||
|
||||
int main() {
|
||||
foo();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#[crate_type = "dylib"];
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn foo() {}
|
|
@ -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)
|
|
@ -0,0 +1,6 @@
|
|||
void foo();
|
||||
|
||||
int main() {
|
||||
foo();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#[crate_type = "staticlib"];
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn foo() {}
|
|
@ -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)
|
|
@ -0,0 +1,5 @@
|
|||
extern mod foo;
|
||||
|
||||
fn main() {
|
||||
foo::rsfoo();
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
int foo() { return 0; }
|
|
@ -0,0 +1,10 @@
|
|||
#[crate_type = "dylib"];
|
||||
|
||||
#[link(name = "cfoo")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
pub fn rsfoo() {
|
||||
unsafe { foo() }
|
||||
}
|
|
@ -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)
|
|
@ -0,0 +1,5 @@
|
|||
extern mod foo;
|
||||
|
||||
fn main() {
|
||||
foo::rsfoo();
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
int foo() { return 0; }
|
|
@ -0,0 +1,10 @@
|
|||
#[crate_type = "rlib"];
|
||||
|
||||
#[link(name = "cfoo")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
pub fn rsfoo() {
|
||||
unsafe { foo() }
|
||||
}
|
|
@ -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)
|
|
@ -0,0 +1,2 @@
|
|||
#[crate_type = "dylib"];
|
||||
pub fn m1() {}
|
|
@ -0,0 +1,4 @@
|
|||
#[crate_type = "dylib"];
|
||||
extern mod m1;
|
||||
|
||||
pub fn m2() { m1::m1() }
|
|
@ -0,0 +1,4 @@
|
|||
#[crate_type = "dylib"];
|
||||
extern mod m2;
|
||||
|
||||
pub fn m3() { m2::m2() }
|
|
@ -0,0 +1,3 @@
|
|||
extern mod m3;
|
||||
|
||||
fn main() { m3::m3() }
|
|
@ -0,0 +1,7 @@
|
|||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) both.rs
|
||||
$(RUSTC) dylib.rs -Z prefer-dynamic
|
||||
$(RUSTC) prog.rs
|
||||
$(call RUN,prog)
|
|
@ -0,0 +1,4 @@
|
|||
#[crate_type = "rlib"];
|
||||
#[crate_type = "dylib"];
|
||||
|
||||
pub static foo: int = 4;
|
|
@ -0,0 +1,6 @@
|
|||
#[crate_type = "dylib"];
|
||||
extern mod both;
|
||||
|
||||
use std::cast;
|
||||
|
||||
pub fn addr() -> uint { unsafe { cast::transmute(&both::foo) } }
|
|
@ -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());
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
#[crate_type = "dylib"];
|
||||
extern mod rlib;
|
||||
|
||||
pub fn dylib() { rlib::rlib() }
|
|
@ -0,0 +1,7 @@
|
|||
extern mod dylib;
|
||||
extern mod rlib;
|
||||
|
||||
fn main() {
|
||||
dylib::dylib();
|
||||
rlib::rlib();
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
#[crate_type = "rlib"];
|
||||
pub fn rlib() {}
|
|
@ -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)
|
|
@ -0,0 +1 @@
|
|||
pub fn bar() {}
|
|
@ -0,0 +1,5 @@
|
|||
extern mod bar;
|
||||
|
||||
fn main() {
|
||||
bar::bar();
|
||||
}
|
|
@ -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)
|
|
@ -0,0 +1 @@
|
|||
pub fn bar() {}
|
|
@ -0,0 +1,5 @@
|
|||
extern mod bar;
|
||||
|
||||
fn main() {
|
||||
bar::bar();
|
||||
}
|
|
@ -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)
|
|
@ -0,0 +1,2 @@
|
|||
#[crate_type = "rlib"];
|
||||
pub fn m1() {}
|
|
@ -0,0 +1,4 @@
|
|||
#[crate_type = "rlib"];
|
||||
extern mod m1;
|
||||
|
||||
pub fn m2() { m1::m1() }
|
|
@ -0,0 +1,4 @@
|
|||
#[crate_type = "rlib"];
|
||||
extern mod m2;
|
||||
|
||||
pub fn m3() { m2::m2() }
|
|
@ -0,0 +1,3 @@
|
|||
extern mod m3;
|
||||
|
||||
fn main() { m3::m3() }
|
|
@ -0,0 +1,5 @@
|
|||
-include ../tools.mk
|
||||
all:
|
||||
$(RUSTC) bar.rs --dylib
|
||||
$(RUSTC) foo.rs
|
||||
$(call RUN,foo)
|
|
@ -0,0 +1 @@
|
|||
pub fn bar() {}
|
|
@ -0,0 +1,5 @@
|
|||
extern mod bar;
|
||||
|
||||
fn main() {
|
||||
bar::bar();
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
-include ../tools.mk
|
||||
all:
|
||||
$(RUSTC) bar.rs --rlib
|
||||
$(RUSTC) foo.rs
|
||||
$(call RUN,foo)
|
|
@ -0,0 +1 @@
|
|||
pub fn bar() {}
|
|
@ -0,0 +1,5 @@
|
|||
extern mod bar;
|
||||
|
||||
fn main() {
|
||||
bar::bar();
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) lib.rs
|
||||
$(RUSTC) main.rs
|
||||
$(call RUN,main)
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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 $@ $<
|
||||
|
Loading…
Reference in New Issue