Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4730e55

Browse files
committedMar 3, 2025
Auto merge of rust-lang#137925 - tgross35:rollup-vjzjgsg, r=tgross35
Rollup of 6 pull requests Successful merges: - rust-lang#135695 (Support raw-dylib link kind on ELF) - rust-lang#136975 (Look for `python3` first on MacOS, not `py`) - rust-lang#137240 (Slightly reformat `std::fs::remove_dir_all` error docs) - rust-lang#137758 (fix usage of ty decl macro fragments in attributes) - rust-lang#137772 (Fix char count in `Display` for `ByteStr`) - rust-lang#137794 (make qnx pass a test) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 81d8edc + 09b0533 commit 4730e55

File tree

75 files changed

+888
-216
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+888
-216
lines changed
 

‎compiler/rustc_attr_parsing/src/parser.rs

+9
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,15 @@ impl<'a> MetaItemListParserContext<'a> {
473473
{
474474
self.inside_delimiters.next();
475475
return Some(MetaItemOrLitParser::Lit(lit));
476+
} else if let Some(TokenTree::Delimited(.., Delimiter::Invisible(_), inner_tokens)) =
477+
self.inside_delimiters.peek()
478+
{
479+
self.inside_delimiters.next();
480+
return MetaItemListParserContext {
481+
inside_delimiters: inner_tokens.iter().peekable(),
482+
dcx: self.dcx,
483+
}
484+
.next();
476485
}
477486

478487
// or a path.

‎compiler/rustc_codegen_ssa/src/back/link.rs

+81-137
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
mod raw_dylib;
2+
13
use std::collections::BTreeSet;
24
use std::ffi::OsString;
35
use std::fs::{File, OpenOptions, read};
@@ -12,7 +14,7 @@ use itertools::Itertools;
1214
use regex::Regex;
1315
use rustc_arena::TypedArena;
1416
use rustc_ast::CRATE_NODE_ID;
15-
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
17+
use rustc_data_structures::fx::FxIndexSet;
1618
use rustc_data_structures::memmap::Mmap;
1719
use rustc_data_structures::temp_dir::MaybeTempDir;
1820
use rustc_errors::{DiagCtxtHandle, LintDiagnostic};
@@ -30,7 +32,6 @@ use rustc_session::config::{
3032
self, CFGuard, CrateType, DebugInfo, LinkerFeaturesCli, OutFileName, OutputFilenames,
3133
OutputType, PrintKind, SplitDwarfKind, Strip,
3234
};
33-
use rustc_session::cstore::DllImport;
3435
use rustc_session::lint::builtin::LINKER_MESSAGES;
3536
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
3637
use rustc_session::search_paths::PathKind;
@@ -41,22 +42,21 @@ use rustc_session::{Session, filesearch};
4142
use rustc_span::Symbol;
4243
use rustc_target::spec::crt_objects::CrtObjects;
4344
use rustc_target::spec::{
44-
Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFeatures,
45-
LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel, SanitizerSet,
46-
SplitDebuginfo,
45+
BinaryFormat, Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault,
46+
LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel,
47+
SanitizerSet, SplitDebuginfo,
4748
};
4849
use tempfile::Builder as TempFileBuilder;
4950
use tracing::{debug, info, warn};
5051

51-
use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder, ImportLibraryItem};
52+
use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
5253
use super::command::Command;
5354
use super::linker::{self, Linker};
5455
use super::metadata::{MetadataPosition, create_wrapper_file};
5556
use super::rpath::{self, RPathConfig};
5657
use super::{apple, versioned_llvm_target};
5758
use crate::{
58-
CodegenResults, CompiledModule, CrateInfo, NativeLib, common, errors,
59-
looks_like_rust_object_file,
59+
CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, looks_like_rust_object_file,
6060
};
6161

6262
pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) {
@@ -376,16 +376,22 @@ fn link_rlib<'a>(
376376
}
377377
}
378378

