]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #10733 : alexcrichton/rust/ignore-on-windows, r=pcwalton
authorbors <bors@rust-lang.org>
Sun, 1 Dec 2013 02:31:46 +0000 (18:31 -0800)
committerbors <bors@rust-lang.org>
Sun, 1 Dec 2013 02:31:46 +0000 (18:31 -0800)
I've seen this fail on windows twice now, and it's not clear to me why it's
failing. For now, ignore it on that platform while investigation enuses.

175 files changed:
Makefile.in
configure
doc/rust.md
mk/clean.mk
mk/host.mk
mk/install.mk
mk/llvm.mk
mk/platform.mk
mk/rt.mk
mk/target.mk
mk/tests.mk
src/etc/maketest.py [new file with mode: 0644]
src/etc/snapshot.py
src/libextra/flate.rs
src/libextra/json.rs
src/libextra/lib.rs
src/libextra/test.rs
src/libextra/workcache.rs
src/librustc/back/archive.rs [new file with mode: 0644]
src/librustc/back/arm.rs
src/librustc/back/link.rs
src/librustc/back/mips.rs
src/librustc/back/rpath.rs
src/librustc/back/target_strs.rs
src/librustc/back/x86.rs
src/librustc/back/x86_64.rs
src/librustc/driver/driver.rs
src/librustc/driver/session.rs
src/librustc/front/feature_gate.rs
src/librustc/lib.rs
src/librustc/lib/llvm.rs
src/librustc/metadata/common.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/cstore.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/loader.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/lint.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/intrinsic.rs
src/librustc/middle/typeck/check/mod.rs
src/librustdoc/html/markdown.rs
src/librustdoc/lib.rs
src/librustpkg/lib.rs
src/librustpkg/tests.rs
src/librustpkg/util.rs
src/librustuv/lib.rs
src/librustuv/uvll.rs
src/libstd/any.rs
src/libstd/fmt/mod.rs
src/libstd/io/buffered.rs
src/libstd/io/mem.rs
src/libstd/lib.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/i16.rs
src/libstd/num/i32.rs
src/libstd/num/i64.rs
src/libstd/num/i8.rs
src/libstd/num/int.rs
src/libstd/num/int_macros.rs
src/libstd/num/u16.rs
src/libstd/num/u32.rs
src/libstd/num/u64.rs
src/libstd/num/u8.rs
src/libstd/num/uint.rs
src/libstd/num/uint_macros.rs
src/libstd/rt/logging.rs
src/libstd/rtdeps.rs [new file with mode: 0644]
src/libstd/tuple.rs
src/libstd/unstable/intrinsics.rs
src/libstd/vec.rs
src/libsyntax/lib.rs
src/libsyntax/parse/mod.rs
src/rt/rustrt.def.in [deleted file]
src/rustllvm/rustllvm.def.in
src/test/auxiliary/anon-extern-mod-cross-crate-1.rs
src/test/auxiliary/extern-crosscrate-source.rs
src/test/auxiliary/foreign_lib.rs
src/test/auxiliary/typeid-intrinsic.rs
src/test/auxiliary/typeid-intrinsic2.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]
src/test/run-make/c-dynamic-dylib/Makefile [new file with mode: 0644]
src/test/run-make/c-dynamic-dylib/bar.rs [new file with mode: 0644]
src/test/run-make/c-dynamic-dylib/cfoo.c [new file with mode: 0644]
src/test/run-make/c-dynamic-dylib/foo.rs [new file with mode: 0644]
src/test/run-make/c-dynamic-rlib/Makefile [new file with mode: 0644]
src/test/run-make/c-dynamic-rlib/bar.rs [new file with mode: 0644]
src/test/run-make/c-dynamic-rlib/cfoo.c [new file with mode: 0644]
src/test/run-make/c-dynamic-rlib/foo.rs [new file with mode: 0644]
src/test/run-make/c-link-to-rust-dylib/Makefile [new file with mode: 0644]
src/test/run-make/c-link-to-rust-dylib/bar.c [new file with mode: 0644]
src/test/run-make/c-link-to-rust-dylib/foo.rs [new file with mode: 0644]
src/test/run-make/c-link-to-rust-staticlib/Makefile [new file with mode: 0644]
src/test/run-make/c-link-to-rust-staticlib/bar.c [new file with mode: 0644]
src/test/run-make/c-link-to-rust-staticlib/foo.rs [new file with mode: 0644]
src/test/run-make/c-static-dylib/Makefile [new file with mode: 0644]
src/test/run-make/c-static-dylib/bar.rs [new file with mode: 0644]
src/test/run-make/c-static-dylib/cfoo.c [new file with mode: 0644]
src/test/run-make/c-static-dylib/foo.rs [new file with mode: 0644]
src/test/run-make/c-static-rlib/Makefile [new file with mode: 0644]
src/test/run-make/c-static-rlib/bar.rs [new file with mode: 0644]
src/test/run-make/c-static-rlib/cfoo.c [new file with mode: 0644]
src/test/run-make/c-static-rlib/foo.rs [new file with mode: 0644]
src/test/run-make/dylib-chain/Makefile [new file with mode: 0644]
src/test/run-make/dylib-chain/m1.rs [new file with mode: 0644]
src/test/run-make/dylib-chain/m2.rs [new file with mode: 0644]
src/test/run-make/dylib-chain/m3.rs [new file with mode: 0644]
src/test/run-make/dylib-chain/m4.rs [new file with mode: 0644]
src/test/run-make/mixing-deps/Makefile [new file with mode: 0644]
src/test/run-make/mixing-deps/both.rs [new file with mode: 0644]
src/test/run-make/mixing-deps/dylib.rs [new file with mode: 0644]
src/test/run-make/mixing-deps/prog.rs [new file with mode: 0644]
src/test/run-make/mixing-libs/Makefile [new file with mode: 0644]
src/test/run-make/mixing-libs/dylib.rs [new file with mode: 0644]
src/test/run-make/mixing-libs/prog.rs [new file with mode: 0644]
src/test/run-make/mixing-libs/rlib.rs [new file with mode: 0644]
src/test/run-make/prefer-dylib/Makefile [new file with mode: 0644]
src/test/run-make/prefer-dylib/bar.rs [new file with mode: 0644]
src/test/run-make/prefer-dylib/foo.rs [new file with mode: 0644]
src/test/run-make/prefer-rlib/Makefile [new file with mode: 0644]
src/test/run-make/prefer-rlib/bar.rs [new file with mode: 0644]
src/test/run-make/prefer-rlib/foo.rs [new file with mode: 0644]
src/test/run-make/rlib-chain/Makefile [new file with mode: 0644]
src/test/run-make/rlib-chain/m1.rs [new file with mode: 0644]
src/test/run-make/rlib-chain/m2.rs [new file with mode: 0644]
src/test/run-make/rlib-chain/m3.rs [new file with mode: 0644]
src/test/run-make/rlib-chain/m4.rs [new file with mode: 0644]
src/test/run-make/simple-dylib/Makefile [new file with mode: 0644]
src/test/run-make/simple-dylib/bar.rs [new file with mode: 0644]
src/test/run-make/simple-dylib/foo.rs [new file with mode: 0644]
src/test/run-make/simple-rlib/Makefile [new file with mode: 0644]
src/test/run-make/simple-rlib/bar.rs [new file with mode: 0644]
src/test/run-make/simple-rlib/foo.rs [new file with mode: 0644]
src/test/run-make/static-unwinding/Makefile [new file with mode: 0644]
src/test/run-make/static-unwinding/lib.rs [new file with mode: 0644]
src/test/run-make/static-unwinding/main.rs [new file with mode: 0644]
src/test/run-make/tools.mk [new file with mode: 0644]
src/test/run-pass/anon-extern-mod-cross-crate-2.rs
src/test/run-pass/anon-extern-mod.rs
src/test/run-pass/c-stack-as-value.rs
src/test/run-pass/extern-call-deep.rs
src/test/run-pass/extern-call-deep2.rs
src/test/run-pass/extern-call-indirect.rs
src/test/run-pass/extern-call-scrub.rs
src/test/run-pass/extern-pass-TwoU16s.rs
src/test/run-pass/extern-pass-TwoU32s.rs
src/test/run-pass/extern-pass-TwoU64s.rs
src/test/run-pass/extern-pass-TwoU8s.rs
src/test/run-pass/extern-pass-char.rs
src/test/run-pass/extern-pass-double.rs
src/test/run-pass/extern-pass-u32.rs
src/test/run-pass/extern-pass-u64.rs
src/test/run-pass/extern-return-TwoU16s.rs
src/test/run-pass/extern-return-TwoU32s.rs
src/test/run-pass/extern-return-TwoU64s.rs
src/test/run-pass/extern-return-TwoU8s.rs
src/test/run-pass/extern-stress.rs
src/test/run-pass/extern-yield.rs
src/test/run-pass/foreign-call-no-runtime.rs
src/test/run-pass/foreign-dupe.rs
src/test/run-pass/foreign-no-abi.rs
src/test/run-pass/invoke-external-foreign.rs
src/test/run-pass/issue-10734.rs [new file with mode: 0644]
src/test/run-pass/issue-4016.rs
src/test/run-pass/issue-4036.rs
src/test/run-pass/static-mut-foreign.rs
src/test/run-pass/struct-return.rs
src/test/run-pass/typeid-intrinsic.rs

index f5bb3cb2ed00fcdacc16ea594ac04f11a60d005c..b575312c03b407f52289f2c877f9e620c4e97eda 100644 (file)
@@ -130,6 +130,14 @@ ifndef DEBUG_BORROWS
   RUSTFLAGS_STAGE2 += -Z no-debug-borrows
 endif
 
+# The executables crated during this compilation process have no need to include
+# static copies of libstd and libextra. We also generate dynamic versions of all
+# libraries, so in the interest of space, prefer dynamic linking throughout the
+# compilation process.
+RUSTFLAGS_STAGE1 += -Z prefer-dynamic
+RUSTFLAGS_STAGE2 += -Z prefer-dynamic
+RUSTFLAGS_STAGE3 += -Z prefer-dynamic
+
 # platform-specific auto-configuration
 include $(CFG_SRC_DIR)mk/platform.mk
 
@@ -214,7 +222,7 @@ GENERATED :=
 
 define DEF_LIBS
 
-CFG_RUNTIME_$(1) :=$(call CFG_LIB_NAME_$(1),rustrt)
+CFG_RUNTIME_$(1) :=$(call CFG_STATIC_LIB_NAME_$(1),rustrt)
 CFG_RUSTLLVM_$(1) :=$(call CFG_LIB_NAME_$(1),rustllvm)
 CFG_STDLIB_$(1) :=$(call CFG_LIB_NAME_$(1),std)
 CFG_EXTRALIB_$(1) :=$(call CFG_LIB_NAME_$(1),extra)
@@ -239,6 +247,10 @@ LIBRUSTPKG_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustpkg)
 LIBRUSTDOC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustdoc)
 LIBRUSTUV_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustuv)
 
+EXTRALIB_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,extra)
+STDLIB_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,std)
+LIBRUSTUV_RGLOB_$(1) :=$(call CFG_RLIB_GLOB,rustuv)
+
 endef
 
 # $(1) is the path for directory to match against
@@ -392,42 +404,25 @@ TBIN$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/bin
 TLIB$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/$$(CFG_LIBDIR)
 
 # The name of the standard and extra libraries used by rustc
-ifdef CFG_DISABLE_SHAREDSTD
-  HSTDLIB_DEFAULT$(1)_H_$(3) = \
-    $$(HLIB$(1)_H_$(3))/libstd.rlib
-  TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
-    $$(TLIB$(1)_T_$(2)_H_$(3))/libstd.rlib
-
-  HEXTRALIB_DEFAULT$(1)_H_$(3) = \
-    $$(HLIB$(1)_H_$(3))/libextra.rlib
-  TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
-    $$(TLIB$(1)_T_$(2)_H_$(3))/libextra.rlib
-
-  HLIBRUSTC_DEFAULT$(1)_H_$(3) = \
-    $$(HLIB$(1)_H_$(3))/librustc.rlib
-  TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3) = \
-    $$(TLIB$(1)_T_$(2)_H_$(3))/librustc.rlib
-else
-  HSTDLIB_DEFAULT$(1)_H_$(3) = \
-    $$(HLIB$(1)_H_$(3))/$(CFG_STDLIB_$(3))
-  TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
-    $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2))
-
-  HEXTRALIB_DEFAULT$(1)_H_$(3) = \
-    $$(HLIB$(1)_H_$(3))/$(CFG_EXTRALIB_$(3))
-  TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
-    $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))
-
-  HLIBRUSTC_DEFAULT$(1)_H_$(3) = \
-    $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTC_$(3))
-  TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3) = \
-    $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2))
-
-  HLIBRUSTUV_DEFAULT$(1)_H_$(3) = \
-    $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTUV_$(3))
-  TLIBRUSTUV_DEFAULT$(1)_T_$(2)_H_$(3) = \
-    $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2))
-endif
+HSTDLIB_DEFAULT$(1)_H_$(3) = \
+  $$(HLIB$(1)_H_$(3))/$(CFG_STDLIB_$(3))
+TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
+  $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2))
+
+HEXTRALIB_DEFAULT$(1)_H_$(3) = \
+  $$(HLIB$(1)_H_$(3))/$(CFG_EXTRALIB_$(3))
+TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
+  $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))
+
+HLIBRUSTC_DEFAULT$(1)_H_$(3) = \
+  $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTC_$(3))
+TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3) = \
+  $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2))
+
+HLIBRUSTUV_DEFAULT$(1)_H_$(3) = \
+  $$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTUV_$(3))
+TLIBRUSTUV_DEFAULT$(1)_T_$(2)_H_$(3) = \
+  $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2))
 
 # Preqrequisites for using the stageN compiler
 HSREQ$(1)_H_$(3) = \
index 2390016b3f189e28e09cbdc14480197c44900c07..bd76c32fbfa0806a98fc8a0c011e978b2aed3cf3 100755 (executable)
--- a/configure
+++ b/configure
@@ -364,7 +364,6 @@ fi
 BOOL_OPTIONS=""
 VAL_OPTIONS=""
 
-opt sharedstd 1 "build libstd as a shared library"
 opt valgrind 0 "run tests with valgrind (memcheck by default)"
 opt helgrind 0 "run tests with helgrind instead of memcheck"
 opt docs     1 "build documentation"
@@ -398,7 +397,7 @@ valopt sysconfdir "/etc" "install system configuration files"
 valopt datadir "${CFG_PREFIX}/share" "install data"
 valopt infodir "${CFG_PREFIX}/share/info" "install additional info"
 valopt mandir "${CFG_PREFIX}/share/man" "install man pages in PATH"
-valopt libdir "${CFG_PREFIX}/lib" "install libraries" 
+valopt libdir "${CFG_PREFIX}/lib" "install libraries"
 
 # Validate Options
 step_msg "validating $CFG_SELF args"
@@ -608,7 +607,7 @@ CFG_PREFIX=${CFG_PREFIX%/}
 CFG_MANDIR=${CFG_MANDIR%/}
 CFG_HOST="$(echo $CFG_HOST | tr ',' ' ')"
 CFG_TARGET="$(echo $CFG_TARGET | tr ',' ' ')"
-CFG_SUPPORTED_TARGET="$(grep ^CC_*=* $CFG_SRC_DIR/mk/platform.mk | sed -e 's/^CC_//' -e 's/\([^=]*\).*/\1/' | xargs)"
+CFG_SUPPORTED_TARGET="$(grep ^CC_*=* ${CFG_SRC_DIR}mk/platform.mk | sed -e 's/^CC_//' -e 's/\([^=]*\).*/\1/' | xargs)"
 
 # copy host-triples to target-triples so that hosts are a subset of targets
 V_TEMP=""
index a25f19371bd7b70e0148fad92a245c4d91a2dfe9..969e40e632a158cf972cff38af942277b0ac071b 100644 (file)
@@ -1507,19 +1507,15 @@ an `abi` string, as shown here:
 extern "stdcall" { }
 ~~~~
 
-The `link_name` attribute allows the name of the library to be specified.
+The `link` attribute allows the name of the library to be specified. When
+specified the compiler will attempt to link against the native library of the
+specified name.
 
 ~~~~ {.xfail-test}
-#[link_name = "crypto"]
+#[link(name = "crypto")]
 extern { }
 ~~~~
 
-The `nolink` attribute tells the Rust compiler
-not to do any linking for the external block.
-This is particularly useful for creating external blocks for libc,
-which tends to not follow standard library naming conventions
-and is linked to all Rust programs anyway.
-
 The type of a function
 declared in an extern block
 is `extern "abi" fn(A1, ..., An) -> R`,
index dc2aefeb8653475587559a1acac443131e9bc2c7..1994fec0990caf129ea4ca41838edb383a73b040 100644 (file)
@@ -59,6 +59,7 @@ clean-generic-$(2)-$(1):
        $(Q)find $(1)/rustllvm \
                 $(1)/rt \
                 $(1)/test \
+                $(1)/stage* \
          -name '*.[odasS]' -o \
          -name '*.so' -o      \
          -name '*.dylib' -o   \
@@ -91,13 +92,16 @@ clean$(1)_H_$(2):
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTC_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBSYNTAX_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(STDLIB_GLOB_$(2))
+       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(STDLIB_RGLOB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(EXTRALIB_GLOB_$(2))
+       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(EXTRALIB_RGLOB_$(2))
+       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTUV_GLOB_$(2))
+       $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTUV_RGLOB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTC_GLOB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBSYNTAX_GLOB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTPKG_GLOB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTDOC_GLOB_$(2))
        $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUSTLLVM_$(2))
-       $(Q)rm -f $$(HLIB$(1)_H_$(2))/libstd.rlib
 
 endef
 
@@ -122,14 +126,16 @@ clean$(1)_T_$(2)_H_$(3):
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(STDLIB_GLOB_$(2))
+       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(STDLIB_RGLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(EXTRALIB_GLOB_$(2))
+       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(EXTRALIB_RGLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTUV_GLOB_$(2))
+       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTUV_RGLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTC_GLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBSYNTAX_GLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTPKG_GLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTDOC_GLOB_$(2))
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM_$(2))
-       $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libstd.rlib
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/librun_pass_stage* # For unix
        $(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/run_pass_stage* # For windows
index 9ba2b978f1075775ef028186493da62d9121536c..7e8a3e8a6eb1497497e182aced1a08986f92cf4b 100644 (file)
@@ -50,7 +50,7 @@ $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)): \
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(4)),$$(notdir $$@))
        $$(Q)cp $$< $$@
        $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTC_GLOB_$(4)) \
-               $(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTC_DSYM_GLOB_$(4))) \
+               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTC_DSYM_GLOB_$(4))) \
                $$(HLIB$(2)_H_$(4))
        $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTC_GLOB_$(4)),$$(notdir $$@))
 
@@ -82,6 +82,7 @@ $$(HLIB$(2)_H_$(4))/$(CFG_STDLIB_$(4)): \
        | $$(HLIB$(2)_H_$(4))/
        @$$(call E, cp: $$@)
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(4)),$$(notdir $$@))
+       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_RGLOB_$(4)),$$(notdir $$@))
        $$(Q)cp $$< $$@
 # Subtle: We do not let the shell expand $$(STDLIB_DSYM_GLOB) directly rather
 # we use Make's $$(wildcard) facility. The reason is that, on mac, when using
@@ -91,9 +92,11 @@ $$(HLIB$(2)_H_$(4))/$(CFG_STDLIB_$(4)): \
 # Make instead expands the glob to nothing, which gives us the correct behavior.
 # (Copy .dsym file if it exists, but do nothing otherwise)
        $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(STDLIB_GLOB_$(4)) \
+               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(STDLIB_RGLOB_$(4))) \
                $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(STDLIB_DSYM_GLOB_$(4))) \
                $$(HLIB$(2)_H_$(4))
        $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(4)),$$(notdir $$@))
+       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_RGLOB_$(4)),$$(notdir $$@))
 
 $$(HLIB$(2)_H_$(4))/$(CFG_EXTRALIB_$(4)): \
        $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
@@ -102,11 +105,14 @@ $$(HLIB$(2)_H_$(4))/$(CFG_EXTRALIB_$(4)): \
        | $$(HLIB$(2)_H_$(4))/
        @$$(call E, cp: $$@)
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(4)),$$(notdir $$@))
+       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_RGLOB_$(4)),$$(notdir $$@))
        $$(Q)cp $$< $$@
        $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(EXTRALIB_GLOB_$(4)) \
+               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(EXTRALIB_RGLOB_$(4))) \
                $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(EXTRALIB_DSYM_GLOB_$(4))) \
                $$(HLIB$(2)_H_$(4))
        $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(4)),$$(notdir $$@))
+       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_RGLOB_$(4)),$$(notdir $$@))
 
 $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTUV_$(4)): \
        $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTUV_$(4)) \
@@ -115,35 +121,14 @@ $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTUV_$(4)): \
        | $$(HLIB$(2)_H_$(4))/
        @$$(call E, cp: $$@)
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(4)),$$(notdir $$@))
+       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_RGLOB_$(4)),$$(notdir $$@))
        $$(Q)cp $$< $$@
        $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTUV_GLOB_$(4)) \
+               $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTUV_RGLOB_$(4))) \
                $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTUV_DSYM_GLOB_$(4))) \
                $$(HLIB$(2)_H_$(4))
        $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(4)),$$(notdir $$@))
-
-$$(HLIB$(2)_H_$(4))/libstd.rlib: \
-       $$(TLIB$(1)_T_$(4)_H_$(3))/libstd.rlib \
-       $$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME_$(4)) \
-       | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
-
-$$(HLIB$(2)_H_$(4))/libextra.rlib: \
-       $$(TLIB$(1)_T_$(4)_H_$(3))/libextra.rlib \
-       $$(HLIB$(2)_H_$(4))/libstd.rlib \
-       $$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME_$(4)) \
-       | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
-
-$$(HLIB$(2)_H_$(4))/librustc.rlib: \
-       $$(TLIB$(1)_T_$(4)_H_$(3))/librustc.rlib \
-       $$(HLIB$(2)_H_$(4))/libstd.rlib \
-       $$(HLIB$(2)_H_$(4))/libextra.rlib \
-       $$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME_$(4)) \
-       | $$(HLIB$(2)_H_$(4))/
-       @$$(call E, cp: $$@)
-       $$(Q)cp $$< $$@
+       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_RGLOB_$(4)),$$(notdir $$@))
 
 $$(HLIB$(2)_H_$(4))/$(CFG_RUSTLLVM_$(4)): \
        $$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_RUSTLLVM_$(4)) \
index 49f1fdbf547c958f76886fd0ad715f0dc80a968c..7d6c0ea5264268c742beb28e3d90d8dbcb0c2aec 100644 (file)
@@ -88,7 +88,6 @@ install-target-$(1)-host-$(2): LIB_SOURCE_DIR=$$(TL$(1)$(2))
 install-target-$(1)-host-$(2): LIB_DESTIN_DIR=$$(PTL$(1)$(2))
 install-target-$(1)-host-$(2): $$(TSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
        $$(Q)$$(call MK_INSTALL_DIR,$$(PTL$(1)$(2)))
-       $$(Q)$$(call INSTALL_LIB,$$(CFG_RUNTIME_$(1)))
        $$(Q)$$(call INSTALL_LIB,$$(STDLIB_GLOB_$(1)))
        $$(Q)$$(call INSTALL_LIB,$$(EXTRALIB_GLOB_$(1)))
        $$(Q)$$(call INSTALL_LIB,$$(LIBRUSTUV_GLOB_$(1)))
@@ -101,7 +100,6 @@ install-target-$(1)-host-$(2): LIB_SOURCE_DIR=$$(TL$(1)$(2))
 install-target-$(1)-host-$(2): LIB_DESTIN_DIR=$$(PTL$(1)$(2))
 install-target-$(1)-host-$(2): $$(CSREQ$$(ISTAGE)_T_$(1)_H_$(2))
        $$(Q)$$(call MK_INSTALL_DIR,$$(PTL$(1)$(2)))
-       $$(Q)$$(call INSTALL_LIB,$$(CFG_RUNTIME_$(1)))
        $$(Q)$$(call INSTALL_LIB,$$(CFG_RUSTLLVM_$(1)))
        $$(Q)$$(call INSTALL_LIB,$$(STDLIB_GLOB_$(1)))
        $$(Q)$$(call INSTALL_LIB,$$(EXTRALIB_GLOB_$(1)))
@@ -144,13 +142,15 @@ install-host: $(CSREQ$(ISTAGE)_T_$(CFG_BUILD_)_H_$(CFG_BUILD_))
        $(Q)$(call INSTALL,$(HB2),$(PHB),rustpkg$(X_$(CFG_BUILD)))
        $(Q)$(call INSTALL,$(HB2),$(PHB),rustdoc$(X_$(CFG_BUILD)))
        $(Q)$(call INSTALL_LIB,$(STDLIB_GLOB_$(CFG_BUILD)))
+       $(Q)$(call INSTALL_LIB,$(STDLIB_RGLOB_$(CFG_BUILD)))
        $(Q)$(call INSTALL_LIB,$(EXTRALIB_GLOB_$(CFG_BUILD)))
+       $(Q)$(call INSTALL_LIB,$(EXTRALIB_RGLOB_$(CFG_BUILD)))
        $(Q)$(call INSTALL_LIB,$(LIBRUSTUV_GLOB_$(CFG_BUILD)))
+       $(Q)$(call INSTALL_LIB,$(LIBRUSTUV_RGLOB_$(CFG_BUILD)))
        $(Q)$(call INSTALL_LIB,$(LIBRUSTC_GLOB_$(CFG_BUILD)))
        $(Q)$(call INSTALL_LIB,$(LIBSYNTAX_GLOB_$(CFG_BUILD)))
        $(Q)$(call INSTALL_LIB,$(LIBRUSTPKG_GLOB_$(CFG_BUILD)))
        $(Q)$(call INSTALL_LIB,$(LIBRUSTDOC_GLOB_$(CFG_BUILD)))
-       $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUNTIME_$(CFG_BUILD)))
        $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUSTLLVM_$(CFG_BUILD)))
        $(Q)$(call INSTALL,$(S)/man,$(CFG_MANDIR)/man1,rustc.1)
        $(Q)$(call INSTALL,$(S)/man,$(CFG_MANDIR)/man1,rustdoc.1)
@@ -167,11 +167,13 @@ uninstall:
        $(Q)rm -f $(PHB)/rustpkg$(X_$(CFG_BUILD))
        $(Q)rm -f $(PHB)/rustdoc$(X_$(CFG_BUILD))
        $(Q)rm -f $(PHL)/$(CFG_RUSTLLVM_$(CFG_BUILD))
-       $(Q)rm -f $(PHL)/$(CFG_RUNTIME_$(CFG_BUILD))
        $(Q)for i in \
           $(call HOST_LIB_FROM_HL_GLOB,$(STDLIB_GLOB_$(CFG_BUILD))) \
+          $(call HOST_LIB_FROM_HL_GLOB,$(STDLIB_RGLOB_$(CFG_BUILD))) \
           $(call HOST_LIB_FROM_HL_GLOB,$(EXTRALIB_GLOB_$(CFG_BUILD))) \
+          $(call HOST_LIB_FROM_HL_GLOB,$(EXTRALIB_RGLOB_$(CFG_BUILD))) \
           $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTUV_GLOB_$(CFG_BUILD))) \
+          $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTUV_RGLOB_$(CFG_BUILD))) \
           $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTC_GLOB_$(CFG_BUILD))) \
           $(call HOST_LIB_FROM_HL_GLOB,$(LIBSYNTAX_GLOB_$(CFG_BUILD))) \
           $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTPKG_GLOB_$(CFG_BUILD))) \
@@ -232,7 +234,6 @@ endif
 define INSTALL_RUNTIME_TARGET_N
 install-runtime-target-$(1)-host-$(2): $$(TSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
        $(Q)$(call ADB_SHELL,mkdir,$(CFG_RUNTIME_PUSH_DIR))
-       $(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(CFG_RUNTIME_$(1)),$(CFG_RUNTIME_PUSH_DIR))
        $(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(STDLIB_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
        $(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(EXTRALIB_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
        $(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(LIBRUSTUV_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
@@ -241,7 +242,6 @@ endef
 define INSTALL_RUNTIME_TARGET_CLEANUP_N
 install-runtime-target-$(1)-cleanup:
        $(Q)$(call ADB,remount)
-       $(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(CFG_RUNTIME_$(1)))
        $(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(STDLIB_GLOB_$(1)))
        $(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(EXTRALIB_GLOB_$(1)))
        $(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(LIBRUSTUV_GLOB_$(1)))
index 53f955bd284aa80b2948223b9934cbf069cf6d0b..efaa109c29e91c2da37c065fa45faf90e0c28ab3 100644 (file)
@@ -14,8 +14,8 @@ LLVM_DEPS := $(S)/.gitmodules
 else
 
 # This is just a rough approximation of LLVM deps
-LLVM_DEPS_SRC=$(call rwildcard,$(CFG_LLVM_SRC_DIR)/lib,*cpp *hpp)
-LLVM_DEPS_INC=$(call rwildcard,$(CFG_LLVM_SRC_DIR)/include,*cpp *hpp)
+LLVM_DEPS_SRC=$(call rwildcard,$(CFG_LLVM_SRC_DIR)lib,*cpp *hpp)
+LLVM_DEPS_INC=$(call rwildcard,$(CFG_LLVM_SRC_DIR)include,*cpp *hpp)
 LLVM_DEPS=$(LLVM_DEPS_SRC) $(LLVM_DEPS_INC)
 endif
 
index bc2536cce4834874c7b1f383c23f74cc8876daca..35d4279eaef97bb7f925e068b52da86bc1b47ce1 100644 (file)
@@ -138,6 +138,7 @@ endif
 endif
 endif
 
+CFG_RLIB_GLOB=lib$(1)-*.rlib
 
 # x86_64-unknown-linux-gnu configuration
 CC_x86_64-unknown-linux-gnu=$(CC)
index cc22d5781a6a2dd8e8013e9f63120726667f340c..f27ed8714f471c12d0a800321a8b247bcaed065c 100644 (file)
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -121,11 +121,9 @@ $$(RT_BUILD_DIR_$(1)_$(2))/arch/$$(HOST_$(1))/libmorestack.a: $$(MORESTACK_OBJS_
        @$$(call E, link: $$@)
        $$(Q)$(AR_$(1)) rcs $$@ $$^
 
-$$(RT_BUILD_DIR_$(1)_$(2))/$(CFG_RUNTIME_$(1)): $$(RUNTIME_OBJS_$(1)_$(2)) $$(MKFILE_DEPS) \
-                        $$(RUNTIME_DEF_$(1)_$(2))
+$$(RT_BUILD_DIR_$(1)_$(2))/$(CFG_RUNTIME_$(1)): $$(RUNTIME_OBJS_$(1)_$(2)) $$(MKFILE_DEPS)
        @$$(call E, link: $$@)
-       $$(Q)$$(call CFG_LINK_CXX_$(1),$$@, $$(RUNTIME_OBJS_$(1)_$(2)) \
-           $$(CFG_LIBUV_LINK_FLAGS_$(1)),$$(RUNTIME_DEF_$(1)_$(2)),$$(CFG_RUNTIME_$(1)))
+       $$(Q)$(AR_$(1)) rcs $$@ $$(RUNTIME_OBJS_$(1)_$(2))
 
 # These could go in rt.mk or rustllvm.mk, they're needed for both.
 
index f7d8ec83a5a17cc70775b9bd923d17de066aa14a..a8606cbdbcb658baa0368b9324ddd714aa17a1ff 100644 (file)
@@ -60,8 +60,10 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)): \
                | $$(TLIB$(1)_T_$(2)_H_$(3))/
        @$$(call E, compile_and_link: $$@)
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(2)),$$(notdir $$@))
+       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_RGLOB_$(2)),$$(notdir $$@))
        $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) --out-dir $$(@D) $$< && touch $$@
        $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_GLOB_$(2)),$$(notdir $$@))
