diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 00aee1d17dc..fc7044ed88a 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -75,6 +75,8 @@ #![allow(missing_doc)] #![allow(uppercase_variables)] +#![feature(link_args)] // NOTE: remove after stage0 + #[cfg(test)] extern crate std; #[cfg(test)] extern crate test; #[cfg(test)] extern crate native; @@ -197,6 +199,11 @@ pub use funcs::posix88::unistd::{rmdir, unlink, write}; #[link(name = "m")] extern {} +// NOTE: remove this after a stage0 snap +#[cfg(stage0, windows)] +#[link_args = "-Wl,--enable-long-section-names"] +extern {} + /// A wrapper for a nullable pointer. Don't use this except for interacting /// with libc. Basically Option, but without the dependance on libstd. // If/when libprim happens, this can be removed in favor of that diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index a329f850ed4..19ec2d465c2 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -1127,6 +1127,33 @@ fn link_args(sess: &Session, // DWARF stack unwinding will not work. // This behavior may be overridden by --link-args "-static-libgcc" args.push(~"-shared-libgcc"); + + // And here, we see obscure linker flags #45. On windows, it has been + // found to be necessary to have this flag to compile liblibc. + // + // First a bit of background. On Windows, the file format is not ELF, + // but COFF (at least according to LLVM). COFF doesn't officially allow + // for section names over 8 characters, apparently. Our metadata + // section, ".note.rustc", you'll note is over 8 characters. + // + // On more recent versions of gcc on mingw, apparently the section name + // is *not* truncated, but rather stored elsewhere in a separate lookup + // table. On older versions of gcc, they apparently always truncated the + // section names (at least in some cases). Truncating the section name + // actually creates "invalid" objects [1] [2], but only for some + // introspection tools, not in terms of whether it can be loaded. + // + // Long story shory, passing this flag forces the linker to *not* + // truncate section names (so we can find the metadata section after + // it's compiled). The real kicker is that rust compiled just fine on + // windows for quite a long time *without* this flag, so I have no idea + // why it suddenly started failing for liblibc. Regardless, we + // definitely don't want section name truncation, so we're keeping this + // flag for windows. + // + // [1] - https://sourceware.org/bugzilla/show_bug.cgi?id=13130 + // [2] - https://code.google.com/p/go/issues/detail?id=2139 + args.push(~"-Wl,--enable-long-section-names"); } if sess.targ_cfg.os == abi::OsAndroid { diff --git a/src/test/run-make/lto-smoke-c/Makefile b/src/test/run-make/lto-smoke-c/Makefile index 6a703927736..8658950f174 100644 --- a/src/test/run-make/lto-smoke-c/Makefile +++ b/src/test/run-make/lto-smoke-c/Makefile @@ -4,6 +4,9 @@ ifneq ($(shell uname),Darwin) EXTRAFLAGS := -lm -lrt -ldl -lpthread endif +# Apparently older versions of GCC segfault if -g is passed... +CC := $(CC:-g=) + all: $(RUSTC) foo.rs -Z lto ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo) diff --git a/src/test/run-make/lto-smoke-c/foo.rs b/src/test/run-make/lto-smoke-c/foo.rs index 4cb7a749385..1bb19016700 100644 --- a/src/test/run-make/lto-smoke-c/foo.rs +++ b/src/test/run-make/lto-smoke-c/foo.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[crate_type = "staticlib"]; +#![crate_type = "staticlib"] #[no_mangle] pub extern "C" fn foo() {}