379-
for output_path in create_dll_import_libs(
380-
sess,
381-
archive_builder_builder,
382-
codegen_results.crate_info.used_libraries.iter(),
383-
tmpdir.as_ref(),
384-
true,
385-
) {
386-
ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| {
387-
sess.dcx().emit_fatal(errors::AddNativeLibrary { library_path: output_path, error });
388-
});
379+
// On Windows, we add the raw-dylib import libraries to the rlibs already.
380+
// But on ELF, this is not possible, as a shared object cannot be a member of a static library.
381+
// Instead, we add all raw-dylibs to the final link on ELF.
382+
if sess.target.is_like_windows {
383+
for output_path in raw_dylib::create_raw_dylib_dll_import_libs(
384+
sess,
385+
archive_builder_builder,
386+
codegen_results.crate_info.used_libraries.iter(),
387+
tmpdir.as_ref(),
388+
true,
389+
) {
390+
ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| {
391+
sess.dcx()
392+
.emit_fatal(errors::AddNativeLibrary { library_path: output_path, error });
393+
});
394+
}
389395
}
390396

391397
if let Some(trailing_metadata) = trailing_metadata {
@@ -426,108 +432,6 @@ fn link_rlib<'a>(
426432
ab
427433
}
428434

429-
/// Extract all symbols defined in raw-dylib libraries, collated by library name.
430-
///
431-
/// If we have multiple extern blocks that specify symbols defined in the same raw-dylib library,
432-
/// then the CodegenResults value contains one NativeLib instance for each block. However, the
433-
/// linker appears to expect only a single import library for each library used, so we need to
434-
/// collate the symbols together by library name before generating the import libraries.
435-
fn collate_raw_dylibs<'a>(
436-
sess: &Session,
437-
used_libraries: impl IntoIterator<Item = &'a NativeLib>,
438-
) -> Vec<(String, Vec<DllImport>)> {
439-
// Use index maps to preserve original order of imports and libraries.
440-
let mut dylib_table = FxIndexMap::<String, FxIndexMap<Symbol, &DllImport>>::default();
441-
442-
for lib in used_libraries {
443-
if lib.kind == NativeLibKind::RawDylib {
444-
let ext = if lib.verbatim { "" } else { ".dll" };
445-
let name = format!("{}{}", lib.name, ext);
446-
let imports = dylib_table.entry(name.clone()).or_default();
447-
for import in &lib.dll_imports {
448-
if let Some(old_import) = imports.insert(import.name, import) {
449-
// FIXME: when we add support for ordinals, figure out if we need to do anything
450-
// if we have two DllImport values with the same name but different ordinals.
451-
if import.calling_convention != old_import.calling_convention {
452-
sess.dcx().emit_err(errors::MultipleExternalFuncDecl {
453-
span: import.span,
454-
function: import.name,
455-
library_name: &name,
456-
});
457-
}
458-
}
459-
}
460-
}
461-
}
462-
sess.dcx().abort_if_errors();
463-
dylib_table
464-
.into_iter()
465-
.map(|(name, imports)| {
466-
(name, imports.into_iter().map(|(_, import)| import.clone()).collect())
467-
})
468-
.collect()
469-
}
470-
471-
fn create_dll_import_libs<'a>(
472-
sess: &Session,
473-
archive_builder_builder: &dyn ArchiveBuilderBuilder,
474-
used_libraries: impl IntoIterator<Item = &'a NativeLib>,
475-
tmpdir: &Path,
476-
is_direct_dependency: bool,
477-
) -> Vec<PathBuf> {
478-
collate_raw_dylibs(sess, used_libraries)
479-
.into_iter()
480-
.map(|(raw_dylib_name, raw_dylib_imports)| {
481-
let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" };
482-
let output_path = tmpdir.join(format!("{raw_dylib_name}{name_suffix}.lib"));
483-
484-
let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(&sess.target);
485-
486-
let items: Vec<ImportLibraryItem> = raw_dylib_imports
487-
.iter()
488-
.map(|import: &DllImport| {
489-
if sess.target.arch == "x86" {
490-
ImportLibraryItem {
491-
name: common::i686_decorated_name(
492-
import,
493-
mingw_gnu_toolchain,
494-
false,
495-
false,
496-
),
497-
ordinal: import.ordinal(),
498-
symbol_name: import.is_missing_decorations().then(|| {
499-
common::i686_decorated_name(
500-
import,
501-
mingw_gnu_toolchain,
502-
false,
503-
true,
504-
)
505-
}),
506-
is_data: !import.is_fn,
507-
}
508-
} else {
509-
ImportLibraryItem {
510-
name: import.name.to_string(),
511-
ordinal: import.ordinal(),
512-
symbol_name: None,
513-
is_data: !import.is_fn,
514-
}
515-
}
516-
})
517-
.collect();
518-
519-
archive_builder_builder.create_dll_import_lib(
520-
sess,
521-
&raw_dylib_name,
522-
items,
523-
&output_path,
524-
);
525-
526-
output_path
527-
})
528-
.collect()
529-
}
530-
531435
/// Create a static archive.
532436
///
533437
/// This is essentially the same thing as an rlib, but it also involves adding all of the upstream
@@ -2422,15 +2326,39 @@ fn linker_with_args(
24222326
link_output_kind,
24232327
);
24242328