+       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(STDLIB_RGLOB_$(2)),$$(notdir $$@))
 
 $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \
                $$(EXTRALIB_CRATE) $$(EXTRALIB_INPUTS) \
@@ -70,8 +72,10 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \
                | $$(TLIB$(1)_T_$(2)_H_$(3))/
        @$$(call E, compile_and_link: $$@)
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(2)),$$(notdir $$@))
+       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_RGLOB_$(2)),$$(notdir $$@))
        $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) --out-dir $$(@D) $$< && touch $$@
        $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_GLOB_$(2)),$$(notdir $$@))
+       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(EXTRALIB_RGLOB_$(2)),$$(notdir $$@))
 
 $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2)): \
                $$(LIBRUSTUV_CRATE) $$(LIBRUSTUV_INPUTS) \
@@ -82,11 +86,13 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTUV_$(2)): \
                | $$(TLIB$(1)_T_$(2)_H_$(3))/
        @$$(call E, compile_and_link: $$@)
        $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(2)),$$(notdir $$@))
+       $$(call REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_RGLOB_$(2)),$$(notdir $$@))
        $$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) \
                -L $$(UV_SUPPORT_DIR_$(2)) \
                -L $$(dir $$(LIBUV_LIB_$(2))) \
                --out-dir $$(@D) $$< && touch $$@
        $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_GLOB_$(2)),$$(notdir $$@))
+       $$(call LIST_ALL_OLD_GLOB_MATCHES_EXCEPT,$$(dir $$@),$(LIBRUSTUV_RGLOB_$(2)),$$(notdir $$@))
 
 $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)): \
                 $$(LIBSYNTAX_CRATE) $$(LIBSYNTAX_INPUTS) \
index a24791d76af975d8a54c26d161fdba7be6aa58f7..86436abe43ded4ae8d3d76bd7eabe9a0ab6a49aa 100644 (file)
@@ -98,7 +98,7 @@ ifdef CFG_UNIXY_$(1)
 endif
 
 ifdef CFG_WINDOWSY_$(1)
