99// except according to those terms.
1010
1111use back:: wasm;
12- use cc:: windows_registry;
1312use super :: archive:: { ArchiveBuilder , ArchiveConfig } ;
1413use super :: bytecode:: RLIB_BYTECODE_EXTENSION ;
14+ use rustc_codegen_ssa:: back:: linker:: Linker ;
15+ use rustc_codegen_ssa:: back:: link:: { remove, ignored_for_lto, each_linked_rlib, linker_and_flavor,
16+ get_linker} ;
17+ use rustc_codegen_ssa:: back:: command:: Command ;
1518use super :: rpath:: RPathConfig ;
1619use super :: rpath;
1720use metadata:: METADATA_FILENAME ;
@@ -20,18 +23,15 @@ use rustc::session::config::{RUST_CGU_EXT, Lto};
2023use rustc:: session:: filesearch;
2124use rustc:: session:: search_paths:: PathKind ;
2225use rustc:: session:: Session ;
23- use rustc:: middle:: cstore:: { NativeLibrary , LibSource , NativeLibraryKind } ;
26+ use rustc:: middle:: cstore:: { NativeLibrary , NativeLibraryKind } ;
2427use rustc:: middle:: dependency_format:: Linkage ;
25- use rustc_codegen_ssa:: CrateInfo ;
26- use CodegenResults ;
28+ use rustc_codegen_ssa:: CodegenResults ;
2729use rustc:: util:: common:: time;
2830use rustc_fs_util:: fix_windows_verbatim_for_gcc;
2931use rustc:: hir:: def_id:: CrateNum ;
3032use tempfile:: { Builder as TempFileBuilder , TempDir } ;
3133use rustc_target:: spec:: { PanicStrategy , RelroLevel , LinkerFlavor } ;
3234use rustc_data_structures:: fx:: FxHashSet ;
33- use rustc_codegen_utils:: linker:: Linker ;
34- use rustc_codegen_utils:: command:: Command ;
3535use context:: get_reloc_model;
3636use llvm;
3737
@@ -51,69 +51,6 @@ pub use rustc_codegen_utils::link::{find_crate_name, filename_for_input, default
5151 invalid_output_for_target, filename_for_metadata,
5252 out_filename, check_file_is_writeable} ;
5353
54- // The third parameter is for env vars, used on windows to set up the
55- // path for MSVC to find its DLLs, and gcc to find its bundled
56- // toolchain
57- pub fn get_linker ( sess : & Session , linker : & Path , flavor : LinkerFlavor ) -> ( PathBuf , Command ) {
58- let msvc_tool = windows_registry:: find_tool ( & sess. opts . target_triple . triple ( ) , "link.exe" ) ;
59-
60- // If our linker looks like a batch script on Windows then to execute this
61- // we'll need to spawn `cmd` explicitly. This is primarily done to handle
62- // emscripten where the linker is `emcc.bat` and needs to be spawned as
63- // `cmd /c emcc.bat ...`.
64- //
65- // This worked historically but is needed manually since #42436 (regression
66- // was tagged as #42791) and some more info can be found on #44443 for
67- // emscripten itself.
68- let mut cmd = match linker. to_str ( ) {
69- Some ( linker) if cfg ! ( windows) && linker. ends_with ( ".bat" ) => Command :: bat_script ( linker) ,
70- _ => match flavor {
71- LinkerFlavor :: Lld ( f) => Command :: lld ( linker, f) ,
72- LinkerFlavor :: Msvc
73- if sess. opts . cg . linker . is_none ( ) && sess. target . target . options . linker . is_none ( ) =>
74- {
75- Command :: new ( msvc_tool. as_ref ( ) . map ( |t| t. path ( ) ) . unwrap_or ( linker) )
76- } ,
77- _ => Command :: new ( linker) ,
78- }
79- } ;
80-
81- // The compiler's sysroot often has some bundled tools, so add it to the
82- // PATH for the child.
83- let mut new_path = sess. host_filesearch ( PathKind :: All )
84- . get_tools_search_paths ( ) ;
85- let mut msvc_changed_path = false ;
86- if sess. target . target . options . is_like_msvc {
87- if let Some ( ref tool) = msvc_tool {
88- cmd. args ( tool. args ( ) ) ;
89- for & ( ref k, ref v) in tool. env ( ) {
90- if k == "PATH" {
91- new_path. extend ( env:: split_paths ( v) ) ;
92- msvc_changed_path = true ;
93- } else {
94- cmd. env ( k, v) ;
95- }
96- }
97- }
98- }
99-
100- if !msvc_changed_path {
101- if let Some ( path) = env:: var_os ( "PATH" ) {
102- new_path. extend ( env:: split_paths ( & path) ) ;
103- }
104- }
105- cmd. env ( "PATH" , env:: join_paths ( new_path) . unwrap ( ) ) ;
106-
107- ( linker. to_path_buf ( ) , cmd)
108- }
109-
110- pub fn remove ( sess : & Session , path : & Path ) {
111- if let Err ( e) = fs:: remove_file ( path) {
112- sess. err ( & format ! ( "failed to remove {}: {}" ,
113- path. display( ) ,
114- e) ) ;
115- }
116- }
11754
11855/// Perform the linkage portion of the compilation phase. This will generate all
11956/// of the requested outputs for this compilation session.
@@ -215,60 +152,6 @@ fn preserve_objects_for_their_debuginfo(sess: &Session) -> bool {
215152 false
216153}
217154
218- pub ( crate ) fn each_linked_rlib ( sess : & Session ,
219- info : & CrateInfo ,
220- f : & mut dyn FnMut ( CrateNum , & Path ) ) -> Result < ( ) , String > {
221- let crates = info. used_crates_static . iter ( ) ;
222- let fmts = sess. dependency_formats . borrow ( ) ;
223- let fmts = fmts. get ( & config:: CrateType :: Executable )
224- . or_else ( || fmts. get ( & config:: CrateType :: Staticlib ) )
225- . or_else ( || fmts. get ( & config:: CrateType :: Cdylib ) )
226- . or_else ( || fmts. get ( & config:: CrateType :: ProcMacro ) ) ;
227- let fmts = match fmts {
228- Some ( f) => f,
229- None => return Err ( "could not find formats for rlibs" . to_string ( ) )
230- } ;
231- for & ( cnum, ref path) in crates {
232- match fmts. get ( cnum. as_usize ( ) - 1 ) {
233- Some ( & Linkage :: NotLinked ) |
234- Some ( & Linkage :: IncludedFromDylib ) => continue ,
235- Some ( _) => { }
236- None => return Err ( "could not find formats for rlibs" . to_string ( ) )
237- }
238- let name = & info. crate_name [ & cnum] ;
239- let path = match * path {
240- LibSource :: Some ( ref p) => p,
241- LibSource :: MetadataOnly => {
242- return Err ( format ! ( "could not find rlib for: `{}`, found rmeta (metadata) file" ,
243- name) )
244- }
245- LibSource :: None => {
246- return Err ( format ! ( "could not find rlib for: `{}`" , name) )
247- }
248- } ;
249- f ( cnum, & path) ;
250- }
251- Ok ( ( ) )
252- }
253-
254- /// Returns a boolean indicating whether the specified crate should be ignored
255- /// during LTO.
256- ///
257- /// Crates ignored during LTO are not lumped together in the "massive object
258- /// file" that we create and are linked in their normal rlib states. See
259- /// comments below for what crates do not participate in LTO.
260- ///
261- /// It's unusual for a crate to not participate in LTO. Typically only
262- /// compiler-specific and unstable crates have a reason to not participate in
263- /// LTO.
264- pub ( crate ) fn ignored_for_lto ( sess : & Session , info : & CrateInfo , cnum : CrateNum ) -> bool {
265- // If our target enables builtin function lowering in LLVM then the
266- // crates providing these functions don't participate in LTO (e.g.
267- // no_builtins or compiler builtins crates).
268- !sess. target . target . options . no_builtins &&
269- ( info. compiler_builtins == Some ( cnum) || info. is_no_builtins . contains ( & cnum) )
270- }
271-
272155fn link_binary_output ( sess : & Session ,
273156 codegen_results : & CodegenResults ,
274157 crate_type : config:: CrateType ,
@@ -353,8 +236,11 @@ fn archive_config<'a>(sess: &'a Session,
353236/// building an `.rlib` (stomping over one another), or writing an `.rmeta` into a
354237/// directory being searched for `extern crate` (observing an incomplete file).
355238/// The returned path is the temporary file containing the complete metadata.
356- fn emit_metadata < ' a > ( sess : & ' a Session , codegen_results : & CodegenResults , tmpdir : & TempDir )
357- -> PathBuf {
239+ fn emit_metadata < ' a > (
240+ sess : & ' a Session ,
241+ codegen_results : & CodegenResults ,
242+ tmpdir : & TempDir
243+ ) -> PathBuf {
358244 let out_filename = tmpdir. path ( ) . join ( METADATA_FILENAME ) ;
359245 let result = fs:: write ( & out_filename, & codegen_results. metadata . raw_data ) ;
360246
@@ -576,69 +462,6 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLibrary]) {
576462 }
577463}
578464
579- pub fn linker_and_flavor ( sess : & Session ) -> ( PathBuf , LinkerFlavor ) {
580- fn infer_from (
581- sess : & Session ,
582- linker : Option < PathBuf > ,
583- flavor : Option < LinkerFlavor > ,
584- ) -> Option < ( PathBuf , LinkerFlavor ) > {
585- match ( linker, flavor) {
586- ( Some ( linker) , Some ( flavor) ) => Some ( ( linker, flavor) ) ,
587- // only the linker flavor is known; use the default linker for the selected flavor
588- ( None , Some ( flavor) ) => Some ( ( PathBuf :: from ( match flavor {
589- LinkerFlavor :: Em => if cfg ! ( windows) { "emcc.bat" } else { "emcc" } ,
590- LinkerFlavor :: Gcc => "cc" ,
591- LinkerFlavor :: Ld => "ld" ,
592- LinkerFlavor :: Msvc => "link.exe" ,
593- LinkerFlavor :: Lld ( _) => "lld" ,
594- } ) , flavor) ) ,
595- ( Some ( linker) , None ) => {
596- let stem = linker. file_stem ( ) . and_then ( |stem| stem. to_str ( ) ) . unwrap_or_else ( || {
597- sess. fatal ( "couldn't extract file stem from specified linker" ) ;
598- } ) . to_owned ( ) ;
599-
600- let flavor = if stem == "emcc" {
601- LinkerFlavor :: Em
602- } else if stem == "gcc" || stem. ends_with ( "-gcc" ) {
603- LinkerFlavor :: Gcc
604- } else if stem == "ld" || stem == "ld.lld" || stem. ends_with ( "-ld" ) {
605- LinkerFlavor :: Ld
606- } else if stem == "link" || stem == "lld-link" {
607- LinkerFlavor :: Msvc
608- } else if stem == "lld" || stem == "rust-lld" {
609- LinkerFlavor :: Lld ( sess. target . target . options . lld_flavor )
610- } else {
611- // fall back to the value in the target spec
612- sess. target . target . linker_flavor
613- } ;
614-
615- Some ( ( linker, flavor) )
616- } ,
617- ( None , None ) => None ,
618- }
619- }
620-
621- // linker and linker flavor specified via command line have precedence over what the target
622- // specification specifies
623- if let Some ( ret) = infer_from (
624- sess,
625- sess. opts . cg . linker . clone ( ) ,
626- sess. opts . debugging_opts . linker_flavor ,
627- ) {
628- return ret;
629- }
630-
631- if let Some ( ret) = infer_from (
632- sess,
633- sess. target . target . options . linker . clone ( ) . map ( PathBuf :: from) ,
634- Some ( sess. target . target . linker_flavor ) ,
635- ) {
636- return ret;
637- }
638-
639- bug ! ( "Not enough information provided to determine how to invoke the linker" ) ;
640- }
641-
642465// Create a dynamic library or executable
643466//
644467// This will invoke the system linker/cc to create the resulting file. This
0 commit comments