Skip to content

Move add_rlib and add_native_library to cg_ssa #88559

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

Merged
merged 1 commit into from
Sep 5, 2021
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
83 changes: 19 additions & 64 deletions compiler/rustc_codegen_cranelift/src/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use std::collections::BTreeMap;
use std::fs::File;
use std::path::{Path, PathBuf};

use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder};
use rustc_codegen_ssa::METADATA_FILENAME;
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
use rustc_session::Session;

use object::{Object, ObjectSymbol, SymbolKind};
Expand All @@ -19,7 +18,6 @@ enum ArchiveEntry {
pub(crate) struct ArArchiveBuilder<'a> {
sess: &'a Session,
dst: PathBuf,
lib_search_paths: Vec<PathBuf>,
use_gnu_style_archive: bool,
no_builtin_ranlib: bool,

Expand All @@ -31,8 +29,6 @@ pub(crate) struct ArArchiveBuilder<'a> {

impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self {
use rustc_codegen_ssa::back::link::archive_search_paths;

let (src_archives, entries) = if let Some(input) = input {
let mut archive = ar::Archive::new(File::open(input).unwrap());
let mut entries = Vec::new();
Expand All @@ -55,7 +51,6 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
ArArchiveBuilder {
sess,
dst: output.to_path_buf(),
lib_search_paths: archive_search_paths(sess),
use_gnu_style_archive: sess.target.archive_format == "gnu",
// FIXME fix builtin ranlib on macOS
no_builtin_ranlib: sess.target.is_like_osx,
Expand Down Expand Up @@ -85,42 +80,27 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
));
}

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);
});
}

fn add_rlib(
&mut self,
rlib: &Path,
name: &str,
lto: bool,
skip_objects: bool,
) -> std::io::Result<()> {
let obj_start = name.to_owned();

self.add_archive(rlib.to_owned(), 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 && fname.starts_with(&obj_start) && fname.ends_with(".o") {
return true;
}
fn add_archive<F>(&mut self, archive_path: &Path, mut skip: F) -> std::io::Result<()>
where
F: FnMut(&str) -> bool + 'static,
{
let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?);
let archive_index = self.src_archives.len();

// Otherwise if this is *not* a rust object and we're skipping
// objects then skip this file
if skip_objects && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) {
return true;
let mut i = 0;
while let Some(entry) = archive.next_entry() {
let entry = entry?;
let file_name = String::from_utf8(entry.header().identifier().to_vec())
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
if !skip(&file_name) {
self.entries
.push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i }));
}
i += 1;
}

// ok, don't skip this
false
})
self.src_archives.push((archive_path.to_owned(), archive));
Ok(())
}

fn update_symbols(&mut self) {}
Expand Down Expand Up @@ -264,28 +244,3 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
bug!("injecting dll imports is not supported");
}
}

impl<'a> ArArchiveBuilder<'a> {
fn add_archive<F>(&mut self, archive_path: PathBuf, mut skip: F) -> std::io::Result<()>
where
F: FnMut(&str) -> bool + 'static,
{
let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?);
let archive_index = self.src_archives.len();

let mut i = 0;
while let Some(entry) = archive.next_entry() {
let entry = entry?;
let file_name = String::from_utf8(entry.header().identifier().to_vec())
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
if !skip(&file_name) {
self.entries
.push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i }));
}
i += 1;
}

self.src_archives.push((archive_path, archive));
Ok(())
}
}
98 changes: 18 additions & 80 deletions compiler/rustc_codegen_llvm/src/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@ use std::str;

use crate::llvm::archive_ro::{ArchiveRO, Child};
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder};
use rustc_codegen_ssa::{looks_like_rust_object_file, METADATA_FILENAME};
use rustc_codegen_ssa::back::archive::ArchiveBuilder;
use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_middle::middle::cstore::{DllCallingConvention, DllImport};
use rustc_session::Session;
use rustc_span::symbol::Symbol;

struct ArchiveConfig<'a> {
pub sess: &'a Session,
pub dst: PathBuf,
pub src: Option<PathBuf>,
pub lib_search_paths: Vec<PathBuf>,
}

/// Helper for adding many files to an archive.
Expand Down Expand Up @@ -54,13 +51,7 @@ fn is_relevant_child(c: &Child<'_>) -> bool {
}

fn archive_config<'a>(sess: &'a Session, output: &Path, input: Option<&Path>) -> ArchiveConfig<'a> {
use rustc_codegen_ssa::back::link::archive_search_paths;
ArchiveConfig {
sess,
dst: output.to_path_buf(),
src: input.map(|p| p.to_path_buf()),
lib_search_paths: archive_search_paths(sess),
}
ArchiveConfig { sess, dst: output.to_path_buf(), src: input.map(|p| p.to_path_buf()) }
}

/// Map machine type strings to values of LLVM's MachineTypes enum.
Expand Down Expand Up @@ -111,57 +102,23 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
.collect()
}

