Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The name of NativeLib will be presented #109243

Merged
merged 2 commits into from
Mar 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,9 @@ fn link_rlib<'a>(
let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src);
let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str());
packed_bundled_libs.push(wrapper_file);
} else if let Some(name) = lib.name {
} else {
let path =
find_native_static_library(name.as_str(), lib.verbatim, &lib_search_paths, sess);
find_native_static_library(lib.name.as_str(), lib.verbatim, &lib_search_paths, sess);
ab.add_archive(&path, Box::new(|_| false)).unwrap_or_else(|error| {
sess.emit_fatal(errors::AddNativeLibrary { library_path: path, error })});
}
Expand Down Expand Up @@ -436,7 +436,7 @@ fn collate_raw_dylibs<'a, 'b>(
for lib in used_libraries {
if lib.kind == NativeLibKind::RawDylib {
let ext = if lib.verbatim { "" } else { ".dll" };
let name = format!("{}{}", lib.name.expect("unnamed raw-dylib library"), ext);
let name = format!("{}{}", lib.name, ext);
let imports = dylib_table.entry(name.clone()).or_default();
for import in &lib.dll_imports {
if let Some(old_import) = imports.insert(import.name, import) {
Expand Down Expand Up @@ -1294,7 +1294,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
.iter()
.filter(|l| relevant_lib(sess, l))
.filter_map(|lib| {
let name = lib.name?;
let name = lib.name;
match lib.kind {
NativeLibKind::Static { bundle: Some(false), .. }
| NativeLibKind::Dylib { .. }
Expand All @@ -1315,6 +1315,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
// These are included, no need to print them
NativeLibKind::Static { bundle: None | Some(true), .. }
| NativeLibKind::LinkArg
| NativeLibKind::WasmImportModule
| NativeLibKind::RawDylib => None,
}
})
Expand Down Expand Up @@ -2273,21 +2274,18 @@ fn add_native_libs_from_crate(

let mut last = (None, NativeLibKind::Unspecified, false);
for lib in native_libs {
let Some(name) = lib.name else {
continue;
};
if !relevant_lib(sess, lib) {
continue;
}

// Skip if this library is the same as the last.
last = if (lib.name, lib.kind, lib.verbatim) == last {
last = if (Some(lib.name), lib.kind, lib.verbatim) == last {
continue;
} else {
(lib.name, lib.kind, lib.verbatim)
(Some(lib.name), lib.kind, lib.verbatim)
};

let name = name.as_str();
let name = lib.name.as_str();
let verbatim = lib.verbatim;
match lib.kind {
NativeLibKind::Static { bundle, whole_archive } => {
Expand Down Expand Up @@ -2344,6 +2342,7 @@ fn add_native_libs_from_crate(
NativeLibKind::RawDylib => {
// Handled separately in `linker_with_args`.
}
NativeLibKind::WasmImportModule => {}
NativeLibKind::LinkArg => {
if link_static {
cmd.arg(name);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/back/symbol_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, S

let mut ret = FxHashMap::default();
for (def_id, lib) in tcx.foreign_modules(cnum).iter() {
let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module);
let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module());
let Some(module) = module else { continue };
ret.extend(lib.foreign_items.iter().map(|id| {
assert_eq!(id.krate, cnum);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ bitflags::bitflags! {
#[derive(Clone, Debug, Encodable, Decodable, HashStable)]
pub struct NativeLib {
pub kind: NativeLibKind,
pub name: Option<Symbol>,
pub name: Symbol,
pub filename: Option<Symbol>,
pub cfg: Option<ast::MetaItem>,
pub verbatim: bool,
Expand Down
76 changes: 35 additions & 41 deletions compiler/rustc_metadata/src/native_libs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn find_native_static_library(
}

fn find_bundled_library(
name: Option<Symbol>,
name: Symbol,
verbatim: Option<bool>,
kind: NativeLibKind,
has_cfg: bool,
Expand All @@ -58,7 +58,7 @@ fn find_bundled_library(
{
let verbatim = verbatim.unwrap_or(false);
let search_paths = &sess.target_filesearch(PathKind::Native).search_path_dirs();
return find_native_static_library(name.unwrap().as_str(), verbatim, search_paths, sess)
return find_native_static_library(name.as_str(), verbatim, search_paths, sess)
.file_name()
.and_then(|s| s.to_str())
.map(Symbol::intern);
Expand Down Expand Up @@ -336,10 +336,16 @@ impl<'tcx> Collector<'tcx> {
if name.is_some() || kind.is_some() || modifiers.is_some() || cfg.is_some() {
sess.emit_err(errors::IncompatibleWasmLink { span });
}
} else if name.is_none() {
sess.emit_err(errors::LinkRequiresName { span: m.span });
}

if wasm_import_module.is_some() {
(name, kind) = (wasm_import_module, Some(NativeLibKind::WasmImportModule));
}
let Some((name, name_span)) = name else {
sess.emit_err(errors::LinkRequiresName { span: m.span });
continue;
};

// Do this outside of the loop so that `import_name_type` can be specified before `kind`.
if let Some((_, span)) = import_name_type {
if kind != Some(NativeLibKind::RawDylib) {
Expand All @@ -349,8 +355,8 @@ impl<'tcx> Collector<'tcx> {

let dll_imports = match kind {
Some(NativeLibKind::RawDylib) => {
if let Some((name, span)) = name && name.as_str().contains('\0') {
sess.emit_err(errors::RawDylibNoNul { span });
if name.as_str().contains('\0') {
sess.emit_err(errors::RawDylibNoNul { span: name_span });
}
foreign_mod_items
.iter()
Expand Down Expand Up @@ -389,7 +395,6 @@ impl<'tcx> Collector<'tcx> {
}
};

let name = name.map(|(name, _)| name);
let kind = kind.unwrap_or(NativeLibKind::Unspecified);
let filename = find_bundled_library(name, verbatim, kind, cfg.is_some(), sess);
self.libs.push(NativeLib {
Expand All @@ -398,7 +403,6 @@ impl<'tcx> Collector<'tcx> {
kind,
cfg,
foreign_module: Some(it.owner_id.to_def_id()),
wasm_import_module: wasm_import_module.map(|(name, _)| name),
verbatim,
dll_imports,
});
Expand All @@ -415,11 +419,7 @@ impl<'tcx> Collector<'tcx> {
self.tcx.sess.emit_err(errors::LibFrameworkApple);
}
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() == lib.name);
let any_duplicate = self.libs.iter().any(|n| n.name.as_str() == lib.name);
if new_name.is_empty() {
self.tcx.sess.emit_err(errors::EmptyRenamingTarget { lib_name: &lib.name });
} else if !any_duplicate {
Expand All @@ -444,41 +444,36 @@ impl<'tcx> Collector<'tcx> {
let mut existing = self
.libs
.drain_filter(|lib| {
if let Some(lib_name) = lib.name {
if lib_name.as_str() == passed_lib.name {
// FIXME: This whole logic is questionable, whether modifiers are
// involved or not, library reordering and kind overriding without
// explicit `:rename` in particular.
if lib.has_modifiers() || passed_lib.has_modifiers() {
match lib.foreign_module {
Some(def_id) => {
self.tcx.sess.emit_err(errors::NoLinkModOverride {
span: Some(self.tcx.def_span(def_id)),
})
}
None => self
.tcx
.sess
.emit_err(errors::NoLinkModOverride { span: None }),
};
}
if passed_lib.kind != NativeLibKind::Unspecified {
lib.kind = passed_lib.kind;
}
if let Some(new_name) = &passed_lib.new_name {
lib.name = Some(Symbol::intern(new_name));
}
lib.verbatim = passed_lib.verbatim;
return true;
if lib.name.as_str() == passed_lib.name {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a behavior change - wasm_import_modules can now be overridden from command line, but that's probably fine.

// FIXME: This whole logic is questionable, whether modifiers are
// involved or not, library reordering and kind overriding without
// explicit `:rename` in particular.
if lib.has_modifiers() || passed_lib.has_modifiers() {
match lib.foreign_module {
Some(def_id) => self.tcx.sess.emit_err(errors::NoLinkModOverride {
span: Some(self.tcx.def_span(def_id)),
}),
None => {
self.tcx.sess.emit_err(errors::NoLinkModOverride { span: None })
}
};
}
if passed_lib.kind != NativeLibKind::Unspecified {
lib.kind = passed_lib.kind;
}
if let Some(new_name) = &passed_lib.new_name {
lib.name = Symbol::intern(new_name);
}
lib.verbatim = passed_lib.verbatim;
return true;
}
false
})
.collect::<Vec<_>>();
if existing.is_empty() {
// Add if not found
let new_name: Option<&str> = passed_lib.new_name.as_deref();
let name = Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name)));
let name = Symbol::intern(new_name.unwrap_or(&passed_lib.name));
let sess = self.tcx.sess;
let filename =
find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, false, sess);
Expand All @@ -488,7 +483,6 @@ impl<'tcx> Collector<'tcx> {
kind: passed_lib.kind,
cfg: None,
foreign_module: None,
wasm_import_module: None,
verbatim: passed_lib.verbatim,
dll_imports: Vec::new(),
});
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_session/src/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,11 @@ pub enum LinkagePreference {
#[derive(Debug, Encodable, Decodable, HashStable_Generic)]
pub struct NativeLib {
pub kind: NativeLibKind,
pub name: Option<Symbol>,
pub name: Symbol,
/// If packed_bundled_libs enabled, actual filename of library is stored.
pub filename: Option<Symbol>,
pub cfg: Option<ast::MetaItem>,
pub foreign_module: Option<DefId>,
pub wasm_import_module: Option<Symbol>,
pub verbatim: Option<bool>,
pub dll_imports: Vec<DllImport>,
}
Expand All @@ -81,6 +80,10 @@ impl NativeLib {
pub fn has_modifiers(&self) -> bool {
self.verbatim.is_some() || self.kind.has_modifiers()
}

pub fn wasm_import_module(&self) -> Option<Symbol> {
if self.kind == NativeLibKind::WasmImportModule { Some(self.name) } else { None }
}
}

/// Different ways that the PE Format can decorate a symbol name.
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_session/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ pub enum NativeLibKind {
/// Argument which is passed to linker, relative order with libraries and other arguments
/// is preserved
LinkArg,

/// Module imported from WebAssembly
WasmImportModule,

/// The library kind wasn't specified, `Dylib` is currently used as a default.
Unspecified,
}
Expand All @@ -50,7 +54,10 @@ impl NativeLibKind {
NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } => {
as_needed.is_some()
}
NativeLibKind::RawDylib | NativeLibKind::Unspecified | NativeLibKind::LinkArg => false,
NativeLibKind::RawDylib
| NativeLibKind::Unspecified
| NativeLibKind::LinkArg
| NativeLibKind::WasmImportModule => false,
}
}

Expand Down
4 changes: 4 additions & 0 deletions tests/ui/linkage-attr/issue-109144.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#![crate_type = "lib"]
#[link(kind = "static", modifiers = "+whole-archive,+bundle")]
//~^ ERROR `#[link]` attribute requires a `name = "string"` argument
extern {}
9 changes: 9 additions & 0 deletions tests/ui/linkage-attr/issue-109144.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0459]: `#[link]` attribute requires a `name = "string"` argument
--> $DIR/issue-109144.rs:2:1
|
LL | #[link(kind = "static", modifiers = "+whole-archive,+bundle")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `name` argument

error: aborting due to previous error

For more information about this error, try `rustc --explain E0459`.