1
Fork 0

Auto merge of #84982 - Dylan-DPC:rollup-q4cbec2, r=Dylan-DPC

Rollup of 8 pull requests

Successful merges:

 - #83507 (Implement RFC 2951: Native link modifiers)
 - #84328 (Stablize {HashMap,BTreeMap}::into_{keys,values})
 - #84712 (Simplify chdir implementation and minimize unsafe block)
 - #84851 (⬆️ rust-analyzer)
 - #84923 (Only compute Obligation `cache_key` once  in `register_obligation_at`)
 - #84945 (E0583: Include secondary path in error message)
 - #84949 (Fix typo in `MaybeUninit::array_assume_init` safety comment)
 - #84950 (Revert PR 83866)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-05-06 15:19:39 +00:00
commit d44f647ffc
60 changed files with 885 additions and 273 deletions

View file

@ -326,6 +326,45 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
);
}
}
// Check for unstable modifiers on `#[link(..)]` attribute
if self.sess.check_name(attr, sym::link) {
for nested_meta in attr.meta_item_list().unwrap_or_default() {
if nested_meta.has_name(sym::modifiers) {
gate_feature_post!(
self,
native_link_modifiers,
nested_meta.span(),
"native link modifiers are experimental"
);
if let Some(modifiers) = nested_meta.value_str() {
for modifier in modifiers.as_str().split(',') {
if let Some(modifier) = modifier.strip_prefix(&['+', '-'][..]) {
macro_rules! gate_modifier { ($($name:literal => $feature:ident)*) => {
$(if modifier == $name {
let msg = concat!("`#[link(modifiers=\"", $name, "\")]` is unstable");
gate_feature_post!(
self,
$feature,
nested_meta.name_value_literal_span().unwrap(),
msg
);
})*
}}
gate_modifier!(
"bundle" => native_link_modifiers_bundle
"verbatim" => native_link_modifiers_verbatim
"whole-archive" => native_link_modifiers_whole_archive
"as-needed" => native_link_modifiers_as_needed
);
}
}
}
}
}
}
}
fn visit_item(&mut self, i: &'a ast::Item) {

View file

@ -85,8 +85,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
));
}
fn add_native_library(&mut self, name: rustc_span::symbol::Symbol) {
let location = find_library(name, &self.lib_search_paths, self.sess);
fn add_native_library(&mut self, name: rustc_span::symbol::Symbol, verbatim: bool) {
let location = find_library(name, verbatim, &self.lib_search_paths, self.sess);
self.add_archive(location.clone(), |_| false).unwrap_or_else(|e| {
panic!("failed to add native library {}: {}", location.to_string_lossy(), e);
});

View file

@ -100,8 +100,9 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
/// Adds all of the contents of a native library to this archive. This will
/// search in the relevant locations for a library named `name`.
fn add_native_library(&mut self, name: Symbol) {
let location = find_library(name, &self.config.lib_search_paths, self.config.sess);
fn add_native_library(&mut self, name: Symbol, verbatim: bool) {
let location =
find_library(name, verbatim, &self.config.lib_search_paths, self.config.sess);
self.add_archive(&location, |_| false).unwrap_or_else(|e| {
self.config.sess.fatal(&format!(
"failed to add native library {}: {}",

View file

@ -4,11 +4,19 @@ use rustc_span::symbol::Symbol;
use std::io;
use std::path::{Path, PathBuf};
pub fn find_library(name: Symbol, search_paths: &[PathBuf], sess: &Session) -> PathBuf {
pub fn find_library(
name: Symbol,
verbatim: bool,
search_paths: &[PathBuf],
sess: &Session,
) -> PathBuf {
// On Windows, static libraries sometimes show up as libfoo.a and other
// times show up as foo.lib
let oslibname =
format!("{}{}{}", sess.target.staticlib_prefix, name, sess.target.staticlib_suffix);
let oslibname = if verbatim {
name.to_string()
} else {
format!("{}{}{}", sess.target.staticlib_prefix, name, sess.target.staticlib_suffix)
};
let unixlibname = format!("lib{}.a", name);
for path in search_paths {
@ -45,7 +53,7 @@ pub trait ArchiveBuilder<'a> {
lto: bool,
skip_objects: bool,
) -> io::Result<()>;
fn add_native_library(&mut self, name: Symbol);
fn add_native_library(&mut self, name: Symbol, verbatim: bool);
fn update_symbols(&mut self);
fn build(self);

View file

@ -329,15 +329,15 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
// metadata of the rlib we're generating somehow.
for lib in codegen_results.crate_info.used_libraries.iter() {
match lib.kind {
NativeLibKind::StaticBundle => {}
NativeLibKind::StaticNoBundle
| NativeLibKind::Dylib
| NativeLibKind::Framework
NativeLibKind::Static { bundle: None | Some(true), .. } => {}
NativeLibKind::Static { bundle: Some(false), .. }
| NativeLibKind::Dylib { .. }
| NativeLibKind::Framework { .. }
| NativeLibKind::RawDylib
| NativeLibKind::Unspecified => continue,
}
if let Some(name) = lib.name {
ab.add_native_library(name);
ab.add_native_library(name, lib.verbatim.unwrap_or(false));
}
}
@ -430,9 +430,10 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(
// Clearly this is not sufficient for a general purpose feature, and
// we'd want to read from the library's metadata to determine which
// object files come from where and selectively skip them.
let skip_object_files = native_libs
.iter()
.any(|lib| lib.kind == NativeLibKind::StaticBundle && !relevant_lib(sess, lib));
let skip_object_files = native_libs.iter().any(|lib| {
matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
&& !relevant_lib(sess, lib)
});
ab.add_rlib(
path,
&name.as_str(),
@ -931,7 +932,7 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
let path = find_sanitizer_runtime(&sess, &filename);
let rpath = path.to_str().expect("non-utf8 component in path");
linker.args(&["-Wl,-rpath", "-Xlinker", rpath]);
linker.link_dylib(Symbol::intern(&filename));
linker.link_dylib(Symbol::intern(&filename), false, true);
} else {
let filename = format!("librustc{}_rt.{}.a", channel, name);
let path = find_sanitizer_runtime(&sess, &filename).join(&filename);
@ -1080,21 +1081,25 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
.filter_map(|lib| {
let name = lib.name?;
match lib.kind {
NativeLibKind::StaticNoBundle
| NativeLibKind::Dylib
NativeLibKind::Static { bundle: Some(false), .. }
| NativeLibKind::Dylib { .. }
| NativeLibKind::Unspecified => {
let verbatim = lib.verbatim.unwrap_or(false);
if sess.target.is_like_msvc {
Some(format!("{}.lib", name))
Some(format!("{}{}", name, if verbatim { "" } else { ".lib" }))
} else if sess.target.linker_is_gnu {
Some(format!("-l{}{}", if verbatim { ":" } else { "" }, name))
} else {
Some(format!("-l{}", name))
}
}
NativeLibKind::Framework => {
NativeLibKind::Framework { .. } => {
// ld-only syntax, since there are no frameworks in MSVC
Some(format!("-framework {}", name))
}
// These are included, no need to print them
NativeLibKind::StaticBundle | NativeLibKind::RawDylib => None,
NativeLibKind::Static { bundle: None | Some(true), .. }
| NativeLibKind::RawDylib => None,
}
})
.collect();
@ -1812,11 +1817,20 @@ fn add_local_native_libraries(
Some(l) => l,
None => continue,
};
let verbatim = lib.verbatim.unwrap_or(false);
match lib.kind {
NativeLibKind::Dylib | NativeLibKind::Unspecified => cmd.link_dylib(name),
NativeLibKind::Framework => cmd.link_framework(name),
NativeLibKind::StaticNoBundle => cmd.link_staticlib(name),
NativeLibKind::StaticBundle => cmd.link_whole_staticlib(name, &search_path),
NativeLibKind::Dylib { as_needed } => {
cmd.link_dylib(name, verbatim, as_needed.unwrap_or(true))
}
NativeLibKind::Unspecified => cmd.link_dylib(name, verbatim, true),
NativeLibKind::Framework { as_needed } => {
cmd.link_framework(name, as_needed.unwrap_or(true))
}
NativeLibKind::Static { bundle: None | Some(true), .. }
| NativeLibKind::Static { whole_archive: Some(true), .. } => {
cmd.link_whole_staticlib(name, verbatim, &search_path);
}
NativeLibKind::Static { .. } => cmd.link_staticlib(name, verbatim),
NativeLibKind::RawDylib => {
// FIXME(#58713): Proper handling for raw dylibs.
bug!("raw_dylib feature not yet implemented");
@ -2000,9 +2014,10 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
// there's a static library that's not relevant we skip all object
// files.
let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
let skip_native = native_libs
.iter()
.any(|lib| lib.kind == NativeLibKind::StaticBundle && !relevant_lib(sess, lib));
let skip_native = native_libs.iter().any(|lib| {
matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
&& !relevant_lib(sess, lib)
});
if (!are_upstream_rust_objects_already_included(sess)
|| ignored_for_lto(sess, &codegen_results.crate_info, cnum))
@ -2144,22 +2159,28 @@ fn add_upstream_native_libraries(
if !relevant_lib(sess, &lib) {
continue;
}
let verbatim = lib.verbatim.unwrap_or(false);
match lib.kind {
NativeLibKind::Dylib | NativeLibKind::Unspecified => cmd.link_dylib(name),
NativeLibKind::Framework => cmd.link_framework(name),
NativeLibKind::StaticNoBundle => {
NativeLibKind::Dylib { as_needed } => {
cmd.link_dylib(name, verbatim, as_needed.unwrap_or(true))
}
NativeLibKind::Unspecified => cmd.link_dylib(name, verbatim, true),
NativeLibKind::Framework { as_needed } => {
cmd.link_framework(name, as_needed.unwrap_or(true))
}
NativeLibKind::Static { bundle: Some(false), .. } => {
// Link "static-nobundle" native libs only if the crate they originate from
// is being linked statically to the current crate. If it's linked dynamically
// or is an rlib already included via some other dylib crate, the symbols from
// native libs will have already been included in that dylib.
if data[cnum.as_usize() - 1] == Linkage::Static {
cmd.link_staticlib(name)
cmd.link_staticlib(name, verbatim)
}
}
// ignore statically included native libraries here as we've
// already included them when we included the rust library
// previously
NativeLibKind::StaticBundle => {}
NativeLibKind::Static { bundle: None | Some(true), .. } => {}
NativeLibKind::RawDylib => {
// FIXME(#58713): Proper handling for raw dylibs.
bug!("raw_dylib feature not yet implemented");

View file

@ -103,18 +103,19 @@ impl LinkerInfo {
pub trait Linker {
fn cmd(&mut self) -> &mut Command;
fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path);
fn link_dylib(&mut self, lib: Symbol);
fn link_dylib(&mut self, lib: Symbol, verbatim: bool, as_needed: bool);
fn link_rust_dylib(&mut self, lib: Symbol, path: &Path);
fn link_framework(&mut self, framework: Symbol);
fn link_staticlib(&mut self, lib: Symbol);
fn link_framework(&mut self, framework: Symbol, as_needed: bool);
fn link_staticlib(&mut self, lib: Symbol, verbatim: bool);
fn link_rlib(&mut self, lib: &Path);
fn link_whole_rlib(&mut self, lib: &Path);
fn link_whole_staticlib(&mut self, lib: Symbol, search_path: &[PathBuf]);
fn link_whole_staticlib(&mut self, lib: Symbol, verbatim: bool, search_path: &[PathBuf]);
fn include_path(&mut self, path: &Path);
fn framework_path(&mut self, path: &Path);
fn output_filename(&mut self, path: &Path);
fn add_object(&mut self, path: &Path);
fn gc_sections(&mut self, keep_metadata: bool);
fn no_gc_sections(&mut self);
fn full_relro(&mut self);
fn partial_relro(&mut self);
fn no_relro(&mut self);
@ -338,13 +339,32 @@ impl<'a> Linker for GccLinker<'a> {
}
}
fn link_dylib(&mut self, lib: Symbol) {
fn link_dylib(&mut self, lib: Symbol, verbatim: bool, as_needed: bool) {
if !as_needed {
if self.sess.target.is_like_osx {
// FIXME(81490): ld64 doesn't support these flags but macOS 11
// has -needed-l{} / -needed_library {}
// but we have no way to detect that here.
self.sess.warn("`as-needed` modifier not implemented yet for ld64");
} else if self.sess.target.linker_is_gnu {
self.linker_arg("--no-as-needed");
} else {
self.sess.warn("`as-needed` modifier not supported for current linker");
}
}
self.hint_dynamic();
self.cmd.arg(format!("-l{}", lib));
self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib));
if !as_needed {
if self.sess.target.is_like_osx {
// See above FIXME comment
} else if self.sess.target.linker_is_gnu {
self.linker_arg("--as-needed");
}
}
}
fn link_staticlib(&mut self, lib: Symbol) {
fn link_staticlib(&mut self, lib: Symbol, verbatim: bool) {
self.hint_static();
self.cmd.arg(format!("-l{}", lib));
self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib));
}
fn link_rlib(&mut self, lib: &Path) {
self.hint_static();
@ -378,8 +398,14 @@ impl<'a> Linker for GccLinker<'a> {
self.cmd.arg(format!("-l{}", lib));
}
fn link_framework(&mut self, framework: Symbol) {
fn link_framework(&mut self, framework: Symbol, as_needed: bool) {
self.hint_dynamic();
if !as_needed {
// FIXME(81490): ld64 as of macOS 11 supports the -needed_framework
// flag but we have no way to detect that here.
// self.cmd.arg("-needed_framework").sym_arg(framework);
self.sess.warn("`as-needed` modifier not implemented yet for ld64");
}
self.cmd.arg("-framework").sym_arg(framework);
}
@ -389,17 +415,21 @@ impl<'a> Linker for GccLinker<'a> {
// don't otherwise explicitly reference them. This can occur for
// libraries which are just providing bindings, libraries with generic
// functions, etc.
fn link_whole_staticlib(&mut self, lib: Symbol, search_path: &[PathBuf]) {
fn link_whole_staticlib(&mut self, lib: Symbol, verbatim: bool, search_path: &[PathBuf]) {
self.hint_static();
let target = &self.sess.target;
if !target.is_like_osx {
self.linker_arg("--whole-archive").cmd.arg(format!("-l{}", lib));
self.linker_arg("--whole-archive").cmd.arg(format!(
"-l{}{}",
if verbatim { ":" } else { "" },
lib
));
self.linker_arg("--no-whole-archive");
} else {
// -force_load is the macOS equivalent of --whole-archive, but it
// involves passing the full path to the library to link.
self.linker_arg("-force_load");
let lib = archive::find_library(lib, search_path, &self.sess);
let lib = archive::find_library(lib, verbatim, search_path, &self.sess);
self.linker_arg(&lib);
}
}
@ -443,6 +473,16 @@ impl<'a> Linker for GccLinker<'a> {
}
}
fn no_gc_sections(&mut self) {
if self.sess.target.is_like_osx {
self.linker_arg("-no_dead_strip");
} else if self.sess.target.is_like_solaris {
self.linker_arg("-zrecord");
} else {
self.linker_arg("--no-gc-sections");
}
}
fn optimize(&mut self) {
if !self.sess.target.linker_is_gnu {
return;
@ -710,8 +750,12 @@ impl<'a> Linker for MsvcLinker<'a> {
}
}
fn link_dylib(&mut self, lib: Symbol) {
self.cmd.arg(&format!("{}.lib", lib));
fn no_gc_sections(&mut self) {
self.cmd.arg("/OPT:NOREF,NOICF");
}
fn link_dylib(&mut self, lib: Symbol, verbatim: bool, _as_needed: bool) {
self.cmd.arg(format!("{}{}", lib, if verbatim { "" } else { ".lib" }));
}
fn link_rust_dylib(&mut self, lib: Symbol, path: &Path) {
@ -725,8 +769,8 @@ impl<'a> Linker for MsvcLinker<'a> {
}
}
fn link_staticlib(&mut self, lib: Symbol) {
self.cmd.arg(&format!("{}.lib", lib));
fn link_staticlib(&mut self, lib: Symbol, verbatim: bool) {
self.cmd.arg(format!("{}{}", lib, if verbatim { "" } else { ".lib" }));
}
fn full_relro(&mut self) {
@ -764,13 +808,13 @@ impl<'a> Linker for MsvcLinker<'a> {
fn framework_path(&mut self, _path: &Path) {
bug!("frameworks are not supported on windows")
}
fn link_framework(&mut self, _framework: Symbol) {
fn link_framework(&mut self, _framework: Symbol, _as_needed: bool) {
bug!("frameworks are not supported on windows")
}
fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) {
self.link_staticlib(lib);
self.cmd.arg(format!("/WHOLEARCHIVE:{}.lib", lib));
fn link_whole_staticlib(&mut self, lib: Symbol, verbatim: bool, _search_path: &[PathBuf]) {
self.link_staticlib(lib, verbatim);
self.cmd.arg(format!("/WHOLEARCHIVE:{}{}", lib, if verbatim { "" } else { ".lib" }));
}
fn link_whole_rlib(&mut self, path: &Path) {
self.link_rlib(path);
@ -919,7 +963,7 @@ impl<'a> Linker for EmLinker<'a> {
self.cmd.arg("-L").arg(path);
}
fn link_staticlib(&mut self, lib: Symbol) {
fn link_staticlib(&mut self, lib: Symbol, _verbatim: bool) {
self.cmd.arg("-l").sym_arg(lib);
}
@ -931,14 +975,14 @@ impl<'a> Linker for EmLinker<'a> {
self.cmd.arg(path);
}
fn link_dylib(&mut self, lib: Symbol) {
fn link_dylib(&mut self, lib: Symbol, verbatim: bool, _as_needed: bool) {
// Emscripten always links statically
self.link_staticlib(lib);
self.link_staticlib(lib, verbatim);
}
fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) {
fn link_whole_staticlib(&mut self, lib: Symbol, verbatim: bool, _search_path: &[PathBuf]) {
// not supported?
self.link_staticlib(lib);
self.link_staticlib(lib, verbatim);
}
fn link_whole_rlib(&mut self, lib: &Path) {
@ -947,7 +991,7 @@ impl<'a> Linker for EmLinker<'a> {
}
fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) {
self.link_dylib(lib);
self.link_dylib(lib, false, true);
}
fn link_rlib(&mut self, lib: &Path) {
@ -970,7 +1014,7 @@ impl<'a> Linker for EmLinker<'a> {
bug!("frameworks are not supported on Emscripten")
}
fn link_framework(&mut self, _framework: Symbol) {
fn link_framework(&mut self, _framework: Symbol, _as_needed: bool) {
bug!("frameworks are not supported on Emscripten")
}
@ -978,6 +1022,10 @@ impl<'a> Linker for EmLinker<'a> {
// noop
}
fn no_gc_sections(&mut self) {
// noop
}
fn optimize(&mut self) {
// Emscripten performs own optimizations
self.cmd.arg(match self.sess.opts.optimize {
@ -1121,11 +1169,11 @@ impl<'a> Linker for WasmLd<'a> {
}
}
fn link_dylib(&mut self, lib: Symbol) {
fn link_dylib(&mut self, lib: Symbol, _verbatim: bool, _as_needed: bool) {
self.cmd.arg("-l").sym_arg(lib);
}
fn link_staticlib(&mut self, lib: Symbol) {
fn link_staticlib(&mut self, lib: Symbol, _verbatim: bool) {
self.cmd.arg("-l").sym_arg(lib);
}
@ -1159,11 +1207,11 @@ impl<'a> Linker for WasmLd<'a> {
self.cmd.arg("-l").sym_arg(lib);
}
fn link_framework(&mut self, _framework: Symbol) {
fn link_framework(&mut self, _framework: Symbol, _as_needed: bool) {
panic!("frameworks not supported")
}
fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) {
fn link_whole_staticlib(&mut self, lib: Symbol, _verbatim: bool, _search_path: &[PathBuf]) {
self.cmd.arg("-l").sym_arg(lib);
}
@ -1175,6 +1223,10 @@ impl<'a> Linker for WasmLd<'a> {
self.cmd.arg("--gc-sections");
}
fn no_gc_sections(&mut self) {
self.cmd.arg("--no-gc-sections");
}
fn optimize(&mut self) {
self.cmd.arg(match self.sess.opts.optimize {
OptLevel::No => "-O0",
@ -1329,7 +1381,7 @@ impl<'a> Linker for PtxLinker<'a> {
});
}
fn link_dylib(&mut self, _lib: Symbol) {
fn link_dylib(&mut self, _lib: Symbol, _verbatim: bool, _as_needed: bool) {
panic!("external dylibs not supported")
}
@ -1337,11 +1389,11 @@ impl<'a> Linker for PtxLinker<'a> {
panic!("external dylibs not supported")
}
fn link_staticlib(&mut self, _lib: Symbol) {
fn link_staticlib(&mut self, _lib: Symbol, _verbatim: bool) {
panic!("staticlibs not supported")
}
fn link_whole_staticlib(&mut self, _lib: Symbol, _search_path: &[PathBuf]) {
fn link_whole_staticlib(&mut self, _lib: Symbol, _verbatim: bool, _search_path: &[PathBuf]) {
panic!("staticlibs not supported")
}
@ -1349,7 +1401,7 @@ impl<'a> Linker for PtxLinker<'a> {
panic!("frameworks not supported")
}
fn link_framework(&mut self, _framework: Symbol) {
fn link_framework(&mut self, _framework: Symbol, _as_needed: bool) {
panic!("frameworks not supported")
}
@ -1361,6 +1413,8 @@ impl<'a> Linker for PtxLinker<'a> {
fn gc_sections(&mut self, _keep_metadata: bool) {}
fn no_gc_sections(&mut self) {}
fn pgo_gen(&mut self) {}
fn no_crt_objects(&mut self) {}

View file

@ -114,11 +114,12 @@ pub struct NativeLib {
pub kind: NativeLibKind,
pub name: Option<Symbol>,
pub cfg: Option<ast::MetaItem>,
pub verbatim: Option<bool>,
}
impl From<&cstore::NativeLib> for NativeLib {
fn from(lib: &cstore::NativeLib) -> Self {
NativeLib { kind: lib.kind, name: lib.name, cfg: lib.cfg.clone() }
NativeLib { kind: lib.kind, name: lib.name, cfg: lib.cfg.clone(), verbatim: lib.verbatim }
}
}

View file

@ -336,12 +336,13 @@ impl<O: ForestObligation> ObligationForest<O> {
// Returns Err(()) if we already know this obligation failed.
fn register_obligation_at(&mut self, obligation: O, parent: Option<usize>) -> Result<(), ()> {
if self.done_cache.contains(&obligation.as_cache_key()) {
let cache_key = obligation.as_cache_key();
if self.done_cache.contains(&cache_key) {
debug!("register_obligation_at: ignoring already done obligation: {:?}", obligation);
return Ok(());
}
match self.active_cache.entry(obligation.as_cache_key()) {
match self.active_cache.entry(cache_key.clone()) {
Entry::Occupied(o) => {
let node = &mut self.nodes[*o.get()];
if let Some(parent_index) = parent {
@ -365,7 +366,7 @@ impl<O: ForestObligation> ObligationForest<O> {
&& self
.error_cache
.get(&obligation_tree_id)
.map(|errors| errors.contains(&obligation.as_cache_key()))
.map(|errors| errors.contains(&cache_key))
.unwrap_or(false);
if already_failed {

View file

@ -36,7 +36,7 @@ crate struct ParsedExternalMod {
pub enum ModError<'a> {
CircularInclusion(Vec<PathBuf>),
ModInBlock(Option<Ident>),
FileNotFound(Ident, PathBuf),
FileNotFound(Ident, PathBuf, PathBuf),
MultipleCandidates(Ident, PathBuf, PathBuf),
ParserError(DiagnosticBuilder<'a>),
}
@ -219,7 +219,7 @@ pub fn default_submod_path<'a>(
file_path: secondary_path,
dir_ownership: DirOwnership::Owned { relative: None },
}),
(false, false) => Err(ModError::FileNotFound(ident, default_path)),
(false, false) => Err(ModError::FileNotFound(ident, default_path, secondary_path)),
(true, true) => Err(ModError::MultipleCandidates(ident, default_path, secondary_path)),
}
}
@ -247,7 +247,7 @@ impl ModError<'_> {
}
err
}
ModError::FileNotFound(ident, default_path) => {
ModError::FileNotFound(ident, default_path, secondary_path) => {
let mut err = struct_span_err!(
diag,
span,
@ -256,9 +256,10 @@ impl ModError<'_> {
ident,
);
err.help(&format!(
"to create the module `{}`, create file \"{}\"",
"to create the module `{}`, create file \"{}\" or \"{}\"",
ident,
default_path.display(),
secondary_path.display(),
));
err
}

View file

@ -656,6 +656,21 @@ declare_features! (
/// Allows using imported `main` function
(active, imported_main, "1.53.0", Some(28937), None),
/// Allows specifying modifiers in the link attribute: `#[link(modifiers = "...")]`
(active, native_link_modifiers, "1.53.0", Some(81490), None),
/// Allows specifying the bundle link modifier
(active, native_link_modifiers_bundle, "1.53.0", Some(81490), None),
/// Allows specifying the verbatim link modifier
(active, native_link_modifiers_verbatim, "1.53.0", Some(81490), None),
/// Allows specifying the whole-archive link modifier
(active, native_link_modifiers_whole_archive, "1.53.0", Some(81490), None),
/// Allows specifying the as-needed link modifier
(active, native_link_modifiers_as_needed, "1.53.0", Some(81490), None),
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
@ -683,6 +698,11 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
sym::const_generics_defaults,
sym::inherent_associated_types,
sym::type_alias_impl_trait,
sym::native_link_modifiers,
sym::native_link_modifiers_bundle,
sym::native_link_modifiers_verbatim,
sym::native_link_modifiers_whole_archive,
sym::native_link_modifiers_as_needed,
];
/// Some features are not allowed to be used together at the same time, if

View file

@ -12,7 +12,7 @@ use rustc_session::config::{
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
use rustc_session::utils::{CanonicalizedPath, NativeLibKind};
use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
use rustc_session::{build_session, getopts, DiagnosticOutput, Session};
use rustc_span::edition::{Edition, DEFAULT_EDITION};
use rustc_span::symbol::sym;
@ -303,38 +303,122 @@ fn test_native_libs_tracking_hash_different_values() {
let mut v2 = Options::default();
let mut v3 = Options::default();
let mut v4 = Options::default();
let mut v5 = Options::default();
// Reference
v1.libs = vec![
(String::from("a"), None, NativeLibKind::StaticBundle),
(String::from("b"), None, NativeLibKind::Framework),
(String::from("c"), None, NativeLibKind::Unspecified),
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
verbatim: None,
},
NativeLib {
name: String::from("b"),
new_name: None,
kind: NativeLibKind::Framework { as_needed: None },
verbatim: None,
},
NativeLib {
name: String::from("c"),
new_name: None,
kind: NativeLibKind::Unspecified,
verbatim: None,
},
];
// Change label
v2.libs = vec![
(String::from("a"), None, NativeLibKind::StaticBundle),
(String::from("X"), None, NativeLibKind::Framework),
(String::from("c"), None, NativeLibKind::Unspecified),
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
verbatim: None,
},
NativeLib {
name: String::from("X"),
new_name: None,
kind: NativeLibKind::Framework { as_needed: None },
verbatim: None,
},
NativeLib {
name: String::from("c"),
new_name: None,
kind: NativeLibKind::Unspecified,
verbatim: None,
},
];
// Change kind
v3.libs = vec![
(String::from("a"), None, NativeLibKind::StaticBundle),
(String::from("b"), None, NativeLibKind::StaticBundle),
(String::from("c"), None, NativeLibKind::Unspecified),
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
verbatim: None,
},
NativeLib {
name: String::from("b"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
verbatim: None,
},
NativeLib {
name: String::from("c"),
new_name: None,
kind: NativeLibKind::Unspecified,
verbatim: None,
},
];
// Change new-name
v4.libs = vec![
(String::from("a"), None, NativeLibKind::StaticBundle),
(String::from("b"), Some(String::from("X")), NativeLibKind::Framework),
(String::from("c"), None, NativeLibKind::Unspecified),
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
verbatim: None,
},
NativeLib {
name: String::from("b"),
new_name: Some(String::from("X")),
kind: NativeLibKind::Framework { as_needed: None },
verbatim: None,
},
NativeLib {
name: String::from("c"),
new_name: None,
kind: NativeLibKind::Unspecified,
verbatim: None,
},
];
// Change verbatim
v5.libs = vec![
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
verbatim: None,
},
NativeLib {
name: String::from("b"),
new_name: None,
kind: NativeLibKind::Framework { as_needed: None },
verbatim: Some(true),
},
NativeLib {
name: String::from("c"),
new_name: None,
kind: NativeLibKind::Unspecified,
verbatim: None,
},
];
assert_different_hash(&v1, &v2);
assert_different_hash(&v1, &v3);
assert_different_hash(&v1, &v4);
assert_different_hash(&v1, &v5);
}
#[test]
@ -345,21 +429,66 @@ fn test_native_libs_tracking_hash_different_order() {
// Reference
v1.libs = vec![
(String::from("a"), None, NativeLibKind::StaticBundle),
(String::from("b"), None, NativeLibKind::Framework),
(String::from("c"), None, NativeLibKind::Unspecified),
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
verbatim: None,
},
NativeLib {
name: String::from("b"),
new_name: None,
kind: NativeLibKind::Framework { as_needed: None },
verbatim: None,
},
NativeLib {
name: String::from("c"),
new_name: None,
kind: NativeLibKind::Unspecified,
verbatim: None,
},
];
v2.libs = vec![
(String::from("b"), None, NativeLibKind::Framework),
(String::from("a"), None, NativeLibKind::StaticBundle),
(String::from("c"), None, NativeLibKind::Unspecified),
NativeLib {
name: String::from("b"),
new_name: None,
kind: NativeLibKind::Framework { as_needed: None },
verbatim: None,
},
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
verbatim: None,
},
NativeLib {
name: String::from("c"),
new_name: None,
kind: NativeLibKind::Unspecified,
verbatim: None,
},
];
v3.libs = vec![
(String::from("c"), None, NativeLibKind::Unspecified),
(String::from("a"), None, NativeLibKind::StaticBundle),
(String::from("b"), None, NativeLibKind::Framework),
NativeLib {
name: String::from("c"),
new_name: None,
kind: NativeLibKind::Unspecified,
verbatim: None,
},
NativeLib {
name: String::from("a"),
new_name: None,
kind: NativeLibKind::Static { bundle: None, whole_archive: None },
verbatim: None,
},
NativeLib {
name: String::from("b"),
new_name: None,
kind: NativeLibKind::Framework { as_needed: None },
verbatim: None,
},
];
assert_same_hash(&v1, &v2);

View file

@ -8,8 +8,8 @@ use rustc_middle::ty::TyCtxt;
use rustc_session::parse::feature_err;
use rustc_session::utils::NativeLibKind;
use rustc_session::Session;
use rustc_span::source_map::Span;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span;
use rustc_target::spec::abi::Abi;
crate fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> {
@ -56,6 +56,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
cfg: None,
foreign_module: Some(it.def_id.to_def_id()),
wasm_import_module: None,
verbatim: None,
};
let mut kind_specified = false;
@ -67,10 +68,18 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
None => continue, // skip like historical compilers
};
lib.kind = match &*kind.as_str() {
"static" => NativeLibKind::StaticBundle,
"static-nobundle" => NativeLibKind::StaticNoBundle,
"dylib" => NativeLibKind::Dylib,
"framework" => NativeLibKind::Framework,
"static" => NativeLibKind::Static { bundle: None, whole_archive: None },
"static-nobundle" => {
sess.struct_span_warn(
item.span(),
"library kind `static-nobundle` has been superseded by specifying \
modifier `-bundle` with library kind `static`",
)
.emit();
NativeLibKind::Static { bundle: Some(false), whole_archive: None }
}
"dylib" => NativeLibKind::Dylib { as_needed: None },
"framework" => NativeLibKind::Framework { as_needed: None },
"raw-dylib" => NativeLibKind::RawDylib,
k => {
struct_span_err!(sess, item.span(), E0458, "unknown kind: `{}`", k)
@ -108,6 +117,71 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
}
}
// Do this outside the above loop so we don't depend on modifiers coming
// after kinds
if let Some(item) = items.iter().find(|item| item.has_name(sym::modifiers)) {
if let Some(modifiers) = item.value_str() {
let span = item.name_value_literal_span().unwrap();
for modifier in modifiers.as_str().split(',') {
let (modifier, value) = match modifier.strip_prefix(&['+', '-'][..]) {
Some(m) => (m, modifier.starts_with('+')),
None => {
sess.span_err(
span,
"invalid linking modifier syntax, expected '+' or '-' prefix \
before one of: bundle, verbatim, whole-archive, as-needed",
);
continue;
}
};
match (modifier, &mut lib.kind) {
("bundle", NativeLibKind::Static { bundle, .. }) => {
*bundle = Some(value);
}
("bundle", _) => sess.span_err(
span,
"bundle linking modifier is only compatible with \
`static` linking kind",
),
("verbatim", _) => lib.verbatim = Some(value),
("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
*whole_archive = Some(value);
}
("whole-archive", _) => sess.span_err(
span,
"whole-archive linking modifier is only compatible with \
`static` linking kind",
),
("as-needed", NativeLibKind::Dylib { as_needed })
| ("as-needed", NativeLibKind::Framework { as_needed }) => {
*as_needed = Some(value);
}
("as-needed", _) => sess.span_err(
span,
"as-needed linking modifier is only compatible with \
`dylib` and `framework` linking kinds",
),
_ => sess.span_err(
span,
&format!(
"unrecognized linking modifier `{}`, expected one \
of: bundle, verbatim, whole-archive, as-needed",
modifier
),
),
}
}
} else {
let msg = "must be of the form `#[link(modifiers = \"...\")]`";
sess.span_err(item.span(), msg);
}
}
// In general we require #[link(name = "...")] but we allow
// #[link(wasm_import_module = "...")] without the `name`.
let requires_name = kind_specified || lib.wasm_import_module.is_none();
@ -152,7 +226,7 @@ impl Collector<'tcx> {
return;
}
let is_osx = self.tcx.sess.target.is_like_osx;
if lib.kind == NativeLibKind::Framework && !is_osx {
if matches!(lib.kind, NativeLibKind::Framework { .. }) && !is_osx {
let msg = "native frameworks are only available on macOS targets";
match span {
Some(span) => struct_span_err!(self.tcx.sess, span, E0455, "{}", msg).emit(),
@ -168,7 +242,9 @@ impl Collector<'tcx> {
)
.emit();
}
if lib.kind == NativeLibKind::StaticNoBundle && !self.tcx.features().static_nobundle {
if matches!(lib.kind, NativeLibKind::Static { bundle: Some(false), .. })
&& !self.tcx.features().static_nobundle
{
feature_err(
&self.tcx.sess.parse_sess,
sym::static_nobundle,
@ -193,30 +269,30 @@ impl Collector<'tcx> {
fn process_command_line(&mut self) {
// First, check for errors
let mut renames = FxHashSet::default();
for (name, new_name, _) in &self.tcx.sess.opts.libs {
if let Some(ref new_name) = new_name {
for lib in &self.tcx.sess.opts.libs {
if let Some(ref new_name) = lib.new_name {
let any_duplicate = self
.libs
.iter()
.filter_map(|lib| lib.name.as_ref())
.any(|n| &n.as_str() == name);
.any(|n| &n.as_str() == &lib.name);
if new_name.is_empty() {
self.tcx.sess.err(&format!(
"an empty renaming target was specified for library `{}`",
name
lib.name
));
} else if !any_duplicate {
self.tcx.sess.err(&format!(
"renaming of the library `{}` was specified, \
however this crate contains no `#[link(...)]` \
attributes referencing this library.",
name
lib.name
));
} else if !renames.insert(name) {
} else if !renames.insert(&lib.name) {
self.tcx.sess.err(&format!(
"multiple renamings were \
specified for library `{}` .",
name
lib.name
));
}
}
@ -229,7 +305,7 @@ impl Collector<'tcx> {
// it. (This ensures that the linker is able to see symbols from
// all possible dependent libraries before linking in the library
// in question.)
for &(ref name, ref new_name, kind) in &self.tcx.sess.opts.libs {
for passed_lib in &self.tcx.sess.opts.libs {
// If we've already added any native libraries with the same
// name, they will be pulled out into `existing`, so that we
// can move them to the end of the list below.
@ -237,13 +313,14 @@ impl Collector<'tcx> {
.libs
.drain_filter(|lib| {
if let Some(lib_name) = lib.name {
if lib_name.as_str() == *name {
if kind != NativeLibKind::Unspecified {
lib.kind = kind;
if lib_name.as_str() == passed_lib.name {
if passed_lib.kind != NativeLibKind::Unspecified {
lib.kind = passed_lib.kind;
}
if let Some(new_name) = new_name {
if let Some(new_name) = &passed_lib.new_name {
lib.name = Some(Symbol::intern(new_name));
}
lib.verbatim = passed_lib.verbatim;
return true;
}
}
@ -252,13 +329,14 @@ impl Collector<'tcx> {
.collect::<Vec<_>>();
if existing.is_empty() {
// Add if not found
let new_name = new_name.as_ref().map(|s| &**s); // &Option<String> -> Option<&str>
let new_name = passed_lib.new_name.as_ref().map(|s| &**s); // &Option<String> -> Option<&str>
let lib = NativeLib {
name: Some(Symbol::intern(new_name.unwrap_or(name))),
kind,
name: Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name))),
kind: passed_lib.kind,
cfg: None,
foreign_module: None,
wasm_import_module: None,
verbatim: passed_lib.verbatim,
};
self.register_native_lib(None, lib);
} else {

View file

@ -256,16 +256,13 @@ pub fn provide(providers: &mut Providers) {
// resolve! Does this work? Unsure! That's what the issue is about
*providers = Providers {
is_dllimport_foreign_item: |tcx, id| match tcx.native_library_kind(id) {
Some(NativeLibKind::Dylib | NativeLibKind::RawDylib | NativeLibKind::Unspecified) => {
true
}
Some(
NativeLibKind::Dylib { .. } | NativeLibKind::RawDylib | NativeLibKind::Unspecified,
) => true,
_ => false,
},
is_statically_included_foreign_item: |tcx, id| {
matches!(
tcx.native_library_kind(id),
Some(NativeLibKind::StaticBundle | NativeLibKind::StaticNoBundle)
)
matches!(tcx.native_library_kind(id), Some(NativeLibKind::Static { .. }))
},
native_library_kind: |tcx, id| {
tcx.native_libraries(id.krate)

View file

@ -94,6 +94,7 @@ pub struct NativeLib {
pub cfg: Option<ast::MetaItem>,
pub foreign_module: Option<DefId>,
pub wasm_import_module: Option<Symbol>,
pub verbatim: Option<bool>,
}
#[derive(Clone, TyEncodable, TyDecodable, HashStable, Debug)]

View file

@ -5,7 +5,7 @@ pub use crate::options::*;
use crate::lint;
use crate::search_paths::SearchPath;
use crate::utils::{CanonicalizedPath, NativeLibKind};
use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
use crate::{early_error, early_warn, Session};
use rustc_data_structures::fx::FxHashSet;
@ -1027,8 +1027,11 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
"",
"Link the generated crate(s) to the specified native
library NAME. The optional KIND can be one of
static, framework, or dylib (the default).",
"[KIND=]NAME",
static, framework, or dylib (the default).
Optional comma separated MODIFIERS (bundle|verbatim|whole-archive|as-needed)
may be specified each with a prefix of either '+' to
enable or '-' to disable.",
"[KIND[:MODIFIERS]=]NAME[:RENAME]",
),
make_crate_type_option(),
opt::opt_s("", "crate-name", "Specify the name of the crate being built", "NAME"),
@ -1591,52 +1594,127 @@ fn select_debuginfo(
}
}
fn parse_libs(
matches: &getopts::Matches,
fn parse_native_lib_kind(kind: &str, error_format: ErrorOutputType) -> NativeLibKind {
match kind {
"dylib" => NativeLibKind::Dylib { as_needed: None },
"framework" => NativeLibKind::Framework { as_needed: None },
"static" => NativeLibKind::Static { bundle: None, whole_archive: None },
"static-nobundle" => {
early_warn(
error_format,
"library kind `static-nobundle` has been superseded by specifying \
`-bundle` on library kind `static`. Try `static:-bundle`",
);
NativeLibKind::Static { bundle: Some(false), whole_archive: None }
}
s => early_error(
error_format,
&format!("unknown library kind `{}`, expected one of dylib, framework, or static", s),
),
}
}
fn parse_native_lib_modifiers(
is_nightly: bool,
mut kind: NativeLibKind,
modifiers: &str,
error_format: ErrorOutputType,
) -> Vec<(String, Option<String>, NativeLibKind)> {
) -> (NativeLibKind, Option<bool>) {
let mut verbatim = None;
for modifier in modifiers.split(',') {
let (modifier, value) = match modifier.strip_prefix(&['+', '-'][..]) {
Some(m) => (m, modifier.starts_with('+')),
None => early_error(
error_format,
"invalid linking modifier syntax, expected '+' or '-' prefix \
before one of: bundle, verbatim, whole-archive, as-needed",
),
};
if !is_nightly {
early_error(
error_format,
"linking modifiers are currently unstable and only accepted on \
the nightly compiler",
);
}
match (modifier, &mut kind) {
("bundle", NativeLibKind::Static { bundle, .. }) => {
*bundle = Some(value);
}
("bundle", _) => early_error(
error_format,
"bundle linking modifier is only compatible with \
`static` linking kind",
),
("verbatim", _) => verbatim = Some(value),
("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
*whole_archive = Some(value);
}
("whole-archive", _) => early_error(
error_format,
"whole-archive linking modifier is only compatible with \
`static` linking kind",
),
("as-needed", NativeLibKind::Dylib { as_needed })
| ("as-needed", NativeLibKind::Framework { as_needed }) => {
*as_needed = Some(value);
}
("as-needed", _) => early_error(
error_format,
"as-needed linking modifier is only compatible with \
`dylib` and `framework` linking kinds",
),
_ => early_error(
error_format,
&format!(
"unrecognized linking modifier `{}`, expected one \
of: bundle, verbatim, whole-archive, as-needed",
modifier
),
),
}
}
(kind, verbatim)
}
fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<NativeLib> {
let is_nightly = nightly_options::match_is_nightly_build(matches);
matches
.opt_strs("l")
.into_iter()
.map(|s| {
// Parse string of the form "[KIND=]lib[:new_name]",
// where KIND is one of "dylib", "framework", "static".
let (name, kind) = match s.split_once('=') {
None => (s, NativeLibKind::Unspecified),
// Parse string of the form "[KIND[:MODIFIERS]=]lib[:new_name]",
// where KIND is one of "dylib", "framework", "static" and
// where MODIFIERS are a comma separated list of supported modifiers
// (bundle, verbatim, whole-archive, as-needed). Each modifier is prefixed
// with either + or - to indicate whether it is enabled or disabled.
// The last value specified for a given modifier wins.
let (name, kind, verbatim) = match s.split_once('=') {
None => (s, NativeLibKind::Unspecified, None),
Some((kind, name)) => {
let kind = match kind {
"dylib" => NativeLibKind::Dylib,
"framework" => NativeLibKind::Framework,
"static" => NativeLibKind::StaticBundle,
"static-nobundle" => NativeLibKind::StaticNoBundle,
s => {
early_error(
error_format,
&format!(
"unknown library kind `{}`, expected \
one of dylib, framework, or static",
s
),
);
let (kind, verbatim) = match kind.split_once(':') {
None => (parse_native_lib_kind(kind, error_format), None),
Some((kind, modifiers)) => {
let kind = parse_native_lib_kind(kind, error_format);
parse_native_lib_modifiers(is_nightly, kind, modifiers, error_format)
}
};
(name.to_string(), kind)
(name.to_string(), kind, verbatim)
}
};
if kind == NativeLibKind::StaticNoBundle
&& !nightly_options::match_is_nightly_build(matches)
{
early_error(
error_format,
"the library kind 'static-nobundle' is only \
accepted on the nightly compiler",
);
}
let (name, new_name) = match name.split_once(':') {
None => (name, None),
Some((name, new_name)) => (name.to_string(), Some(new_name.to_owned())),
};
(name, new_name, kind)
NativeLib { name, new_name, kind, verbatim }
})
.collect()
}
@ -2316,7 +2394,7 @@ crate mod dep_tracking {
};
use crate::lint;
use crate::options::WasiExecModel;
use crate::utils::NativeLibKind;
use crate::utils::{NativeLib, NativeLibKind};
use rustc_feature::UnstableFeatures;
use rustc_span::edition::Edition;
use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, RelocModel};
@ -2391,6 +2469,7 @@ crate mod dep_tracking {
DebugInfo,
UnstableFeatures,
OutputTypes,
NativeLib,
NativeLibKind,
SanitizerSet,
CFGuard,
@ -2409,8 +2488,8 @@ crate mod dep_tracking {
PathBuf,
(PathBuf, PathBuf),
CrateType,
NativeLib,
(String, lint::Level),
(String, Option<String>, NativeLibKind),
(String, u64)
);

View file

@ -3,7 +3,7 @@ use crate::config::*;
use crate::early_error;
use crate::lint;
use crate::search_paths::SearchPath;
use crate::utils::NativeLibKind;
use crate::utils::NativeLib;
use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy, SanitizerSet};
use rustc_target::spec::{RelocModel, RelroLevel, SplitDebuginfo, TargetTriple, TlsModel};
@ -133,7 +133,7 @@ top_level_options!(
describe_lints: bool [UNTRACKED],
output_types: OutputTypes [TRACKED],
search_paths: Vec<SearchPath> [UNTRACKED],
libs: Vec<(String, Option<String>, NativeLibKind)> [TRACKED],
libs: Vec<NativeLib> [TRACKED],
maybe_sysroot: Option<PathBuf> [UNTRACKED],
target_triple: TargetTriple [TRACKED],

View file

@ -19,25 +19,42 @@ impl Session {
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
pub enum NativeLibKind {
/// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC) included
/// when linking a final binary, but not when archiving an rlib.
StaticNoBundle,
/// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC) included
/// when linking a final binary, but also included when archiving an rlib.
StaticBundle,
/// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC)
Static {
/// Whether to bundle objects from static library into produced rlib
bundle: Option<bool>,
/// Whether to link static library without throwing any object files away
whole_archive: Option<bool>,
},
/// Dynamic library (e.g. `libfoo.so` on Linux)
/// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC).
Dylib,
Dylib {
/// Whether the dynamic library will be linked only if it satifies some undefined symbols
as_needed: Option<bool>,
},
/// Dynamic library (e.g. `foo.dll` on Windows) without a corresponding import library.
RawDylib,
/// A macOS-specific kind of dynamic libraries.
Framework,
Framework {
/// Whether the framework will be linked only if it satifies some undefined symbols
as_needed: Option<bool>,
},
/// The library kind wasn't specified, `Dylib` is currently used as a default.
Unspecified,
}
rustc_data_structures::impl_stable_hash_via_hash!(NativeLibKind);
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
pub struct NativeLib {
pub name: String,
pub new_name: Option<String>,
pub kind: NativeLibKind,
pub verbatim: Option<bool>,
}
rustc_data_structures::impl_stable_hash_via_hash!(NativeLib);
/// A path that has been canonicalized along with its original, non-canonicalized form
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct CanonicalizedPath {

View file

@ -748,6 +748,7 @@ symbols! {
minnumf64,
mips_target_feature,
misc,
modifiers,
module,
module_path,
more_struct_aliases,
@ -763,6 +764,11 @@ symbols! {
naked,
naked_functions,
name,
native_link_modifiers,
native_link_modifiers_as_needed,
native_link_modifiers_bundle,
native_link_modifiers_verbatim,
native_link_modifiers_whole_archive,
ne,
nearbyintf32,
nearbyintf64,