-  CFG_TESTLIB_$(1)=$$(CFG_BUILD_DIR)/$$(2)/$$(strip \
+  CFG_TESTLIB_$(1)=$$(CFG_BUILD_DIR)$$(2)/$$(strip \
    $$(if $$(findstring stage0,$$(1)), \
        stage0/$$(CFG_LIBDIR), \
       $$(if $$(findstring stage1,$$(1)), \
@@ -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 \
@@ -584,6 +585,10 @@ TEST_SREQ$(1)_T_$(2)_H_$(3) = \
 # remove directive, if present, from CFG_RUSTC_FLAGS (issue #7898).
 CTEST_RUSTC_FLAGS := $$(subst --cfg ndebug,,$$(CFG_RUSTC_FLAGS))
 
+# There's no need our entire test suite to take up gigabytes of space on disk
+# including copies of libstd/libextra all over the place
+CTEST_RUSTC_FLAGS := $$(CTEST_RUSTC_FLAGS) -Z prefer-dynamic
+
 # The tests can not be optimized while the rest of the compiler is optimized, so
 # filter out the optimization (if any) from rustc and then figure out if we need
 # to be optimized
@@ -766,6 +771,7 @@ TEST_GROUPS = \
        cfail \
        bench \
        perf \
+       rmake \
        debuginfo \
        codegen \
        doc \
@@ -896,3 +902,37 @@ 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: $$*
+       $$(Q)python $(S)src/etc/maketest.py $$(dir $$<) \
+           $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
+           $(3)/test/run-make/$$* \
+           "$$(CC_$(3)) $$(CFG_GCCISH_CFLAGS_$(3))"
+       @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 (file)
index 0000000..96c658e
--- /dev/null
@@ -0,0 +1,27 @@
+# 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]))
+os.putenv('CC', sys.argv[4])
+
+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)
+
index 99193d905f87fdabb5bdaa98d54fa9093ae2765b..03ada0eef18331057b69642110b2eb9623f6d2ed 100644 (file)
@@ -31,7 +31,6 @@ snapshot_files = {
               "lib/librustc-*.so",
               "lib/libsyntax-*.so",
               "lib/librustuv-*.so",
-              "lib/librustrt.so",
               "lib/librustllvm.so"],
     "macos": ["bin/rustc",
               "lib/libstd-*.dylib",
@@ -39,7 +38,6 @@ snapshot_files = {
               "lib/librustc-*.dylib",
               "lib/libsyntax-*.dylib",
               "lib/librustuv-*.dylib",
-              "lib/librustrt.dylib",
               "lib/librustllvm.dylib"],
     "winnt": ["bin/rustc.exe",
               "bin/std-*.dll",
@@ -47,7 +45,6 @@ snapshot_files = {
               "bin/rustc-*.dll",
               "bin/syntax-*.dll",
               "bin/rustuv-*.dll",
-              "bin/rustrt.dll",
               "bin/rustllvm.dll"],
     "freebsd": ["bin/rustc",
                 "lib/libstd-*.so",
@@ -55,7 +52,6 @@ snapshot_files = {
                 "lib/librustc-*.so",
                 "lib/libsyntax-*.so",
                 "lib/librustuv-*.so",
-                "lib/librustrt.so",
                 "lib/librustllvm.so"]
     }
 
index 3d1d0c91e317d1c57b52d4f4cc09bea35f5ba098..a4a10ccfa73fa98067cf752ddc792750cf38b01d 100644 (file)
@@ -23,7 +23,7 @@
 pub mod rustrt {
     use std::libc::{c_int, c_void, size_t};
 
-    #[link_name = "rustrt"]
+    #[link(name = "rustrt")]
     extern {
         pub fn tdefl_compress_mem_to_heap(psrc_buf: *c_void,
                                           src_buf_len: size_t,
index 273996513926608497e689f1da301ed7322ab943..30288a08c79df5c48f7c9370864495f6809a55ac 100644 (file)
@@ -54,7 +54,7 @@ pub struct Error {
     /// The column number at which the error occurred
     priv col: uint,
     /// A message describing the type of the error
-    priv msg: @~str,
+    priv msg: ~str,
 }
 
 fn escape_str(s: &str) -> ~str {
@@ -84,17 +84,19 @@ fn spaces(n: uint) -> ~str {
 }
 
 /// A structure for implementing serialization to JSON.
-pub struct Encoder {
-    priv wr: @mut io::Writer,
+pub struct Encoder<'self> {
+    priv wr: &'self mut io::Writer,
 }
 
-/// Creates a new JSON encoder whose output will be written to the writer
-/// specified.
-pub fn Encoder(wr: @mut io::Writer) -> Encoder {
-    Encoder { wr: wr }
+impl<'self> Encoder<'self> {
+    /// Creates a new JSON encoder whose output will be written to the writer
+    /// specified.
+    pub fn init<'a>(wr: &'a mut io::Writer) -> Encoder<'a> {
+        Encoder { wr: wr }
+    }
 }
 
-impl serialize::Encoder for Encoder {
+impl<'self> serialize::Encoder for Encoder<'self> {
     fn emit_nil(&mut self) { write!(self.wr, "null") }
 
     fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); }
@@ -127,13 +129,13 @@ fn emit_str(&mut self, v: &str) {
         write!(self.wr, "{}", escape_str(v))
     }
 
-    fn emit_enum(&mut self, _name: &str, f: |&mut Encoder|) { f(self) }
+    fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'self>|) { f(self) }
 
     fn emit_enum_variant(&mut self,
                          name: &str,
                          _id: uint,
                          cnt: uint,
-                         f: |&mut Encoder|) {
+                         f: |&mut Encoder<'self>|) {
         // enums are encoded as strings or objects
         // Bunny => "Bunny"
         // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
@@ -148,7 +150,7 @@ fn emit_enum_variant(&mut self,
         }
     }
 
-    fn emit_enum_variant_arg(&mut self, idx: uint, f: |&mut Encoder|) {
+    fn emit_enum_variant_arg(&mut self, idx: uint, f: |&mut Encoder<'self>|) {
         if idx != 0 {
             write!(self.wr, ",");
         }
@@ -159,18 +161,18 @@ fn emit_enum_struct_variant(&mut self,
                                 name: &str,
                                 id: uint,
                                 cnt: uint,
-                                f: |&mut Encoder|) {
+                                f: |&mut Encoder<'self>|) {
         self.emit_enum_variant(name, id, cnt, f)
     }
 
     fn emit_enum_struct_variant_field(&mut self,
                                       _: &str,
                                       idx: uint,
-                                      f: |&mut Encoder|) {
+                                      f: |&mut Encoder<'self>|) {
         self.emit_enum_variant_arg(idx, f)
     }
 
-    fn emit_struct(&mut self, _: &str, _: uint, f: |&mut Encoder|) {
+    fn emit_struct(&mut self, _: &str, _: uint, f: |&mut Encoder<'self>|) {
         write!(self.wr, r"\{");
         f(self);
         write!(self.wr, r"\}");
@@ -179,58 +181,58 @@ fn emit_struct(&mut self, _: &str, _: uint, f: |&mut Encoder|) {
     fn emit_struct_field(&mut self,
                          name: &str,
                          idx: uint,
-                         f: |&mut Encoder|) {
+                         f: |&mut Encoder<'self>|) {
         if idx != 0 { write!(self.wr, ",") }
         write!(self.wr, "{}:", escape_str(name));
         f(self);
     }
 
-    fn emit_tuple(&mut self, len: uint, f: |&mut Encoder|) {
+    fn emit_tuple(&mut self, len: uint, f: |&mut Encoder<'self>|) {
         self.emit_seq(len, f)
     }
-    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder|) {
+    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut Encoder<'self>|) {
         self.emit_seq_elt(idx, f)
     }
 
     fn emit_tuple_struct(&mut self,
                          _name: &str,
                          len: uint,
-                         f: |&mut Encoder|) {
+                         f: |&mut Encoder<'self>|) {
         self.emit_seq(len, f)
     }
-    fn emit_tuple_struct_arg(&mut self, idx: uint, f: |&mut Encoder|) {
+    fn emit_tuple_struct_arg(&mut self, idx: uint, f: |&mut Encoder<'self>|) {
         self.emit_seq_elt(idx, f)
     }
 
-    fn emit_option(&mut self, f: |&mut Encoder|) { f(self); }
+    fn emit_option(&mut self, f: |&mut Encoder<'self>|) { f(self); }
     fn emit_option_none(&mut self) { self.emit_nil(); }
-    fn emit_option_some(&mut self, f: |&mut Encoder|) { f(self); }
+    fn emit_option_some(&mut self, f: |&mut Encoder<'self>|) { f(self); }
 
-    fn emit_seq(&mut self, _len: uint, f: |&mut Encoder|) {
+    fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'self>|) {
         write!(self.wr, "[");
         f(self);
         write!(self.wr, "]");
     }
 
-    fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder|) {
+    fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder<'self>|) {
         if idx != 0 {
             write!(self.wr, ",");
         }
         f(self)
     }
 
-    fn emit_map(&mut self, _len: uint, f: |&mut Encoder|) {
+    fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'self>|) {
         write!(self.wr, r"\{");
         f(self);
         write!(self.wr, r"\}");
     }
 
-    fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Encoder|) {
+    fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Encoder<'self>|) {
         if idx != 0 { write!(self.wr, ",") }
         f(self)
     }
 
-    fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder|) {
+    fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'self>|) {
         write!(self.wr, ":");
         f(self)
     }
@@ -238,20 +240,22 @@ fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder|) {
 
 /// Another encoder for JSON, but prints out human-readable JSON instead of
 /// compact data
-pub struct PrettyEncoder {
-    priv wr: @mut io::Writer,
+pub struct PrettyEncoder<'self> {
+    priv wr: &'self mut io::Writer,
     priv indent: uint,
 }
 
-/// Creates a new encoder whose output will be written to the specified writer
-pub fn PrettyEncoder(wr: @mut io::Writer) -> PrettyEncoder {
-    PrettyEncoder {
-        wr: wr,
-        indent: 0,
+impl<'self> PrettyEncoder<'self> {
+    /// Creates a new encoder whose output will be written to the specified writer
+    pub fn init<'a>(wr: &'a mut io::Writer) -> PrettyEncoder<'a> {
+        PrettyEncoder {
+            wr: wr,
+            indent: 0,
+        }
     }
 }
 
-impl serialize::Encoder for PrettyEncoder {
+impl<'self> serialize::Encoder for PrettyEncoder<'self> {
     fn emit_nil(&mut self) { write!(self.wr, "null") }
 
     fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); }
@@ -282,7 +286,7 @@ fn emit_f64(&mut self, v: f64) {
     fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) }
     fn emit_str(&mut self, v: &str) { write!(self.wr, "{}", escape_str(v)); }
 
-    fn emit_enum(&mut self, _name: &str, f: |&mut PrettyEncoder|) {
+    fn emit_enum(&mut self, _name: &str, f: |&mut PrettyEncoder<'self>|) {
         f(self)
     }
 
@@ -290,7 +294,7 @@ fn emit_enum_variant(&mut self,
                          name: &str,
                          _: uint,
                          cnt: uint,
-                         f: |&mut PrettyEncoder|) {
+                         f: |&mut PrettyEncoder<'self>|) {
         if cnt == 0 {
             write!(self.wr, "{}", escape_str(name));
         } else {
@@ -304,7 +308,7 @@ fn emit_enum_variant(&mut self,
 
     fn emit_enum_variant_arg(&mut self,
                              idx: uint,
-                             f: |&mut PrettyEncoder|) {
+                             f: |&mut PrettyEncoder<'self>|) {
         if idx != 0 {
             write!(self.wr, ",\n");
         }
@@ -316,14 +320,14 @@ fn emit_enum_struct_variant(&mut self,
                                 name: &str,
                                 id: uint,
                                 cnt: uint,
-                                f: |&mut PrettyEncoder|) {
+                                f: |&mut PrettyEncoder<'self>|) {
         self.emit_enum_variant(name, id, cnt, f)
     }
 
     fn emit_enum_struct_variant_field(&mut self,
                                       _: &str,
                                       idx: uint,
-                                      f: |&mut PrettyEncoder|) {
+                                      f: |&mut PrettyEncoder<'self>|) {
         self.emit_enum_variant_arg(idx, f)
     }
 
@@ -331,7 +335,7 @@ fn emit_enum_struct_variant_field(&mut self,
     fn emit_struct(&mut self,
                    _: &str,
                    len: uint,
-                   f: |&mut PrettyEncoder|) {
+                   f: |&mut PrettyEncoder<'self>|) {
         if len == 0 {
             write!(self.wr, "\\{\\}");
         } else {
@@ -346,7 +350,7 @@ fn emit_struct(&mut self,
     fn emit_struct_field(&mut self,
                          name: &str,
                          idx: uint,
-                         f: |&mut PrettyEncoder|) {
+                         f: |&mut PrettyEncoder<'self>|) {
         if idx == 0 {
             write!(self.wr, "\n");
         } else {
@@ -356,30 +360,30 @@ fn emit_struct_field(&mut self,
         f(self);
     }
 
-    fn emit_tuple(&mut self, len: uint, f: |&mut PrettyEncoder|) {
+    fn emit_tuple(&mut self, len: uint, f: |&mut PrettyEncoder<'self>|) {
         self.emit_seq(len, f)
     }
-    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut PrettyEncoder|) {
+    fn emit_tuple_arg(&mut self, idx: uint, f: |&mut PrettyEncoder<'self>|) {
         self.emit_seq_elt(idx, f)
     }
 
     fn emit_tuple_struct(&mut self,
                          _: &str,
                          len: uint,
-                         f: |&mut PrettyEncoder|) {
+                         f: |&mut PrettyEncoder<'self>|) {
         self.emit_seq(len, f)
     }
     fn emit_tuple_struct_arg(&mut self,
                              idx: uint,
-                             f: |&mut PrettyEncoder|) {
+                             f: |&mut PrettyEncoder<'self>|) {
         self.emit_seq_elt(idx, f)
     }
 
-    fn emit_option(&mut self, f: |&mut PrettyEncoder|) { f(self); }
+    fn emit_option(&mut self, f: |&mut PrettyEncoder<'self>|) { f(self); }
     fn emit_option_none(&mut self) { self.emit_nil(); }
-    fn emit_option_some(&mut self, f: |&mut PrettyEncoder|) { f(self); }
+    fn emit_option_some(&mut self, f: |&mut PrettyEncoder<'self>|) { f(self); }
 
-    fn emit_seq(&mut self, len: uint, f: |&mut PrettyEncoder|) {
+    fn emit_seq(&mut self, len: uint, f: |&mut PrettyEncoder<'self>|) {
         if len == 0 {
             write!(self.wr, "[]");
         } else {
@@ -391,7 +395,7 @@ fn emit_seq(&mut self, len: uint, f: |&mut PrettyEncoder|) {
         }
     }
 
-    fn emit_seq_elt(&mut self, idx: uint, f: |&mut PrettyEncoder|) {
+    fn emit_seq_elt(&mut self, idx: uint, f: |&mut PrettyEncoder<'self>|) {
         if idx == 0 {
             write!(self.wr, "\n");
         } else {
@@ -401,7 +405,7 @@ fn emit_seq_elt(&mut self, idx: uint, f: |&mut PrettyEncoder|) {
         f(self)
     }
 
-    fn emit_map(&mut self, len: uint, f: |&mut PrettyEncoder|) {
+    fn emit_map(&mut self, len: uint, f: |&mut PrettyEncoder<'self>|) {
         if len == 0 {
             write!(self.wr, "\\{\\}");
         } else {
@@ -413,7 +417,7 @@ fn emit_map(&mut self, len: uint, f: |&mut PrettyEncoder|) {
         }
     }
 
-    fn emit_map_elt_key(&mut self, idx: uint, f: |&mut PrettyEncoder|) {
+    fn emit_map_elt_key(&mut self, idx: uint, f: |&mut PrettyEncoder<'self>|) {
         if idx == 0 {
             write!(self.wr, "\n");
         } else {
@@ -423,7 +427,7 @@ fn emit_map_elt_key(&mut self, idx: uint, f: |&mut PrettyEncoder|) {
         f(self);
     }
 
-    fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut PrettyEncoder|) {
+    fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut PrettyEncoder<'self>|) {
         write!(self.wr, ": ");
         f(self);
     }
@@ -444,43 +448,45 @@ fn encode(&self, e: &mut E) {
 
 impl Json{
     /// Encodes a json value into a io::writer.  Uses a single line.
-    pub fn to_writer(&self, wr: @mut io::Writer) {
-        let mut encoder = Encoder(wr);
+    pub fn to_writer(&self, wr: &mut io::Writer) {
+        let mut encoder = Encoder::init(wr);
         self.encode(&mut encoder)
     }
 
     /// Encodes a json value into a io::writer.
     /// Pretty-prints in a more readable format.
-    pub fn to_pretty_writer(&self, wr: @mut io::Writer) {
-        let mut encoder = PrettyEncoder(wr);
+    pub fn to_pretty_writer(&self, wr: &mut io::Writer) {
+        let mut encoder = PrettyEncoder::init(wr);
         self.encode(&mut encoder)
     }
 
     /// Encodes a json value into a string
     pub fn to_pretty_str(&self) -> ~str {
-        let s = @mut MemWriter::new();
-        self.to_pretty_writer(s as @mut io::Writer);
-        str::from_utf8(s.inner_ref().as_slice())
+        let mut s = MemWriter::new();
+        self.to_pretty_writer(&mut s as &mut io::Writer);
+        str::from_utf8_owned(s.inner())
     }
 }
 
 pub struct Parser<T> {
-    priv rdr: ~T,
+    priv rdr: T,
     priv ch: char,
     priv line: uint,
     priv col: uint,
 }
 
-/// Decode a json value from an Iterator<char>
-pub fn Parser<T : Iterator<char>>(rdr: ~T) -> Parser<T> {
-    let mut p = Parser {
-        rdr: rdr,
-        ch: '\x00',
-        line: 1,
-        col: 0,
-    };
-    p.bump();
-    p
+impl<T: Iterator<char>> Parser<T> {
+    /// Decode a json value from an Iterator<char>
+    pub fn init(rdr: T) -> Parser<T> {
+        let mut p = Parser {
+            rdr: rdr,
+            ch: '\x00',
+            line: 1,
+            col: 0,
+        };
+        p.bump();
+        p
+    }
 }
 
 impl<T: Iterator<char>> Parser<T> {
@@ -525,7 +531,7 @@ fn next_char(&mut self) -> char {
     }
 
     fn error<T>(&self, msg: ~str) -> Result<T, Error> {
-        Err(Error { line: self.line, col: self.col, msg: @msg })
+        Err(Error { line: self.line, col: self.col, msg: msg })
     }
 
     fn parse_value(&mut self) -> Result<Json, Error> {
@@ -841,14 +847,14 @@ fn parse_object(&mut self) -> Result<Json, Error> {
 
 /// Decodes a json value from an `&mut io::Reader`
 pub fn from_reader(rdr: &mut io::Reader) -> Result<Json, Error> {
-    let s = str::from_utf8(rdr.read_to_end());
-    let mut parser = Parser(~s.chars());
+    let s = str::from_utf8_owned(rdr.read_to_end());
+    let mut parser = Parser::init(s.chars());
     parser.parse()
 }
 
 /// Decodes a json value from a string
 pub fn from_str(s: &str) -> Result<Json, Error> {
-    let mut parser = Parser(~s.chars());
+    let mut parser = Parser::init(s.chars());
     parser.parse()
 }
 
@@ -857,10 +863,12 @@ pub struct Decoder {
     priv stack: ~[Json],
 }
 
-/// Creates a new decoder instance for decoding the specified JSON value.
-pub fn Decoder(json: Json) -> Decoder {
-    Decoder {
-        stack: ~[json]
+impl Decoder {
+    /// Creates a new decoder instance for decoding the specified JSON value.
+    pub fn init(json: Json) -> Decoder {
+        Decoder {
+            stack: ~[json]
+        }
     }
 }
 
@@ -1195,10 +1203,6 @@ impl ToJson for Json {
     fn to_json(&self) -> Json { (*self).clone() }
 }
 
-impl ToJson for @Json {
-    fn to_json(&self) -> Json { (**self).to_json() }
-}
-
 impl ToJson for int {
     fn to_json(&self) -> Json { Number(*self as f64) }
 }
@@ -1259,10 +1263,6 @@ impl ToJson for ~str {
     fn to_json(&self) -> Json { String((*self).clone()) }
 }
 
-impl ToJson for @~str {
-    fn to_json(&self) -> Json { String((**self).clone()) }
-}
-
 impl<A:ToJson,B:ToJson> ToJson for (A, B) {
     fn to_json(&self) -> Json {
         match *self {
@@ -1319,15 +1319,15 @@ fn to_json(&self) -> Json {
 impl to_str::ToStr for Json {
     /// Encodes a json value into a string
     fn to_str(&self) -> ~str {
-        let s = @mut MemWriter::new();
-        self.to_writer(s as @mut io::Writer);
-        str::from_utf8(s.inner_ref().as_slice())
+        let mut s = MemWriter::new();
+        self.to_writer(&mut s as &mut io::Writer);
+        str::from_utf8_owned(s.inner())
     }
 }
 
 impl to_str::ToStr for Error {
     fn to_str(&self) -> ~str {
-        format!("{}:{}: {}", self.line, self.col, *self.msg)
+        format!("{}:{}: {}", self.line, self.col, self.msg)
     }
 }
 
@@ -1507,14 +1507,14 @@ fn test_write_object() {
         assert_eq!(a.clone(), from_str(a.to_pretty_str()).unwrap());
     }
 
-    fn with_str_writer(f: |@mut io::Writer|) -> ~str {
+    fn with_str_writer(f: |&mut io::Writer|) -> ~str {
         use std::io::mem::MemWriter;
         use std::io::Decorator;
         use std::str;
 
-        let m = @mut MemWriter::new();
-        f(m as @mut io::Writer);
-        str::from_utf8(*m.inner_ref())
+        let mut m = MemWriter::new();
+        f(&mut m as &mut io::Writer);
+        str::from_utf8_owned(m.inner())
     }
 
     #[test]
@@ -1522,14 +1522,14 @@ fn test_write_enum() {
         let animal = Dog;
         assert_eq!(
             with_str_writer(|wr| {
-                let mut encoder = Encoder(wr);
+                let mut encoder = Encoder::init(wr);
                 animal.encode(&mut encoder);
             }),
             ~"\"Dog\""
         );
         assert_eq!(
             with_str_writer(|wr| {
-                let mut encoder = PrettyEncoder(wr);
+                let mut encoder = PrettyEncoder::init(wr);
                 animal.encode(&mut encoder);
             }),
             ~"\"Dog\""
@@ -1538,14 +1538,14 @@ fn test_write_enum() {
         let animal = Frog(~"Henry", 349);
         assert_eq!(
             with_str_writer(|wr| {
-                let mut encoder = Encoder(wr);
+                let mut encoder = Encoder::init(wr);
                 animal.encode(&mut encoder);
             }),
             ~"{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"
         );
         assert_eq!(
             with_str_writer(|wr| {
-                let mut encoder = PrettyEncoder(wr);
+                let mut encoder = PrettyEncoder::init(wr);
                 animal.encode(&mut encoder);
             }),
             ~"\
@@ -1561,14 +1561,14 @@ fn test_write_enum() {
     fn test_write_some() {
         let value = Some(~"jodhpurs");
         let s = with_str_writer(|wr| {
-            let mut encoder = Encoder(wr);
+            let mut encoder = Encoder::init(wr);
             value.encode(&mut encoder);
         });
         assert_eq!(s, ~"\"jodhpurs\"");
 
         let value = Some(~"jodhpurs");
         let s = with_str_writer(|wr| {
-            let mut encoder = PrettyEncoder(wr);
+            let mut encoder = PrettyEncoder::init(wr);
             value.encode(&mut encoder);
         });
         assert_eq!(s, ~"\"jodhpurs\"");
@@ -1578,13 +1578,13 @@ fn test_write_some() {
     fn test_write_none() {
         let value: Option<~str> = None;
         let s = with_str_writer(|wr| {
-            let mut encoder = Encoder(wr);
+            let mut encoder = Encoder::init(wr);
             value.encode(&mut encoder);
         });
         assert_eq!(s, ~"null");
 
         let s = with_str_writer(|wr| {
-            let mut encoder = Encoder(wr);
+            let mut encoder = Encoder::init(wr);
             value.encode(&mut encoder);
         });
         assert_eq!(s, ~"null");
@@ -1593,35 +1593,35 @@ fn test_write_none() {
     #[test]
     fn test_trailing_characters() {
         assert_eq!(from_str("nulla"),
-            Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"}));
+            Err(Error {line: 1u, col: 5u, msg: ~"trailing characters"}));
         assert_eq!(from_str("truea"),
-            Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"}));
+            Err(Error {line: 1u, col: 5u, msg: ~"trailing characters"}));
         assert_eq!(from_str("falsea"),
-            Err(Error {line: 1u, col: 6u, msg: @~"trailing characters"}));
+            Err(Error {line: 1u, col: 6u, msg: ~"trailing characters"}));
         assert_eq!(from_str("1a"),
-            Err(Error {line: 1u, col: 2u, msg: @~"trailing characters"}));
+            Err(Error {line: 1u, col: 2u, msg: ~"trailing characters"}));
         assert_eq!(from_str("[]a"),
-            Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"}));
+            Err(Error {line: 1u, col: 3u, msg: ~"trailing characters"}));
         assert_eq!(from_str("{}a"),
-            Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"}));
+            Err(Error {line: 1u, col: 3u, msg: ~"trailing characters"}));
     }
 
     #[test]
     fn test_read_identifiers() {
         assert_eq!(from_str("n"),
-            Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
+            Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"}));
         assert_eq!(from_str("nul"),
-            Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
+            Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"}));
 
         assert_eq!(from_str("t"),
-            Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
+            Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"}));
         assert_eq!(from_str("truz"),
-            Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
+            Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"}));
 
         assert_eq!(from_str("f"),
-            Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}));
+            Err(Error {line: 1u, col: 2u, msg: ~"invalid syntax"}));
         assert_eq!(from_str("faz"),
-            Err(Error {line: 1u, col: 3u, msg: @~"invalid syntax"}));
+            Err(Error {line: 1u, col: 3u, msg: ~"invalid syntax"}));
 
         assert_eq!(from_str("null"), Ok(Null));
         assert_eq!(from_str("true"), Ok(Boolean(true)));
@@ -1633,15 +1633,15 @@ fn test_read_identifiers() {
 
     #[test]
     fn test_decode_identifiers() {
-        let mut decoder = Decoder(from_str("null").unwrap());
+        let mut decoder = Decoder::init(from_str("null").unwrap());
         let v: () = Decodable::decode(&mut decoder);
         assert_eq!(v, ());
 
-        let mut decoder = Decoder(from_str("true").unwrap());
+        let mut decoder = Decoder::init(from_str("true").unwrap());
         let v: bool = Decodable::decode(&mut decoder);
         assert_eq!(v, true);
 
-        let mut decoder = Decoder(from_str("false").unwrap());
+        let mut decoder = Decoder::init(from_str("false").unwrap());
         let v: bool = Decodable::decode(&mut decoder);
         assert_eq!(v, false);
     }
@@ -1649,20 +1649,20 @@ fn test_decode_identifiers() {
     #[test]
     fn test_read_number() {
         assert_eq!(from_str("+"),
-            Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"}));
+            Err(Error {line: 1u, col: 1u, msg: ~"invalid syntax"}));
         assert_eq!(from_str("."),
-            Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"}));
+            Err(Error {line: 1u, col: 1u, msg: ~"invalid syntax"}));
 
         assert_eq!(from_str("-"),
-            Err(Error {line: 1u, col: 2u, msg: @~"invalid number"}));
+            Err(Error {line: 1u, col: 2u, msg: ~"invalid number"}));
         assert_eq!(from_str("00"),
-            Err(Error {line: 1u, col: 2u, msg: @~"invalid number"}));
+            Err(Error {line: 1u, col: 2u, msg: ~"invalid number"}));
         assert_eq!(from_str("1."),
-            Err(Error {line: 1u, col: 3u, msg: @~"invalid number"}));
+            Err(Error {line: 1u, col: 3u, msg: ~"invalid number"}));
         assert_eq!(from_str("1e"),
-            Err(Error {line: 1u, col: 3u, msg: @~"invalid number"}));
+            Err(Error {line: 1u, col: 3u, msg: ~"invalid number"}));
         assert_eq!(from_str("1e+"),
-            Err(Error {line: 1u, col: 4u, msg: @~"invalid number"}));
+            Err(Error {line: 1u, col: 4u, msg: ~"invalid number"}));
 
         assert_eq!(from_str("3"), Ok(Number(3.0)));
         assert_eq!(from_str("3.1"), Ok(Number(3.1)));
@@ -1676,31 +1676,31 @@ fn test_read_number() {
 
     #[test]
     fn test_decode_numbers() {
-        let mut decoder = Decoder(from_str("3").unwrap());
+        let mut decoder = Decoder::init(from_str("3").unwrap());
         let v: f64 = Decodable::decode(&mut decoder);
         assert_eq!(v, 3.0);
 
-        let mut decoder = Decoder(from_str("3.1").unwrap());
+        let mut decoder = Decoder::init(from_str("3.1").unwrap());
         let v: f64 = Decodable::decode(&mut decoder);
         assert_eq!(v, 3.1);
 
-        let mut decoder = Decoder(from_str("-1.2").unwrap());
+        let mut decoder = Decoder::init(from_str("-1.2").unwrap());
         let v: f64 = Decodable::decode(&mut decoder);
         assert_eq!(v, -1.2);
 
-        let mut decoder = Decoder(from_str("0.4").unwrap());
+        let mut decoder = Decoder::init(from_str("0.4").unwrap());
         let v: f64 = Decodable::decode(&mut decoder);
         assert_eq!(v, 0.4);
 
-        let mut decoder = Decoder(from_str("0.4e5").unwrap());
+        let mut decoder = Decoder::init(from_str("0.4e5").unwrap());
         let v: f64 = Decodable::decode(&mut decoder);
         assert_eq!(v, 0.4e5);
 
-        let mut decoder = Decoder(from_str("0.4e15").unwrap());
+        let mut decoder = Decoder::init(from_str("0.4e15").unwrap());
         let v: f64 = Decodable::decode(&mut decoder);
         assert_eq!(v, 0.4e15);
 
-        let mut decoder = Decoder(from_str("0.4e-01").unwrap());
+        let mut decoder = Decoder::init(from_str("0.4e-01").unwrap());
         let v: f64 = Decodable::decode(&mut decoder);
         assert_eq!(v, 0.4e-01);
     }
@@ -1708,10 +1708,10 @@ fn test_decode_numbers() {
     #[test]
     fn test_read_str() {
         assert_eq!(from_str("\""),
-            Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing string"
+            Err(Error {line: 1u, col: 2u, msg: ~"EOF while parsing string"
         }));
         assert_eq!(from_str("\"lol"),
-            Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing string"
+            Err(Error {line: 1u, col: 5u, msg: ~"EOF while parsing string"
         }));
 
         assert_eq!(from_str("\"\""), Ok(String(~"")));
@@ -1728,39 +1728,39 @@ fn test_read_str() {
 
     #[test]
     fn test_decode_str() {
-        let mut decoder = Decoder(from_str("\"\"").unwrap());
+        let mut decoder = Decoder::init(from_str("\"\"").unwrap());
         let v: ~str = Decodable::decode(&mut decoder);
         assert_eq!(v, ~"");
 
-        let mut decoder = Decoder(from_str("\"foo\"").unwrap());
+        let mut decoder = Decoder::init(from_str("\"foo\"").unwrap());
         let v: ~str = Decodable::decode(&mut decoder);
         assert_eq!(v, ~"foo");
 
-        let mut decoder = Decoder(from_str("\"\\\"\"").unwrap());
+        let mut decoder = Decoder::init(from_str("\"\\\"\"").unwrap());
         let v: ~str = Decodable::decode(&mut decoder);
         assert_eq!(v, ~"\"");
 
-        let mut decoder = Decoder(from_str("\"\\b\"").unwrap());
+        let mut decoder = Decoder::init(from_str("\"\\b\"").unwrap());
         let v: ~str = Decodable::decode(&mut decoder);
         assert_eq!(v, ~"\x08");
 
-        let mut decoder = Decoder(from_str("\"\\n\"").unwrap());
+        let mut decoder = Decoder::init(from_str("\"\\n\"").unwrap());
         let v: ~str = Decodable::decode(&mut decoder);
         assert_eq!(v, ~"\n");
 
-        let mut decoder = Decoder(from_str("\"\\r\"").unwrap());
+        let mut decoder = Decoder::init(from_str("\"\\r\"").unwrap());
         let v: ~str = Decodable::decode(&mut decoder);
         assert_eq!(v, ~"\r");
 
-        let mut decoder = Decoder(from_str("\"\\t\"").unwrap());
+        let mut decoder = Decoder::init(from_str("\"\\t\"").unwrap());
         let v: ~str = Decodable::decode(&mut decoder);
         assert_eq!(v, ~"\t");
 
-        let mut decoder = Decoder(from_str("\"\\u12ab\"").unwrap());
+        let mut decoder = Decoder::init(from_str("\"\\u12ab\"").unwrap());
         let v: ~str = Decodable::decode(&mut decoder);
         assert_eq!(v, ~"\u12ab");
 
-        let mut decoder = Decoder(from_str("\"\\uAB12\"").unwrap());
+        let mut decoder = Decoder::init(from_str("\"\\uAB12\"").unwrap());
         let v: ~str = Decodable::decode(&mut decoder);
         assert_eq!(v, ~"\uAB12");
     }
@@ -1768,15 +1768,15 @@ fn test_decode_str() {
     #[test]
     fn test_read_list() {
         assert_eq!(from_str("["),
-            Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing value"}));
+            Err(Error {line: 1u, col: 2u, msg: ~"EOF while parsing value"}));
         assert_eq!(from_str("[1"),
-            Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing list"}));
+            Err(Error {line: 1u, col: 3u, msg: ~"EOF while parsing list"}));
         assert_eq!(from_str("[1,"),
-            Err(Error {line: 1u, col: 4u, msg: @~"EOF while parsing value"}));
+            Err(Error {line: 1u, col: 4u, msg: ~"EOF while parsing value"}));
         assert_eq!(from_str("[1,]"),
-            Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}));
+            Err(Error {line: 1u, col: 4u, msg: ~"invalid syntax"}));
         assert_eq!(from_str("[6 7]"),
-            Err(Error {line: 1u, col: 4u, msg: @~"expected `,` or `]`"}));
+            Err(Error {line: 1u, col: 4u, msg: ~"expected `,` or `]`"}));
 
         assert_eq!(from_str("[]"), Ok(List(~[])));
         assert_eq!(from_str("[ ]"), Ok(List(~[])));
@@ -1793,27 +1793,27 @@ fn test_read_list() {
 
     #[test]
     fn test_decode_list() {
-        let mut decoder = Decoder(from_str("[]").unwrap());
+        let mut decoder = Decoder::init(from_str("[]").unwrap());
         let v: ~[()] = Decodable::decode(&mut decoder);
         assert_eq!(v, ~[]);
 
-        let mut decoder = Decoder(from_str("[null]").unwrap());
+        let mut decoder = Decoder::init(from_str("[null]").unwrap());
         let v: ~[()] = Decodable::decode(&mut decoder);
         assert_eq!(v, ~[()]);
 
-        let mut decoder = Decoder(from_str("[true]").unwrap());
+        let mut decoder = Decoder::init(from_str("[true]").unwrap());
         let v: ~[bool] = Decodable::decode(&mut decoder);
         assert_eq!(v, ~[true]);
 
-        let mut decoder = Decoder(from_str("[true]").unwrap());
+        let mut decoder = Decoder::init(from_str("[true]").unwrap());
         let v: ~[bool] = Decodable::decode(&mut decoder);
         assert_eq!(v, ~[true]);
 
-        let mut decoder = Decoder(from_str("[3, 1]").unwrap());
+        let mut decoder = Decoder::init(from_str("[3, 1]").unwrap());
         let v: ~[int] = Decodable::decode(&mut decoder);
         assert_eq!(v, ~[3, 1]);
 
-        let mut decoder = Decoder(from_str("[[3], [1, 2]]").unwrap());
+        let mut decoder = Decoder::init(from_str("[[3], [1, 2]]").unwrap());
         let v: ~[~[uint]] = Decodable::decode(&mut decoder);
         assert_eq!(v, ~[~[3], ~[1, 2]]);
     }
@@ -1824,49 +1824,49 @@ fn test_read_object() {
             Err(Error {
                 line: 1u,
                 col: 2u,
-                msg: @~"EOF while parsing object"}));
+                msg: ~"EOF while parsing object"}));
         assert_eq!(from_str("{ "),
             Err(Error {
                 line: 1u,
                 col: 3u,
-                msg: @~"EOF while parsing object"}));
+                msg: ~"EOF while parsing object"}));
         assert_eq!(from_str("{1"),
             Err(Error {
                 line: 1u,
                 col: 2u,
-                msg: @~"key must be a string"}));
+                msg: ~"key must be a string"}));
         assert_eq!(from_str("{ \"a\""),
             Err(Error {
                 line: 1u,
                 col: 6u,
-                msg: @~"EOF while parsing object"}));
+                msg: ~"EOF while parsing object"}));
         assert_eq!(from_str("{\"a\""),
             Err(Error {
                 line: 1u,
                 col: 5u,
-                msg: @~"EOF while parsing object"}));
+                msg: ~"EOF while parsing object"}));
         assert_eq!(from_str("{\"a\" "),
             Err(Error {
                 line: 1u,
                 col: 6u,
-                msg: @~"EOF while parsing object"}));
+                msg: ~"EOF while parsing object"}));
 
         assert_eq!(from_str("{\"a\" 1"),
-            Err(Error {line: 1u, col: 6u, msg: @~"expected `:`"}));
+            Err(Error {line: 1u, col: 6u, msg: ~"expected `:`"}));
         assert_eq!(from_str("{\"a\":"),
-            Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing value"}));
+            Err(Error {line: 1u, col: 6u, msg: ~"EOF while parsing value"}));
         assert_eq!(from_str("{\"a\":1"),
             Err(Error {
                 line: 1u,
                 col: 7u,
-                msg: @~"EOF while parsing object"}));
+                msg: ~"EOF while parsing object"}));
         assert_eq!(from_str("{\"a\":1 1"),
-            Err(Error {line: 1u, col: 8u, msg: @~"expected `,` or `}`"}));
+            Err(Error {line: 1u, col: 8u, msg: ~"expected `,` or `}`"}));
         assert_eq!(from_str("{\"a\":1,"),
             Err(Error {
                 line: 1u,
                 col: 8u,
-                msg: @~"EOF while parsing object"}));
+                msg: ~"EOF while parsing object"}));
 
         assert_eq!(from_str("{}").unwrap(), mk_object([]));
         assert_eq!(from_str("{\"a\": 3}").unwrap(),
@@ -1915,7 +1915,7 @@ fn test_decode_struct() {
                 { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] }
             ]
         }";
-        let mut decoder = Decoder(from_str(s).unwrap());
+        let mut decoder = Decoder::init(from_str(s).unwrap());
         let v: Outer = Decodable::decode(&mut decoder);
         assert_eq!(
             v,
@@ -1929,23 +1929,23 @@ fn test_decode_struct() {
 
     #[test]
     fn test_decode_option() {
-        let mut decoder = Decoder(from_str("null").unwrap());
+        let mut decoder = Decoder::init(from_str("null").unwrap());
         let value: Option<~str> = Decodable::decode(&mut decoder);
         assert_eq!(value, None);
 
-        let mut decoder = Decoder(from_str("\"jodhpurs\"").unwrap());
+        let mut decoder = Decoder::init(from_str("\"jodhpurs\"").unwrap());
         let value: Option<~str> = Decodable::decode(&mut decoder);
         assert_eq!(value, Some(~"jodhpurs"));
     }
 
     #[test]
     fn test_decode_enum() {
-        let mut decoder = Decoder(from_str("\"Dog\"").unwrap());
+        let mut decoder = Decoder::init(from_str("\"Dog\"").unwrap());
         let value: Animal = Decodable::decode(&mut decoder);
         assert_eq!(value, Dog);
 
-        let mut decoder =
-            Decoder(from_str("{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}").unwrap());
+        let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}";
+        let mut decoder = Decoder::init(from_str(s).unwrap());
         let value: Animal = Decodable::decode(&mut decoder);
         assert_eq!(value, Frog(~"Henry", 349));
     }
@@ -1953,7 +1953,7 @@ fn test_decode_enum() {
     #[test]
     fn test_decode_map() {
         let s = ~"{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\"fields\":[\"Henry\", 349]}}";
-        let mut decoder = Decoder(from_str(s).unwrap());
+        let mut decoder = Decoder::init(from_str(s).unwrap());
         let mut map: TreeMap<~str, Animal> = Decodable::decode(&mut decoder);
 
         assert_eq!(map.pop(&~"a"), Some(Dog));
@@ -1966,7 +1966,7 @@ fn test_multiline_errors() {
             Err(Error {
                 line: 3u,
                 col: 8u,
-                msg: @~"EOF while parsing object"}));
+                msg: ~"EOF while parsing object"}));
     }
 
     #[deriving(Decodable)]
@@ -1990,7 +1990,7 @@ fn check_err<T: Decodable<Decoder>>(to_parse: &'static str, expected_error: &str
             match from_str(to_parse) {
                 Err(e) => Some(e.to_str()),
                 Ok(json) => {
-                    let _: T = Decodable::decode(&mut Decoder(json));
+                    let _: T = Decodable::decode(&mut Decoder::init(json));
                     None
                 }
             }
index a74c4993be3507e6b317bd9c019481d0f0a2b137..ce504d8bf6fcffc04f61ad8173d09fa9de2ed9eb 100644 (file)
 
 #[comment = "Rust extras"];
 #[license = "MIT/ASL2"];
-#[crate_type = "lib"];
+#[crate_type = "lib"]; // NOTE: remove after stage0 snapshot
+#[crate_type = "rlib"];
+#[crate_type = "dylib"];
 
 #[feature(macro_rules, globs, managed_boxes)];
 
 #[deny(non_camel_case_types)];
 #[deny(missing_doc)];
+#[allow(attribute_usage)]; // NOTE: remove after the next snapshot
 
 use std::str::{StrSlice, OwnedStr};
 
index 2fd38825ae2fb630db725f887980c6130233709e..93ffb8f9fde5eeda21b76aa670c93ad73c442ca9 100644 (file)
@@ -945,8 +945,9 @@ pub fn new() -> MetricMap {
     /// Load MetricDiff from a file.
     pub fn load(p: &Path) -> MetricMap {
         assert!(p.exists());
-        let f = @mut File::open(p) as @mut io::Reader;
-        let mut decoder = json::Decoder(json::from_reader(f).unwrap());
+        let mut f = File::open(p);
+        let value = json::from_reader(&mut f as &mut io::Reader).unwrap();
+        let mut decoder = json::Decoder::init(value);
         MetricMap(Decodable::decode(&mut decoder))
     }
 
index beb211339083dcce2bd8560a334b06f2f6ef36be..ab36defe5221418f28e6aa49114c8e09ef49b9b1 100644 (file)
@@ -191,7 +191,7 @@ fn load(&mut self) {
                     Err(e) => fail!("Couldn't parse workcache database (from file {}): {}",
                                     self.db_filename.display(), e.to_str()),
                     Ok(r) => {
-                        let mut decoder = json::Decoder(r);
+                        let mut decoder = json::Decoder::init(r);
                         self.db_cache = Decodable::decode(&mut decoder);
                     }
             }
@@ -256,9 +256,9 @@ enum Work<'self, T> {
     WorkFromTask(&'self Prep<'self>, PortOne<(Exec, T)>),
 }
 
-fn json_encode<T:Encodable<json::Encoder>>(t: &T) -> ~str {
-    let writer = @mut MemWriter::new();
-    let mut encoder = json::Encoder(writer as @mut io::Writer);
+fn json_encode<'self, T:Encodable<json::Encoder<'self>>>(t: &T) -> ~str {
+    let mut writer = MemWriter::new();
+    let mut encoder = json::Encoder::init(&mut writer as &mut io::Writer);
     t.encode(&mut encoder);
     str::from_utf8(writer.inner_ref().as_slice())
 }
@@ -267,7 +267,7 @@ fn json_encode<T:Encodable<json::Encoder>>(t: &T) -> ~str {
 fn json_decode<T:Decodable<json::Decoder>>(s: &str) -> T {
     debug!("json decoding: {}", s);
     let j = json::from_str(s).unwrap();
-    let mut decoder = json::Decoder(j);
+    let mut decoder = json::Decoder::init(j);
     Decodable::decode(&mut decoder)
 }
 
@@ -396,15 +396,15 @@ fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool {
         return true;
     }
 
-    pub fn exec<T:Send +
-        Encodable<json::Encoder> +
+    pub fn exec<'self, T:Send +
+        Encodable<json::Encoder<'self>> +
         Decodable<json::Decoder>>(
             &'self self, blk: proc(&mut Exec) -> T) -> T {
         self.exec_work(blk).unwrap()
     }
 
-    fn exec_work<T:Send +
-        Encodable<json::Encoder> +
+    fn exec_work<'self, T:Send +
+        Encodable<json::Encoder<'self>> +
         Decodable<json::Decoder>>( // FIXME(#5121)
             &'self self, blk: proc(&mut Exec) -> T) -> Work<'self, T> {
         let mut bo = Some(blk);
@@ -449,7 +449,7 @@ fn exec_work<T:Send +
 }
 
 impl<'self, T:Send +
-       Encodable<json::Encoder> +
+       Encodable<json::Encoder<'self>> +
        Decodable<json::Decoder>>
     Work<'self, T> { // FIXME(#5121)
 
diff --git a/src/librustc/back/archive.rs b/src/librustc/back/archive.rs
new file mode 100644 (file)
index 0000000..9f5aaf3
--- /dev/null
@@ -0,0 +1,138 @@
+// 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.
+
+//! A helper class for dealing with static archives
+
+use driver::session::Session;
+use metadata::filesearch;
+
+use std::io::fs;
+use std::os;
+use std::run::{ProcessOptions, Process, ProcessOutput};
+use std::str;
+use extra::tempfile::TempDir;
+use syntax::abi;
+
+pub struct Archive {
+    priv sess: Session,
+    priv dst: Path,
+}
+
+fn run_ar(sess: Session, args: &str, cwd: Option<&Path>,
+        paths: &[&Path]) -> ProcessOutput {
+    let ar = sess.opts.ar.clone().unwrap_or_else(|| ~"ar");
+    let mut args = ~[args.to_owned()];
+    let mut paths = paths.iter().map(|p| p.as_str().unwrap().to_owned());
+    args.extend(&mut paths);
+    let mut opts = ProcessOptions::new();
+    opts.dir = cwd;
+    debug!("{} {}", ar, args.connect(" "));
+    match cwd {
+        Some(p) => { debug!("inside {}", p.display()); }
+        None => {}
+    }
+    let o = Process::new(ar, args.as_slice(), opts).finish_with_output();
+    if !o.status.success() {
+        sess.err(format!("{} failed with: {}", ar, o.status));
+        sess.note(format!("stdout ---\n{}", str::from_utf8(o.output)));
+        sess.note(format!("stderr ---\n{}", str::from_utf8(o.error)));
+        sess.abort_if_errors();
+    }
+    o
+}
+
+impl Archive {
+    /// Initializes a new static archive with the given object file
+    pub fn create<'a>(sess: Session, dst: &'a Path,
+                      initial_object: &'a Path) -> Archive {
+        run_ar(sess, "crus", None, [dst, initial_object]);
+        Archive { sess: sess, dst: dst.clone() }
+    }
+
+    /// Opens an existing static archive
+    pub fn open(sess: Session, dst: Path) -> Archive {
+        assert!(dst.exists());
+        Archive { sess: sess, dst: dst }
+    }
+
+    /// Read a file in the archive
+    pub fn read(&self, file: &str) -> ~[u8] {
+        // Apparently if "ar p" is used on windows, it generates a corrupt file
+        // which has bad headers and LLVM will immediately choke on it
+        if cfg!(windows) && cfg!(windows) { // FIXME(#10734) double-and
+            let loc = TempDir::new("rsar").unwrap();
+            let archive = os::make_absolute(&self.dst);
+            run_ar(self.sess, "x", Some(loc.path()), [&archive,
+                                                      &Path::init(file)]);
+            fs::File::open(&loc.path().join(file)).read_to_end()
+        } else {
+            run_ar(self.sess, "p", None, [&self.dst, &Path::init(file)]).output
+        }
+    }
+
+    /// Adds all of the contents of a native library to this archive. This will
+    /// search in the relevant locations for a library named `name`.
+    pub fn add_native_library(&mut self, name: &str) {
+        let location = self.find_library(name);
+        self.add_archive(&location, name);
+    }
+
+    /// Adds all of the contents of the rlib at the specified path to this
+    /// archive.
+    pub fn add_rlib(&mut self, rlib: &Path) {
+        let name = rlib.filename_str().unwrap().split('-').next().unwrap();
+        self.add_archive(rlib, name);
+    }
+
+    fn add_archive(&mut self, archive: &Path, name: &str) {
+        let loc = TempDir::new("rsar").unwrap();
+
+        // First, extract the contents of the archive to a temporary directory
+        let archive = os::make_absolute(archive);
+        run_ar(self.sess, "x", Some(loc.path()), [&archive]);
+
+        // Next, we must rename all of the inputs to "guaranteed unique names".
+        // The reason for this is that archives are keyed off the name of the
+        // files, so if two files have the same name they will override one
+        // another in the archive (bad).
+        let files = fs::readdir(loc.path());
+        let mut inputs = ~[];
+        for file in files.iter() {
+            let filename = file.filename_str().unwrap();
+            let filename = format!("r-{}-{}", name, filename);
+            let new_filename = file.with_filename(filename);
+            fs::rename(file, &new_filename);
+            inputs.push(new_filename);
+        }
+
+        // Finally, add all the renamed files to this archive
+        let mut args = ~[&self.dst];
+        args.extend(&mut inputs.iter());
+        run_ar(self.sess, "r", None, args.as_slice());
+    }
+
+    fn find_library(&self, name: &str) -> Path {
+        let (prefix, ext) = match self.sess.targ_cfg.os {
+            abi::OsWin32 => ("", "lib"), _ => ("lib", "a"),
+        };
+        let libname = format!("{}{}.{}", prefix, name, ext);
+
+        let mut rustpath = filesearch::rust_path();
+        rustpath.push(self.sess.filesearch.get_target_lib_path());
+        let path = self.sess.opts.addl_lib_search_paths.iter();
+        for path in path.chain(rustpath.iter()) {
+            debug!("looking for {} inside {}", name, path.display());
+            let test = path.join(libname.clone());
+            if test.exists() { return test }
+        }
+        self.sess.fatal(format!("could not find native static library `{}`, \
+                                 perhaps an -L flag is missing?", name));
+    }
+}
index a3ac468a5f02427cbbeaa25b56e973894c9778d7..c155f4bd15b899371e84b39e042badc1eccdc433 100644 (file)
@@ -63,6 +63,6 @@ pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs::
 
         target_triple: target_triple,
 
-        cc_args: ~[~"-marm"]
+        cc_args: ~[~"-marm"],
     };
 }
index 9aba16422d3fd4fdb637d23f21397390d96c7937..8119618da57dcda7f40214271d63c74217872a38 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 
+use back::archive::Archive;
 use back::rpath;
 use driver::session::Session;
 use driver::session;
@@ -16,7 +17,7 @@
 use lib::llvm::ModuleRef;
 use lib;
 use metadata::common::LinkMeta;
-use metadata::{encoder, cstore, filesearch};
+use metadata::{encoder, cstore, filesearch, csearch};
 use middle::trans::context::CrateContext;
 use middle::trans::common::gensym_name;
 use middle::ty;
@@ -30,7 +31,6 @@
 use std::ptr;
 use std::run;
 use std::str;
-use std::vec;
 use std::io::fs;
 use syntax::abi;
 use syntax::ast;
@@ -88,7 +88,6 @@ pub mod jit {
     use driver::session::Session;
     use lib::llvm::llvm;
     use lib::llvm::{ModuleRef, ContextRef, ExecutionEngineRef};
-    use metadata::cstore;
 
     use std::c_str::ToCStr;
     use std::cast;
@@ -125,19 +124,6 @@ pub fn exec(sess: Session,
             // core linked into rustc. We don't want that,
             // incase the user wants to use an older extra library.
 
-            let cstore = sess.cstore;
-            let r = cstore::get_used_crate_files(cstore);
-            for cratepath in r.iter() {
-                debug!("linking: {}", cratepath.display());
-
-                cratepath.with_c_str(|buf_t| {
-                    if !llvm::LLVMRustLoadCrate(manager, buf_t) {
-                        llvm_err(sess, ~"Could not link");
-                    }
-                    debug!("linked: {}", cratepath.display());
-                })
-            }
-
             // We custom-build a JIT execution engine via some rust wrappers
             // first. This wrappers takes ownership of the module passed in.
             let ee = llvm::LLVMRustBuildJIT(manager, m, stacks);
@@ -368,20 +354,20 @@ pub fn run_passes(sess: Session,
     }
 
     pub fn run_assembler(sess: Session, assembly: &Path, object: &Path) {
-        let cc_prog = super::get_cc_prog(sess);
+        let cc = super::get_cc_prog(sess);
 
         // FIXME (#9639): This needs to handle non-utf8 paths
-        let cc_args = ~[
+        let args = [
             ~"-c",
             ~"-o", object.as_str().unwrap().to_owned(),
             assembly.as_str().unwrap().to_owned()];
 
-        let prog = run::process_output(cc_prog, cc_args);
+        debug!("{} {}", cc, args.connect(" "));
+        let prog = run::process_output(cc, args);
 
         if !prog.status.success() {
-            sess.err(format!("linking with `{}` failed: {}", cc_prog, prog.status));
-            sess.note(format!("{} arguments: {}",
-                        cc_prog, cc_args.connect(" ")));
+            sess.err(format!("linking with `{}` failed: {}", cc, prog.status));
+            sess.note(format!("{} arguments: {}", cc, args.connect(" ")));
             sess.note(str::from_utf8(prog.error + prog.output));
             sess.abort_if_errors();
         }
@@ -876,90 +862,71 @@ pub fn mangle_internal_name_by_path(ccx: &mut CrateContext, path: path) -> ~str
     mangle(ccx.sess, path, None, None)
 }
 
-
-pub fn output_dll_filename(os: abi::Os, lm: LinkMeta) -> ~str {
-    let (dll_prefix, dll_suffix) = match os {
-        abi::OsWin32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
-        abi::OsMacos => (macos::DLL_PREFIX, macos::DLL_SUFFIX),
-        abi::OsLinux => (linux::DLL_PREFIX, linux::DLL_SUFFIX),
-        abi::OsAndroid => (android::DLL_PREFIX, android::DLL_SUFFIX),
-        abi::OsFreebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
-    };
-    format!("{}{}-{}-{}{}", dll_prefix, lm.name, lm.extras_hash, lm.vers, dll_suffix)
+pub fn output_lib_filename(lm: LinkMeta) -> ~str {
+    format!("{}-{}-{}", lm.name, lm.extras_hash, lm.vers)
 }
 
 pub fn get_cc_prog(sess: Session) -> ~str {
+    match sess.opts.linker {
+        Some(ref linker) => return linker.to_owned(),
+        None => {}
+    }
+
     // In the future, FreeBSD will use clang as default compiler.
     // It would be flexible to use cc (system's default C compiler)
     // instead of hard-coded gcc.
-    // For win32, there is no cc command, so we add a condition to make it use g++.
-    // We use g++ rather than gcc because it automatically adds linker options required
-    // for generation of dll modules that correctly register stack unwind tables.
-    match sess.opts.linker {
-        Some(ref linker) => linker.to_str(),
-        None => match sess.targ_cfg.os {
-            abi::OsAndroid =>
-                match &sess.opts.android_cross_path {
-                    &Some(ref path) => {
-                        format!("{}/bin/arm-linux-androideabi-gcc", *path)
-                    }
-                    &None => {
-                        sess.fatal("need Android NDK path for linking \
-                                    (--android-cross-path)")
-                    }
-                },
-            abi::OsWin32 => ~"g++",
-            _ => ~"cc"
-        }
+    // For win32, there is no cc command, so we add a condition to make it use
+    // g++.  We use g++ rather than gcc because it automatically adds linker
+    // options required for generation of dll modules that correctly register
+    // stack unwind tables.
+    match sess.targ_cfg.os {
+        abi::OsAndroid => match sess.opts.android_cross_path {
+            Some(ref path) => format!("{}/bin/arm-linux-androideabi-gcc", *path),
+            None => {
+                sess.fatal("need Android NDK path for linking \
+                            (--android-cross-path)")
+            }
+        },
+        abi::OsWin32 => ~"g++",
+        _ => ~"cc",
     }
 }
 
-// If the user wants an exe generated we need to invoke
-// cc to link the object file with some libs
+/// Perform the linkage portion of the compilation phase. This will generate all
+/// of the requested outputs for this compilation session.
 pub fn link_binary(sess: Session,
+                   crate_types: &[~str],
                    obj_filename: &Path,
                    out_filename: &Path,
                    lm: LinkMeta) {
-
-    let cc_prog = get_cc_prog(sess);
-    // The invocations of cc share some flags across platforms
-
-    let output = if *sess.building_library {
-        let long_libname = output_dll_filename(sess.targ_cfg.os, lm);
-        debug!("link_meta.name:  {}", lm.name);
-        debug!("long_libname: {}", long_libname);
-        debug!("out_filename: {}", out_filename.display());
-        let out_dirname = out_filename.dir_path();
-        debug!("dirname(out_filename): {}", out_dirname.display());
-
-        out_filename.with_filename(long_libname)
+    let outputs = if sess.opts.test {
+        // If we're generating a test executable, then ignore all other output
+        // styles at all other locations
+        ~[session::OutputExecutable]
     } else {
-        out_filename.clone()
+        // Always generate whatever was specified on the command line, but also
+        // look at what was in the crate file itself for generating output
+        // formats.
+        let mut outputs = sess.opts.outputs.clone();
+        for ty in crate_types.iter() {
+            if "bin" == *ty {
+                outputs.push(session::OutputExecutable);
+            } else if "dylib" == *ty || "lib" == *ty {
+                outputs.push(session::OutputDylib);
+            } else if "rlib" == *ty {
+                outputs.push(session::OutputRlib);
+            } else if "staticlib" == *ty {
+                outputs.push(session::OutputStaticlib);
+            }
+        }
+        if outputs.len() == 0 {
+            outputs.push(session::OutputExecutable);
+        }
+        outputs
     };
 
-    debug!("output: {}", output.display());
-    let cc_args = link_args(sess, obj_filename, out_filename, lm);
-    debug!("{} link args: {}", cc_prog, cc_args.connect(" "));
-    if (sess.opts.debugging_opts & session::print_link_args) != 0 {
-        println!("{} link args: {}", cc_prog, cc_args.connect(" "));
-    }
-
-    // We run 'cc' here
-    let prog = run::process_output(cc_prog, cc_args);
-
-    if !prog.status.success() {
-        sess.err(format!("linking with `{}` failed: {}", cc_prog, prog.status));
-        sess.note(format!("{} arguments: {}",
-                    cc_prog, cc_args.connect(" ")));
-        sess.note(str::from_utf8(prog.error + prog.output));
-        sess.abort_if_errors();
-    }
-
-    // On OSX, debuggers needs this utility to get run to do some munging of the
-    // symbols
-    if sess.targ_cfg.os == abi::OsMacos && sess.opts.debuginfo {
-        // FIXME (#9639): This needs to handle non-utf8 paths
-        run::process_status("dsymutil", [output.as_str().unwrap().to_owned()]);
+    for output in outputs.move_iter() {
+        link_binary_output(sess, output, obj_filename, out_filename, lm);
     }
 
     // Remove the temporary object file if we aren't saving temps
@@ -971,34 +938,36 @@ pub fn link_binary(sess: Session,
 fn is_writeable(p: &Path) -> bool {
     use std::io;
 
-    !p.exists() ||
-        (match io::result(|| p.stat()) {
-            Err(..) => false,
-            Ok(m) => m.perm & io::UserWrite == io::UserWrite
-        })
+    match io::result(|| p.stat()) {
+        Err(..) => true,
+        Ok(m) => m.perm & io::UserWrite == io::UserWrite
+    }
 }
 
-pub fn link_args(sess: Session,
-                 obj_filename: &Path,
-                 out_filename: &Path,
-                 lm:LinkMeta) -> ~[~str] {
-
-    // Converts a library file-stem into a cc -l argument
-    fn unlib(config: @session::config, stem: ~str) -> ~str {
-        if stem.starts_with("lib") &&
-            config.os != abi::OsWin32 {
-            stem.slice(3, stem.len()).to_owned()
-        } else {
-            stem
+fn link_binary_output(sess: Session,
+                      output: session::OutputStyle,
+                      obj_filename: &Path,
+                      out_filename: &Path,
+                      lm: LinkMeta) {
+    let libname = output_lib_filename(lm);
+    let out_filename = match output {
+        session::OutputRlib => {
+            out_filename.with_filename(format!("lib{}.rlib", libname))
         }
-    }
-
-
-    let output = if *sess.building_library {
-        let long_libname = output_dll_filename(sess.targ_cfg.os, lm);
-        out_filename.with_filename(long_libname)
-    } else {
-        out_filename.clone()
+        session::OutputDylib => {
+            let (prefix, suffix) = match sess.targ_cfg.os {
+                abi::OsWin32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
+                abi::OsMacos => (macos::DLL_PREFIX, macos::DLL_SUFFIX),
+                abi::OsLinux => (linux::DLL_PREFIX, linux::DLL_SUFFIX),
+                abi::OsAndroid => (android::DLL_PREFIX, android::DLL_SUFFIX),
+                abi::OsFreebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
+            };
+            out_filename.with_filename(format!("{}{}{}", prefix, libname, suffix))
+        }
+        session::OutputStaticlib => {
+            out_filename.with_filename(format!("lib{}.a", libname))
+        }
+        session::OutputExecutable => out_filename.clone(),
     };
 
     // Make sure the output and obj_filename are both writeable.
@@ -1006,139 +975,294 @@ fn unlib(config: @session::config, stem: ~str) -> ~str {
     // however, the Linux linker will happily overwrite a read-only file.
     // We should be consistent.
     let obj_is_writeable = is_writeable(obj_filename);
-    let out_is_writeable = is_writeable(&output);
+    let out_is_writeable = is_writeable(&out_filename);
     if !out_is_writeable {
         sess.fatal(format!("Output file {} is not writeable -- check its permissions.",
-                           output.display()));
+                           out_filename.display()));
     }
     else if !obj_is_writeable {
         sess.fatal(format!("Object file {} is not writeable -- check its permissions.",
                            obj_filename.display()));
     }
 
-    // The default library location, we need this to find the runtime.
-    // The location of crates will be determined as needed.
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    let lib_path = sess.filesearch.get_target_lib_path();
-    let stage: ~str = ~"-L" + lib_path.as_str().unwrap();
-
-    let mut args = vec::append(~[stage], sess.targ_cfg.target_strs.cc_args);
-
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    args.push_all([
-        ~"-o", output.as_str().unwrap().to_owned(),
-        obj_filename.as_str().unwrap().to_owned()]);
-
-    let lib_cmd = match sess.targ_cfg.os {
-        abi::OsMacos => ~"-dynamiclib",
-        _ => ~"-shared"
-    };
+    match output {
+        session::OutputRlib => {
+            link_rlib(sess, obj_filename, &out_filename);
+        }
+        session::OutputStaticlib => {
+            link_staticlib(sess, obj_filename, &out_filename);
+        }
+        session::OutputExecutable => {
+            link_natively(sess, false, obj_filename, &out_filename);
+        }
+        session::OutputDylib => {
+            link_natively(sess, true, obj_filename, &out_filename);
+        }
+    }
+}
 
-    // # Crate linking
+// Create an 'rlib'
+//
+// An rlib in its current incarnation is essentially a renamed .a file. The
+// rlib primarily contains the object file of the crate, but it also contains
+// all of the object files from native libraries. This is done by unzipping
+// native libraries and inserting all of the contents into this archive.
+fn link_rlib(sess: Session, obj_filename: &Path,
+             out_filename: &Path) -> Archive {
+    let mut a = Archive::create(sess, out_filename, obj_filename);
+    for &(ref l, kind) in cstore::get_used_libraries(sess.cstore).iter() {
+        match kind {
+            cstore::NativeStatic => {
+                a.add_native_library(l.as_slice());
+            }
+            cstore::NativeUnknown => {}
+        }
+    }
+    return a;
+}
 
-    let cstore = sess.cstore;
-    let r = cstore::get_used_crate_files(cstore);
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    for cratepath in r.iter() {
-        if cratepath.extension_str() == Some("rlib") {
-            args.push(cratepath.as_str().unwrap().to_owned());
-            continue;
+// Create a static archive
+//
+// This is essentially the same thing as an rlib, but it also involves adding
+// all of the upstream crates' objects into the the archive. This will slurp in
+// all of the native libraries of upstream dependencies as well.
+//
+// Additionally, there's no way for us to link dynamic libraries, so we warn
+// about all dynamic library dependencies that they're not linked in.
+fn link_staticlib(sess: Session, obj_filename: &Path, out_filename: &Path) {
+    let mut a = link_rlib(sess, obj_filename, out_filename);
+    a.add_native_library("morestack");
+
+    let crates = cstore::get_used_crates(sess.cstore, cstore::RequireStatic);
+    for &(cnum, ref path) in crates.iter() {
+        let p = match *path {
+            Some(ref p) => p.clone(), None => {
+                sess.err(format!("could not find rlib for: `{}`",
+                                 cstore::get_crate_data(sess.cstore, cnum).name));
+                continue
+            }
+        };
+        a.add_rlib(&p);
+        let native_libs = csearch::get_native_libraries(sess.cstore, cnum);
+        for lib in native_libs.iter() {
+            sess.warn(format!("unlinked native library: {}", *lib));
         }
-        let dir = cratepath.dirname_str().unwrap();
-        if !dir.is_empty() { args.push("-L" + dir); }
-        let libarg = unlib(sess.targ_cfg, cratepath.filestem_str().unwrap().to_owned());
-        args.push("-l" + libarg);
     }
+}
 
-    let ula = cstore::get_used_link_args(cstore);
-    for arg in ula.iter() { args.push(arg.to_owned()); }
+// Create a dynamic library or executable
+//
+// This will invoke the system linker/cc to create the resulting file. This
+// links to all upstream files as well.
+fn link_natively(sess: Session, dylib: bool, obj_filename: &Path,
+                 out_filename: &Path) {
+    // The invocations of cc share some flags across platforms
+    let cc_prog = get_cc_prog(sess);
+    let mut cc_args = sess.targ_cfg.target_strs.cc_args.clone();
+    cc_args.push_all_move(link_args(sess, dylib, obj_filename, out_filename));
+    if (sess.opts.debugging_opts & session::print_link_args) != 0 {
+        println!("{} link args: {}", cc_prog, cc_args.connect(" "));
+    }
 
-    // # Extern library linking
+    // May have not found libraries in the right formats.
+    sess.abort_if_errors();
 
-    // User-supplied library search paths (-L on the cammand line) These are
-    // the same paths used to find Rust crates, so some of them may have been
-    // added already by the previous crate linking code. This only allows them
-    // to be found at compile time so it is still entirely up to outside
-    // forces to make sure that library can be found at runtime.
+    // Invoke the system linker
+    debug!("{} {}", cc_prog, cc_args.connect(" "));
+    let prog = run::process_output(cc_prog, cc_args);
 
-    for path in sess.opts.addl_lib_search_paths.iter() {
-        // FIXME (#9639): This needs to handle non-utf8 paths
-        args.push("-L" + path.as_str().unwrap().to_owned());
+    if !prog.status.success() {
+        sess.err(format!("linking with `{}` failed: {}", cc_prog, prog.status));
+        sess.note(format!("{} arguments: {}", cc_prog, cc_args.connect(" ")));
+        sess.note(str::from_utf8(prog.error + prog.output));
+        sess.abort_if_errors();
     }
 
-    let rustpath = filesearch::rust_path();
-    for path in rustpath.iter() {
+
+    // On OSX, debuggers need this utility to get run to do some munging of
+    // the symbols
+    if sess.targ_cfg.os == abi::OsMacos && sess.opts.debuginfo {
         // FIXME (#9639): This needs to handle non-utf8 paths
-        args.push("-L" + path.as_str().unwrap().to_owned());
+        run::process_status("dsymutil",
+                            [out_filename.as_str().unwrap().to_owned()]);
     }
+}
 
-    if sess.targ_cfg.os == abi::OsLinux {
-        // GNU-style linkers will use this to omit linking to libraries which don't actually fulfill
-        // any relocations, but only for libraries which follow this flag. Thus, use it before
-        // specifing libraries to link to.
-        args.push(~"-Wl,--as-needed");
-    }
+fn link_args(sess: Session,
+             dylib: bool,
+             obj_filename: &Path,
+             out_filename: &Path) -> ~[~str] {
 
-    // The names of the extern libraries
-    let used_libs = cstore::get_used_libraries(cstore);
-    for l in used_libs.iter() { args.push(~"-l" + *l); }
+    // The default library location, we need this to find the runtime.
+    // The location of crates will be determined as needed.
+    // FIXME (#9639): This needs to handle non-utf8 paths
+    let lib_path = sess.filesearch.get_target_lib_path();
+    let stage: ~str = ~"-L" + lib_path.as_str().unwrap();
 
-    if *sess.building_library {
-        args.push(lib_cmd);
+    let mut args = ~[stage];
 
-        // On mac we need to tell the linker to let this library
-        // be rpathed
-        if sess.targ_cfg.os == abi::OsMacos {
-            // FIXME (#9639): This needs to handle non-utf8 paths
-            args.push("-Wl,-install_name,@rpath/"
-                      + output.filename_str().unwrap());
-        }
-    }
+    // FIXME (#9639): This needs to handle non-utf8 paths
+    args.push_all([
+        ~"-o", out_filename.as_str().unwrap().to_owned(),
+        obj_filename.as_str().unwrap().to_owned()]);
 
-    // On linux librt and libdl are an indirect dependencies via rustrt,
-    // and binutils 2.22+ won't add them automatically
     if sess.targ_cfg.os == abi::OsLinux {
-        // GNU-style linkers supports optimization with -O. --gc-sections removes metadata and
-        // potentially other useful things, so don't include it. GNU ld doesn't need a numeric
-        // argument, but other linkers do.
-        if sess.opts.optimize == session::Default || sess.opts.optimize == session::Aggressive {
+        // GNU-style linkers will use this to omit linking to libraries which
+        // don't actually fulfill any relocations, but only for libraries which
+        // follow this flag. Thus, use it before specifing libraries to link to.
+        args.push(~"-Wl,--as-needed");
+
+        // GNU-style linkers support optimization with -O. --gc-sections
+        // removes metadata and potentially other useful things, so don't
+        // include it. GNU ld doesn't need a numeric argument, but other linkers
+        // do.
+        if sess.opts.optimize == session::Default ||
+           sess.opts.optimize == session::Aggressive {
             args.push(~"-Wl,-O1");
         }
+    }
 
-        args.push_all([~"-lrt", ~"-ldl"]);
+    add_upstream_rust_crates(&mut args, sess, dylib);
+    add_local_native_libraries(&mut args, sess);
 
-        // LLVM implements the `frem` instruction as a call to `fmod`,
-        // which lives in libm. Similar to above, on some linuxes we
-        // have to be explicit about linking to it. See #2510
-        args.push(~"-lm");
-    }
-    else if sess.targ_cfg.os == abi::OsAndroid {
-        args.push_all([~"-ldl", ~"-llog",  ~"-lsupc++", ~"-lgnustl_shared"]);
-        args.push(~"-lm");
+    // # Telling the linker what we're doing
+
+    if dylib {
+        // On mac we need to tell the linker to let this library be rpathed
+        if sess.targ_cfg.os == abi::OsMacos {
+            args.push(~"-dynamiclib");
+            args.push(~"-Wl,-dylib");
+            // FIXME (#9639): This needs to handle non-utf8 paths
+            args.push(~"-Wl,-install_name,@rpath/" +
+                      out_filename.filename_str().unwrap());
+        } else {
+            args.push(~"-shared")
+        }
     }
 
     if sess.targ_cfg.os == abi::OsFreebsd {
-        args.push_all([~"-pthread", ~"-lrt",
-                       ~"-L/usr/local/lib", ~"-lexecinfo",
+        args.push_all([~"-L/usr/local/lib",
                        ~"-L/usr/local/lib/gcc46",
-                       ~"-L/usr/local/lib/gcc44", ~"-lstdc++",
-                       ~"-Wl,-z,origin",
-                       ~"-Wl,-rpath,/usr/local/lib/gcc46",
-                       ~"-Wl,-rpath,/usr/local/lib/gcc44"]);
+                       ~"-L/usr/local/lib/gcc44"]);
     }
 
     // Stack growth requires statically linking a __morestack function
     args.push(~"-lmorestack");
 
-    // Always want the runtime linked in
-    args.push(~"-lrustrt");
+    // FIXME (#2397): At some point we want to rpath our guesses as to
+    // where extern libraries might live, based on the
+    // addl_lib_search_paths
+    args.push_all(rpath::get_rpath_flags(sess, out_filename));
 
-    // FIXME (#2397): At some point we want to rpath our guesses as to where
-    // extern libraries might live, based on the addl_lib_search_paths
-    args.push_all(rpath::get_rpath_flags(sess, &output));
-
-    // Finally add all the linker arguments provided on the command line
+    // Finally add all the linker arguments provided on the command line along
+    // with any #[link_args] attributes found inside the crate
     args.push_all(sess.opts.linker_args);
-
+    for arg in cstore::get_used_link_args(sess.cstore).iter() {
+        args.push(arg.clone());
+    }
     return args;
 }
+
+// # Rust Crate linking
+//
+// Rust crates are not considered at all when creating an rlib output. All
+// dependencies will be linked when producing the final output (instead of
+// the intermediate rlib version)
+fn add_upstream_rust_crates(args: &mut ~[~str], sess: Session,
+                            dylib: bool) {
+    // Converts a library file-stem into a cc -l argument
+    fn unlib(config: @session::config, stem: &str) -> ~str {
+        if stem.starts_with("lib") &&
+            config.os != abi::OsWin32 {
+            stem.slice(3, stem.len()).to_owned()
+        } else {
+            stem.to_owned()
+        }
+    }
+
+    let cstore = sess.cstore;
+    if !dylib && !sess.prefer_dynamic() {
+        // With an executable, things get a little interesting. As a limitation
+        // of the current implementation, we require that everything must be
+        // static, or everything must be dynamic. The reasons for this are a
+        // little subtle, but as with the above two cases, the goal is to
+        // prevent duplicate copies of the same library showing up. For example,
+        // a static immediate dependency might show up as an upstream dynamic
+        // dependency and we currently have no way of knowing that. We know that
+        // all dynamic libaries require dynamic dependencies (see above), so
+        // it's satisfactory to include either all static libraries or all
+        // dynamic libraries.
+        let crates = cstore::get_used_crates(cstore,
+                                             cstore::RequireStatic);
+        if crates.iter().all(|&(_, ref p)| p.is_some()) {
+            for &(cnum, ref path) in crates.iter() {
+                let cratepath = path.clone().unwrap();
+
+                // If we're linking to the static version of the crate, then
+                // we're mostly good to go. The caveat here is that we need to
+                // pull in the static crate's native dependencies.
+                args.push(cratepath.as_str().unwrap().to_owned());
+
+                let libs = csearch::get_native_libraries(sess.cstore, cnum);
+                for lib in libs.iter() {
+                    args.push("-l" + *lib);
+                }
+            }
+            return;
+        }
+    }
+
+    // This is a fallback of three different  cases of linking:
+    //
+    // * When creating a dynamic library, all inputs are required to be dynamic
+    //   as well
+    // * If an executable is created with a preference on dynamic linking, then
+    //   this case is the fallback
+    // * If an executable is being created, and one of the inputs is missing as
+    //   a static library, then this is the fallback case.
+    let crates = cstore::get_used_crates(cstore, cstore::RequireDynamic);
+    for &(cnum, ref path) in crates.iter() {
+        let cratepath = match *path {
+            Some(ref p) => p.clone(),
+            None => {
+                sess.err(format!("could not find dynamic library for: `{}`",
+                                 cstore::get_crate_data(sess.cstore, cnum).name));
+                return
+            }
+        };
+        // Just need to tell the linker about where the library lives and what
+        // its name is
+        let dir = cratepath.dirname_str().unwrap();
+        if !dir.is_empty() { args.push("-L" + dir); }
+        let libarg = unlib(sess.targ_cfg, cratepath.filestem_str().unwrap());
+        args.push("-l" + libarg);
+    }
+}
+
+// # Native library linking
+//
+// User-supplied library search paths (-L on the cammand line) These are
+// the same paths used to find Rust crates, so some of them may have been
+// added already by the previous crate linking code. This only allows them
+// to be found at compile time so it is still entirely up to outside
+// forces to make sure that library can be found at runtime.
+//
+// Also note that the native libraries linked here are only the ones located
+// in the current crate. Upstream crates with native library dependencies
+// may have their native library pulled in above.
+fn add_local_native_libraries(args: &mut ~[~str], sess: Session) {
+    for path in sess.opts.addl_lib_search_paths.iter() {
+        // FIXME (#9639): This needs to handle non-utf8 paths
+        args.push("-L" + path.as_str().unwrap().to_owned());
+    }
+
+    let rustpath = filesearch::rust_path();
+    for path in rustpath.iter() {
+        // FIXME (#9639): This needs to handle non-utf8 paths
+        args.push("-L" + path.as_str().unwrap().to_owned());
+    }
+
+    for &(ref l, _) in cstore::get_used_libraries(sess.cstore).iter() {
+        args.push(~"-l" + *l);
+    }
+}
index cbe39efdf8cf0646c0c8e20189f3c0aef559b041..ce716f6f94b3570e079ae24928f2b199a3616ca1 100644 (file)
@@ -63,6 +63,6 @@ pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs::
 
         target_triple: target_triple,
 
-        cc_args: ~[]
+        cc_args: ~[],
     };
 }
index 5f01a57c23f8e46d17e008d720ef3dac5402c4f0..0853213a5294375f01a76910970b80ad537192f7 100644 (file)
@@ -21,8 +21,7 @@ fn not_win32(os: abi::Os) -> bool {
   os != abi::OsWin32
 }
 
-pub fn get_rpath_flags(sess: session::Session, out_filename: &Path)
-                    -> ~[~str] {
+pub fn get_rpath_flags(sess: session::Session, out_filename: &Path) -> ~[~str] {
     let os = sess.targ_cfg.os;
 
     // No rpath on windows
@@ -30,18 +29,28 @@ pub fn get_rpath_flags(sess: session::Session, out_filename: &Path)
         return ~[];
     }
 
+    let mut flags = ~[];
+
+    if sess.targ_cfg.os == abi::OsFreebsd {
+        flags.push_all([~"-Wl,-rpath,/usr/local/lib/gcc46",
+                        ~"-Wl,-rpath,/usr/local/lib/gcc44",
+                        ~"-Wl,-z,origin"]);
+    }
+
     debug!("preparing the RPATH!");
 
     let sysroot = sess.filesearch.sysroot();
     let output = out_filename;
-    let libs = cstore::get_used_crate_files(sess.cstore);
+    let libs = cstore::get_used_crates(sess.cstore, cstore::RequireDynamic);
+    let libs = libs.move_iter().filter_map(|(_, l)| l.map(|p| p.clone())).collect();
     // We don't currently rpath extern libraries, but we know
     // where rustrt is and we know every rust program needs it
     let libs = vec::append_one(libs, get_sysroot_absolute_rt_lib(sess));
 
     let rpaths = get_rpaths(os, sysroot, output, libs,
                             sess.opts.target_triple);
-    rpaths_to_flags(rpaths)
+    flags.push_all(rpaths_to_flags(rpaths));
+    flags
 }
 
 fn get_sysroot_absolute_rt_lib(sess: session::Session) -> Path {
@@ -52,8 +61,11 @@ fn get_sysroot_absolute_rt_lib(sess: session::Session) -> Path {
 }
 
 pub fn rpaths_to_flags(rpaths: &[~str]) -> ~[~str] {
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    rpaths.iter().map(|rpath| format!("-Wl,-rpath,{}",*rpath)).collect()
+    let mut ret = ~[];
+    for rpath in rpaths.iter() {
+        ret.push("-Wl,-rpath," + *rpath);
+    }
+    return ret;
 }
 
 fn get_rpaths(os: abi::Os,
index 7baaac4fc9537687b37466cc23dd066ca9971159..8713323787825e3d4de0952577b16d086b2cc356 100644 (file)
@@ -14,5 +14,5 @@ pub struct t {
     meta_sect_name: ~str,
     data_layout: ~str,
     target_triple: ~str,
-    cc_args: ~[~str]
+    cc_args: ~[~str],
 }
index b3c92bc40577e69ba22e02419ec6296104c58cdc..de0372b83b972453783381bcfd56ba85481c73cc 100644 (file)
@@ -46,6 +46,6 @@ pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs::
 
         target_triple: target_triple,
 
-        cc_args: ~[~"-m32"]
+        cc_args: ~[~"-m32"],
     };
 }
index 3237085dfb9ece94f1ef5294550e57fc7e5e31a6..dce4de3dce3c10d593d232090213d9e58970e91b 100644 (file)
@@ -54,6 +54,6 @@ pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs::
 
         target_triple: target_triple,
 
-        cc_args: ~[~"-m64"]
+        cc_args: ~[~"-m64"],
     };
 }
index 8821f5f622978e5c1fd55630a24f12a0a44894f7..7d13cb2da6501eaf81c1201d228699266f0a8c88 100644 (file)
@@ -11,7 +11,7 @@
 
 use back::link;
 use back::{arm, x86, x86_64, mips};
-use driver::session::{Aggressive};
+use driver::session::{Aggressive, OutputExecutable};
 use driver::session::{Session, Session_, No, Less, Default};
 use driver::session;
 use front;
@@ -164,8 +164,11 @@ pub fn phase_2_configure_and_expand(sess: Session,
                                     mut crate: ast::Crate) -> ast::Crate {
     let time_passes = sess.time_passes();
 
-    *sess.building_library = session::building_library(sess.opts.crate_type,
-                                                       &crate, sess.opts.test);
+    *sess.building_library = session::building_library(sess.opts, &crate);
+    let want_exe = sess.opts.outputs.iter().any(|&o| o == OutputExecutable);
+    if *sess.building_library && want_exe {
+        sess.err("cannot build both a library and an executable");
+    }
 
     time(time_passes, "gated feature checking", (), |_|
          front::feature_gate::check_crate(sess, &crate));
@@ -225,10 +228,8 @@ pub fn phase_3_run_analysis_passes(sess: Session,
                        syntax::ast_map::map_crate(sess.diagnostic(), crate));
 
     time(time_passes, "external crate/lib resolution", (), |_|
-         creader::read_crates(sess.diagnostic(), crate, sess.cstore,
-                              sess.filesearch,
+         creader::read_crates(sess, crate,
                               session::sess_os_to_meta_os(sess.targ_cfg.os),
-                              sess.opts.is_static,
                               token::get_ident_interner()));
 
     let lang_items = time(time_passes, "language item collection", (), |_|
@@ -330,7 +331,8 @@ pub fn phase_3_run_analysis_passes(sess: Session,
 pub struct CrateTranslation {
     context: ContextRef,
     module: ModuleRef,
-    link: LinkMeta
+    link: LinkMeta,
+    crate_types: ~[~str],
 }
 
 /// Run the translation phase to LLVM, after which the AST and analysis can
@@ -390,6 +392,7 @@ pub fn phase_6_link_output(sess: Session,
                            outputs: &OutputFilenames) {
     time(sess.time_passes(), "linking", (), |_|
          link::link_binary(sess,
+                           trans.crate_types,
                            &outputs.obj_filename,
                            &outputs.out_filename,
                            trans.link));
@@ -417,11 +420,6 @@ pub fn stop_after_phase_5(sess: Session) -> bool {
         return true;
     }
 
-    if sess.opts.is_static && *sess.building_library {
-        debug!("building static library, returning early from compile_input");
-        return true;
-    }
-
     if sess.opts.jit {
         debug!("running JIT, returning early from compile_input");
         return true;
@@ -652,13 +650,21 @@ pub fn build_session_options(binary: @str,
                              matches: &getopts::Matches,
                              demitter: @diagnostic::Emitter)
                              -> @session::options {
-    let crate_type = if matches.opt_present("lib") {
-        session::lib_crate
-    } else if matches.opt_present("bin") {
-        session::bin_crate
-    } else {
-        session::unknown_crate
-    };
+    let mut outputs = ~[];
+    if matches.opt_present("rlib") {
+        outputs.push(session::OutputRlib)
+    }
+    if matches.opt_present("staticlib") {
+        outputs.push(session::OutputStaticlib)
+    }
+    // dynamic libraries are the "compiler blesssed" default library
+    if matches.opt_present("dylib") || matches.opt_present("lib") {
+        outputs.push(session::OutputDylib)
+    }
+    if matches.opt_present("bin") {
+        outputs.push(session::OutputExecutable)
+    }
+
     let parse_only = matches.opt_present("parse-only");
     let no_trans = matches.opt_present("no-trans");
 
@@ -750,11 +756,10 @@ pub fn build_session_options(binary: @str,
     let debuginfo = debugging_opts & session::debug_info != 0 ||
         extra_debuginfo;
 
-    let statik = debugging_opts & session::statik != 0;
-
     let addl_lib_search_paths = matches.opt_strs("L").map(|s| {
-      Path::init(s.as_slice())
+        Path::init(s.as_slice())
     }).move_iter().collect();
+    let ar = matches.opt_str("ar");
     let linker = matches.opt_str("linker");
     let linker_args = matches.opt_strs("link-args").flat_map( |a| {
         a.split(' ').map(|arg| arg.to_owned()).collect()
@@ -782,8 +787,7 @@ pub fn build_session_options(binary: @str,
     };
 
     let sopts = @session::options {
-        crate_type: crate_type,
-        is_static: statik,
+        outputs: outputs,
         gc: gc,
         optimize: opt_level,
         custom_passes: custom_passes,
@@ -795,6 +799,7 @@ pub fn build_session_options(binary: @str,
         jit: jit,
         output_type: output_type,
         addl_lib_search_paths: @mut addl_lib_search_paths,
+        ar: ar,
         linker: linker,
         linker_args: linker_args,
         maybe_sysroot: sysroot_opt,
@@ -871,7 +876,6 @@ pub fn parse_pretty(sess: Session, name: &str) -> PpMode {
 // rustc command line options
 pub fn optgroups() -> ~[getopts::groups::OptGroup] {
  ~[
-  optflag("",  "bin", "Compile an executable crate (default)"),
   optflag("c", "",    "Compile and assemble, but do not link"),
   optmulti("", "cfg", "Configure the compilation
                           environment", "SPEC"),
@@ -881,8 +885,13 @@ pub fn optgroups() -> ~[getopts::groups::OptGroup] {
   optflag("h", "help","Display this message"),
   optmulti("L", "",   "Add a directory to the library search path",
                               "PATH"),
-  optflag("",  "lib", "Compile a library crate"),
+  optflag("",  "bin", "Compile an executable crate (default)"),
+  optflag("",  "lib", "Compile a rust library crate using the compiler's default"),
+  optflag("",  "rlib", "Compile a rust library crate as an rlib file"),
+  optflag("",  "staticlib", "Compile a static library crate"),
+  optflag("",  "dylib", "Compile a dynamic library crate"),
   optopt("", "linker", "Program to use for linking instead of the default.", "LINKER"),
+  optopt("", "ar", "Program to use for managing archives instead of the default.", "AR"),
   optmulti("",  "link-args", "FLAGS is a space-separated list of flags
                             passed to the linker", "FLAGS"),
   optflag("",  "ls",  "List the symbols defined by a library crate"),
@@ -957,19 +966,16 @@ pub fn build_output_filenames(input: &input,
     let obj_path;
     let out_path;
     let sopts = sess.opts;
-    let stop_after_codegen =
-        sopts.output_type != link::output_type_exe ||
-            sopts.is_static && *sess.building_library;
-
-    let obj_suffix =
-        match sopts.output_type {
-          link::output_type_none => ~"none",
-          link::output_type_bitcode => ~"bc",
-          link::output_type_assembly => ~"s",
-          link::output_type_llvm_assembly => ~"ll",
-          // Object and exe output both use the '.o' extension here
-          link::output_type_object | link::output_type_exe => ~"o"
-        };
+    let stop_after_codegen = sopts.output_type != link::output_type_exe;
+
+    let obj_suffix = match sopts.output_type {
+        link::output_type_none => ~"none",
+        link::output_type_bitcode => ~"bc",
+        link::output_type_assembly => ~"s",
+        link::output_type_llvm_assembly => ~"ll",
+        // Object and exe output both use the '.o' extension here
+        link::output_type_object | link::output_type_exe => ~"o"
+    };
 
     match *ofile {
       None => {
@@ -1047,6 +1053,7 @@ pub fn early_error(emitter: @diagnostic::Emitter, msg: &str) -> ! {
 
 pub fn list_metadata(sess: Session, path: &Path, out: @mut io::Writer) {
     metadata::loader::list_file_metadata(
+        sess,
         token::get_ident_interner(),
         session::sess_os_to_meta_os(sess.targ_cfg.os), path, out);
 }
index e497caa494604cd9232be437de824a262dc95337..e45ea533f7937bcbbbbe18f8c33d5d3534573963 100644 (file)
@@ -13,7 +13,6 @@
 use back::target_strs;
 use back;
 use driver::driver::host_triple;
-use driver::session;
 use metadata::filesearch;
 use metadata;
 use middle::lint;
 
 use std::hashmap::{HashMap,HashSet};
 
-#[deriving(Clone)]
-pub enum crate_type {
-    bin_crate,
-    lib_crate,
-    unknown_crate,
-}
-
 pub struct config {
     os: abi::Os,
     arch: abi::Architecture,
@@ -66,16 +58,16 @@ pub struct config {
 pub static jit:                     uint = 1 << 18;
 pub static debug_info:              uint = 1 << 19;
 pub static extra_debug_info:        uint = 1 << 20;
-pub static statik:                  uint = 1 << 21;
-pub static print_link_args:         uint = 1 << 22;
-pub static no_debug_borrows:        uint = 1 << 23;
-pub static lint_llvm:               uint = 1 << 24;
-pub static print_llvm_passes:       uint = 1 << 25;
-pub static no_vectorize_loops:      uint = 1 << 26;
-pub static no_vectorize_slp:        uint = 1 << 27;
-pub static no_prepopulate_passes:   uint = 1 << 28;
-pub static use_softfp:              uint = 1 << 29;
-pub static gen_crate_map:           uint = 1 << 30;
+pub static print_link_args:         uint = 1 << 21;
+pub static no_debug_borrows:        uint = 1 << 22;
+pub static lint_llvm:               uint = 1 << 23;
+pub static print_llvm_passes:       uint = 1 << 24;
+pub static no_vectorize_loops:      uint = 1 << 25;
+pub static no_vectorize_slp:        uint = 1 << 26;
+pub static no_prepopulate_passes:   uint = 1 << 27;
+pub static use_softfp:              uint = 1 << 28;
+pub static gen_crate_map:           uint = 1 << 29;
+pub static prefer_dynamic:          uint = 1 << 30;
 
 pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] {
     ~[("verbose", "in general, enable more debug printouts", verbose),
@@ -107,7 +99,6 @@ pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] {
      ("extra-debug-info", "Extra debugging info (experimental)",
       extra_debug_info),
      ("debug-info", "Produce debug info (experimental)", debug_info),
-     ("static", "Use or produce static libraries or binaries (experimental)", statik),
      ("no-debug-borrows",
       "do not show where borrow checks fail",
       no_debug_borrows),
@@ -129,6 +120,7 @@ pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] {
       no_vectorize_slp),
      ("soft-float", "Generate software floating point library calls", use_softfp),
      ("gen-crate-map", "Force generation of a toplevel crate map", gen_crate_map),
+     ("prefer-dynamic", "Prefer dynamic linking to static linking", prefer_dynamic),
     ]
 }
 
@@ -144,8 +136,8 @@ pub enum OptLevel {
 pub struct options {
     // The crate config requested for the session, which may be combined
     // with additional crate configurations during the compile process
-    crate_type: crate_type,
-    is_static: bool,
+    outputs: ~[OutputStyle],
+
     gc: bool,
     optimize: OptLevel,
     custom_passes: ~[~str],
@@ -159,6 +151,7 @@ pub struct options {
     addl_lib_search_paths: @mut HashSet<Path>, // This is mutable for rustpkg, which
                                                // updates search paths based on the
                                                // parsed code
+    ar: Option<~str>,
     linker: Option<~str>,
     linker_args: ~[~str],
     maybe_sysroot: Option<@Path>,
@@ -194,6 +187,14 @@ pub enum EntryFnType {
     EntryNone,
 }
 
+#[deriving(Eq, Clone)]
+pub enum OutputStyle {
+    OutputExecutable,
+    OutputDylib,
+    OutputRlib,
+    OutputStaticlib,
+}
+
 pub struct Session_ {
     targ_cfg: @config,
     opts: @options,
@@ -337,6 +338,9 @@ pub fn no_vectorize_slp(&self) -> bool {
     pub fn gen_crate_map(&self) -> bool {
         self.debugging_opt(gen_crate_map)
     }
+    pub fn prefer_dynamic(&self) -> bool {
+        self.debugging_opt(prefer_dynamic)
+    }
 
     // pointless function, now...
     pub fn str_of(&self, id: ast::Ident) -> @str {
@@ -357,8 +361,7 @@ pub fn intr(&self) -> @syntax::parse::token::ident_interner {
 /// Some reasonable defaults
 pub fn basic_options() -> @options {
     @options {
-        crate_type: session::lib_crate,
-        is_static: false,
+        outputs: ~[],
         gc: false,
         optimize: No,
         custom_passes: ~[],
@@ -370,6 +373,7 @@ pub fn basic_options() -> @options {
         jit: false,
         output_type: link::output_type_exe,
         addl_lib_search_paths: @mut HashSet::new(),
+        ar: None,
         linker: None,
         linker_args: ~[],
         maybe_sysroot: None,
@@ -391,24 +395,17 @@ pub fn expect<T:Clone>(sess: Session, opt: Option<T>, msg: || -> ~str) -> T {
     diagnostic::expect(sess.diagnostic(), opt, msg)
 }
 
-pub fn building_library(req_crate_type: crate_type,
-                        crate: &ast::Crate,
-                        testing: bool) -> bool {
-    match req_crate_type {
-      bin_crate => false,
-      lib_crate => true,
-      unknown_crate => {
-        if testing {
-            false
-        } else {
-            match syntax::attr::first_attr_value_str_by_name(
-                crate.attrs,
-                "crate_type") {
-              Some(s) => "lib" == s,
-              _ => false
-            }
+pub fn building_library(options: &options, crate: &ast::Crate) -> bool {
+    for output in options.outputs.iter() {
+        match *output {
+            OutputExecutable => {}
+            OutputStaticlib | OutputDylib | OutputRlib => return true
         }
-      }
+    }
+    if options.test { return false }
+    match syntax::attr::first_attr_value_str_by_name(crate.attrs, "crate_type") {
+        Some(s) => "lib" == s || "rlib" == s || "dylib" == s || "staticlib" == s,
+        _ => false
     }
 }
 
@@ -423,75 +420,3 @@ pub fn sess_os_to_meta_os(os: abi::Os) -> metadata::loader::Os {
         abi::OsFreebsd => loader::OsFreebsd
     }
 }
-
-#[cfg(test)]
-mod test {
-    use driver::session::{bin_crate, building_library, lib_crate};
-    use driver::session::{unknown_crate};
-
-    use syntax::ast;
-    use syntax::attr;
-    use syntax::codemap;
-
-    fn make_crate_type_attr(t: @str) -> ast::Attribute {
-        attr::mk_attr(attr::mk_name_value_item_str(@"crate_type", t))
-    }
-
-    fn make_crate(with_bin: bool, with_lib: bool) -> @ast::Crate {
-        let mut attrs = ~[];
-        if with_bin {
-            attrs.push(make_crate_type_attr(@"bin"));
-        }
-        if with_lib {
-            attrs.push(make_crate_type_attr(@"lib"));
-        }
-        @ast::Crate {
-            module: ast::_mod { view_items: ~[], items: ~[] },
-            attrs: attrs,
-            config: ~[],
-            span: codemap::dummy_sp(),
-        }
-    }
-
-    #[test]
-    fn bin_crate_type_attr_results_in_bin_output() {
-        let crate = make_crate(true, false);
-        assert!(!building_library(unknown_crate, crate, false));
-    }
-
-    #[test]
-    fn lib_crate_type_attr_results_in_lib_output() {
-        let crate = make_crate(false, true);
-        assert!(building_library(unknown_crate, crate, false));
-    }
-
-    #[test]
-    fn bin_option_overrides_lib_crate_type() {
-        let crate = make_crate(false, true);
-        assert!(!building_library(bin_crate, crate, false));
-    }
-
-    #[test]
-    fn lib_option_overrides_bin_crate_type() {
-        let crate = make_crate(true, false);
-        assert!(building_library(lib_crate, crate, false));
-    }
-
-    #[test]
-    fn bin_crate_type_is_default() {
-        let crate = make_crate(false, false);
-        assert!(!building_library(unknown_crate, crate, false));
-    }
-
-    #[test]
-    fn test_option_overrides_lib_crate_type() {
-        let crate = make_crate(false, true);
-        assert!(!building_library(unknown_crate, crate, true));
-    }
-
-    #[test]
-    fn test_option_does_not_override_requested_lib_type() {
-        let crate = make_crate(false, false);
-        assert!(building_library(lib_crate, crate, true));
-    }
-}
index 82ddb9c2f973cf55e6c34c2bea869ea68d3d3d4c..d18a8306812c96f3b1eaebfa0bd0e55304fda619 100644 (file)
@@ -21,6 +21,7 @@
 use middle::lint;
 
 use syntax::ast;
+use syntax::attr;
 use syntax::attr::AttrMetaMethods;
 use syntax::codemap::Span;
 use syntax::visit;
@@ -41,6 +42,7 @@
     ("managed_boxes", Active),
     ("non_ascii_idents", Active),
     ("thread_local", Active),
+    ("link_args", Active),
 
     // These are used to test this portion of the compiler, they don't actually
     // mean anything
@@ -111,7 +113,8 @@ fn visit_view_item(&mut self, i: &ast::view_item, _: ()) {
 
     fn visit_item(&mut self, i: @ast::item, _:()) {
         for attr in i.attrs.iter() {
-            if "thread_local" == attr.name() {
+            if "thread_local" == attr.name() &&
+               cfg!(stage0, remove_this_on_next_snapshot) { // NOTE: snap rem
                 self.gate_feature("thread_local", i.span,
                                   "`#[thread_local]` is an experimental feature, and does not \
                                   currently handle destructors. There is no corresponding \
@@ -132,6 +135,16 @@ fn visit_item(&mut self, i: @ast::item, _:()) {
                 }
             }
 
+            ast::item_foreign_mod(..) => {
+                if attr::contains_name(i.attrs, "link_args") &&
+                    cfg!(stage0, remove_this_on_next_snapshot) { // NOTE: snap
+                    self.gate_feature("link_args", i.span,
+                                      "the `link_args` attribute is not portable \
+                                       across platforms, it is recommended to \
+                                       use `#[link(name = \"foo\")]` instead")
+                }
+            }
+
             _ => {}
         }
 
index b5703a62a1fd527695bbb23f42169219dbde0d75..e0073e7ce12e111890925667a09a290115a368bd 100644 (file)
 
 #[comment = "The Rust compiler"];
 #[license = "MIT/ASL2"];
-#[crate_type = "lib"];
+#[crate_type = "lib"]; // NOTE: remove after stage0 snapshot
+#[crate_type = "dylib"];
 
 #[feature(macro_rules, globs, struct_variant, managed_boxes)];
+#[allow(attribute_usage)]; // NOTE: remove after the next snapshot
 
 extern mod extra;
 extern mod syntax;
@@ -87,6 +89,7 @@ pub mod front {
 }
 
 pub mod back {
+    pub mod archive;
     pub mod link;
     pub mod abi;
     pub mod upcall;
index a6a96b25ff5591e7829b9ad8f902d6214acb9d90..5e5cc242358bf9bd9a2d9b288b4593bac0dba31a 100644 (file)
@@ -14,7 +14,6 @@
 use std::hashmap::HashMap;
 use std::libc::{c_uint, c_ushort, c_void, free};
 use std::str::raw::from_c_str;
-use std::option;
 
 use middle::trans::type_::Type;
 
@@ -304,9 +303,16 @@ pub mod llvm {
     use super::{ValueRef, TargetMachineRef, FileType};
     use super::{CodeGenModel, RelocMode, CodeGenOptLevel};
     use super::debuginfo::*;
-    use std::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong};
+    use std::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong,
+                    size_t};
 
+    #[cfg(stage0)]
     #[link_args = "-lrustllvm"]
+    extern {}
+    #[cfg(not(stage0))] // if you're deleting this, put this on the block below
+    #[link(name = "rustllvm")]
+    extern {}
+
     extern {
         /* Create and destroy contexts. */
         pub fn LLVMContextCreate() -> ContextRef;
@@ -1426,6 +1432,16 @@ pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
             LLVMDisposeMemoryBuffer() to get rid of it. */
         pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *c_char)
             -> MemoryBufferRef;
+        /** Borrows the contents of the memory buffer (doesn't copy it) */
+        pub fn LLVMCreateMemoryBufferWithMemoryRange(InputData: *c_char,
+                                                     InputDataLength: size_t,
+                                                     BufferName: *c_char,
+                                                     RequiresNull: Bool)
+            -> MemoryBufferRef;
+        pub fn LLVMCreateMemoryBufferWithMemoryRangeCopy(InputData: *c_char,
+                                                         InputDataLength: size_t,
+                                                         BufferName: *c_char)
+            -> MemoryBufferRef;
 
         /** Returns a string describing the last error caused by an LLVMRust*
             call. */
@@ -1901,38 +1917,32 @@ pub fn mk_pass_manager() -> PassManager {
 
 /* Memory-managed interface to object files. */
 
-pub struct object_file_res {
-    ObjectFile: ObjectFileRef,
+pub struct ObjectFile {
+    llof: ObjectFileRef,
 }
 
-impl Drop for object_file_res {
-    fn drop(&mut self) {
+impl ObjectFile {
+    // This will take ownership of llmb
+    pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
         unsafe {
-            llvm::LLVMDisposeObjectFile(self.ObjectFile);
+            let llof = llvm::LLVMCreateObjectFile(llmb);
+            if llof as int == 0 {
+                llvm::LLVMDisposeMemoryBuffer(llmb);
+                return None
+            }
+
+            Some(ObjectFile {
+                llof: llof,
+            })
         }
     }
 }
 
-pub fn object_file_res(ObjFile: ObjectFileRef) -> object_file_res {
-    object_file_res {
-        ObjectFile: ObjFile
-    }
-}
-
-pub struct ObjectFile {
-    llof: ObjectFileRef,
-    dtor: @object_file_res
-}
-
-pub fn mk_object_file(llmb: MemoryBufferRef) -> Option<ObjectFile> {
-    unsafe {
-        let llof = llvm::LLVMCreateObjectFile(llmb);
-        if llof as int == 0 { return option::None::<ObjectFile>; }
-
-        option::Some(ObjectFile {
-            llof: llof,
-            dtor: @object_file_res(llof)
-        })
+impl Drop for ObjectFile {
+    fn drop(&mut self) {
+        unsafe {
+            llvm::LLVMDisposeObjectFile(self.llof);
+        }
     }
 }
 
index 5e6d0f276152341c3f282e6583a3ac6649f86f4b..5ed1eac746c495e0ab627d8c748a84b738323cf3 100644 (file)
@@ -197,6 +197,8 @@ pub fn from_uint(value : uint) -> Option<astencode_tag> {
 pub static tag_region_param_def_ident: uint = 0x101;
 pub static tag_region_param_def_def_id: uint = 0x102;
 
+pub static tag_native_libraries: uint = 0x103;
+pub static tag_native_libraries_lib: uint = 0x104;
 
 pub struct LinkMeta {
     name: @str,
index f18357999a19430736de92a988591221f955deb0..9d28a5abed2258a3f6ef5c8a80d9e014122cd779 100644 (file)
 
 //! Validates all used crates and extern libraries and loads their metadata
 
-
+use driver::session::Session;
 use metadata::cstore;
 use metadata::decoder;
-use metadata::filesearch::FileSearch;
 use metadata::loader;
 
 use std::hashmap::HashMap;
 
 // Traverses an AST, reading all the information about use'd crates and extern
 // libraries necessary for later resolving, typechecking, linking, etc.
-pub fn read_crates(diag: @mut span_handler,
+pub fn read_crates(sess: Session,
                    crate: &ast::Crate,
-                   cstore: @mut cstore::CStore,
-                   filesearch: @FileSearch,
                    os: loader::Os,
-                   statik: bool,
                    intr: @ident_interner) {
     let e = @mut Env {
-        diag: diag,
-        filesearch: filesearch,
-        cstore: cstore,
+        sess: sess,
         os: os,
-        statik: statik,
         crate_cache: @mut ~[],
         next_crate_num: 1,
         intr: intr
@@ -50,7 +43,7 @@ pub fn read_crates(diag: @mut span_handler,
     visit_crate(e, crate);
     visit::walk_crate(&mut v, crate, ());
     dump_crates(*e.crate_cache);
-    warn_if_multiple_versions(e, diag, *e.crate_cache);
+    warn_if_multiple_versions(e, sess.diagnostic(), *e.crate_cache);
 }
 
 struct ReadCrateVisitor { e:@mut Env }
@@ -113,18 +106,15 @@ fn warn_if_multiple_versions(e: @mut Env,
 }
 
 struct Env {
-    diag: @mut span_handler,
-    filesearch: @FileSearch,
-    cstore: @mut cstore::CStore,
+    sess: Session,
     os: loader::Os,
-    statik: bool,
     crate_cache: @mut ~[cache_entry],
     next_crate_num: ast::CrateNum,
     intr: @ident_interner
 }
 
 fn visit_crate(e: &Env, c: &ast::Crate) {
-    let cstore = e.cstore;
+    let cstore = e.sess.cstore;
 
     for a in c.attrs.iter().filter(|m| "link_args" == m.name()) {
         match a.value_str() {
@@ -146,7 +136,7 @@ fn visit_view_item(e: @mut Env, i: &ast::view_item) {
                   let p_path = Path::init(p);
                   match p_path.filestem_str() {
                       None|Some("") =>
-                          e.diag.span_bug(i.span, "Bad package path in `extern mod` item"),
+                          e.sess.span_bug(i.span, "Bad package path in `extern mod` item"),
                       Some(s) =>
                           vec::append(
                               ~[attr::mk_name_value_item_str(@"package_id", p),
@@ -162,7 +152,7 @@ fn visit_view_item(e: @mut Env, i: &ast::view_item) {
                                    meta_items,
                                    @"",
                                    i.span);
-          cstore::add_extern_mod_stmt_cnum(e.cstore, id, cnum);
+          cstore::add_extern_mod_stmt_cnum(e.sess.cstore, id, cnum);
       }
       _ => ()
   }
@@ -170,60 +160,62 @@ fn visit_view_item(e: @mut Env, i: &ast::view_item) {
 
 fn visit_item(e: &Env, i: @ast::item) {
     match i.node {
-      ast::item_foreign_mod(ref fm) => {
-        if fm.abis.is_rust() || fm.abis.is_intrinsic() {
-            return;
-        }
-
-        let cstore = e.cstore;
-        let link_args = i.attrs.iter()
-            .filter_map(|at| if "link_args" == at.name() {Some(at)} else {None})
-            .collect::<~[&ast::Attribute]>();
-
-        // XXX: two whom it may concern, this was the old logic applied to the
-        //      ast's extern mod blocks which had names (we used to allow
-        //      "extern mod foo"). This code was never run for anonymous blocks,
-        //      and we now only have anonymous blocks. We're still in the midst
-        //      of figuring out what the exact operations we'd like to support
-        //      when linking external modules, but I wanted to leave this logic
-        //      here for the time beging to refer back to it
-
-        //let mut already_added = false;
-        //let link_name = i.attrs.iter()
-        //    .find(|at| "link_name" == at.name())
-        //    .and_then(|at| at.value_str());
+        ast::item_foreign_mod(ref fm) => {
+            if fm.abis.is_rust() || fm.abis.is_intrinsic() {
+                return;
+            }
 
-        //let foreign_name = match link_name {
-        //        Some(nn) => {
-        //            if nn.is_empty() {
-        //                e.diag.span_fatal(
-        //                    i.span,
-        //                    "empty #[link_name] not allowed; use \
-        //                     #[nolink].");
-        //            }
-        //            nn
-        //        }
-        //        None => token::ident_to_str(&i.ident)
-        //    };
-        //if !attr::contains_name(i.attrs, "nolink") {
-        //    already_added =
-        //        !cstore::add_used_library(cstore, foreign_name);
-        //}
-        //if !link_args.is_empty() && already_added {
-        //    e.diag.span_fatal(i.span, ~"library '" + foreign_name +
-        //               "' already added: can't specify link_args.");
-        //}
+            // First, add all of the custom link_args attributes
+            let cstore = e.sess.cstore;
+            let link_args = i.attrs.iter()
+                .filter_map(|at| if "link_args" == at.name() {Some(at)} else {None})
+                .to_owned_vec();
+            for m in link_args.iter() {
+                match m.value_str() {
+                    Some(linkarg) => {
+                        cstore::add_used_link_args(cstore, linkarg);
+                    }
+                    None => { /* fallthrough */ }
+                }
+            }
 
-        for m in link_args.iter() {
-            match m.value_str() {
-                Some(linkarg) => {
-                    cstore::add_used_link_args(cstore, linkarg);
+            // Next, process all of the #[link(..)]-style arguments
+            let cstore = e.sess.cstore;
+            let link_args = i.attrs.iter()
+                .filter_map(|at| if "link" == at.name() {Some(at)} else {None})
+                .to_owned_vec();
+            for m in link_args.iter() {
+                match m.meta_item_list() {
+                    Some(items) => {
+                        let kind = items.iter().find(|k| {
+                            "kind" == k.name()
+                        }).and_then(|a| a.value_str());
+                        let kind = match kind {
+                            Some(k) if "static" == k => cstore::NativeStatic,
+                            Some(k) => {
+                                e.sess.span_fatal(i.span,
+                                    format!("unknown kind: `{}`", k));
+                            }
+                            None => cstore::NativeUnknown
+                        };
+                        let n = items.iter().find(|n| {
+                            "name" == n.name()
+                        }).and_then(|a| a.value_str());
+                        let n = match n {
+                            Some(n) => n,
+                            None => {
+                                e.sess.span_fatal(i.span,
+                                    "#[link(...)] specified without \
+                                     `name = \"foo\"`");
+                            }
+                        };
+                        cstore::add_used_library(cstore, n.to_owned(), kind);
+                    }
+                    None => {}
                 }
-                None => { /* fallthrough */ }
             }
         }
-      }
-      _ => { }
+        _ => { }
     }
 }
 
@@ -263,24 +255,21 @@ fn resolve_crate(e: @mut Env,
     match existing_match(e, metas, hash) {
       None => {
         let load_ctxt = loader::Context {
-            diag: e.diag,
-            filesearch: e.filesearch,
+            sess: e.sess,
             span: span,
             ident: ident,
             metas: metas,
             hash: hash,
             os: e.os,
-            is_static: e.statik,
             intr: e.intr
         };
-        let (lident, ldata) = loader::load_library_crate(&load_ctxt);
+        let loader::Library {
+            dylib, rlib, metadata
+        } = load_ctxt.load_library_crate();
 
-        let cfilename = Path::init(lident);
-        let cdata = ldata;
-
-        let attrs = decoder::get_crate_attributes(cdata);
+        let attrs = decoder::get_crate_attributes(metadata);
         let linkage_metas = attr::find_linkage_metas(attrs);
-        let hash = decoder::get_crate_hash(cdata);
+        let hash = decoder::get_crate_hash(metadata);
 
         // Claim this crate number and cache it
         let cnum = e.next_crate_num;
@@ -293,7 +282,7 @@ fn resolve_crate(e: @mut Env,
         e.next_crate_num += 1;
 
         // Now resolve the crates referenced by this crate
-        let cnum_map = resolve_crate_deps(e, cdata);
+        let cnum_map = resolve_crate_deps(e, metadata);
 
         let cname =
             match attr::last_meta_item_value_str_by_name(load_ctxt.metas,
@@ -303,14 +292,18 @@ fn resolve_crate(e: @mut Env,
             };
         let cmeta = @cstore::crate_metadata {
             name: cname,
-            data: cdata,
+            data: metadata,
             cnum_map: cnum_map,
             cnum: cnum
         };
 
-        let cstore = e.cstore;
+        let cstore = e.sess.cstore;
         cstore::set_crate_data(cstore, cnum, cmeta);
-        cstore::add_used_crate_file(cstore, &cfilename);
+        cstore::add_used_crate_source(cstore, cstore::CrateSource {
+            dylib: dylib,
+            rlib: rlib,
+            cnum: cnum,
+        });
         return cnum;
       }
       Some(cnum) => {
index 9c9dba524534bb64a26c4d37ba8fdb28298dd2d7..96250fd5ec81d761260cc3a13941eb2f8c223568 100644 (file)
@@ -262,6 +262,12 @@ pub fn get_item_visibility(cstore: @mut cstore::CStore,
     decoder::get_item_visibility(cdata, def_id.node)
 }
 
+pub fn get_native_libraries(cstore: @mut cstore::CStore,
+                            crate_num: ast::CrateNum) -> ~[~str] {
+    let cdata = cstore::get_crate_data(cstore, crate_num);
+    decoder::get_native_libraries(cdata)
+}
+
 pub fn each_impl(cstore: @mut cstore::CStore,
                  crate_num: ast::CrateNum,
                  callback: |ast::DefId|) {
index bc15312d98e18cdfbe076ed568580fdcaca02981..50da84d389538666cf8a8ed89430d6b3928782d2 100644 (file)
@@ -34,12 +34,33 @@ pub struct crate_metadata {
     cnum: ast::CrateNum
 }
 
+#[deriving(Eq)]
+pub enum LinkagePreference {
+    RequireDynamic,
+    RequireStatic,
+}
+
+#[deriving(Eq)]
+pub enum NativeLibaryKind {
+    NativeStatic,
+    NativeUnknown,
+}
+
+// Where a crate came from on the local filesystem. One of these two options
+// must be non-None.
+#[deriving(Eq)]
+pub struct CrateSource {
+    dylib: Option<Path>,
+    rlib: Option<Path>,
+    cnum: ast::CrateNum,
+}
+
 pub struct CStore {
     priv metas: HashMap <ast::CrateNum, @crate_metadata>,
     priv extern_mod_crate_map: extern_mod_crate_map,
-    priv used_crate_files: ~[Path],
-    priv used_libraries: ~[@str],
-    priv used_link_args: ~[@str],
+    priv used_crate_sources: ~[CrateSource],
+    priv used_libraries: ~[(~str, NativeLibaryKind)],
+    priv used_link_args: ~[~str],
     intr: @ident_interner
 }
 
@@ -50,7 +71,7 @@ pub fn mk_cstore(intr: @ident_interner) -> CStore {
     return CStore {
         metas: HashMap::new(),
         extern_mod_crate_map: HashMap::new(),
-        used_crate_files: ~[],
+        used_crate_sources: ~[],
         used_libraries: ~[],
         used_link_args: ~[],
         intr: intr
@@ -88,39 +109,50 @@ pub fn iter_crate_data(cstore: &CStore, i: |ast::CrateNum, @crate_metadata|) {
     }
 }
 
-pub fn add_used_crate_file(cstore: &mut CStore, lib: &Path) {
-    if !cstore.used_crate_files.contains(lib) {
-        cstore.used_crate_files.push((*lib).clone());
+pub fn add_used_crate_source(cstore: &mut CStore, src: CrateSource) {
+    if !cstore.used_crate_sources.contains(&src) {
+        cstore.used_crate_sources.push(src);
     }
 }
 
-pub fn get_used_crate_files(cstore: &CStore) -> ~[Path] {
-    // XXX(pcwalton): Bad copy.
-    return cstore.used_crate_files.clone();
+pub fn get_used_crate_sources<'a>(cstore: &'a CStore) -> &'a [CrateSource] {
+    cstore.used_crate_sources.as_slice()
+}
+
+pub fn get_used_crates(cstore: &CStore, prefer: LinkagePreference)
+    -> ~[(ast::CrateNum, Option<Path>)]
+{
+    let mut ret = ~[];
+    for src in cstore.used_crate_sources.iter() {
+        ret.push((src.cnum, match prefer {
+            RequireDynamic => src.dylib.clone(),
+            RequireStatic => src.rlib.clone(),
+        }));
+    }
+    return ret;
 }
 
-pub fn add_used_library(cstore: &mut CStore, lib: @str) -> bool {
+pub fn add_used_library(cstore: &mut CStore,
+                        lib: ~str, kind: NativeLibaryKind) -> bool {
     assert!(!lib.is_empty());
 
-    if cstore.used_libraries.iter().any(|x| x == &lib) { return false; }
-    cstore.used_libraries.push(lib);
+    if cstore.used_libraries.iter().any(|&(ref x, _)| x == &lib) { return false; }
+    cstore.used_libraries.push((lib, kind));
     true
 }
 
-pub fn get_used_libraries<'a>(cstore: &'a CStore) -> &'a [@str] {
-    let slice: &'a [@str] = cstore.used_libraries;
-    slice
+pub fn get_used_libraries<'a>(cstore: &'a CStore) -> &'a [(~str, NativeLibaryKind)] {
+    cstore.used_libraries.as_slice()
 }
 
 pub fn add_used_link_args(cstore: &mut CStore, args: &str) {
     for s in args.split(' ') {
-        cstore.used_link_args.push(s.to_managed());
+        cstore.used_link_args.push(s.to_owned());
     }
 }
 
-pub fn get_used_link_args<'a>(cstore: &'a CStore) -> &'a [@str] {
-    let slice: &'a [@str] = cstore.used_link_args;
-    slice
+pub fn get_used_link_args<'a>(cstore: &'a CStore) -> &'a [~str] {
+    cstore.used_link_args.as_slice()
 }
 
 pub fn add_extern_mod_stmt_cnum(cstore: &mut CStore,
index 48621459228fb4fcbd98fddc576f812c34058837..441f1620e4d8995d03071c2ed994b50f4bac2f12 100644 (file)
@@ -1529,3 +1529,13 @@ pub fn get_trait_of_method(cdata: Cmd, id: ast::NodeId, tcx: ty::ctxt)
     }
 }
 
+
+pub fn get_native_libraries(cdata: Cmd) -> ~[~str] {
+    let libraries = reader::get_doc(reader::Doc(cdata.data), tag_native_libraries);
+    let mut result = ~[];
+    reader::tagged_docs(libraries, tag_native_libraries_lib, |lib_doc| {
+        result.push(lib_doc.as_str());
+        true
+    });
+    return result;
+}
index 6da75397002df4662ecc42fb009eecc6763985e9..269054c6fd21fdb9509144f42b5aab2dd7823aa7 100644 (file)
@@ -75,6 +75,7 @@ struct Stats {
     attr_bytes: u64,
     dep_bytes: u64,
     lang_item_bytes: u64,
+    native_lib_bytes: u64,
     impl_bytes: u64,
     misc_bytes: u64,
     item_bytes: u64,
@@ -1633,6 +1634,23 @@ fn encode_lang_items(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) {
     ebml_w.end_tag();   // tag_lang_items
 }
 
+fn encode_native_libraries(ecx: &EncodeContext, ebml_w: &mut writer::Encoder) {
+    ebml_w.start_tag(tag_native_libraries);
+
+    for &(ref lib, kind) in cstore::get_used_libraries(ecx.cstore).iter() {
+        match kind {
+            cstore::NativeStatic => {} // these libraries are not propagated
+            cstore::NativeUnknown => {
+                ebml_w.start_tag(tag_native_libraries_lib);
+                ebml_w.writer.write(lib.as_bytes());
+                ebml_w.end_tag();
+            }
+        }
+    }
+
+    ebml_w.end_tag();
+}
+
 struct ImplVisitor<'self> {
     ecx: &'self EncodeContext<'self>,
     ebml_w: &'self mut writer::Encoder,
@@ -1750,6 +1768,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
         attr_bytes: 0,
         dep_bytes: 0,
         lang_item_bytes: 0,
+        native_lib_bytes: 0,
         impl_bytes: 0,
         misc_bytes: 0,
         item_bytes: 0,
@@ -1806,6 +1825,11 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
     encode_lang_items(&ecx, &mut ebml_w);
     ecx.stats.lang_item_bytes = wr.tell() - i;
 
+    // Encode the native libraries used
+    i = wr.tell();
+    encode_native_libraries(&ecx, &mut ebml_w);
+    ecx.stats.native_lib_bytes = wr.tell() - i;
+
     // Encode the def IDs of impls, for coherence checking.
     i = wr.tell();
     encode_impls(&ecx, crate, &mut ebml_w);
@@ -1842,6 +1866,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
         println!(" attribute bytes: {}", ecx.stats.attr_bytes);
         println!("       dep bytes: {}", ecx.stats.dep_bytes);
         println!(" lang item bytes: {}", ecx.stats.lang_item_bytes);
+        println!("    native bytes: {}", ecx.stats.native_lib_bytes);
         println!("      impl bytes: {}", ecx.stats.impl_bytes);
         println!("      misc bytes: {}", ecx.stats.misc_bytes);
         println!("      item bytes: {}", ecx.stats.item_bytes);
index ecd1c8985bd00dc52404f3aa9e4eb71bfd67737f..40fca0f42f1a27d8a629b6b3835b394ff12562b3 100644 (file)
 
 //! Finds crate binaries and loads their metadata
 
-
-use lib::llvm::{False, llvm, mk_object_file, mk_section_iter};
+use back::archive::Archive;
+use driver::session::Session;
+use lib::llvm::{False, llvm, ObjectFile, mk_section_iter};
 use metadata::decoder;
 use metadata::encoder;
-use metadata::filesearch::{FileSearch, FileMatch, FileMatches, FileDoesntMatch};
+use metadata::filesearch::{FileMatches, FileDoesntMatch};
 use metadata::filesearch;
 use syntax::codemap::Span;
 use syntax::diagnostic::span_handler;
@@ -26,6 +27,7 @@
 use std::c_str::ToCStr;
 use std::cast;
 use std::io;
+use std::libc;
 use std::num;
 use std::option;
 use std::os::consts::{macos, freebsd, linux, android, win32};
@@ -43,103 +45,176 @@ pub enum Os {
 }
 
 pub struct Context {
-    diag: @mut span_handler,
-    filesearch: @FileSearch,
+    sess: Session,
     span: Span,
     ident: @str,
     metas: ~[@ast::MetaItem],
     hash: @str,
     os: Os,
-    is_static: bool,
     intr: @ident_interner
 }
 
-pub fn load_library_crate(cx: &Context) -> (~str, @~[u8]) {
-    match find_library_crate(cx) {
-      Some(t) => t,
-      None => {
-        cx.diag.span_fatal(cx.span,
-                           format!("can't find crate for `{}`",
-                                cx.ident));
-      }
-    }
+pub struct Library {
+    dylib: Option<Path>,
+    rlib: Option<Path>,
+    metadata: @~[u8],
 }
 
-fn find_library_crate(cx: &Context) -> Option<(~str, @~[u8])> {
-    attr::require_unique_names(cx.diag, cx.metas);
-    find_library_crate_aux(cx, libname(cx), cx.filesearch)
-}
+impl Context {
+    pub fn load_library_crate(&self) -> Library {
+        match self.find_library_crate() {
+            Some(t) => t,
+            None => {
+                self.sess.span_fatal(self.span,
+                                     format!("can't find crate for `{}`",
+                                             self.ident));
+            }
+        }
+    }
 
-fn libname(cx: &Context) -> (~str, ~str) {
-    if cx.is_static { return (~"lib", ~".rlib"); }
-    let (dll_prefix, dll_suffix) = match cx.os {
-        OsWin32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
-        OsMacos => (macos::DLL_PREFIX, macos::DLL_SUFFIX),
-        OsLinux => (linux::DLL_PREFIX, linux::DLL_SUFFIX),
-        OsAndroid => (android::DLL_PREFIX, android::DLL_SUFFIX),
-        OsFreebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
-    };
+    fn find_library_crate(&self) -> Option<Library> {
+        attr::require_unique_names(self.sess.diagnostic(), self.metas);
+        let filesearch = self.sess.filesearch;
+        let crate_name = crate_name_from_metas(self.metas);
+        let (dyprefix, dysuffix) = self.dylibname();
 
-    (dll_prefix.to_owned(), dll_suffix.to_owned())
-}
+        // want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
+        let dylib_prefix = format!("{}{}-", dyprefix, crate_name);
+        let rlib_prefix = format!("lib{}-", crate_name);
 
-fn find_library_crate_aux(
-    cx: &Context,
-    (prefix, suffix): (~str, ~str),
-    filesearch: @filesearch::FileSearch
-) -> Option<(~str, @~[u8])> {
-    let crate_name = crate_name_from_metas(cx.metas);
-    // want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
-    let prefix = format!("{}{}-", prefix, crate_name);
-    let mut matches = ~[];
-    filesearch::search(filesearch, |path| -> FileMatch {
-      // FIXME (#9639): This needs to handle non-utf8 paths
-      let path_str = path.filename_str();
-      match path_str {
-          None => FileDoesntMatch,
-          Some(path_str) =>
-              if path_str.starts_with(prefix) && path_str.ends_with(suffix) {
-                  debug!("{} is a candidate", path.display());
-                  match get_metadata_section(cx.os, path) {
-                      Some(cvec) =>
-                          if !crate_matches(cvec, cx.metas, cx.hash) {
-                              debug!("skipping {}, metadata doesn't match",
-                                  path.display());
-                              FileDoesntMatch
-                          } else {
-                              debug!("found {} with matching metadata", path.display());
-                              // FIXME (#9639): This needs to handle non-utf8 paths
-                              matches.push((path.as_str().unwrap().to_owned(), cvec));
-                              FileMatches
-                          },
-                      _ => {
-                          debug!("could not load metadata for {}", path.display());
-                          FileDoesntMatch
-                      }
-                  }
-               }
-               else {
-                   FileDoesntMatch
-               }
-      }
-    });
+        let mut matches = ~[];
+        filesearch::search(filesearch, |path| {
+            match path.filename_str() {
+                None => FileDoesntMatch,
+                Some(file) => {
+                    let (candidate, existing) = if file.starts_with(rlib_prefix) &&
+                                                   file.ends_with(".rlib") {
+                        debug!("{} is an rlib candidate", path.display());
+                        (true, self.add_existing_rlib(matches, path, file))
+                    } else if file.starts_with(dylib_prefix) &&
+                              file.ends_with(dysuffix) {
+                        debug!("{} is a dylib candidate", path.display());
+                        (true, self.add_existing_dylib(matches, path, file))
+                    } else {
+                        (false, false)
+                    };
+
+                    if candidate && existing {
+                        FileMatches
+                    } else if candidate {
+                        match get_metadata_section(self.sess, self.os, path,
+                                                   crate_name) {
+                            Some(cvec) =>
+                                if crate_matches(cvec, self.metas, self.hash) {
+                                    debug!("found {} with matching metadata",
+                                           path.display());
+                                    let (rlib, dylib) = if file.ends_with(".rlib") {
+                                        (Some(path.clone()), None)
+                                    } else {
+                                        (None, Some(path.clone()))
+                                    };
+                                    matches.push(Library {
+                                        rlib: rlib,
+                                        dylib: dylib,
+                                        metadata: cvec,
+                                    });
+                                    FileMatches
+                                } else {
+                                    debug!("skipping {}, metadata doesn't match",
+                                           path.display());
+                                    FileDoesntMatch
+                                },
+                                _ => {
+                                    debug!("could not load metadata for {}",
+                                           path.display());
+                                    FileDoesntMatch
+                                }
+                        }
+                    } else {
+                        FileDoesntMatch
+                    }
+                }
+            }
+        });
 
-    match matches.len() {
-        0 => None,
-        1 => Some(matches[0]),
-        _ => {
-            cx.diag.span_err(
-                    cx.span, format!("multiple matching crates for `{}`", crate_name));
-                cx.diag.handler().note("candidates:");
-                for pair in matches.iter() {
-                    let ident = pair.first();
-                    let data = pair.second();
-                    cx.diag.handler().note(format!("path: {}", ident));
-                    let attrs = decoder::get_crate_attributes(data);
-                    note_linkage_attrs(cx.intr, cx.diag, attrs);
+        match matches.len() {
+            0 => None,
+            1 => Some(matches[0]),
+            _ => {
+                self.sess.span_err(self.span,
+                    format!("multiple matching crates for `{}`", crate_name));
+                self.sess.note("candidates:");
+                for lib in matches.iter() {
+                    match lib.dylib {
+                        Some(ref p) => {
+                            self.sess.note(format!("path: {}", p.display()));
+                        }
+                        None => {}
+                    }
+                    match lib.rlib {
+                        Some(ref p) => {
+                            self.sess.note(format!("path: {}", p.display()));
+                        }
+                        None => {}
+                    }
+                    let attrs = decoder::get_crate_attributes(lib.metadata);
+                    note_linkage_attrs(self.intr, self.sess.diagnostic(), attrs);
                 }
-                cx.diag.handler().abort_if_errors();
+                self.sess.abort_if_errors();
                 None
+            }
+        }
+    }
+
+    fn add_existing_rlib(&self, libs: &mut [Library],
+                         path: &Path, file: &str) -> bool {
+        let (prefix, suffix) = self.dylibname();
+        let file = file.slice_from(3); // chop off 'lib'
+        let file = file.slice_to(file.len() - 5); // chop off '.rlib'
+        let file = format!("{}{}{}", prefix, file, suffix);
+
+        for lib in libs.mut_iter() {
+            match lib.dylib {
+                Some(ref p) if p.filename_str() == Some(file.as_slice()) => {
+                    assert!(lib.rlib.is_none()); // XXX: legit compiler error
+                    lib.rlib = Some(path.clone());
+                    return true;
+                }
+                Some(..) | None => {}
+            }
+        }
+        return false;
+    }
+
+    fn add_existing_dylib(&self, libs: &mut [Library],
+                          path: &Path, file: &str) -> bool {
+        let (prefix, suffix) = self.dylibname();
+        let file = file.slice_from(prefix.len());
+        let file = file.slice_to(file.len() - suffix.len());
+        let file = format!("lib{}.rlib", file);
+
+        for lib in libs.mut_iter() {
+            match lib.rlib {
+                Some(ref p) if p.filename_str() == Some(file.as_slice()) => {
+                    assert!(lib.dylib.is_none()); // XXX: legit compiler error
+                    lib.dylib = Some(path.clone());
+                    return true;
+                }
+                Some(..) | None => {}
+            }
+        }
+        return false;
+    }
+
+    // Returns the corresponding (prefix, suffix) that files need to have for
+    // dynamic libraries
+    fn dylibname(&self) -> (&'static str, &'static str) {
+        match self.os {
+            OsWin32 => (win32::DLL_PREFIX, win32::DLL_SUFFIX),
+            OsMacos => (macos::DLL_PREFIX, macos::DLL_SUFFIX),
+            OsLinux => (linux::DLL_PREFIX, linux::DLL_SUFFIX),
+            OsAndroid => (android::DLL_PREFIX, android::DLL_SUFFIX),
+            OsFreebsd => (freebsd::DLL_PREFIX, freebsd::DLL_SUFFIX),
         }
     }
 }
@@ -196,16 +271,26 @@ pub fn metadata_matches(extern_metas: &[@ast::MetaItem],
     local_metas.iter().all(|needed| attr::contains(extern_metas, *needed))
 }
 
-fn get_metadata_section(os: Os,
-                        filename: &Path) -> Option<@~[u8]> {
+fn get_metadata_section(sess: Session, os: Os, filename: &Path,
+                        crate_name: &str) -> Option<@~[u8]> {
     unsafe {
-        let mb = filename.with_c_str(|buf| {
-            llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
-        });
-        if mb as int == 0 { return option::None::<@~[u8]>; }
-        let of = match mk_object_file(mb) {
-            option::Some(of) => of,
-            _ => return option::None::<@~[u8]>
+        let mb = if filename.filename_str().unwrap().ends_with(".rlib") {
+            let archive = Archive::open(sess, filename.clone());
+            let contents = archive.read(crate_name + ".o");
+            let ptr = vec::raw::to_ptr(contents);
+            crate_name.with_c_str(|name| {
+                llvm::LLVMCreateMemoryBufferWithMemoryRangeCopy(
+                    ptr as *i8, contents.len() as libc::size_t, name)
+            })
+        } else {
+            filename.with_c_str(|buf| {
+                llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
+            })
+        };
+        if mb as int == 0 { return None }
+        let of = match ObjectFile::new(mb) {
+            Some(of) => of,
+            _ => return None
         };
         let si = mk_section_iter(of.llof);
         while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
@@ -266,11 +351,17 @@ pub fn read_meta_section_name(os: Os) -> &'static str {
 }
 
 // A diagnostic function for dumping crate metadata to an output stream
-pub fn list_file_metadata(intr: @ident_interner,
+pub fn list_file_metadata(sess: Session,
+                          intr: @ident_interner,
                           os: Os,
                           path: &Path,
                           out: @mut io::Writer) {
-    match get_metadata_section(os, path) {
+    // guess the crate name from the pathname
+    let crate_name = path.filename_str().unwrap();
+    let crate_name = if crate_name.starts_with("lib") {
+        crate_name.slice_from(3) } else { crate_name };
+    let crate_name = crate_name.split('-').next().unwrap();
+    match get_metadata_section(sess, os, path, crate_name) {
       option::Some(bytes) => decoder::list_crate_metadata(intr, bytes, out),
       option::None => {
         write!(out, "could not find metadata in {}.\n", path.display())
index c8f245d5555d8081bada6cd1a7e7fe70fcd9e9a0..d8eaffd5563cbdd1514dedf83ca8b4de7356ce5f 100644 (file)
@@ -82,16 +82,18 @@ pub enum LangItem {
     OpaqueStructLangItem,              // 38
 
     EventLoopFactoryLangItem,          // 39
+
+    TypeIdLangItem,                    // 40
 }
 
 pub struct LanguageItems {
-    items: [Option<ast::DefId>, ..40]
+    items: [Option<ast::DefId>, ..41]
 }
 
 impl LanguageItems {
     pub fn new() -> LanguageItems {
         LanguageItems {
-            items: [ None, ..40 ]
+            items: [ None, ..41 ]
         }
     }
 
@@ -148,6 +150,8 @@ pub fn item_name(index: uint) -> &'static str {
 
             39 => "event_loop_factory",
 
+            40 => "type_id",
+
             _ => "???"
         }
     }
@@ -298,6 +302,9 @@ pub fn opaque(&self) -> Option<ast::DefId> {
     pub fn event_loop_factory(&self) -> Option<ast::DefId> {
         self.items[EventLoopFactoryLangItem as uint]
     }
+    pub fn type_id(&self) -> Option<ast::DefId> {
+        self.items[TypeIdLangItem as uint]
+    }
 }
 
 struct LanguageItemCollector {
@@ -382,6 +389,7 @@ pub fn new(session: Session) -> LanguageItemCollector {
         item_refs.insert("ty_visitor", TyVisitorTraitLangItem as uint);
         item_refs.insert("opaque", OpaqueStructLangItem as uint);
         item_refs.insert("event_loop_factory", EventLoopFactoryLangItem as uint);
+        item_refs.insert("type_id", TypeIdLangItem as uint);
 
         LanguageItemCollector {
             session: session,
index 4c6ca53694a0e7af5cf99f3b0e2a07e5250495e9..1b2ae78c627bc19411ee806cbb5bcbeda16f248a 100644 (file)
@@ -808,7 +808,7 @@ fn check_heap_item(cx: &Context, it: &ast::item) {
 }
 
 static crate_attrs: &'static [&'static str] = &[
-    "crate_type", "link", "feature", "no_uv", "no_main", "no_std",
+    "crate_type", "feature", "no_uv", "no_main", "no_std",
     "desc", "comment", "license", "copyright", // not used in rustc now
 ];
 
@@ -830,7 +830,7 @@ fn check_heap_item(cx: &Context, it: &ast::item) {
     "deprecated", "experimental", "unstable", "stable", "locked", "frozen", //item stability
     "crate_map", "cfg", "doc", "export_name", "link_section", "no_freeze",
     "no_mangle", "no_send", "static_assert", "unsafe_no_drop_flag",
-    "packed", "simd", "repr", "deriving", "unsafe_destructor",
+    "packed", "simd", "repr", "deriving", "unsafe_destructor", "link",
 
     //mod-level
     "path", "link_name", "link_args", "nolink", "macro_escape", "no_implicit_prelude",
index ac7b82401768226118cec65b9819e9d259f338e8..deb4f00d7a02fb425249a1f658d0d43408545ac0 100644 (file)
 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::attr::AttrMetaMethods;
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::parse::token::{special_idents};
 use syntax::print::pprust::stmt_to_str;
 use syntax::{ast, ast_util, codemap, ast_map};
+use syntax::attr::AttrMetaMethods;
 use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic, OsWin32, OsAndroid};
 use syntax::visit;
 use syntax::visit::Visitor;
@@ -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);
@@ -3106,18 +3107,6 @@ pub fn write_metadata(cx: &CrateContext, crate: &ast::Crate) {
     }
 }
 
-// Writes the current ABI version into the crate.
-pub fn write_abi_version(ccx: &mut CrateContext) {
-    unsafe {
-        let llval = C_uint(ccx, abi::abi_version);
-        let llglobal = "rust_abi_version".with_c_str(|buf| {
-            llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf)
-        });
-        llvm::LLVMSetInitializer(llglobal, llval);
-        llvm::LLVMSetGlobalConstant(llglobal, True);
-    }
-}
-
 pub fn trans_crate(sess: session::Session,
                    crate: ast::Crate,
                    analysis: &CrateAnalysis,
@@ -3177,7 +3166,6 @@ pub fn trans_crate(sess: session::Session,
     }
 
     glue::emit_tydescs(ccx);
-    write_abi_version(ccx);
     if ccx.sess.opts.debuginfo {
         debuginfo::finalize(ccx);
     }
@@ -3217,10 +3205,18 @@ pub fn trans_crate(sess: session::Session,
     let llcx = ccx.llcx;
     let link_meta = ccx.link_meta;
     let llmod = ccx.llmod;
+    let crate_types = crate.attrs.iter().filter_map(|a| {
+        if "crate_type" == a.name() {
+            a.value_str()
+        } else {
+            None
+        }
+    }).map(|a| a.to_owned()).collect();
 
     return CrateTranslation {
         context: llcx,
         module: llmod,
-        link: link_meta
+        link: link_meta,
+        crate_types: crate_types,
     };
 }
index 952854e7d047f63600f7b4fa680da523a029d39e..c62757e1353895a275608451508bcfdecb7b514e 100644 (file)
@@ -77,7 +77,7 @@ pub fn trans_if(bcx: @mut Block,
             return with_scope(bcx, thn.info(), "if_true_then", |bcx| {
                 let bcx_out = trans_block(bcx, thn, dest);
                 debuginfo::clear_source_location(bcx.fcx);
-                trans_block_cleanups(bcx_out, block_cleanups(bcx))
+                bcx_out
             })
         } else {
             let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx } ;
@@ -90,9 +90,9 @@ pub fn trans_if(bcx: @mut Block,
                                       elexpr.info(),
                                       "if_false_then",
                                       |bcx| {
-                        let bcx_out = trans_if_else(bcx, elexpr, dest);
+                        let bcx_out = trans_if_else(bcx, elexpr, dest, false);
                         debuginfo::clear_source_location(bcx.fcx);
-                        trans_block_cleanups(bcx_out, block_cleanups(bcx))
+                        bcx_out
                     })
                 }
                 // if false { .. }
@@ -116,7 +116,7 @@ pub fn trans_if(bcx: @mut Block,
     let (else_bcx_in, next_bcx) = match els {
       Some(elexpr) => {
           let else_bcx_in = scope_block(bcx, elexpr.info(), "else");
-          let else_bcx_out = trans_if_else(else_bcx_in, elexpr, dest);
+          let else_bcx_out = trans_if_else(else_bcx_in, elexpr, dest, true);
           (else_bcx_in, join_blocks(bcx, [then_bcx_out, else_bcx_out]))
       }
       _ => {
@@ -138,7 +138,7 @@ pub fn trans_if(bcx: @mut Block,
 
     // trans `else [ if { .. } ... | { .. } ]`
     fn trans_if_else(else_bcx_in: @mut Block, elexpr: @ast::Expr,
-                     dest: expr::Dest) -> @mut Block {
+                     dest: expr::Dest, cleanup: bool) -> @mut Block {
         let else_bcx_out = match elexpr.node {
             ast::ExprIf(_, _, _) => {
                 let elseif_blk = ast_util::block_from_expr(elexpr);
@@ -150,8 +150,12 @@ fn trans_if_else(else_bcx_in: @mut Block, elexpr: @ast::Expr,
             // would be nice to have a constraint on ifs
             _ => else_bcx_in.tcx().sess.bug("strange alternative in if")
         };
-        debuginfo::clear_source_location(else_bcx_in.fcx);
-        trans_block_cleanups(else_bcx_out, block_cleanups(else_bcx_in))
+        if cleanup {
+            debuginfo::clear_source_location(else_bcx_in.fcx);
+            trans_block_cleanups(else_bcx_out, block_cleanups(else_bcx_in))
+        } else {
+            else_bcx_out
+        }
     }
 }
 
index ac65719f02e861cc69ba757cd15f345c5fe73639..2a0840a0ef8ad380b5747144b8605b43b88adc80 100644 (file)
 
 
 use back::{link};
-use std::libc::c_uint;
-use lib::llvm::{ValueRef, CallConv, StructRetAttribute};
 use lib::llvm::llvm;
+use lib::llvm::{ValueRef, CallConv, StructRetAttribute};
 use lib;
-use middle::trans::machine;
-use middle::trans::base;
 use middle::trans::base::push_ctxt;
-use middle::trans::cabi;
+use middle::trans::base;
 use middle::trans::build::*;
 use middle::trans::builder::noname;
+use middle::trans::cabi;
 use middle::trans::common::*;
+use middle::trans::machine;
+use middle::trans::type_::Type;
 use middle::trans::type_of::*;
 use middle::trans::type_of;
-use middle::ty;
 use middle::ty::FnSig;
-
-use std::uint;
+use middle::ty;
+use std::cmp;
+use std::libc::c_uint;
 use std::vec;
+use syntax::abi::{Cdecl, Aapcs, C, AbiSet, Win64};
+use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall, System};
 use syntax::codemap::Span;
+use syntax::parse::token::special_idents;
 use syntax::{ast};
 use syntax::{attr, ast_map};
-use syntax::parse::token::special_idents;
-use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall, System,
-                  Cdecl, Aapcs, C, AbiSet, Win64};
 use util::ppaux::{Repr, UserString};
-use middle::trans::type_::Type;
 
 ///////////////////////////////////////////////////////////////////////////
 // Type definitions
@@ -332,7 +331,7 @@ pub fn trans_native_call(bcx: @mut Block,
             let llrust_size = machine::llsize_of_store(ccx, llrust_ret_ty);
             let llforeign_align = machine::llalign_of_min(ccx, llforeign_ret_ty);
             let llrust_align = machine::llalign_of_min(ccx, llrust_ret_ty);
-            let llalign = uint::min(llforeign_align, llrust_align);
+            let llalign = cmp::min(llforeign_align, llrust_align);
             debug!("llrust_size={:?}", llrust_size);
             base::call_memcpy(bcx, llretptr_i8, llscratch_i8,
                               C_uint(ccx, llrust_size), llalign as u32);
index e57eed480eb53e41f8a5ba818e36f39e400ee203..110e964bdbc48aac602af0da051fa6f6f6fc541e 100644 (file)
@@ -287,7 +287,16 @@ fn count_zeros_intrinsic(bcx: @mut Block, name: &'static str) {
         "type_id" => {
             let hash = ty::hash_crate_independent(ccx.tcx, substs.tys[0],
                                                   ccx.link_meta.extras_hash);
-            Ret(bcx, C_i64(hash as i64))
+            // NB: This needs to be kept in lockstep with the TypeId struct in
+            //     libstd/unstable/intrinsics.rs
+            let val = C_named_struct(type_of::type_of(ccx, output_type), [C_u64(hash)]);
+            match bcx.fcx.llretptr {
+                Some(ptr) => {
+                    Store(bcx, val, ptr);
+                    RetVoid(bcx);
+                },
+                None => Ret(bcx, val)
+            }
         }
         "init" => {
             let tp_ty = substs.tys[0];
index 8caf873a8896ab7a7cd0a0c8fd009400a7216884..e3160dbc40236149beba90724b711ee36afdb249 100644 (file)
 use middle::typeck::{lookup_def_ccx};
 use middle::typeck::no_params;
 use middle::typeck::{require_same_types, method_map, vtable_map};
+use middle::lang_items::TypeIdLangItem;
 use util::common::{block_query, indenter, loop_query};
 use util::ppaux::UserString;
 use util::ppaux;
@@ -4013,7 +4014,17 @@ fn param(ccx: @mut CrateCtxt, n: uint) -> ty::t {
               });
               (1u, ~[], td_ptr)
             }
-            "type_id" => (1u, ~[], ty::mk_u64()),
+            "type_id" => {
+                let langid = ccx.tcx.lang_items.require(TypeIdLangItem);
+                match langid {
+                    Ok(did) => (1u, ~[], ty::mk_struct(ccx.tcx, did, substs {
+                                                 self_ty: None,
+                                                 tps: ~[],
+                                                 regions: ty::NonerasedRegions(opt_vec::Empty)
+                                                 }) ),
+                    Err(msg) => { tcx.sess.span_fatal(it.span, msg); }
+                }
+            },
             "visit_tydesc" => {
               let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) {
                   Ok(t) => t,
index ac7c50fdfd809673571474ea653919dbcec324a2..3dcc1dbebcab2d932bb5c2470e673fde9ea9d25a 100644 (file)
@@ -67,7 +67,7 @@ struct buf {
 }
 
 // sundown FFI
-#[link_args = "-lsundown"]
+#[link(name = "sundown", kind = "static")]
 extern {
     fn sdhtml_renderer(callbacks: *sd_callbacks,
                        options_ptr: *html_renderopt,
index c51244cddf52f065f03c03e5e52cc6c0a449aabb..7cab7846f15b85b95fc31c0701e14988c370e9b0 100644 (file)
@@ -16,7 +16,8 @@
 
 #[desc = "rustdoc, the Rust documentation extractor"];
 #[license = "MIT/ASL2"];
-#[crate_type = "lib"];
+#[crate_type = "lib"]; // NOTE: remove after stage0 snapshot
+#[crate_type = "dylib"];
 
 #[feature(globs, struct_variant, managed_boxes)];
 
@@ -283,7 +284,7 @@ fn json_input(input: &str) -> Result<Output, ~str> {
             }
             let crate = match obj.pop(&~"crate") {
                 Some(json) => {
-                    let mut d = json::Decoder(json);
+                    let mut d = json::Decoder::init(json);
                     Decodable::decode(&mut d)
                 }
                 None => return Err(~"malformed json"),
@@ -312,9 +313,12 @@ fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
     // FIXME #8335: yuck, Rust -> str -> JSON round trip! No way to .encode
     // straight to the Rust JSON representation.
     let crate_json_str = {
-        let w = @mut MemWriter::new();
-        crate.encode(&mut json::Encoder(w as @mut io::Writer));
-        str::from_utf8(*w.inner_ref())
+        let mut w = MemWriter::new();
+        {
+            let mut encoder = json::Encoder::init(&mut w as &mut io::Writer);
+            crate.encode(&mut encoder);
+        }
+        str::from_utf8_owned(w.inner())
     };
     let crate_json = match json::from_str(crate_json_str) {
         Ok(j) => j,
index b87bd0c58246b59f5ee4188d5c462c6e94387887..157d8ba0105fce76649d8030557c7ec18c79c3fc 100644 (file)
@@ -17,7 +17,8 @@
        url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")];
 
 #[license = "MIT/ASL2"];
-#[crate_type = "lib"];
+#[crate_type = "lib"]; // NOTE: remove after stage0 snapshot
+#[crate_type = "dylib"];
 
 #[feature(globs, managed_boxes)];
 
@@ -114,7 +115,7 @@ fn parse<'a>(sysroot: Path,
         let options = @session::options {
             binary: binary,
             maybe_sysroot: Some(@sysroot),
-            crate_type: session::bin_crate,
+            outputs: ~[session::OutputExecutable],
             .. (*session::basic_options()).clone()
         };
         let input = driver::file_input(script.clone());
index 5e867951b54ed85e492a330f584b7dd61ae23e4f..3b177b449d9109523d8d43e77a13ab741a2721fb 100644 (file)
@@ -36,6 +36,7 @@
                chmod_read_only, platform_library_name};
 use rustc::back::link::get_cc_prog;
 use rustc::metadata::filesearch::rust_path;
+use rustc::driver::session;
 use rustc::driver::driver::{build_session, build_session_options, host_triple, optgroups};
 use syntax::diagnostic;
 use target::*;
@@ -1829,10 +1830,11 @@ fn test_linker_build() {
                                 @diagnostic::Emitter);
     let test_sys = test_sysroot();
     // FIXME (#9639): This needs to handle non-utf8 paths
+    let cc = get_cc_prog(sess);
     command_line_test([test_sys.as_str().unwrap().to_owned(),
                        ~"install",
                        ~"--linker",
-                       get_cc_prog(sess),
+                       cc,
                        ~"foo"],
                       workspace);
     assert_executable_exists(workspace, "foo");
index f21357d0271db524047e3d71c24e22b116d4d3ba..a8dbf145e533321b082413fd6168f23e64eeea6b 100644 (file)
@@ -25,7 +25,6 @@
 use syntax::util::small_vector::SmallVector;
 use rustc::back::link::output_type_exe;
 use rustc::back::link;
-use rustc::driver::session::{lib_crate, bin_crate};
 use context::{in_target, StopBefore, Link, Assemble, BuildContext};
 use package_id::PkgId;
 use package_source::PkgSrc;
@@ -195,8 +194,8 @@ pub fn compile_input(context: &BuildContext,
     debug!("compile_input's sysroot = {}", csysroot.display());
 
     let crate_type = match what {
-        Lib => lib_crate,
-        Test | Bench | Main => bin_crate
+        Lib => session::OutputDylib,
+        Test | Bench | Main => session::OutputExecutable,
     };
     let matches = getopts(debug_flags()
                           + match what {
@@ -239,7 +238,7 @@ pub fn compile_input(context: &BuildContext,
     debug!("Output type = {:?}", output_type);
 
     let options = @session::options {
-        crate_type: crate_type,
+        outputs: ~[crate_type],
         optimize: opt,
         test: what == Test || what == Bench,
         maybe_sysroot: Some(sysroot_to_use),
index 76882e885a8c924c15a230afa59f21433d6c916d..a43759a6da7b0f121dc4daeb67a74e752171bf04 100644 (file)
        url = "https://github.com/mozilla/rust/tree/master/src/librustuv")];
 
 #[license = "MIT/ASL2"];
-#[crate_type = "lib"];
+#[crate_type = "lib"]; // NOTE: remove after stage0 snapshot
+#[crate_type = "rlib"];
+#[crate_type = "dylib"];
 
 #[feature(macro_rules, globs)];
+#[allow(attribute_usage)]; // NOTE: remove after the next snapshot
 
 use std::cast::transmute;
 use std::cast;
index 3917efe9ca823966c48b0469faa9b2e9b0ba8511..ca5c75122a6ef5d863c38aca8dc3ba1330360700 100644 (file)
@@ -524,8 +524,13 @@ pub unsafe fn guess_handle(handle: c_int) -> c_int {
 // second copies of everything. We obviously don't want this, so instead of
 // dying horribly during testing, we allow all of the test rustuv's references
 // to get resolved to the original rustuv crate.
-#[link_args = "-luv_support -luv"]
-#[cfg(not(test))]
+#[cfg(not(test), not(stage0))]
+#[link(name = "uv_support", kind = "static")]
+#[link(name = "uv", kind = "static")]
+extern {}
+
+#[cfg(not(test), stage0)]
+#[link_args = "-luv -luv_support"]
 extern {}
 
 extern {
@@ -717,12 +722,26 @@ pub fn uv_signal_start(h: *uv_signal_t, cb: uv_signal_cb,
     pub fn uv_signal_stop(handle: *uv_signal_t) -> c_int;
 }
 
-// libuv requires various system libraries to successfully link on some
-// platforms
-#[cfg(target_os = "linux")]
+// various platform libraries required by libuv
+#[cfg(not(stage0), not(target_os = "android"))]
+#[link(name = "pthread")]
+extern {}
+#[cfg(stage0)]
 #[link_args = "-lpthread"]
 extern {}
 
-#[cfg(target_os = "win32")]
+#[cfg(target_os = "win32", not(stage0))]
+#[link(name = "ws2_32")]
+#[link(name = "psapi")]
+#[link(name = "iphlpapi")]
+extern {}
+#[cfg(target_os = "win32", stage0)]
 #[link_args = "-lws2_32 -lpsapi -liphlpapi"]
 extern {}
+
+#[cfg(target_os = "freebsd", not(stage0))]
+#[link(name = "kvm")]
+extern {}
+#[cfg(target_os = "freebsd", stage0)]
+#[link_args = "-lkvm"]
+extern {}
index e02bf9f4ba8a316cf57b81770635db5590df078b..7af12bef7b5c29280bffd799823696d68193234f 100644 (file)
 //! of any type.
 
 use cast::transmute;
+#[cfg(stage0)]
 use cmp::Eq;
 use option::{Option, Some, None};
+#[cfg(stage0)]
 use to_bytes::{IterBytes, Cb};
 use to_str::ToStr;
 use unstable::intrinsics;
 use util::Void;
+#[cfg(not(stage0))]
+use unstable::intrinsics::TypeId;
 
 ///////////////////////////////////////////////////////////////////////////////
 // TypeId
 ///////////////////////////////////////////////////////////////////////////////
 
 /// `TypeId` represents a globally unique identifier for a type
+#[cfg(stage0)]
 pub struct TypeId {
     priv t: u64,
 }
 
+#[cfg(stage0)]
 impl TypeId {
     /// Returns the `TypeId` of the type this generic function has been instantiated with
     #[inline]
@@ -36,6 +42,7 @@ pub fn of<T: 'static>() -> TypeId {
     }
 }
 
+#[cfg(stage0)]
 impl Eq for TypeId {
     #[inline]
     fn eq(&self, &other: &TypeId) -> bool {
@@ -43,6 +50,7 @@ fn eq(&self, &other: &TypeId) -> bool {
     }
 }
 
+#[cfg(stage0)]
 impl IterBytes for TypeId {
     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
         self.t.iter_bytes(lsb0, f)
@@ -189,29 +197,6 @@ mod tests {
 
     static TEST: &'static str = "Test";
 
-    #[test]
-    fn type_id() {
-        let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
-                         TypeId::of::<Test>());
-        let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
-                         TypeId::of::<Test>());
-
-        assert!(a != b);
-        assert!(a != c);
-        assert!(b != c);
-
-        assert_eq!(a, d);
-        assert_eq!(b, e);
-        assert_eq!(c, f);
-    }
-
-    #[test]
-    fn type_id_hash() {
-        let (a, b) = (TypeId::of::<uint>(), TypeId::of::<uint>());
-
-        assert_eq!(a.hash(), b.hash());
-    }
-
     #[test]
     fn any_as_void_ptr() {
         let (a, b, c) = (~5u as ~Any, ~TEST as ~Any, ~Test as ~Any);
index 9fa2c7ab1f3b4f36a3916ac9c0875917dbffebed..c74a9bc90517655dc46e002d0a16f6f72d360c1b 100644 (file)
@@ -901,7 +901,7 @@ pub fn pad(&mut self, s: &str) {
                 // case where the maximum length will matter.
                 let char_len = s.char_len();
                 if char_len >= max {
-                    let nchars = ::uint::min(max, char_len);
+                    let nchars = ::cmp::min(max, char_len);
                     self.buf.write(s.slice_chars(0, nchars).as_bytes());
                     return
                 }
@@ -1036,31 +1036,26 @@ pub fn upperhex(buf: &[u8], f: &mut Formatter) {
     f.pad_integral(local.slice_to(buf.len()), "0x", true);
 }
 
-// FIXME(#4375) shouldn't need an inner module
 macro_rules! integer(($signed:ident, $unsigned:ident) => {
-    mod $signed {
-        use super::*;
-
-        // Signed is special because it actuall emits the negative sign,
-        // nothing else should do that, however.
-        impl Signed for $signed {
-            fn fmt(c: &$signed, f: &mut Formatter) {
-                ::$unsigned::to_str_bytes(c.abs() as $unsigned, 10, |buf| {
-                    f.pad_integral(buf, "", *c >= 0);
-                })
-            }
+    // Signed is special because it actuall emits the negative sign,
+    // nothing else should do that, however.
+    impl Signed for $signed {
+        fn fmt(c: &$signed, f: &mut Formatter) {
+            ::$unsigned::to_str_bytes(c.abs() as $unsigned, 10, |buf| {
+                f.pad_integral(buf, "", *c >= 0);
+            })
         }
-        int_base!($signed, $unsigned, 2, Binary, "0b")
-        int_base!($signed, $unsigned, 8, Octal, "0o")
-        int_base!($signed, $unsigned, 16, LowerHex, "0x")
-        upper_hex!($signed, $unsigned)
-
-        int_base!($unsigned, $unsigned, 2, Binary, "0b")
-        int_base!($unsigned, $unsigned, 8, Octal, "0o")
-        int_base!($unsigned, $unsigned, 10, Unsigned, "")
-        int_base!($unsigned, $unsigned, 16, LowerHex, "0x")
-        upper_hex!($unsigned, $unsigned)
     }
+    int_base!($signed, $unsigned, 2, Binary, "0b")
+    int_base!($signed, $unsigned, 8, Octal, "0o")
+    int_base!($signed, $unsigned, 16, LowerHex, "0x")
+    upper_hex!($signed, $unsigned)
+
+    int_base!($unsigned, $unsigned, 2, Binary, "0b")
+    int_base!($unsigned, $unsigned, 8, Octal, "0o")
+    int_base!($unsigned, $unsigned, 10, Unsigned, "")
+    int_base!($unsigned, $unsigned, 16, LowerHex, "0x")
+    upper_hex!($unsigned, $unsigned)
 })
 
 integer!(int, uint)
index 8c1897339cbef9d7e11d977407bd24e6907fc2a4..9c5927f86395ca08ad6e302e17c1c84388e60216 100644 (file)
@@ -166,12 +166,19 @@ pub fn with_capacity(cap: uint, inner: W) -> BufferedWriter<W> {
     pub fn new(inner: W) -> BufferedWriter<W> {
         BufferedWriter::with_capacity(DEFAULT_CAPACITY, inner)
     }
+
+    fn flush_buf(&mut self) {
+        if self.pos != 0 {
+            self.inner.write(self.buf.slice_to(self.pos));
+            self.pos = 0;
+        }
+    }
 }
 
 impl<W: Writer> Writer for BufferedWriter<W> {
     fn write(&mut self, buf: &[u8]) {
         if self.pos + buf.len() > self.buf.len() {
-            self.flush();
+            self.flush_buf();
         }
 
         if buf.len() > self.buf.len() {
@@ -184,16 +191,13 @@ fn write(&mut self, buf: &[u8]) {
     }
 
     fn flush(&mut self) {
-        if self.pos != 0 {
-            self.inner.write(self.buf.slice_to(self.pos));
-            self.pos = 0;
-        }
+        self.flush_buf();
         self.inner.flush();
     }
 }
 
 impl<W: Writer> Decorator<W> for BufferedWriter<W> {
-    fn inner(self) -> W { self.inner }
+    fn inner(mut self) -> W { self.flush_buf(); self.inner }
     fn inner_ref<'a>(&'a self) -> &'a W { &self.inner }
     fn inner_mut_ref<'a>(&'a mut self) -> &'a mut W { &mut self.inner }
 }
@@ -218,7 +222,7 @@ pub fn new(inner: W) -> LineBufferedWriter<W> {
 
 impl<W: Writer> Writer for LineBufferedWriter<W> {
     fn write(&mut self, buf: &[u8]) {
-        match buf.iter().position(|&b| b == '\n' as u8) {
+        match buf.iter().rposition(|&b| b == '\n' as u8) {
             Some(i) => {
                 self.inner.write(buf.slice_to(i + 1));
                 self.inner.flush();
@@ -387,6 +391,15 @@ fn test_buffered_writer() {
                    writer.inner_ref().inner_ref().as_slice());
     }
 
+    #[test]
+    fn test_buffered_writer_inner_flushes() {
+        let mut w = BufferedWriter::with_capacity(3, MemWriter::new());
+        w.write([0, 1]);
+        assert_eq!([], w.inner_ref().inner_ref().as_slice());
+        let w = w.inner();
+        assert_eq!([0, 1], w.inner_ref().as_slice());
+    }
+
     // This is just here to make sure that we don't infinite loop in the
     // newtype struct autoderef weirdness
     #[test]
@@ -430,10 +443,15 @@ fn test_line_buffer() {
         assert_eq!(*writer.inner_ref().inner_ref(), ~[]);
         writer.flush();
         assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1]);
-        writer.write([0, '\n' as u8, 1]);
-        assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1, 0, '\n' as u8]);
+        writer.write([0, '\n' as u8, 1, '\n' as u8, 2]);
+        assert_eq!(*writer.inner_ref().inner_ref(),
+            ~[0, 1, 0, '\n' as u8, 1, '\n' as u8]);
         writer.flush();
-        assert_eq!(*writer.inner_ref().inner_ref(), ~[0, 1, 0, '\n' as u8, 1]);
+        assert_eq!(*writer.inner_ref().inner_ref(),
+            ~[0, 1, 0, '\n' as u8, 1, '\n' as u8, 2]);
+        writer.write([3, '\n' as u8]);
+        assert_eq!(*writer.inner_ref().inner_ref(),
+            ~[0, 1, 0, '\n' as u8, 1, '\n' as u8, 2, 3, '\n' as u8]);
     }
 
     #[bench]
index b08f4af9a54c6c3db981e1801ab8fecbb355429d..aa3eb9a83176333bb2a2a04bad37eea7faa77977 100644 (file)
@@ -27,8 +27,14 @@ pub struct MemWriter {
 }
 
 impl MemWriter {
+    /// Create a new `MemWriter`.
     pub fn new() -> MemWriter {
-        MemWriter { buf: vec::with_capacity(128), pos: 0 }
+        MemWriter::with_capacity(128)
+    }
+    /// Create a new `MemWriter`, allocating at least `n` bytes for
+    /// the internal buffer.
+    pub fn with_capacity(n: uint) -> MemWriter {
+        MemWriter { buf: vec::with_capacity(n), pos: 0 }
     }
 }
 
index a72bc6b832863e0700e35d599f0804b9d57596bb..296091d26e693407afa2dea90f816b311bb51ed1 100644 (file)
@@ -51,7 +51,9 @@
 
 #[comment = "The Rust standard library"];
 #[license = "MIT/ASL2"];
-#[crate_type = "lib"];
+#[crate_type = "lib"]; // NOTE: remove after stage0 snapshot
+#[crate_type = "rlib"];
+#[crate_type = "dylib"];
 
 #[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
@@ -64,6 +66,7 @@
 
 #[deny(non_camel_case_types)];
 #[deny(missing_doc)];
+#[allow(attribute_usage)]; // NOTE: remove after the next snapshot
 
 // When testing libstd, bring in libuv as the I/O backend so tests can print
 // things and all of the std::io tests have an I/O interface to run on top
 #[cfg(test)] pub use ops = realstd::ops;
 #[cfg(test)] pub use cmp = realstd::cmp;
 
-// On Linux, link to the runtime with -lrt.
-#[cfg(target_os = "linux")]
-#[doc(hidden)]
-pub mod linkhack {
-    #[link_args="-lrustrt -lrt"]
-    #[link_args = "-lpthread"]
-    extern {
-    }
-}
+mod rtdeps;
 
 /* The Prelude. */
 
index a0dddffd85184faeb1663230ef187cdcfdeaee54..53bd2d3dc086547fec42e8d68f0b7a99f6c7ce7e 100644 (file)
 //! Operations and constants for `f32`
 #[allow(missing_doc)];
 
+use prelude::*;
+
+use cmath::c_float_utils;
 use default::Default;
-use libc::c_int;
-use num::{Zero, One, strconv};
+use libc::{c_float, c_int};
 use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
+use num::{Zero, One, strconv};
 use num;
-use prelude::*;
 use to_str;
+use unstable::intrinsics;
 
 pub use cmath::c_float_targ_consts::*;
 
-use self::delegated::*;
-
 macro_rules! delegate(
     (
         $(
@@ -33,22 +34,14 @@ fn $name:ident(
             ) -> $rv:ty = $bound_name:path
         ),*
     ) => (
-        // An inner module is required to get the #[inline] attribute on the
-        // functions.
-        mod delegated {
-            use cmath::c_float_utils;
-            use libc::{c_float, c_int};
-            use unstable::intrinsics;
-
-            $(
-                #[inline]
-                pub fn $name($( $arg : $arg_ty ),*) -> $rv {
-                    unsafe {
-                        $bound_name($( $arg ),*)
-                    }
+        $(
+            #[inline]
+            pub fn $name($( $arg : $arg_ty ),*) -> $rv {
+                unsafe {
+                    $bound_name($( $arg ),*)
                 }
-            )*
-        }
+            }
+        )*
     )
 )
 
index 8cb7fa180018646958da64909d3bcae7fde04695..49b20b2c4f473be111aefa67766449465a6401a8 100644 (file)
 
 #[allow(missing_doc)];
 
+use prelude::*;
+
+use cmath::c_double_utils;
 use default::Default;
-use libc::c_int;
-use num::{Zero, One, strconv};
+use libc::{c_double, c_int};
 use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
+use num::{Zero, One, strconv};
 use num;
-use prelude::*;
 use to_str;
+use unstable::intrinsics;
 
 pub use cmath::c_double_targ_consts::*;
 pub use cmp::{min, max};
 
-use self::delegated::*;
-
 macro_rules! delegate(
     (
         $(
@@ -35,22 +36,14 @@ fn $name:ident(
             ) -> $rv:ty = $bound_name:path
         ),*
     ) => (
-        // An inner module is required to get the #[inline] attribute on the
-        // functions.
-        mod delegated {
-            use cmath::c_double_utils;
-            use libc::{c_double, c_int};
-            use unstable::intrinsics;
-
-            $(
-                #[inline]
-                pub fn $name($( $arg : $arg_ty ),*) -> $rv {
-                    unsafe {
-                        $bound_name($( $arg ),*)
-                    }
+        $(
+            #[inline]
+            pub fn $name($( $arg : $arg_ty ),*) -> $rv {
+                unsafe {
+                    $bound_name($( $arg ),*)
                 }
-            )*
-        }
+            }
+        )*
     )
 )
 
index 5c077c7e633d0cc16caa38fbc4ad810bb0a50a1f..fcf1f24d0e4555e8192a5150906c8dbcd549c037 100644 (file)
 
 //! Operations and constants for `i16`
 
+#[allow(non_uppercase_statics)];
+
+use prelude::*;
+
+use default::Default;
 use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
+use num::{CheckedDiv, Zero, One, strconv};
+use num::{ToStrRadix, FromStrRadix};
 use option::{Option, Some, None};
+use str;
 use unstable::intrinsics;
 
-pub use self::generated::*;
-
 int_module!(i16, 16)
 
 impl BitCount for i16 {
index f076e33b3a2183808cbe533378380d174cee4500..385e1c91ca503005014e7ec5da0b091db489aa33 100644 (file)
 
 //! Operations and constants for `i32`
 
+#[allow(non_uppercase_statics)];
+
+use prelude::*;
+
+use default::Default;
 use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
+use num::{CheckedDiv, Zero, One, strconv};
+use num::{ToStrRadix, FromStrRadix};
 use option::{Option, Some, None};
+use str;
 use unstable::intrinsics;
 
-pub use self::generated::*;
-
 int_module!(i32, 32)
 
 impl BitCount for i32 {
index d991bf0330034a7e387280208e51c4d646d41e81..f6b369b1312a5ec494125cc991e0ae175f8017a5 100644 (file)
 
 //! Operations and constants for `i64`
 
-use num::{BitCount, CheckedAdd, CheckedSub};
+#[allow(non_uppercase_statics)];
+
+use prelude::*;
+
+use default::Default;
 #[cfg(target_word_size = "64")]
 use num::CheckedMul;
+use num::{BitCount, CheckedAdd, CheckedSub};
+use num::{CheckedDiv, Zero, One, strconv};
+use num::{ToStrRadix, FromStrRadix};
 use option::{Option, Some, None};
+use str;
 use unstable::intrinsics;
 
-pub use self::generated::*;
-
 int_module!(i64, 64)
 
 impl BitCount for i64 {
index a807f6b9e53f3dbd9d5cd9fcdf6f61fc07fc995b..9de90ca4657d1147388fb4f8b79c5a87e02eedf6 100644 (file)
 
 //! Operations and constants for `i8`
 
+#[allow(non_uppercase_statics)];
+
+use prelude::*;
+
+use default::Default;
 use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
+use num::{CheckedDiv, Zero, One, strconv};
+use num::{ToStrRadix, FromStrRadix};
 use option::{Option, Some, None};
+use str;
 use unstable::intrinsics;
 
-pub use self::generated::*;
-
 int_module!(i8, 8)
 
 impl BitCount for i8 {
index c5364fa3dab963d652d80b5f477f4b1138dacb3f..517bd45e45bd1b51d9d64554ea6e9908db96955d 100644 (file)
 
 #[allow(non_uppercase_statics)];
 
+use prelude::*;
+
+use default::Default;
 use num::{BitCount, CheckedAdd, CheckedSub, CheckedMul};
+use num::{CheckedDiv, Zero, One, strconv};
+use num::{ToStrRadix, FromStrRadix};
 use option::{Option, Some, None};
+use str;
 use unstable::intrinsics;
 
-pub use self::generated::*;
-
-#[cfg(target_word_size = "32")] pub static bits: uint = 32;
-#[cfg(target_word_size = "64")] pub static bits: uint = 64;
-
-int_module!(int, super::bits)
+#[cfg(target_word_size = "32")] int_module!(int, 32)
+#[cfg(target_word_size = "64")] int_module!(int, 64)
 
 #[cfg(target_word_size = "32")]
 impl BitCount for int {
index fc56bf91c2a77da3be867d8b5ce627921ea67cae..8c60b0ec75a694cb841cf92ac34d7334dcca0cc9 100644 (file)
@@ -8,22 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// FIXME(#4375): this shouldn't have to be a nested module named 'generated'
-
 #[macro_escape];
 #[doc(hidden)];
 
-macro_rules! int_module (($T:ty, $bits:expr) => (mod generated {
-
-#[allow(non_uppercase_statics)];
-
-use default::Default;
-use num::{ToStrRadix, FromStrRadix};
-use num::{CheckedDiv, Zero, One, strconv};
-use prelude::*;
-use str;
-
-pub use cmp::{min, max};
+macro_rules! int_module (($T:ty, $bits:expr) => (
 
 pub static bits : uint = $bits;
 pub static bytes : uint = ($bits / 8);
@@ -781,4 +769,4 @@ fn test_signed_checked_div() {
     }
 }
 
-}))
+))
index e227947ca6e5f8d2f60ecf5a97459fc4f2c6e4c5..ed8ec3b6c54b919230c2c34beb7ab73521eee254 100644 (file)
 
 //! Operations and constants for `u16`
 
+#[allow(non_uppercase_statics)];
+
+use prelude::*;
+
+use default::Default;
+use num::BitCount;
 use num::{CheckedAdd, CheckedSub, CheckedMul};
+use num::{CheckedDiv, Zero, One, strconv};
+use num::{ToStrRadix, FromStrRadix};
 use option::{Option, Some, None};
+use str;
 use unstable::intrinsics;
 
-pub use self::generated::*;
-
 uint_module!(u16, i16, 16)
 
 impl CheckedAdd for u16 {
index 4dbd543da7b0b252f71a881df0bc3a948ac33506..2977549803384b5562e87227cc607425ca59a5dc 100644 (file)
 
 //! Operations and constants for `u32`
 
+#[allow(non_uppercase_statics)];
+
+use prelude::*;
+
+use default::Default;
+use num::BitCount;
 use num::{CheckedAdd, CheckedSub, CheckedMul};
+use num::{CheckedDiv, Zero, One, strconv};
+use num::{ToStrRadix, FromStrRadix};
 use option::{Option, Some, None};
+use str;
 use unstable::intrinsics;
 
-pub use self::generated::*;
-
 uint_module!(u32, i32, 32)
 
 impl CheckedAdd for u32 {
index d3077333077d3f65ecf2e3530dce3617f093a869..dc43801eb3958b43fef8ea47e0e94286b2fec650 100644 (file)
 
 //! Operations and constants for `u64`
 
-use num::{CheckedAdd, CheckedSub};
+#[allow(non_uppercase_statics)];
+
+use prelude::*;
+
+use default::Default;
+use num::BitCount;
 #[cfg(target_word_size = "64")]
 use num::CheckedMul;
+use num::{CheckedAdd, CheckedSub};
+use num::{CheckedDiv, Zero, One, strconv};
+use num::{ToStrRadix, FromStrRadix};
 use option::{Option, Some, None};
+use str;
 use unstable::intrinsics;
 
-pub use self::generated::*;
-
 uint_module!(u64, i64, 64)
 
 impl CheckedAdd for u64 {
index ca54af5cecc43808fc85a2131005a96bb962e9f8..12ad4efdbd5d1d4197f00fb89ba6fe5cc9e6b1d3 100644 (file)
 
 //! Operations and constants for `u8`
 
+#[allow(non_uppercase_statics)];
+
+use prelude::*;
+
+use default::Default;
+use num::BitCount;
 use num::{CheckedAdd, CheckedSub, CheckedMul};
+use num::{CheckedDiv, Zero, One, strconv};
+use num::{ToStrRadix, FromStrRadix};
 use option::{Option, Some, None};
+use str;
 use unstable::intrinsics;
 
-pub use self::generated::*;
-
 uint_module!(u8, i8, 8)
 
 impl CheckedAdd for u8 {
index cf28083bb09b941d6106614d85e3f3cbd113d299..549490050c590d412c3d70608ee05e44aca57132 100644 (file)
 
 //! Operations and constants for `uint`
 
-use num;
+#[allow(non_uppercase_statics)];
+
+use prelude::*;
+
+use default::Default;
+use mem;
+use num::BitCount;
 use num::{CheckedAdd, CheckedSub, CheckedMul};
+use num::{CheckedDiv, Zero, One, strconv};
+use num::{ToStrRadix, FromStrRadix};
+use num;
 use option::{Option, Some, None};
+use str;
 use unstable::intrinsics;
-use mem;
-
-pub use self::generated::*;
 
 uint_module!(uint, int, ::int::bits)
 
index 3c276378df86356577e183bc6967af28dd545e42..ee3cd6446089a32bd3d74f030b0bc3b775c2b97e 100644 (file)
@@ -8,23 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// FIXME(#4375): this shouldn't have to be a nested module named 'generated'
-
 #[macro_escape];
 #[doc(hidden)];
 
-macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (mod generated {
-
-#[allow(non_uppercase_statics)];
-
-use default::Default;
-use num::BitCount;
-use num::{ToStrRadix, FromStrRadix};
-use num::{CheckedDiv, Zero, One, strconv};
-use prelude::*;
-use str;
-
-pub use cmp::{min, max};
+macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (
 
 pub static bits : uint = $bits;
 pub static bytes : uint = ($bits / 8);
@@ -554,4 +541,4 @@ fn test_unsigned_checked_div() {
     }
 }
 
-}))
+))
index 13e18f7d9b75ee83c5c8d82f41bc6fc3d6a23c11..3f169b511df9a665a26b89c47494483d0c377bf3 100644 (file)
@@ -17,7 +17,6 @@
 use io::buffered::LineBufferedWriter;
 use rt::crate_map::{ModEntry, CrateMap, iter_crate_map, get_crate_map};
 use str::StrSlice;
-use u32;
 use vec::ImmutableVector;
 #[cfg(test)] use cast::transmute;
 
@@ -46,7 +45,7 @@ fn parse_log_level(level: &str) -> Option<u32> {
             let position = log_level_names.iter().position(|&name| name == level);
             match position {
                 Some(position) => {
-                    log_level = Some(u32::min(MAX_LOG_LEVEL, (position + 1) as u32))
+                    log_level = Some(::cmp::min(MAX_LOG_LEVEL, (position + 1) as u32))
                 },
                 _ => {
                     log_level = None;
diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs
new file mode 100644 (file)
index 0000000..ba4f120
--- /dev/null
@@ -0,0 +1,54 @@
+// 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 module contains the linkage attributes to all runtime dependencies of
+//! the stndard library This varies per-platform, but these libraries are
+//! necessary for running libstd.
+
+// All platforms need to link to rustrt
+#[link(name = "rustrt", kind = "static")]
+extern {}
+
+// LLVM implements the `frem` instruction as a call to `fmod`, which lives in
+// libm. Hence, we must explicitly link to it.
+//
+// On linux librt and libdl are indirect dependencies via rustrt,
+// and binutils 2.22+ won't add them automatically
+#[cfg(target_os = "linux")]
+#[link(name = "rt")]
+#[link(name = "dl")]
+#[link(name = "m")]
+#[link(name = "pthread")]
+#[link(name = "stdc++")]
+extern {}
+
+#[cfg(target_os = "android")]
+#[link(name = "dl")]
+#[link(name = "log")]
+#[link(name = "supc++")]
+#[link(name = "gnustl_shared")]
+#[link(name = "m")]
+extern {}
+
+#[cfg(target_os = "freebsd")]
+#[link(name = "execinfo")]
+#[link(name = "rt")]
+#[link(name = "stdc++")]
+#[link(name = "pthread")]
+extern {}
+
+#[cfg(target_os = "macos")]
+#[link(name = "pthread")]
+#[link(name = "stdc++")]
+extern {}
+
+#[cfg(stage0)]
+#[link_args = "-lstdc++"]
+extern {}
index 623909b79759e6f962d6c04b5b1281bc355d367d..313fd9c79b46a6768c5eb074503225f98545e1c6 100644 (file)
@@ -13,8 +13,9 @@
 #[allow(missing_doc)];
 
 use clone::Clone;
-
-pub use self::inner::*;
+#[cfg(not(test))] use cmp::*;
+#[cfg(not(test))] use default::Default;
+#[cfg(not(test))] use num::Zero;
 
 /// Method extensions to pairs where both types satisfy the `Clone` bound
 pub trait CopyableTuple<T, U> {
@@ -86,116 +87,109 @@ macro_rules! tuple_impls {
             })+
         }
     )+) => {
-        pub mod inner {
-            use clone::Clone;
-            #[cfg(not(test))] use cmp::*;
-            #[cfg(not(test))] use default::Default;
-            #[cfg(not(test))] use num::Zero;
-
-            $(
-                pub trait $move_trait<$($T),+> {
-                    $(fn $get_fn(self) -> $T;)+
-                }
+        $(
+            pub trait $move_trait<$($T),+> {
+                $(fn $get_fn(self) -> $T;)+
+            }
 
-                impl<$($T),+> $move_trait<$($T),+> for ($($T,)+) {
-                    $(
-                        #[inline]
-                        fn $get_fn(self) -> $T {
-                            let $move_pattern = self;
-                            $ret
-                        }
-                    )+
-                }
-
-                pub trait $immutable_trait<$($T),+> {
-                    $(fn $get_ref_fn<'a>(&'a self) -> &'a $T;)+
-                }
+            impl<$($T),+> $move_trait<$($T),+> for ($($T,)+) {
+                $(
+                    #[inline]
+                    fn $get_fn(self) -> $T {
+                        let $move_pattern = self;
+                        $ret
+                    }
+                )+
+            }
 
-                impl<$($T),+> $immutable_trait<$($T),+> for ($($T,)+) {
-                    $(
-                        #[inline]
-                        fn $get_ref_fn<'a>(&'a self) -> &'a $T {
-                            let $ref_pattern = *self;
-                            $ret
-                        }
-                    )+
-                }
+            pub trait $immutable_trait<$($T),+> {
+                $(fn $get_ref_fn<'a>(&'a self) -> &'a $T;)+
+            }
 
-                impl<$($T:Clone),+> Clone for ($($T,)+) {
-                    fn clone(&self) -> ($($T,)+) {
-                        ($(self.$get_ref_fn().clone(),)+)
+            impl<$($T),+> $immutable_trait<$($T),+> for ($($T,)+) {
+                $(
+                    #[inline]
+                    fn $get_ref_fn<'a>(&'a self) -> &'a $T {
+                        let $ref_pattern = *self;
+                        $ret
                     }
+                )+
+            }
+
+            impl<$($T:Clone),+> Clone for ($($T,)+) {
+                fn clone(&self) -> ($($T,)+) {
+                    ($(self.$get_ref_fn().clone(),)+)
                 }
+            }
 
-                #[cfg(not(test))]
-                impl<$($T:Eq),+> Eq for ($($T,)+) {
-                    #[inline]
-                    fn eq(&self, other: &($($T,)+)) -> bool {
-                        $(*self.$get_ref_fn() == *other.$get_ref_fn())&&+
-                    }
-                    #[inline]
-                    fn ne(&self, other: &($($T,)+)) -> bool {
-                        $(*self.$get_ref_fn() != *other.$get_ref_fn())||+
-                    }
+            #[cfg(not(test))]
+            impl<$($T:Eq),+> Eq for ($($T,)+) {
+                #[inline]
+                fn eq(&self, other: &($($T,)+)) -> bool {
+                    $(*self.$get_ref_fn() == *other.$get_ref_fn())&&+
+                }
+                #[inline]
+                fn ne(&self, other: &($($T,)+)) -> bool {
+                    $(*self.$get_ref_fn() != *other.$get_ref_fn())||+
                 }
+            }
 
-                #[cfg(not(test))]
-                impl<$($T:TotalEq),+> TotalEq for ($($T,)+) {
-                    #[inline]
-                    fn equals(&self, other: &($($T,)+)) -> bool {
-                        $(self.$get_ref_fn().equals(other.$get_ref_fn()))&&+
-                    }
+            #[cfg(not(test))]
+            impl<$($T:TotalEq),+> TotalEq for ($($T,)+) {
+                #[inline]
+                fn equals(&self, other: &($($T,)+)) -> bool {
+                    $(self.$get_ref_fn().equals(other.$get_ref_fn()))&&+
                 }
+            }
 
-                #[cfg(not(test))]
-                impl<$($T:Ord + Eq),+> Ord for ($($T,)+) {
-                    #[inline]
-                    fn lt(&self, other: &($($T,)+)) -> bool {
-                        lexical_ord!(lt, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
-                    }
-                    #[inline]
-                    fn le(&self, other: &($($T,)+)) -> bool {
-                        lexical_ord!(le, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
-                    }
-                    #[inline]
-                    fn ge(&self, other: &($($T,)+)) -> bool {
-                        lexical_ord!(ge, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
-                    }
-                    #[inline]
-                    fn gt(&self, other: &($($T,)+)) -> bool {
-                        lexical_ord!(gt, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
-                    }
+            #[cfg(not(test))]
+            impl<$($T:Ord + Eq),+> Ord for ($($T,)+) {
+                #[inline]
+                fn lt(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(lt, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
+                }
+                #[inline]
+                fn le(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(le, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
+                }
+                #[inline]
+                fn ge(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(ge, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
                 }
+                #[inline]
+                fn gt(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(gt, $(self.$get_ref_fn(), other.$get_ref_fn()),+)
+                }
+            }
 
-                #[cfg(not(test))]
-                impl<$($T:TotalOrd),+> TotalOrd for ($($T,)+) {
-                    #[inline]
-                    fn cmp(&self, other: &($($T,)+)) -> Ordering {
-                        lexical_cmp!($(self.$get_ref_fn(), other.$get_ref_fn()),+)
-                    }
+            #[cfg(not(test))]
+            impl<$($T:TotalOrd),+> TotalOrd for ($($T,)+) {
+                #[inline]
+                fn cmp(&self, other: &($($T,)+)) -> Ordering {
+                    lexical_cmp!($(self.$get_ref_fn(), other.$get_ref_fn()),+)
                 }
+            }
 
-                #[cfg(not(test))]
-                impl<$($T:Default),+> Default for ($($T,)+) {
-                    #[inline]
-                    fn default() -> ($($T,)+) {
-                        ($({ let x: $T = Default::default(); x},)+)
-                    }
+            #[cfg(not(test))]
+            impl<$($T:Default),+> Default for ($($T,)+) {
+                #[inline]
+                fn default() -> ($($T,)+) {
+                    ($({ let x: $T = Default::default(); x},)+)
                 }
+            }
 
-                #[cfg(not(test))]
-                impl<$($T:Zero),+> Zero for ($($T,)+) {
-                    #[inline]
-                    fn zero() -> ($($T,)+) {
-                        ($({ let x: $T = Zero::zero(); x},)+)
-                    }
-                    #[inline]
-                    fn is_zero(&self) -> bool {
-                        $(self.$get_ref_fn().is_zero())&&+
-                    }
+            #[cfg(not(test))]
+            impl<$($T:Zero),+> Zero for ($($T,)+) {
+                #[inline]
+                fn zero() -> ($($T,)+) {
+                    ($({ let x: $T = Zero::zero(); x},)+)
                 }
-            )+
-        }
+                #[inline]
+                fn is_zero(&self) -> bool {
+                    $(self.$get_ref_fn().is_zero())&&+
+                }
+            }
+        )+
     }
 }
 
index 89a51a5ddddd3e4956e72f96638d08ab064626c7..01b4225d70bad4126f8e613264ad422c953287c5 100644 (file)
@@ -34,7 +34,7 @@
 
 // This is needed to prevent duplicate lang item definitions.
 #[cfg(test)]
-pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor};
+pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor, TypeId};
 
 pub type GlueFn = extern "Rust" fn(*i8);
 
@@ -313,7 +313,11 @@ fn visit_leave_fn(&mut self, purity: uint, proto: uint,
     /// Gets an identifier which is globally unique to the specified type. This
     /// function will return the same value for a type regardless of whichever
     /// crate it is invoked in.
+    #[cfg(stage0)]
     pub fn type_id<T: 'static>() -> u64;
+    #[cfg(not(stage0))]
+    pub fn type_id<T: 'static>() -> TypeId;
+
 
     /// Create a value initialized to zero.
     ///
@@ -486,3 +490,22 @@ fn visit_leave_fn(&mut self, purity: uint, proto: uint,
 #[cfg(target_endian = "big")]    pub fn to_be32(x: i32) -> i32 { x }
 #[cfg(target_endian = "little")] pub fn to_be64(x: i64) -> i64 { unsafe { bswap64(x) } }
 #[cfg(target_endian = "big")]    pub fn to_be64(x: i64) -> i64 { x }
+
+
+/// `TypeId` represents a globally unique identifier for a type
+#[lang="type_id"] // This needs to be kept in lockstep with the code in trans/intrinsic.rs and
+                  // middle/lang_items.rs
+#[deriving(Eq, IterBytes)]
+#[cfg(not(test))]
+pub struct TypeId {
+    priv t: u64,
+}
+
+#[cfg(not(test))]
+impl TypeId {
+    /// Returns the `TypeId` of the type this generic function has been instantiated with
+    #[cfg(not(stage0))]
+    pub fn of<T: 'static>() -> TypeId {
+        unsafe { type_id::<T>() }
+    }
+}
index e76251e8a1e72b79211087535e10c2d7ad6c376c..293c9ed98172865ec51461bbcc9c197aa93bd95d 100644 (file)
@@ -2463,15 +2463,14 @@ fn default() -> @[A] { @[] }
 }
 
 macro_rules! iterator {
-    /* FIXME: #4375 Cannot attach documentation/attributes to a macro generated struct.
     (struct $name:ident -> $ptr:ty, $elem:ty) => {
+        /// An iterator for iterating over a vector.
         pub struct $name<'self, T> {
             priv ptr: $ptr,
             priv end: $ptr,
-            priv lifetime: $elem // FIXME: #5922
+            priv lifetime: Option<$elem> // FIXME: #5922
         }
-    };*/
-    (impl $name:ident -> $elem:ty) => {
+
         impl<'self, T> Iterator<$elem> for $name<'self, T> {
             #[inline]
             fn next(&mut self) -> Option<$elem> {
@@ -2502,11 +2501,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
                 (exact, Some(exact))
             }
         }
-    }
-}
 
-macro_rules! double_ended_iterator {
-    (impl $name:ident -> $elem:ty) => {
         impl<'self, T> DoubleEndedIterator<$elem> for $name<'self, T> {
             #[inline]
             fn next_back(&mut self) -> Option<$elem> {
@@ -2548,15 +2543,7 @@ fn idx(&self, index: uint) -> Option<&'self T> {
     }
 }
 
-//iterator!{struct VecIterator -> *T, &'self T}
-/// An iterator for iterating over a vector.
-pub struct VecIterator<'self, T> {
-    priv ptr: *T,
-    priv end: *T,
-    priv lifetime: Option<&'self ()> // FIXME: #5922
-}
-iterator!{impl VecIterator -> &'self T}
-double_ended_iterator!{impl VecIterator -> &'self T}
+iterator!{struct VecIterator -> *T, &'self T}
 pub type RevIterator<'self, T> = Invert<VecIterator<'self, T>>;
 
 impl<'self, T> ExactSize<&'self T> for VecIterator<'self, T> {}
@@ -2566,15 +2553,7 @@ impl<'self, T> Clone for VecIterator<'self, T> {
     fn clone(&self) -> VecIterator<'self, T> { *self }
 }
 
-//iterator!{struct VecMutIterator -> *mut T, &'self mut T}
-/// An iterator for mutating the elements of a vector.
-pub struct VecMutIterator<'self, T> {
-    priv ptr: *mut T,
-    priv end: *mut T,
-    priv lifetime: Option<&'self mut ()> // FIXME: #5922
-}
-iterator!{impl VecMutIterator -> &'self mut T}
-double_ended_iterator!{impl VecMutIterator -> &'self mut T}
+iterator!{struct VecMutIterator -> *mut T, &'self mut T}
 pub type MutRevIterator<'self, T> = Invert<VecMutIterator<'self, T>>;
 
 /// An iterator that moves out of a vector.
index 351eab35a77fbfdb5aa6e352fa53a0c926a55244..7fd503a8d42942bbe83bfad68731353ffc996a3d 100644 (file)
@@ -19,7 +19,8 @@
        uuid = "9311401b-d6ea-4cd9-a1d9-61f89499c645")];
 
 #[license = "MIT/ASL2"];
-#[crate_type = "lib"];
+#[crate_type = "lib"]; // NOTE: remove after stage0 snapshot
+#[crate_type = "dylib"];
 
 #[feature(macro_rules, globs, managed_boxes)];
 
index 8fbd152543dd9f4919d56d4b71e3bab2073a8faa..54a3dad94959d2ae523362d5d17a963aaf91f337 100644 (file)
@@ -341,11 +341,12 @@ mod test {
     use util::parser_testing::{string_to_expr, string_to_item};
     use util::parser_testing::string_to_stmt;
 
-    #[cfg(test)] fn to_json_str<E : Encodable<extra::json::Encoder>>(val: @E) -> ~str {
-        let writer = @mut MemWriter::new();
-        let mut encoder = extra::json::Encoder(writer as @mut io::Writer);
+    #[cfg(test)]
+    fn to_json_str<'a, E: Encodable<extra::json::Encoder<'a>>>(val: &E) -> ~str {
+        let mut writer = MemWriter::new();
+        let mut encoder = extra::json::Encoder::init(&mut writer as &mut io::Writer);
         val.encode(&mut encoder);
-        str::from_utf8(*writer.inner_ref())
+        str::from_utf8_owned(writer.inner())
     }
 
     // produce a codemap::span
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
deleted file mode 100644 (file)
index 2a3e687..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-rust_dbg_abi_1
-rust_dbg_abi_2
-rust_dbg_static_mut
-rust_dbg_static_mut_check_four
-rust_get_time
-rust_tzset
-rust_gmtime
-rust_localtime
-rust_timegm
-rust_mktime
-rust_precise_time_ns
-rust_list_dir_val
-rust_list_dir_wfd_size
-rust_list_dir_wfd_fp_buf
-rust_unset_sigprocmask
-rust_env_pairs
-rust_win32_rand_acquire
-rust_win32_rand_gen
-rust_win32_rand_release
-upcall_rust_personality
-upcall_reset_stack_limit
-rust_dbg_call
-rust_dbg_do_nothing
-tdefl_compress_mem_to_heap
-tinfl_decompress_mem_to_heap
-rust_swap_registers
-rust_readdir
-rust_opendir
-rust_dbg_extern_identity_u32
-rust_dbg_extern_identity_u64
-rust_dbg_extern_identity_TwoU8s
-rust_dbg_extern_identity_TwoU16s
-rust_dbg_extern_identity_TwoU32s
-rust_dbg_extern_identity_TwoU64s
-rust_dbg_extern_identity_TwoDoubles
-rust_dbg_extern_return_TwoU8s
-rust_dbg_extern_return_TwoU16s
-rust_dbg_extern_return_TwoU32s
-rust_dbg_extern_return_TwoU64s
-rust_dbg_extern_identity_double
-rust_dbg_extern_identity_u8
-rust_try
-rust_begin_unwind
-rust_valgrind_stack_register
-rust_valgrind_stack_deregister
-rust_running_on_valgrind
-rust_get_num_cpus
-rust_get_test_int
-rust_pthread_mutex_t_size
-rust_pthread_cond_t_size
-rust_crit_section_size
index a6b887f058af89933c1c5c7265020f0cbcd2a556..069f29e909d4b2204ff10b388b3593929d460f9e 100644 (file)
@@ -630,3 +630,5 @@ LLVMAddReturnAttribute
 LLVMRemoveReturnAttribute
 LLVMTypeToString
 LLVMAddColdAttribute
+LLVMCreateMemoryBufferWithMemoryRange
+LLVMCreateMemoryBufferWithMemoryRangeCopy
index ca9c6eb79f98eb37c77e3af2b03073759da04cb9..01a90f1ad449b73e460dce483864dfe896fe33bc 100644 (file)
@@ -8,14 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[link_name = "rustrt"];
-#[link(name = "anonexternmod",
-       vers = "0.1")];
+#[link(name = "anonexternmod", vers = "0.1")];
 
 #[crate_type = "lib"];
 
 use std::libc;
 
 extern {
+    #[link(name = "rustrt")]
     pub fn rust_get_test_int() -> libc::intptr_t;
 }
index e77efce7f5876497169769a30fa7b43681d255cd..89317a45171132d928abb22f6eb5cad8e658240c 100644 (file)
@@ -18,6 +18,7 @@
 pub mod rustrt {
     use std::libc;
 
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
                              data: libc::uintptr_t)
index d67e329b04e887e95ef6fcff9b497f85cf4f7f24..4705d13cd968564e7b1192a227f07c85f9268d58 100644 (file)
@@ -13,6 +13,7 @@
 pub mod rustrt {
     use std::libc;
 
+    #[link(name = "rustrt")]
     extern {
         fn rust_get_test_int() -> libc::intptr_t;
     }
index 768b0d19da3d1695b1812eddbeb351d9754094b7..9bb867372619a2e650be659935f31d4dbc51b9d2 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::unstable::intrinsics;
+use std::unstable::intrinsics::TypeId;
 
 pub struct A;
 pub struct B(Option<A>);
 pub type G = uint;
 pub type H = &'static str;
 
-pub unsafe fn id_A() -> u64 { intrinsics::type_id::<A>() }
-pub unsafe fn id_B() -> u64 { intrinsics::type_id::<B>() }
-pub unsafe fn id_C() -> u64 { intrinsics::type_id::<C>() }
-pub unsafe fn id_D() -> u64 { intrinsics::type_id::<D>() }
-pub unsafe fn id_E() -> u64 { intrinsics::type_id::<E>() }
-pub unsafe fn id_F() -> u64 { intrinsics::type_id::<F>() }
-pub unsafe fn id_G() -> u64 { intrinsics::type_id::<G>() }
-pub unsafe fn id_H() -> u64 { intrinsics::type_id::<H>() }
+pub unsafe fn id_A() -> TypeId { intrinsics::type_id::<A>() }
+pub unsafe fn id_B() -> TypeId { intrinsics::type_id::<B>() }
+pub unsafe fn id_C() -> TypeId { intrinsics::type_id::<C>() }
+pub unsafe fn id_D() -> TypeId { intrinsics::type_id::<D>() }
+pub unsafe fn id_E() -> TypeId { intrinsics::type_id::<E>() }
+pub unsafe fn id_F() -> TypeId { intrinsics::type_id::<F>() }
+pub unsafe fn id_G() -> TypeId { intrinsics::type_id::<G>() }
+pub unsafe fn id_H() -> TypeId { intrinsics::type_id::<H>() }
 
-pub unsafe fn foo<T: 'static>() -> u64 { intrinsics::type_id::<T>() }
+pub unsafe fn foo<T: 'static>() -> TypeId { intrinsics::type_id::<T>() }
index 768b0d19da3d1695b1812eddbeb351d9754094b7..9bb867372619a2e650be659935f31d4dbc51b9d2 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::unstable::intrinsics;
+use std::unstable::intrinsics::TypeId;
 
 pub struct A;
 pub struct B(Option<A>);
 pub type G = uint;
 pub type H = &'static str;
 
-pub unsafe fn id_A() -> u64 { intrinsics::type_id::<A>() }
-pub unsafe fn id_B() -> u64 { intrinsics::type_id::<B>() }
-pub unsafe fn id_C() -> u64 { intrinsics::type_id::<C>() }
-pub unsafe fn id_D() -> u64 { intrinsics::type_id::<D>() }
-pub unsafe fn id_E() -> u64 { intrinsics::type_id::<E>() }
-pub unsafe fn id_F() -> u64 { intrinsics::type_id::<F>() }
-pub unsafe fn id_G() -> u64 { intrinsics::type_id::<G>() }
-pub unsafe fn id_H() -> u64 { intrinsics::type_id::<H>() }
+pub unsafe fn id_A() -> TypeId { intrinsics::type_id::<A>() }
+pub unsafe fn id_B() -> TypeId { intrinsics::type_id::<B>() }
+pub unsafe fn id_C() -> TypeId { intrinsics::type_id::<C>() }
+pub unsafe fn id_D() -> TypeId { intrinsics::type_id::<D>() }
+pub unsafe fn id_E() -> TypeId { intrinsics::type_id::<E>() }
+pub unsafe fn id_F() -> TypeId { intrinsics::type_id::<F>() }
+pub unsafe fn id_G() -> TypeId { intrinsics::type_id::<G>() }
+pub unsafe fn id_H() -> TypeId { intrinsics::type_id::<H>() }
 
-pub unsafe fn foo<T: 'static>() -> u64 { intrinsics::type_id::<T>() }
+pub unsafe fn foo<T: 'static>() -> TypeId { intrinsics::type_id::<T>() }
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);
+}
diff --git a/src/test/run-make/c-dynamic-dylib/Makefile b/src/test/run-make/c-dynamic-dylib/Makefile
new file mode 100644 (file)
index 0000000..2b2e5d5
--- /dev/null
@@ -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 (file)
index 0000000..7c4aca1
--- /dev/null
@@ -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 (file)
index 0000000..9fe07f8
--- /dev/null
@@ -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 (file)
index 0000000..0c4a6f7
--- /dev/null
@@ -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 (file)
index 0000000..1899270
--- /dev/null
@@ -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 (file)
index 0000000..7c4aca1
--- /dev/null
@@ -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 (file)
index 0000000..9fe07f8
--- /dev/null
@@ -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 (file)
index 0000000..e64811a
--- /dev/null
@@ -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 (file)
index 0000000..fb57a08
--- /dev/null
@@ -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 (file)
index 0000000..bb4036b
--- /dev/null
@@ -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 (file)
index 0000000..6b6a786
--- /dev/null
@@ -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 (file)
index 0000000..a81f19d
--- /dev/null
@@ -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 (file)
index 0000000..bb4036b
--- /dev/null
@@ -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 (file)
index 0000000..3da09eb
--- /dev/null
@@ -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 (file)
index 0000000..62d9c8e
--- /dev/null
@@ -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 (file)
index 0000000..7c4aca1
--- /dev/null
@@ -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 (file)
index 0000000..9fe07f8
--- /dev/null
@@ -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 (file)
index 0000000..0c4a6f7
--- /dev/null
@@ -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 (file)
index 0000000..09eb4b1
--- /dev/null
@@ -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 (file)
index 0000000..7c4aca1
--- /dev/null
@@ -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 (file)
index 0000000..9fe07f8
--- /dev/null
@@ -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 (file)
index 0000000..e64811a
--- /dev/null
@@ -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 (file)
index 0000000..e60e904
--- /dev/null
@@ -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 (file)
index 0000000..69ea8dc
--- /dev/null
@@ -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 (file)
index 0000000..2f5d75a
--- /dev/null
@@ -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 (file)
index 0000000..cc4ff2c
--- /dev/null
@@ -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 (file)
index 0000000..c52d1f7
--- /dev/null
@@ -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 (file)
index 0000000..9ab2abc
--- /dev/null
@@ -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 (file)
index 0000000..89d7b64
--- /dev/null
@@ -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 (file)
index 0000000..130bc2f
--- /dev/null
@@ -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 (file)
index 0000000..da90f87
--- /dev/null
@@ -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 (file)
index 0000000..eb00c80
--- /dev/null
@@ -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 (file)
index 0000000..9652cb2
--- /dev/null
@@ -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 (file)
index 0000000..ec67dea
--- /dev/null
@@ -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 (file)
index 0000000..32c322f
--- /dev/null
@@ -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 (file)
index 0000000..8229547
--- /dev/null
@@ -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 (file)
index 0000000..c5c0bc6
--- /dev/null
@@ -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 (file)
index 0000000..f86ef62
--- /dev/null
@@ -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 (file)
index 0000000..eedb70c
--- /dev/null
@@ -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 (file)
index 0000000..c5c0bc6
--- /dev/null
@@ -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 (file)
index 0000000..f86ef62
--- /dev/null
@@ -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 (file)
index 0000000..30b6811
--- /dev/null
@@ -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 (file)
index 0000000..1a244ef
--- /dev/null
@@ -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 (file)
index 0000000..96f7712
--- /dev/null
@@ -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 (file)
index 0000000..cb8d752
--- /dev/null
@@ -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 (file)
index 0000000..c52d1f7
--- /dev/null
@@ -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 (file)
index 0000000..d4f215c
--- /dev/null
@@ -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 (file)
index 0000000..c5c0bc6
--- /dev/null
@@ -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 (file)
index 0000000..f86ef62
--- /dev/null
@@ -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 (file)
index 0000000..e8909ef
--- /dev/null
@@ -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 (file)
index 0000000..c5c0bc6
--- /dev/null
@@ -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 (file)
index 0000000..f86ef62
--- /dev/null
@@ -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 (file)
index 0000000..cb03974
--- /dev/null
@@ -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 (file)
index 0000000..4e2cdb6
--- /dev/null
@@ -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 (file)
index 0000000..029933a
--- /dev/null
@@ -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 (file)
index 0000000..2d670cb
--- /dev/null
@@ -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
+       $(CC) -dynamiclib -Wl,-dylib -o $@ $<
+%.so: %.o
+       $(CC) -o $@ $< -shared
+$(TMPDIR)/lib%.o: %.c
+       $(CC) -c -o $@ $<
+
index a9c6141c18b46fe72515f0eae2c343ca27042068..4c2e78db398452be7e20719fad04ef6798378aa7 100644 (file)
@@ -9,11 +9,15 @@
 // except according to those terms.
 
 // xfail-fast
+// xfail-pretty
 // aux-build:anon-extern-mod-cross-crate-1.rs
 extern mod anonexternmod;
 
 use anonexternmod::rust_get_test_int;
 
+#[link(name = "rustrt")] // we have explicitly chosen to require this
+extern {}
+
 pub fn main() {
     unsafe {
         rust_get_test_int();
index 3323aa4e2cde6dbc689dcce78aebd79f20d4ae10..7e05bcc1fd2266f03fe16c0f2c3fd5ed3ff89792 100644 (file)
@@ -10,7 +10,7 @@
 
 use std::libc;
 
-#[link_name = "rustrt"]
+#[link(name = "rustrt")]
 extern {
     fn rust_get_test_int() -> libc::intptr_t;
 }
index f8d30a9a6672f2e056266590f464978cb4117727..d590c35d9e2185600b860ff6f7b557ef64dd0b20 100644 (file)
@@ -11,6 +11,7 @@
 mod rustrt {
     use std::libc;
 
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_get_test_int() -> libc::intptr_t;
     }
index f55be369b57df546b81aba970579a6bc579c413d..e3b727fafd3c823c43c07f7848f70dc4ce5fbdc3 100644 (file)
@@ -13,6 +13,7 @@
 mod rustrt {
     use std::libc;
 
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
                              data: libc::uintptr_t)
index 5bda762a68bcf1249726832fe6b2b354d33f8996..00ac0bfa118eb19763a092219d45b25d2f84bec8 100644 (file)
@@ -14,6 +14,7 @@
 mod rustrt {
     use std::libc;
 
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
                              data: libc::uintptr_t)
index 6222b681dc994a1448af99ea8110250d8ebd3a85..c49d589572cbedacd5897151d9ab262d851f2037 100644 (file)
@@ -13,6 +13,7 @@
 mod rustrt {
     use std::libc;
 
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
                              data: libc::uintptr_t)
index 548336962f5100124b8dfaac9d4ceca87c1b72be..0044f0f468f306a28b6507bfb10b37ce208cf10c 100644 (file)
@@ -18,6 +18,7 @@
 mod rustrt {
     use std::libc;
 
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
                              data: libc::uintptr_t)
index bb6a68dfda407880bf2bbd290bdee5dc1e515764..c224a2f1f0543fdefc40deb3cec69ce6f02ef115 100644 (file)
@@ -18,6 +18,7 @@ struct TwoU16s {
     one: u16, two: u16
 }
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
 }
index 3389c56c83bf00afd777789a2f270c409f0a8721..592d42c65d1886bb3dad763730e3100714367678 100644 (file)
@@ -16,6 +16,7 @@ struct TwoU32s {
     one: u32, two: u32
 }
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
 }
index 033359f85fa331de175d3121f6bafc090b1a6216..d2520f32c7bd2c4fd5f0aea150660c242f5dee85 100644 (file)
@@ -18,6 +18,7 @@ struct TwoU64s {
     one: u64, two: u64
 }
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
 }
index 8757f9593f77074b413435c572e617e18c0596ef..5548b8a7d3993bf1907aba808cbac9a79cee1c14 100644 (file)
@@ -18,6 +18,7 @@ struct TwoU8s {
     one: u8, two: u8
 }
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
 }
index 0cdfaf29a0582a44e9934eb12c26fa256ab508c8..85d0463fe7252c3d57a388ccf10e14e65b4fea0e 100644 (file)
@@ -10,6 +10,7 @@
 
 // Test a function that takes/returns a u8.
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
 }
index cb0a061a7abd831e2d42e185b43e5c3bf1834e50..2d35fe6043e8fc013cb2184c381d573f4ab7b4a7 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
 }
index aa54f014046127c735d695d8d74b1fec1177af95..5ff3353a8c085a4248940e4e351c98903239b260 100644 (file)
@@ -10,6 +10,7 @@
 
 // Test a function that takes/returns a u32.
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
 }
index 7c39080a5689732dc778d8554e015c0e12a31eee..b94c57a7a663d5b62982c17eccef05b3d21c9d06 100644 (file)
@@ -10,6 +10,7 @@
 
 // Test a call to a function that takes/returns a u64.
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
 }
index ba671a1c4949f3bf82ea231708f881591fcbcd9b..45efbbb278540bb9d2c6ce8c327498a4a3713bc1 100644 (file)
@@ -12,6 +12,7 @@ struct TwoU16s {
     one: u16, two: u16
 }
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
 }
index 90562f0f6b1cec5419f334d707acc5a6b9fdfbc7..8258ee623ab229221f7694abd39dfcca696d07b8 100644 (file)
@@ -12,6 +12,7 @@ struct TwoU32s {
     one: u32, two: u32
 }
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
 }
index b52808ea32db0644e93f424e795aac0b59932632..d8b051f57a92f428fa6c2a6c7100db1bf476557e 100644 (file)
@@ -14,6 +14,7 @@ struct TwoU64s {
     one: u64, two: u64
 }
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
 }
index 5d2fd14075844f46379e416535bd9445d590e38f..99dbd93fb7d3ed3c6542f73ac7519098caf09ec7 100644 (file)
@@ -12,6 +12,7 @@ struct TwoU8s {
     one: u8, two: u8
 }
 
+#[link(name = "rustrt")]
 extern {
     pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
 }
index 6ef196ccd41fc2bd0142ffb5e9cddbf00a3eb8ed..7c16ae74c4a91a1dc65c23a30a6adeeecc79ed61 100644 (file)
@@ -17,6 +17,7 @@
 mod rustrt {
     use std::libc;
 
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
                              data: libc::uintptr_t)
index 1d2f52d8c2eb606d9eb66fef686f469e5e6090d7..a4ac197ac6aed522f2dcc9ce575e3391b72b3874 100644 (file)
@@ -14,6 +14,7 @@
 mod rustrt {
     use std::libc;
 
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_dbg_call(cb: extern "C" fn (libc::uintptr_t) -> libc::uintptr_t,
                              data: libc::uintptr_t)
index 283efa2ac7c6f31345a4716a59daafc3100a45fa..ee54423a97d7d6d998e4faeff5cf922cf1165565 100644 (file)
@@ -2,6 +2,7 @@
 use std::libc;
 use std::unstable::run_in_bare_thread;
 
+#[link(name = "rustrt")]
 extern {
     fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t),
                      data: libc::uintptr_t) -> libc::uintptr_t;
index 66d3bda30e6f210b68b06ad6d17e082f9306304d..260b1f272c234fdfac4ff018c09ac9c5c29d525c 100644 (file)
@@ -14,7 +14,7 @@
 mod rustrt1 {
     use std::libc;
 
-    #[link_name = "rustrt"]
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_get_test_int() -> libc::intptr_t;
     }
@@ -23,7 +23,7 @@ mod rustrt1 {
 mod rustrt2 {
     use std::libc;
 
-    #[link_name = "rustrt"]
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_get_test_int() -> libc::intptr_t;
     }
index 0702d49cfc11200486261ce4e80345e70654dafd..eef45532265a38c84130ed86109c8574ca1ccbb8 100644 (file)
@@ -13,6 +13,7 @@
 mod rustrt {
     use std::libc;
 
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_get_test_int() -> libc::intptr_t;
     }
index 7e79311c5ad1f28da6f295538752b967e01634a1..ec531d391e42283706b4d15e6b72e8455e491266 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // xfail-fast
+// xfail-pretty
 // aux-build:foreign_lib.rs
 
 // The purpose of this test is to check that we can
@@ -17,6 +18,9 @@
 
 extern mod foreign_lib;
 
+#[link(name = "rustrt")] // we have explicitly chosen to require this
+extern {}
+
 pub fn main() {
     unsafe {
         let _foo = foreign_lib::rustrt::rust_get_test_int();
diff --git a/src/test/run-pass/issue-10734.rs b/src/test/run-pass/issue-10734.rs
new file mode 100644 (file)
index 0000000..5123b21
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+pub fn main() {
+    if true {
+        let _a = ~3;
+    }
+    if false {
+        fail!()
+    } else {
+        let _a = ~3;
+    }
+}
index c4178961d9e6946577d558a0018cdf8df04ca640..578d210a6fc3f179f9e4d780f1d7f3994a197175 100644 (file)
@@ -18,7 +18,7 @@ trait JD : Decodable<json::Decoder> { }
 
 fn exec<T: JD>() {
     let doc = json::from_str("").unwrap();
-    let mut decoder = json::Decoder(doc);
+    let mut decoder = json::Decoder::init(doc);
     let _v: T = Decodable::decode(&mut decoder);
     fail!()
 }
index ad82071259593e8b4025a816f4d5f0b2bab81096..bd3ca844263510ce261b9f7f1e68abd68d9a7104 100644 (file)
@@ -17,6 +17,6 @@
 
 pub fn main() {
     let json = json::from_str("[1]").unwrap();
-    let mut decoder = json::Decoder(json);
+    let mut decoder = json::Decoder::init(json);
     let _x: ~[int] = serialize::Decodable::decode(&mut decoder);
 }
index bdfc747c8bc77339e0f3f44228acec4ea97bb0ed..0afe01bf7edc8cea01d44ac0ac9a606c3266b8d2 100644 (file)
@@ -14,7 +14,7 @@
 
 use std::libc;
 
-#[nolink]
+#[link(name = "rustrt")]
 extern {
     static mut rust_dbg_static_mut: libc::c_int;
     pub fn rust_dbg_static_mut_check_four();
index 324186021b8e46b7298c64791a9fd48e647307ae..e2fe7a960163e12908554652d651032949a08880 100644 (file)
@@ -16,7 +16,7 @@ pub struct Floats { a: f64, b: u8, c: f64 }
 mod rustrt {
     use super::{Floats, Quad};
 
-    #[nolink]
+    #[link(name = "rustrt")]
     extern {
         pub fn rust_dbg_abi_1(q: Quad) -> Quad;
         pub fn rust_dbg_abi_2(f: Floats) -> Floats;
index 3fd7c05796bc4b46749838f1148452732753f4eb..1999043c6cdd2bc14888e19a5a1b391c0f0042a7 100644 (file)
 extern mod other2(name = "typeid-intrinsic2");
 
 use std::unstable::intrinsics;
+use std::unstable::intrinsics::TypeId;
 
 struct A;
+struct Test;
 
 fn main() {
     unsafe {
@@ -50,4 +52,23 @@ fn main() {
         assert_eq!(intrinsics::type_id::<A>(), other1::foo::<A>());
         assert_eq!(other2::foo::<A>(), other1::foo::<A>());
     }
+
+    // sanity test of TypeId
+    let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
+                     TypeId::of::<Test>());
+    let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
+                     TypeId::of::<Test>());
+
+    assert!(a != b);
+    assert!(a != c);
+    assert!(b != c);
+
+    assert_eq!(a, d);
+    assert_eq!(b, e);
+    assert_eq!(c, f);
+
+    // check it has a hash
+    let (a, b) = (TypeId::of::<uint>(), TypeId::of::<uint>());
+
+    assert_eq!(a.hash(), b.hash());
 }