2329+
// Raw-dylibs from all crates.
2330+
let raw_dylib_dir = tmpdir.join("raw-dylibs");
2331+
if sess.target.binary_format == BinaryFormat::Elf {
2332+
// On ELF we can't pass the raw-dylibs stubs to the linker as a path,
2333+
// instead we need to pass them via -l. To find the stub, we need to add
2334+
// the directory of the stub to the linker search path.
2335+
// We make an extra directory for this to avoid polluting the search path.
2336+
if let Err(error) = fs::create_dir(&raw_dylib_dir) {
2337+
sess.dcx().emit_fatal(errors::CreateTempDir { error })
2338+
}
2339+
cmd.include_path(&raw_dylib_dir);
2340+
}
2341+
24252342
// Link with the import library generated for any raw-dylib functions.
2426-
for output_path in create_dll_import_libs(
2427-
sess,
2428-
archive_builder_builder,
2429-
codegen_results.crate_info.used_libraries.iter(),
2430-
tmpdir,
2431-
true,
2432-
) {
2433-
cmd.add_object(&output_path);
2343+
if sess.target.is_like_windows {
2344+
for output_path in raw_dylib::create_raw_dylib_dll_import_libs(
2345+
sess,
2346+
archive_builder_builder,
2347+
codegen_results.crate_info.used_libraries.iter(),
2348+
tmpdir,
2349+
true,
2350+
) {
2351+
cmd.add_object(&output_path);
2352+
}
2353+
} else {
2354+
for link_path in raw_dylib::create_raw_dylib_elf_stub_shared_objects(
2355+
sess,
2356+
codegen_results.crate_info.used_libraries.iter(),
2357+
&raw_dylib_dir,
2358+
) {
2359+
// Always use verbatim linkage, see comments in create_raw_dylib_elf_stub_shared_objects.
2360+
cmd.link_dylib_by_name(&link_path, true, false);
2361+
}
24342362
}
24352363
// As with add_upstream_native_libraries, we need to add the upstream raw-dylib symbols in case
24362364
// they are used within inlined functions or instantiated generic functions. We do this *after*
@@ -2449,19 +2377,35 @@ fn linker_with_args(
24492377
.native_libraries
24502378
.iter()
24512379
.filter_map(|(&cnum, libraries)| {
2452-
(dependency_linkage[cnum] != Linkage::Static).then_some(libraries)
2380+
if sess.target.is_like_windows {
2381+
(dependency_linkage[cnum] != Linkage::Static).then_some(libraries)
2382+
} else {
2383+
Some(libraries)
2384+
}
24532385
})
24542386
.flatten()
24552387
.collect::<Vec<_>>();
24562388
native_libraries_from_nonstatics.sort_unstable_by(|a, b| a.name.as_str().cmp(b.name.as_str()));
2457-
for output_path in create_dll_import_libs(
2458-
sess,
2459-
archive_builder_builder,
2460-
native_libraries_from_nonstatics,
2461-
tmpdir,
2462-
false,
2463-
) {
2464-
cmd.add_object(&output_path);
2389+
2390+
if sess.target.is_like_windows {
2391+
for output_path in raw_dylib::create_raw_dylib_dll_import_libs(
2392+
sess,
2393+
archive_builder_builder,
2394+
native_libraries_from_nonstatics,
2395+
tmpdir,
2396+
false,
2397+
) {
2398+
cmd.add_object(&output_path);
2399+
}
2400+
} else {
2401+
for link_path in raw_dylib::create_raw_dylib_elf_stub_shared_objects(
2402+
sess,
2403+
native_libraries_from_nonstatics,
2404+
&raw_dylib_dir,
2405+
) {
2406+
// Always use verbatim linkage, see comments in create_raw_dylib_elf_stub_shared_objects.
2407+
cmd.link_dylib_by_name(&link_path, true, false);
2408+
}
24652409
}
24662410

24672411
// Library linking above uses some global state for things like `-Bstatic`/`-Bdynamic` to make
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.