Skip to content

Commit dedfb9c

Browse files
committedNov 15, 2022
Auto merge of #104091 - BelovDV:issue-103044, r=petrochenkov
Wrap bundled static libraries into object files Fixes #103044 (not sure, couldn't test locally) Bundled static libraries should be wrapped into object files as it's done for metadata file. r? `@petrochenkov`
2 parents 96ddd32 + e16c778 commit dedfb9c

File tree

7 files changed

+51
-19
lines changed

7 files changed

+51
-19
lines changed
 

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

+6
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ use rustc_session::cstore::DllImport;
44
use rustc_session::Session;
55
use rustc_span::symbol::Symbol;
66

7+
use super::metadata::search_for_section;
8+
79
use object::read::archive::ArchiveFile;
810

11+
use std::error::Error;
912
use std::fs::File;
1013
use std::io;
1114
use std::path::{Path, PathBuf};
@@ -56,6 +59,9 @@ pub trait ArchiveBuilderBuilder {
5659
if !bundled_lib_file_names.contains(&Symbol::intern(name)) {
5760
continue; // We need to extract only native libraries.
5861
}
62+
let data = search_for_section(rlib, data, ".bundled_lib").map_err(|e| {
63+
ExtractBundledLibsError::ExtractSection { rlib, error: Box::<dyn Error>::from(e) }
64+
})?;
5965
std::fs::write(&outdir.join(&name), data)
6066
.map_err(|e| ExtractBundledLibsError::WriteFile { rlib, error: Box::new(e) })?;
6167
}

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