/// 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, 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 {}: {}",
location.to_string_lossy(),
e
));
fn add_archive<F>(&mut self, archive: &Path, skip: F) -> io::Result<()>
where
F: FnMut(&str) -> bool + 'static,
{
let archive_ro = match ArchiveRO::open(archive) {
Ok(ar) => ar,
Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)),
};
if self.additions.iter().any(|ar| ar.path() == archive) {
return Ok(());
}
self.additions.push(Addition::Archive {
path: archive.to_path_buf(),
archive: archive_ro,
skip: Box::new(skip),
});
}

/// Adds all of the contents of the rlib at the specified path to this
/// archive.
///
/// This ignores adding the bytecode from the rlib, and if LTO is enabled
/// then the object file also isn't added.
fn add_rlib(
&mut self,
rlib: &Path,
name: &str,
lto: bool,
skip_objects: bool,
) -> io::Result<()> {
// Ignoring obj file starting with the crate name
// as simple comparison is not enough - there
// might be also an extra name suffix
let obj_start = name.to_owned();

self.add_archive(rlib, 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;
}

// Otherwise if this is *not* a rust object and we're skipping
// objects then skip this file
if skip_objects && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) {
return true;
}

// ok, don't skip this
false
})
Ok(())
}

/// Adds an arbitrary file to this archive
Expand Down Expand Up @@ -270,25 +227,6 @@ impl<'a> LlvmArchiveBuilder<'a> {
self.src_archive.as_ref().unwrap().as_ref()
}

fn add_archive<F>(&mut self, archive: &Path, skip: F) -> io::Result<()>
where
F: FnMut(&str) -> bool + 'static,
{
let archive_ro = match ArchiveRO::open(archive) {
Ok(ar) => ar,
Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)),
};
if self.additions.iter().any(|ar| ar.path() == archive) {
return Ok(());
}
self.additions.push(Addition::Archive {
path: archive.to_path_buf(),
archive: archive_ro,
skip: Box::new(skip),
});
Ok(())
}

fn llvm_archive_kind(&self) -> Result<ArchiveKind, &str> {
let kind = &*self.config.sess.target.archive_format;
kind.parse().map_err(|_| kind)
Expand Down
13 changes: 4 additions & 9 deletions compiler/rustc_codegen_ssa/src/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_span::symbol::Symbol;
use std::io;
use std::path::{Path, PathBuf};

pub fn find_library(
pub(super) fn find_library(
name: Symbol,
verbatim: bool,
search_paths: &[PathBuf],
Expand Down Expand Up @@ -48,14 +48,9 @@ pub trait ArchiveBuilder<'a> {
fn remove_file(&mut self, name: &str);
fn src_files(&mut self) -> Vec<String>;

fn add_rlib(
&mut self,
path: &Path,
name: &str,
lto: bool,
skip_objects: bool,
) -> io::Result<()>;
fn add_native_library(&mut self, name: Symbol, verbatim: bool);
fn add_archive<F>(&mut self, archive: &Path, skip: F) -> io::Result<()>
where
F: FnMut(&str) -> bool + 'static;
fn update_symbols(&mut self);

fn build(self);
Expand Down
53 changes: 43 additions & 10 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo};
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target};

use super::archive::ArchiveBuilder;
use super::archive::{find_library, ArchiveBuilder};
use super::command::Command;
use super::linker::{self, Linker};
use super::rpath::{self, RPathConfig};
Expand Down Expand Up @@ -230,6 +230,9 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
tmpdir: &MaybeTempDir,
) -> Result<B, ErrorReported> {
info!("preparing rlib to {:?}", out_filename);

let lib_search_paths = archive_search_paths(sess);

let mut ab = <B as ArchiveBuilder>::new(sess, out_filename, None);

for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
Expand Down Expand Up @@ -262,7 +265,15 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
| NativeLibKind::Unspecified => continue,
}
if let Some(name) = lib.name {
ab.add_native_library(name, lib.verbatim.unwrap_or(false));
let location =
find_library(name, lib.verbatim.unwrap_or(false), &lib_search_paths, sess);
ab.add_archive(&location, |_| false).unwrap_or_else(|e| {
sess.fatal(&format!(
"failed to add native library {}: {}",
location.to_string_lossy(),
e
));
});
}
}

Expand Down Expand Up @@ -541,13 +552,35 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>(
matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
&& !relevant_lib(sess, lib)
});
ab.add_rlib(
path,
&name.as_str(),
are_upstream_rust_objects_already_included(sess)
&& !ignored_for_lto(sess, &codegen_results.crate_info, cnum),
skip_object_files,
)

let lto = are_upstream_rust_objects_already_included(sess)
&& !ignored_for_lto(sess, &codegen_results.crate_info, cnum);

// Ignoring obj file starting with the crate name
// as simple comparison is not enough - there
// 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;
}

// 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;
}

// ok, don't skip this
false
})
.unwrap();

all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
Expand Down Expand Up @@ -1218,7 +1251,7 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool {
sess.split_debuginfo() == SplitDebuginfo::Unpacked
}

pub fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
sess.target_filesearch(PathKind::Native).search_path_dirs()
}

Expand Down