1- use std:: { env, fs , iter , path:: { Path , PathBuf } , process:: Command } ;
1+ use std:: { env:: { self , consts :: EXE_SUFFIX } , path:: PathBuf , process:: Command } ;
22
33use anyhow:: { Context , Result , ensure} ;
4- use yazi_macro:: ok_or_not_found;
54
6- use super :: { cargo, is_linux_target, is_sparc64_target, is_windows_target, run, workspace_root } ;
5+ use super :: { cargo, is_linux_target, is_sparc64_target, is_windows_target, run} ;
76
87pub ( super ) struct Build {
98 pub ( super ) target : String ,
@@ -25,18 +24,21 @@ impl Build {
2524 cmd
2625 . env ( "RUSTC_BOOTSTRAP" , "1" )
2726 . env ( "CARGO_TARGET_DIR" , "target" )
28- . args ( [ "-Z" , "trim-paths" , "- -config", ".cargo/release.toml" , "build" , "--locked" ] )
27+ . args ( [ "--config" , ".cargo/release.toml" , "build" , "--locked" ] )
2928 . args ( [ "--profile" , self . profile ( ) ] ) ;
3029
3130 if !self . target . is_empty ( ) {
3231 cmd. arg ( "--target" ) . arg ( & self . target ) ;
3332 }
33+ if is_linux_target ( & self . target ) && !is_sparc64_target ( & self . target ) && Self :: has_rust_lld ( ) ? {
34+ cmd. args ( [
35+ "--config" ,
36+ r#"target.'cfg(target_os = "linux")'.rustflags=["-Clink-self-contained=+linker"]"# ,
37+ ] ) ;
38+ }
3439 if self . completions {
3540 cmd. env ( "YAZI_GEN_COMPLETIONS" , "1" ) ;
3641 }
37- if is_linux_target ( & self . target ) && !is_sparc64_target ( & self . target ) {
38- self . expose_lld ( & mut cmd) ?;
39- }
4042
4143 run ( & mut cmd) . context ( "failed to build Yazi" )
4244 }
@@ -45,53 +47,23 @@ impl Build {
4547 if is_windows_target ( & self . target ) { "release-windows" } else { "release" }
4648 }
4749
48- fn expose_lld ( & self , cmd : & mut Command ) -> Result < ( ) > {
49- let rust_lld = Self :: rustc_libdir ( ) ?
50- . parent ( )
51- . context ( "Rust target libdir has no parent" ) ?
52- . join ( "bin/rust-lld" ) ;
53- ensure ! ( rust_lld. is_file( ) , "{} does not exist" , rust_lld. display( ) ) ;
54-
55- let temp_dir = workspace_root ( ) ?. join ( "target/.rust-lld" ) ;
56- fs:: create_dir_all ( & temp_dir) . context ( "failed to create `target/.rust-lld` directory" ) ?;
57- for name in [ "ld.lld" . to_owned ( ) ] . into_iter ( ) . chain ( self . lld_alias ( ) ) {
58- let link = temp_dir. join ( name) ;
59- ok_or_not_found ! ( fs:: remove_file( & link) ) ;
60- #[ cfg( unix) ]
61- std:: os:: unix:: fs:: symlink ( & rust_lld, link) ?;
62- #[ cfg( not( unix) ) ]
63- anyhow:: bail!( "bundled rust-lld setup requires a Unix host" ) ;
64- }
65-
66- let path = env:: var_os ( "PATH" ) . unwrap_or_default ( ) ;
67- cmd. env ( "PATH" , env:: join_paths ( iter:: once ( temp_dir) . chain ( env:: split_paths ( & path) ) ) ?) ;
68- Ok ( ( ) )
69- }
70-
71- fn rustc_libdir ( ) -> Result < PathBuf > {
50+ fn has_rust_lld ( ) -> Result < bool > {
7251 let output = Command :: new ( env:: var_os ( "RUSTC" ) . unwrap_or_else ( || "rustc" . into ( ) ) )
7352 . args ( [ "--print" , "target-libdir" ] )
7453 . output ( )
7554 . context ( "failed to locate the Rust target libdir" ) ?;
76-
7755 ensure ! ( output. status. success( ) , "`rustc --print target-libdir` failed" ) ;
78- Ok ( String :: from_utf8 ( output. stdout ) ?. trim ( ) . into ( ) )
79- }
8056
81- // Cross GCC resolves `-fuse-ld=lld` as `<toolchain-prefix>ld.lld`.
82- // For example:
83- // `aarch64-linux-musl-gcc.sh` => `aarch64-linux-musl-ld.lld`
84- // if Cargo has no configured linker:
85- // `CROSS_TOOLCHAIN_PREFIX=x86_64-linux-musl-` => `x86_64-linux-musl-ld.lld`
86- fn lld_alias ( & self ) -> Option < String > {
87- let var = env:: var_os ( format ! (
88- "CARGO_TARGET_{}_LINKER" ,
89- self . target. replace( '-' , "_" ) . to_ascii_uppercase( )
90- ) )
91- . or_else ( || env:: var_os ( "CROSS_TOOLCHAIN_PREFIX" ) ) ?;
92-
93- let prefix = Path :: new ( & var) . file_stem ( ) ?. to_str ( ) ?. trim_end_matches ( "gcc" ) ;
57+ let libdir: PathBuf = String :: from_utf8 ( output. stdout )
58+ . context ( "rustc returned an invalid target libdir" ) ?
59+ . trim ( )
60+ . into ( ) ;
61+ let rust_lld = libdir
62+ . parent ( )
63+ . context ( "Rust target libdir has no parent" ) ?
64+ . join ( "bin" )
65+ . join ( format ! ( "rust-lld{EXE_SUFFIX}" ) ) ;
9466
95- Some ( format ! ( "{prefix}ld.lld" ) )
67+ Ok ( rust_lld . is_file ( ) )
9668 }
9769}
0 commit comments