+14-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_errors::{ErrorGuaranteed, Handler};
88
use rustc_fs_util::fix_windows_verbatim_for_gcc;
99
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
1010
use rustc_metadata::find_native_static_library;
11-
use rustc_metadata::fs::{emit_metadata, METADATA_FILENAME};
11+
use rustc_metadata::fs::{emit_wrapper_file, METADATA_FILENAME};
1212
use rustc_middle::middle::dependency_format::Linkage;
1313
use rustc_middle::middle::exported_symbols::SymbolExportKind;
1414
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Lto, Strip};
@@ -29,7 +29,7 @@ use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo};
2929
use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
3030
use super::command::Command;
3131
use super::linker::{self, Linker};
32-
use super::metadata::{create_rmeta_file, MetadataPosition};
32+
use super::metadata::{create_wrapper_file, MetadataPosition};
3333
use super::rpath::{self, RPathConfig};
3434
use crate::{
3535
errors, looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo, NativeLib,
@@ -44,7 +44,7 @@ use std::borrow::Borrow;
4444
use std::cell::OnceCell;
4545
use std::collections::BTreeSet;
4646
use std::ffi::OsString;
47-
use std::fs::{File, OpenOptions};
47+
use std::fs::{read, File, OpenOptions};
4848
use std::io::{BufWriter, Write};
4949
use std::ops::Deref;
5050
use std::path::{Path, PathBuf};
@@ -292,8 +292,8 @@ fn link_rlib<'a>(
292292
let trailing_metadata = match flavor {
293293
RlibFlavor::Normal => {
294294
let (metadata, metadata_position) =
295-
create_rmeta_file(sess, codegen_results.metadata.raw_data());
296-
let metadata = emit_metadata(sess, &metadata, tmpdir);
295+
create_wrapper_file(sess, b".rmeta".to_vec(), codegen_results.metadata.raw_data());
296+
let metadata = emit_wrapper_file(sess, &metadata, tmpdir, METADATA_FILENAME);
297297
match metadata_position {
298298
MetadataPosition::First => {
299299
// Most of the time metadata in rlib files is wrapped in a "dummy" object
@@ -376,12 +376,18 @@ fn link_rlib<'a>(
376376
let location =
377377
find_native_static_library(name.as_str(), lib.verbatim, &lib_search_paths, sess);
378378
if sess.opts.unstable_opts.packed_bundled_libs && flavor == RlibFlavor::Normal {
379-
packed_bundled_libs.push(find_native_static_library(
380-
lib.filename.unwrap().as_str(),
379+
let filename = lib.filename.unwrap();
380+
let lib_path = find_native_static_library(
381+
filename.as_str(),
381382
Some(true),
382383
&lib_search_paths,
383384
sess,
384-
));
385+
);
386+
let src = read(lib_path)
387+
.map_err(|e| sess.emit_fatal(errors::ReadFileError { message: e }))?;
388+
let (data, _) = create_wrapper_file(sess, b".bundled_lib".to_vec(), &src);
389+
let wrapper_file = emit_wrapper_file(sess, &data, tmpdir, filename.as_str());
390+
packed_bundled_libs.push(wrapper_file);
385391
continue;
386392
}
387393
ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|error| {

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

+11-7
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl MetadataLoader for DefaultMetadataLoader {
6060
let data = entry
6161
.data(data)
6262
.map_err(|e| format!("failed to parse rlib '{}': {}", path.display(), e))?;
63-
return search_for_metadata(path, data, ".rmeta");
63+
return search_for_section(path, data, ".rmeta");
6464
}
6565
}
6666

@@ -69,11 +69,11 @@ impl MetadataLoader for DefaultMetadataLoader {
6969
}
7070

7171
fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> {
72-
load_metadata_with(path, |data| search_for_metadata(path, data, ".rustc"))
72+
load_metadata_with(path, |data| search_for_section(path, data, ".rustc"))
7373
}
7474
}
7575

76-
fn search_for_metadata<'a>(
76+
pub(super) fn search_for_section<'a>(
7777
path: &Path,
7878
bytes: &'a [u8],
7979
section: &str,
@@ -223,7 +223,11 @@ pub enum MetadataPosition {
223223
// * ELF - All other targets are similar to Windows in that there's a
224224
// `SHF_EXCLUDE` flag we can set on sections in an object file to get
225225
// automatically removed from the final output.
226-
pub fn create_rmeta_file(sess: &Session, metadata: &[u8]) -> (Vec<u8>, MetadataPosition) {
226+
pub fn create_wrapper_file(
227+
sess: &Session,
228+
section_name: Vec<u8>,
229+
data: &[u8],
230+
) -> (Vec<u8>, MetadataPosition) {
227231
let Some(mut file) = create_object_file(sess) else {
228232
// This is used to handle all "other" targets. This includes targets
229233
// in two categories:
@@ -241,11 +245,11 @@ pub fn create_rmeta_file(sess: &Session, metadata: &[u8]) -> (Vec<u8>, MetadataP
241245
// WebAssembly and for targets not supported by the `object` crate
242246
// yet it means that work will need to be done in the `object` crate
243247
// to add a case above.
244-
return (metadata.to_vec(), MetadataPosition::Last);
248+
return (data.to_vec(), MetadataPosition::Last);
245249
};
246250
let section = file.add_section(
247251
file.segment_name(StandardSegment::Debug).to_vec(),
248-
b".rmeta".to_vec(),
252+
section_name,
249253
SectionKind::Debug,
250254
);
251255
match file.format() {
@@ -259,7 +263,7 @@ pub fn create_rmeta_file(sess: &Session, metadata: &[u8]) -> (Vec<u8>, MetadataP
259263
}
260264
_ => {}
261265
};
262-
file.append_section_data(section, metadata, 1);
266+
file.append_section_data(section, data, 1);
263267
(file.write().unwrap(), MetadataPosition::First)
264268
}
265269

‎compiler/rustc_codegen_ssa/src/errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,9 @@ pub enum ExtractBundledLibsError<'a> {
507507

508508
#[diag(codegen_ssa_extract_bundled_libs_write_file)]
509509
WriteFile { rlib: &'a Path, error: Box<dyn std::error::Error> },
510+
511+
#[diag(codegen_ssa_extract_bundled_libs_write_file)]
512+
ExtractSection { rlib: &'a Path, error: Box<dyn std::error::Error> },
510513
}
511514

512515
#[derive(Diagnostic)]
@@ -521,3 +524,9 @@ pub enum AppleSdkRootError<'a> {
521524
#[diag(codegen_ssa_apple_sdk_error_sdk_path)]
522525
SdkPath { sdk_name: &'a str, error: Error },
523526
}
527+
528+
#[derive(Diagnostic)]
529+
#[diag(codegen_ssa_read_file)]
530+
pub struct ReadFileError {
531+
pub message: std::io::Error,
532+
}

‎compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,5 @@ codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$
182182
codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`
183183
184184
codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {error}
185+
186+
codegen_ssa_read_file = failed to read file: {message}

‎compiler/rustc_metadata/src/fs.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,14 @@ pub const METADATA_FILENAME: &str = "lib.rmeta";
2222
/// building an `.rlib` (stomping over one another), or writing an `.rmeta` into a
2323
/// directory being searched for `extern crate` (observing an incomplete file).
2424
/// The returned path is the temporary file containing the complete metadata.
25-
pub fn emit_metadata(sess: &Session, metadata: &[u8], tmpdir: &MaybeTempDir) -> PathBuf {
26-
let out_filename = tmpdir.as_ref().join(METADATA_FILENAME);
27-
let result = fs::write(&out_filename, metadata);
25+
pub fn emit_wrapper_file(
26+
sess: &Session,
27+
data: &[u8],
28+
tmpdir: &MaybeTempDir,
29+
name: &str,
30+
) -> PathBuf {
31+
let out_filename = tmpdir.as_ref().join(name);
32+
let result = fs::write(&out_filename, data);
2833

2934
if let Err(err) = result {
3035
sess.emit_fatal(FailedWriteError { filename: out_filename, err });

‎compiler/rustc_metadata/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ pub mod errors;
4141
pub mod fs;
4242
pub mod locator;
4343

44-
pub use fs::{emit_metadata, METADATA_FILENAME};
44+
pub use fs::{emit_wrapper_file, METADATA_FILENAME};
4545
pub use native_libs::find_native_static_library;
4646
pub use rmeta::{encode_metadata, EncodedMetadata, METADATA_HEADER};

0 commit comments

Comments
 (0)
Please sign in to comment.