diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index 68d3f90cd3991..e169cfc4cc829 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -9,7 +9,9 @@ use std::str; use crate::llvm::archive_ro::{ArchiveRO, Child}; use crate::llvm::{self, ArchiveKind}; -use rustc_codegen_ssa::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION}; +use rustc_codegen_ssa::{ + METADATA_FILENAME, RLIB_BYTECODE_EXTENSION, looks_like_rust_object_file +}; use rustc_codegen_ssa::back::archive::{ArchiveBuilder, find_library}; use rustc::session::Session; use syntax::symbol::Symbol; @@ -141,7 +143,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { } // Don't include Rust objects if LTO is enabled - if lto && fname.starts_with(&obj_start) && fname.ends_with(".o") { + if lto && looks_like_rust_object_file(fname) { return true } diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 1c5d3b1a890ee..a2b50ea8e2bf7 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -3,7 +3,7 @@ use rustc::session::{Session, filesearch}; use rustc::session::config::{ - self, RUST_CGU_EXT, DebugInfo, OutputFilenames, OutputType, PrintRequest, Sanitizer + self, DebugInfo, OutputFilenames, OutputType, PrintRequest, Sanitizer }; use rustc::session::search_paths::PathKind; use rustc::middle::dependency_format::Linkage; @@ -15,7 +15,8 @@ use rustc_fs_util::fix_windows_verbatim_for_gcc; use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor}; use syntax::symbol::Symbol; -use crate::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION, CrateInfo, CodegenResults}; +use crate::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION, CrateInfo, + looks_like_rust_object_file, CodegenResults}; use super::archive::ArchiveBuilder; use super::command::Command; use super::linker::Linker; @@ -1549,23 +1550,9 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( let canonical = f.replace("-", "_"); let canonical_name = name.replace("-", "_"); - // Look for `.rcgu.o` at the end of the filename to conclude - // that this is a Rust-related object file. - fn looks_like_rust(s: &str) -> bool { - let path = Path::new(s); - let ext = path.extension().and_then(|s| s.to_str()); - if ext != Some(OutputType::Object.extension()) { - return false - } - let ext2 = path.file_stem() - .and_then(|s| Path::new(s).extension()) - .and_then(|s| s.to_str()); - ext2 == Some(RUST_CGU_EXT) - } - let is_rust_object = canonical.starts_with(&canonical_name) && - looks_like_rust(&f); + 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 diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index 0221a04b04518..dd75883f97deb 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -22,9 +22,9 @@ #[macro_use] extern crate rustc; #[macro_use] extern crate syntax; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use rustc::dep_graph::WorkProduct; -use rustc::session::config::{OutputFilenames, OutputType}; +use rustc::session::config::{OutputFilenames, OutputType, RUST_CGU_EXT}; use rustc::middle::lang_items::LangItem; use rustc::hir::def_id::CrateNum; use rustc::ty::query::Providers; @@ -62,6 +62,7 @@ pub struct ModuleCodegen { pub const METADATA_FILENAME: &str = "rust.metadata.bin"; pub const RLIB_BYTECODE_EXTENSION: &str = "bc.z"; + impl ModuleCodegen { pub fn into_compiled_module(self, emit_obj: bool, @@ -166,3 +167,22 @@ pub fn provide_extern(providers: &mut Providers<'_>) { crate::back::symbol_export::provide_extern(providers); crate::base::provide_both(providers); } + +/// Checks if the given filename ends with the `.rcgu.o` extension that `rustc` +/// uses for the object files it generates. +pub fn looks_like_rust_object_file(filename: &str) -> bool { + let path = Path::new(filename); + let ext = path.extension().and_then(|s| s.to_str()); + if ext != Some(OutputType::Object.extension()) { + // The file name does not end with ".o", so it can't be an object file. + return false + } + + // Strip the ".o" at the end + let ext2 = path.file_stem() + .and_then(|s| Path::new(s).extension()) + .and_then(|s| s.to_str()); + + // Check if the "inner" extension + ext2 == Some(RUST_CGU_EXT) +}