Introduce an ArchiveBuilderBuilder

This avoids monomorphizing all linker code for each codegen backend and
will allow passing in extra information to the archive builder from the
codegen backend.
This commit is contained in:
bjorn3 2022-07-28 09:07:49 +00:00
parent 90da3c6f2b
commit 7c6c7e8785
8 changed files with 214 additions and 148 deletions

View file

@ -5,7 +5,7 @@
use std::io::{self, Read, Seek};
use std::path::{Path, PathBuf};
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
use rustc_session::Session;
use object::read::archive::ArchiveFile;
@ -17,6 +17,32 @@ enum ArchiveEntry {
File(PathBuf),
}
pub(crate) struct ArArchiveBuilderBuilder;
impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a> {
Box::new(ArArchiveBuilder {
sess,
use_gnu_style_archive: sess.target.archive_format == "gnu",
// FIXME fix builtin ranlib on macOS
no_builtin_ranlib: sess.target.is_like_osx,
src_archives: vec![],
entries: vec![],
})
}
fn create_dll_import_lib(
&self,
_sess: &Session,
_lib_name: &str,
_dll_imports: &[rustc_session::cstore::DllImport],
_tmpdir: &Path,
) -> PathBuf {
bug!("creating dll imports is not supported");
}
}
pub(crate) struct ArArchiveBuilder<'a> {
sess: &'a Session,
use_gnu_style_archive: bool,
@ -29,18 +55,6 @@ pub(crate) struct ArArchiveBuilder<'a> {
}
impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
fn new(sess: &'a Session) -> Self {
ArArchiveBuilder {
sess,
use_gnu_style_archive: sess.target.archive_format == "gnu",
// FIXME fix builtin ranlib on macOS
no_builtin_ranlib: sess.target.is_like_osx,
src_archives: vec![],
entries: vec![],
}
}
fn add_file(&mut self, file: &Path) {
self.entries.push((
file.file_name().unwrap().to_str().unwrap().to_string().into_bytes(),
@ -48,10 +62,11 @@ fn add_file(&mut self, file: &Path) {
));
}
fn add_archive<F>(&mut self, archive_path: &Path, mut skip: F) -> std::io::Result<()>
where
F: FnMut(&str) -> bool + 'static,
{
fn add_archive(
&mut self,
archive_path: &Path,
mut skip: Box<dyn FnMut(&str) -> bool + 'static>,
) -> std::io::Result<()> {
let read_cache = ReadCache::new(std::fs::File::open(&archive_path)?);
let archive = ArchiveFile::parse(&read_cache).unwrap();
let archive_index = self.src_archives.len();
@ -72,7 +87,7 @@ fn add_archive<F>(&mut self, archive_path: &Path, mut skip: F) -> std::io::Resul
Ok(())
}
fn build(mut self, output: &Path) -> bool {
fn build(mut self: Box<Self>, output: &Path) -> bool {
enum BuilderKind {
Bsd(ar::Builder<File>),
Gnu(ar::GnuBuilder<File>),
@ -218,13 +233,4 @@ enum BuilderKind {
any_members
}
fn create_dll_import_lib(
_sess: &Session,
_lib_name: &str,
_dll_imports: &[rustc_session::cstore::DllImport],
_tmpdir: &Path,
) -> PathBuf {
bug!("creating dll imports is not supported");
}
}

View file

@ -226,7 +226,7 @@ fn link(
) -> Result<(), ErrorGuaranteed> {
use rustc_codegen_ssa::back::link::link_binary;
link_binary::<crate::archive::ArArchiveBuilder<'_>>(sess, &codegen_results, outputs)
link_binary(sess, &crate::archive::ArArchiveBuilderBuilder, &codegen_results, outputs)
}
}

View file

@ -1,7 +1,7 @@
use std::fs::File;
use std::path::{Path, PathBuf};
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
use rustc_session::Session;
use rustc_session::cstore::DllImport;
@ -21,6 +21,35 @@ enum ArchiveEntry {
File(PathBuf),
}
pub struct ArArchiveBuilderBuilder;
impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a> {
let config = ArchiveConfig {
sess,
use_native_ar: false,
// FIXME test for linux and System V derivatives instead
use_gnu_style_archive: sess.target.options.archive_format == "gnu",
};
Box::new(ArArchiveBuilder {
config,
src_archives: vec![],
entries: vec![],
})
}
fn create_dll_import_lib(
&self,
_sess: &Session,
_lib_name: &str,
_dll_imports: &[DllImport],
_tmpdir: &Path,
) -> PathBuf {
unimplemented!();
}
}
pub struct ArArchiveBuilder<'a> {
config: ArchiveConfig<'a>,
src_archives: Vec<(PathBuf, ar::Archive<File>)>,
@ -30,21 +59,6 @@ pub struct ArArchiveBuilder<'a> {
}
impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
fn new(sess: &'a Session) -> Self {
let config = ArchiveConfig {
sess,
use_native_ar: false,
// FIXME test for linux and System V derivatives instead
use_gnu_style_archive: sess.target.options.archive_format == "gnu",
};
ArArchiveBuilder {
config,
src_archives: vec![],
entries: vec![],
}
}
fn add_file(&mut self, file: &Path) {
self.entries.push((
file.file_name().unwrap().to_str().unwrap().to_string(),
@ -52,10 +66,11 @@ fn add_file(&mut self, file: &Path) {
));
}
fn add_archive<F>(&mut self, archive_path: &Path, mut skip: F) -> std::io::Result<()>
where
F: FnMut(&str) -> bool + 'static,
{
fn add_archive(
&mut self,
archive_path: &Path,
mut skip: Box<dyn FnMut(&str) -> bool + 'static>,
) -> std::io::Result<()> {
let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?);
let archive_index = self.src_archives.len();
@ -75,7 +90,7 @@ fn add_archive<F>(&mut self, archive_path: &Path, mut skip: F) -> std::io::Resul
Ok(())
}
fn build(mut self, output: &Path) -> bool {
fn build(mut self: Box<Self>, output: &Path) -> bool {
use std::process::Command;
fn add_file_using_ar(archive: &Path, file: &Path) {
@ -171,13 +186,4 @@ enum BuilderKind<'a> {
any_members
}
fn create_dll_import_lib(
_sess: &Session,
_lib_name: &str,
_dll_imports: &[DllImport],
_tmpdir: &Path,
) -> PathBuf {
unimplemented!();
}
}

View file

@ -133,8 +133,9 @@ fn join_codegen(&self, ongoing_codegen: Box<dyn Any>, sess: &Session, _outputs:
fn link(&self, sess: &Session, codegen_results: CodegenResults, outputs: &OutputFilenames) -> Result<(), ErrorGuaranteed> {
use rustc_codegen_ssa::back::link::link_binary;
link_binary::<crate::archive::ArArchiveBuilder<'_>>(
link_binary(
sess,
&crate::archive::ArArchiveBuilderBuilder,
&codegen_results,
outputs,
)

View file

@ -10,7 +10,7 @@
use crate::llvm::archive_ro::{ArchiveRO, Child};
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
use rustc_session::cstore::{DllCallingConvention, DllImport};
use rustc_session::Session;
@ -53,16 +53,11 @@ fn llvm_machine_type(cpu: &str) -> LLVMMachineType {
}
impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
/// Creates a new static archive, ready for modifying the archive specified
/// by `config`.
fn new(sess: &'a Session) -> LlvmArchiveBuilder<'a> {
LlvmArchiveBuilder { sess, additions: Vec::new() }
}
fn add_archive<F>(&mut self, archive: &Path, skip: F) -> io::Result<()>
where
F: FnMut(&str) -> bool + 'static,
{
fn add_archive(
&mut self,
archive: &Path,
skip: Box<dyn FnMut(&str) -> bool + 'static>,
) -> io::Result<()> {
let archive_ro = match ArchiveRO::open(archive) {
Ok(ar) => ar,
Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)),
@ -87,14 +82,23 @@ fn add_file(&mut self, file: &Path) {
/// Combine the provided files, rlibs, and native libraries into a single
/// `Archive`.
fn build(mut self, output: &Path) -> bool {
fn build(mut self: Box<Self>, output: &Path) -> bool {
match self.build_with_llvm(output) {
Ok(any_members) => any_members,
Err(e) => self.sess.fatal(&format!("failed to build archive: {}", e)),
}
}
}
pub struct LlvmArchiveBuilderBuilder;
impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a> {
Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() })
}
fn create_dll_import_lib(
&self,
sess: &Session,
lib_name: &str,
dll_imports: &[DllImport],

View file

@ -370,12 +370,12 @@ fn link(
codegen_results: CodegenResults,
outputs: &OutputFilenames,
) -> Result<(), ErrorGuaranteed> {
use crate::back::archive::LlvmArchiveBuilder;
use crate::back::archive::LlvmArchiveBuilderBuilder;
use rustc_codegen_ssa::back::link::link_binary;
// Run the linker on any artifacts that resulted from the LLVM run.
// This should produce either a finished executable or library.
link_binary::<LlvmArchiveBuilder<'_>>(sess, &codegen_results, outputs)
link_binary(sess, &LlvmArchiveBuilderBuilder, &codegen_results, outputs)
}
}

View file

@ -39,16 +39,8 @@ pub(super) fn find_library(
));
}
pub trait ArchiveBuilder<'a> {
fn new(sess: &'a Session) -> Self;
fn add_file(&mut self, path: &Path);
fn add_archive<F>(&mut self, archive: &Path, skip: F) -> io::Result<()>
where
F: FnMut(&str) -> bool + 'static;
fn build(self, output: &Path) -> bool;
pub trait ArchiveBuilderBuilder {
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a>;
/// Creates a DLL Import Library <https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-creation#creating-an-import-library>.
/// and returns the path on disk to that import library.
@ -56,9 +48,22 @@ fn add_archive<F>(&mut self, archive: &Path, skip: F) -> io::Result<()>
/// `linker_with_args`, which is specialized on `ArchiveBuilder` but
/// doesn't take or create an instance of that type.
fn create_dll_import_lib(
&self,
sess: &Session,
lib_name: &str,
dll_imports: &[DllImport],
tmpdir: &Path,
) -> PathBuf;
}
pub trait ArchiveBuilder<'a> {
fn add_file(&mut self, path: &Path);
fn add_archive(
&mut self,
archive: &Path,
skip: Box<dyn FnMut(&str) -> bool + 'static>,
) -> io::Result<()>;
fn build(self: Box<Self>, output: &Path) -> bool;
}

View file

@ -24,7 +24,7 @@
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo};
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target};
use super::archive::{find_library, ArchiveBuilder};
use super::archive::{find_library, ArchiveBuilder, ArchiveBuilderBuilder};
use super::command::Command;
use super::linker::{self, Linker};
use super::metadata::{create_rmeta_file, MetadataPosition};
@ -56,8 +56,9 @@ pub fn ensure_removed(diag_handler: &Handler, path: &Path) {
/// Performs the linkage portion of the compilation phase. This will generate all
/// of the requested outputs for this compilation session.
pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
pub fn link_binary<'a>(
sess: &'a Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
outputs: &OutputFilenames,
) -> Result<(), ErrorGuaranteed> {
@ -102,15 +103,28 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
CrateType::Rlib => {
let _timer = sess.timer("link_rlib");
info!("preparing rlib to {:?}", out_filename);
link_rlib::<B>(sess, codegen_results, RlibFlavor::Normal, &path)?
.build(&out_filename);
link_rlib(
sess,
archive_builder_builder,
codegen_results,
RlibFlavor::Normal,
&path,
)?
.build(&out_filename);
}
CrateType::Staticlib => {
link_staticlib::<B>(sess, codegen_results, &out_filename, &path)?;
link_staticlib(
sess,
archive_builder_builder,
codegen_results,
&out_filename,
&path,
)?;
}
_ => {
link_natively::<B>(
link_natively(
sess,
archive_builder_builder,
crate_type,
&out_filename,
codegen_results,
@ -240,15 +254,16 @@ pub fn each_linked_rlib(
/// the object file of the crate, but it also contains all of the object files from native
/// libraries. This is done by unzipping native libraries and inserting all of the contents into
/// this archive.
fn link_rlib<'a, B: ArchiveBuilder<'a>>(
fn link_rlib<'a>(
sess: &'a Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
flavor: RlibFlavor,
tmpdir: &MaybeTempDir,
) -> Result<B, ErrorGuaranteed> {
) -> Result<Box<dyn ArchiveBuilder<'a> + 'a>, ErrorGuaranteed> {
let lib_search_paths = archive_search_paths(sess);
let mut ab = <B as ArchiveBuilder>::new(sess);
let mut ab = archive_builder_builder.new_archive_builder(sess);
let trailing_metadata = match flavor {
RlibFlavor::Normal => {
@ -333,7 +348,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
if let Some(name) = lib.name {
let location =
find_library(name.as_str(), lib.verbatim.unwrap_or(false), &lib_search_paths, sess);
ab.add_archive(&location, |_| false).unwrap_or_else(|e| {
ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|e| {
sess.fatal(&format!(
"failed to add native library {}: {}",
location.to_string_lossy(),
@ -346,10 +361,14 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
for (raw_dylib_name, raw_dylib_imports) in
collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)?
{
let output_path =
B::create_dll_import_lib(sess, &raw_dylib_name, &raw_dylib_imports, tmpdir.as_ref());
let output_path = archive_builder_builder.create_dll_import_lib(
sess,
&raw_dylib_name,
&raw_dylib_imports,
tmpdir.as_ref(),
);
ab.add_archive(&output_path, |_| false).unwrap_or_else(|e| {
ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|e| {
sess.fatal(&format!("failed to add native library {}: {}", output_path.display(), e));
});
}
@ -442,14 +461,21 @@ fn collate_raw_dylibs(
///
/// There's no need to include metadata in a static archive, so ensure to not link in the metadata
/// object file (and also don't prepare the archive with a metadata file).
fn link_staticlib<'a, B: ArchiveBuilder<'a>>(
fn link_staticlib<'a>(
sess: &'a Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
out_filename: &Path,
tempdir: &MaybeTempDir,
) -> Result<(), ErrorGuaranteed> {
info!("preparing staticlib to {:?}", out_filename);
let mut ab = link_rlib::<B>(sess, codegen_results, RlibFlavor::StaticlibBase, tempdir)?;
let mut ab = link_rlib(
sess,
archive_builder_builder,
codegen_results,
RlibFlavor::StaticlibBase,
tempdir,
)?;
let mut all_native_libs = vec![];
let res = each_linked_rlib(&codegen_results.crate_info, &mut |cnum, path| {
@ -483,26 +509,29 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(
// might be also an extra name suffix
let obj_start = name.as_str().to_owned();
ab.add_archive(path, move |fname: &str| {
// Ignore metadata files, no matter the name.
if fname == METADATA_FILENAME {
return true;
}
ab.add_archive(
path,
Box::new(move |fname: &str| {
// Ignore metadata files, no matter the name.
if fname == METADATA_FILENAME {
return true;
}
// Don't include Rust objects if LTO is enabled
if lto && looks_like_rust_object_file(fname) {
return true;
}
// Don't include Rust objects if LTO is enabled
if lto && looks_like_rust_object_file(fname) {
return true;
}
// Otherwise if this is *not* a rust object and we're skipping
// objects then skip this file
if skip_object_files && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) {
return true;
}
// Otherwise if this is *not* a rust object and we're skipping
// objects then skip this file
if skip_object_files && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) {
return true;
}
// ok, don't skip this
false
})
// ok, don't skip this
false
}),
)
.unwrap();
all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
@ -641,8 +670,9 @@ fn read_input<'arena>(&'arena self, path: &Path) -> std::io::Result<&'arena [u8]
///
/// This will invoke the system linker/cc to create the resulting file. This links to all upstream
/// files as well.
fn link_natively<'a, B: ArchiveBuilder<'a>>(
fn link_natively<'a>(
sess: &'a Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
crate_type: CrateType,
out_filename: &Path,
codegen_results: &CodegenResults,
@ -650,10 +680,11 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
) -> Result<(), ErrorGuaranteed> {
info!("preparing {:?} to {:?}", crate_type, out_filename);
let (linker_path, flavor) = linker_and_flavor(sess);
let mut cmd = linker_with_args::<B>(
let mut cmd = linker_with_args(
&linker_path,
flavor,
sess,
archive_builder_builder,
crate_type,
tmpdir,
out_filename,
@ -1839,10 +1870,11 @@ fn add_rpath_args(
/// to the linking process as a whole.
/// Order-independent options may still override each other in order-dependent fashion,
/// e.g `--foo=yes --foo=no` may be equivalent to `--foo=no`.
fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
fn linker_with_args<'a>(
path: &Path,
flavor: LinkerFlavor,
sess: &'a Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
crate_type: CrateType,
tmpdir: &Path,
out_filename: &Path,
@ -1943,7 +1975,14 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
}
// Upstream rust libraries and their non-bundled static libraries
add_upstream_rust_crates::<B>(cmd, sess, codegen_results, crate_type, tmpdir);
add_upstream_rust_crates(
cmd,
sess,
archive_builder_builder,
codegen_results,
crate_type,
tmpdir,
);
// Upstream dynamic native libraries linked with `#[link]` attributes at and `-l`
// command line options.
@ -1958,7 +1997,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
for (raw_dylib_name, raw_dylib_imports) in
collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)?
{
cmd.add_object(&B::create_dll_import_lib(
cmd.add_object(&archive_builder_builder.create_dll_import_lib(
sess,
&raw_dylib_name,
&raw_dylib_imports,
@ -2248,9 +2287,10 @@ fn add_local_native_libraries(
///
/// Rust crates are not considered at all when creating an rlib output. All dependencies will be
/// linked when producing the final output (instead of the intermediate rlib version).
fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
fn add_upstream_rust_crates<'a>(
cmd: &mut dyn Linker,
sess: &'a Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
crate_type: CrateType,
tmpdir: &Path,
@ -2339,7 +2379,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
let src = &codegen_results.crate_info.used_crate_source[&cnum];
match data[cnum.as_usize() - 1] {
_ if codegen_results.crate_info.profiler_runtime == Some(cnum) => {
add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, cnum);
add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
}
// compiler-builtins are always placed last to ensure that they're
// linked correctly.
@ -2349,7 +2389,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
}
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
Linkage::Static => {
add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, cnum);
add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
// Link static native libs with "-bundle" modifier only if the crate they originate from
// is being linked statically to the current crate. If it's linked dynamically
@ -2408,7 +2448,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
// was already "included" in a dylib (e.g., `libstd` when `-C prefer-dynamic`
// is used)
if let Some(cnum) = compiler_builtins {
add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, cnum);
add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
}
// Converts a library file-stem into a cc -l argument
@ -2434,9 +2474,10 @@ fn unlib<'a>(target: &Target, stem: &'a str) -> &'a str {
// Note, however, that if we're not doing LTO we can just pass the rlib
// blindly to the linker (fast) because it's fine if it's not actually
// included as we're at the end of the dependency chain.
fn add_static_crate<'a, B: ArchiveBuilder<'a>>(
fn add_static_crate<'a>(
cmd: &mut dyn Linker,
sess: &'a Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
tmpdir: &Path,
cnum: CrateNum,
@ -2476,35 +2517,38 @@ fn add_static_crate<'a, B: ArchiveBuilder<'a>>(
let is_builtins = sess.target.no_builtins
|| !codegen_results.crate_info.is_no_builtins.contains(&cnum);
let mut archive = <B as ArchiveBuilder>::new(sess);
if let Err(e) = archive.add_archive(cratepath, move |f| {
if f == METADATA_FILENAME {
return true;
}
let mut archive = archive_builder_builder.new_archive_builder(sess);
if let Err(e) = archive.add_archive(
cratepath,
Box::new(move |f| {
if f == METADATA_FILENAME {
return true;
}
let canonical = f.replace('-', "_");
let canonical = f.replace('-', "_");
let is_rust_object =
canonical.starts_with(&canonical_name) && looks_like_rust_object_file(&f);
let is_rust_object =
canonical.starts_with(&canonical_name) && looks_like_rust_object_file(&f);
// If we've been requested to skip all native object files
// (those not generated by the rust compiler) then we can skip
// this file. See above for why we may want to do this.
let skip_because_cfg_say_so = skip_native && !is_rust_object;
// If we've been requested to skip all native object files
// (those not generated by the rust compiler) then we can skip
// this file. See above for why we may want to do this.
let skip_because_cfg_say_so = skip_native && !is_rust_object;
// If we're performing LTO and this is a rust-generated object
// file, then we don't need the object file as it's part of the
// LTO module. Note that `#![no_builtins]` is excluded from LTO,
// though, so we let that object file slide.
let skip_because_lto =
upstream_rust_objects_already_included && is_rust_object && is_builtins;
// If we're performing LTO and this is a rust-generated object
// file, then we don't need the object file as it's part of the
// LTO module. Note that `#![no_builtins]` is excluded from LTO,
// though, so we let that object file slide.
let skip_because_lto =
upstream_rust_objects_already_included && is_rust_object && is_builtins;
if skip_because_cfg_say_so || skip_because_lto {
return true;
}
if skip_because_cfg_say_so || skip_because_lto {
return true;
}
false
}) {
false
}),
) {
sess.fatal(&format!("failed to build archive from rlib: {}", e));
}
if archive.build(&dst) {