From 91f8144906137335c3683b99d9c5c4ccaaebcde6 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Tue, 13 Dec 2016 09:50:30 -0800 Subject: [PATCH] Implement the "static-nobundle" library kind (RFC 1717). These are static libraries that are not bundled (as the name implies) into rlibs and staticlibs that rustc generates, and must be present when the final binary artifact is being linked. --- src/librustc/middle/cstore.rs | 3 ++- src/librustc/session/config.rs | 1 + src/librustc_metadata/creader.rs | 1 + src/librustc_metadata/cstore.rs | 2 +- src/librustc_trans/back/link.rs | 4 ++++ src/test/run-make/static-nobundle/Makefile | 13 +++++++++++++ src/test/run-make/static-nobundle/bar.rs | 22 ++++++++++++++++++++++ src/test/run-make/static-nobundle/foo.c | 11 +++++++++++ src/test/run-make/static-nobundle/main.rs | 16 ++++++++++++++++ 9 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/test/run-make/static-nobundle/Makefile create mode 100644 src/test/run-make/static-nobundle/bar.rs create mode 100644 src/test/run-make/static-nobundle/foo.c create mode 100644 src/test/run-make/static-nobundle/main.rs diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 496a3d4a4984..e674b6ea8363 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -46,7 +46,7 @@ use rustc_back::target::Target; use hir; use rustc_back::PanicStrategy; -pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown}; +pub use self::NativeLibraryKind::*; // lonely orphan structs and enums looking for a better home @@ -122,6 +122,7 @@ pub enum LinkagePreference { #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] pub enum NativeLibraryKind { NativeStatic, // native static library (.a archive) + NativeStaticNobundle, // native static library, which doesn't get bundled into .rlibs NativeFramework, // OSX-specific NativeUnknown, // default way to specify a dynamic library } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 104c851e057e..ef68b2f76b07 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1473,6 +1473,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) (Some(name), "dylib") => (name, cstore::NativeUnknown), (Some(name), "framework") => (name, cstore::NativeFramework), (Some(name), "static") => (name, cstore::NativeStatic), + (Some(name), "static-nobundle") => (name, cstore::NativeStaticNobundle), (_, s) => { early_error(error_format, &format!("unknown library kind `{}`, expected \ one of dylib, framework, or static", diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 8f7b9c24cbf8..d9c64d3e7b34 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -917,6 +917,7 @@ impl<'a> CrateLoader<'a> { }).and_then(|a| a.value_str()).map(Symbol::as_str); let kind = match kind.as_ref().map(|s| &s[..]) { Some("static") => cstore::NativeStatic, + Some("static-nobundle") => cstore::NativeStaticNobundle, Some("dylib") => cstore::NativeUnknown, Some("framework") => cstore::NativeFramework, Some(k) => { diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 761041ad7198..beba5faf3d03 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -32,7 +32,7 @@ use syntax::symbol::Symbol; use syntax_pos; pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference}; -pub use rustc::middle::cstore::{NativeStatic, NativeFramework, NativeUnknown}; +pub use rustc::middle::cstore::NativeLibraryKind::*; pub use rustc::middle::cstore::{CrateSource, LinkMeta, LibSource}; // A map from external crate numbers (as decoded from some crate file) to diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index defbb44448a9..aa42364f951c 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -476,6 +476,7 @@ fn link_rlib<'a>(sess: &'a Session, for lib in sess.cstore.used_libraries() { match lib.kind { NativeLibraryKind::NativeStatic => {} + NativeLibraryKind::NativeStaticNobundle | NativeLibraryKind::NativeFramework | NativeLibraryKind::NativeUnknown => continue, } @@ -674,6 +675,7 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path, for lib in all_native_libs.iter().filter(|l| relevant_lib(sess, l)) { let name = match lib.kind { + NativeLibraryKind::NativeStaticNobundle | NativeLibraryKind::NativeUnknown => "library", NativeLibraryKind::NativeFramework => "framework", // These are included, no need to print them @@ -985,6 +987,7 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) { match lib.kind { NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()), NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()), + NativeLibraryKind::NativeStaticNobundle => cmd.link_staticlib(&lib.name.as_str()), NativeLibraryKind::NativeStatic => bug!(), } } @@ -1229,6 +1232,7 @@ fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session) { match lib.kind { NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()), NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()), + NativeLibraryKind::NativeStaticNobundle => cmd.link_staticlib(&lib.name.as_str()), // ignore statically included native libraries here as we've // already included them when we included the rust library diff --git a/src/test/run-make/static-nobundle/Makefile b/src/test/run-make/static-nobundle/Makefile new file mode 100644 index 000000000000..b184d54ff9c6 --- /dev/null +++ b/src/test/run-make/static-nobundle/Makefile @@ -0,0 +1,13 @@ +-include ../tools.mk + +all: $(call NATIVE_STATICLIB,foo) + $(RUSTC) bar.rs + + # Check that libbar.rlib does not contain the definition of `func` + nm $(TMPDIR)/libbar.rlib | (! grep "T _*func") + nm $(TMPDIR)/libbar.rlib | grep "U _*func" + + # Check that foo gets passed to the linker (as either `-l foo` or `foo.lib`) + $(RUSTC) main.rs -Z print-link-args | grep -e "-l[\" ]*foo" -e "foo.lib" + + $(call RUN,main) diff --git a/src/test/run-make/static-nobundle/bar.rs b/src/test/run-make/static-nobundle/bar.rs new file mode 100644 index 000000000000..e14b5a669f44 --- /dev/null +++ b/src/test/run-make/static-nobundle/bar.rs @@ -0,0 +1,22 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] + +#[link(name = "foo", kind = "static-nobundle")] +extern { + pub fn func(); +} + +pub fn wrapped_func() { + unsafe { + func(); + } +} diff --git a/src/test/run-make/static-nobundle/foo.c b/src/test/run-make/static-nobundle/foo.c new file mode 100644 index 000000000000..5ccf713f79c6 --- /dev/null +++ b/src/test/run-make/static-nobundle/foo.c @@ -0,0 +1,11 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +void func() {} diff --git a/src/test/run-make/static-nobundle/main.rs b/src/test/run-make/static-nobundle/main.rs new file mode 100644 index 000000000000..7aa730f1dd26 --- /dev/null +++ b/src/test/run-make/static-nobundle/main.rs @@ -0,0 +1,16 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate bar; + +fn main() { + unsafe { bar::func(); } + bar::wrapped_func(); +}