]>
git.proxmox.com Git - rustc.git/blob - compiler/rustc_codegen_cranelift/src/toolchain.rs
1 //! Locating various executables part of a C toolchain.
3 use std
::path
::PathBuf
;
6 use rustc_session
::Session
;
7 use rustc_target
::spec
::LinkerFlavor
;
9 /// Tries to infer the path of a binary for the target toolchain from the linker name.
10 pub(crate) fn get_toolchain_binary(sess
: &Session
, tool
: &str) -> PathBuf
{
11 let (mut linker
, _linker_flavor
) = linker_and_flavor(sess
);
12 let linker_file_name
= linker
14 .and_then(|name
| name
.to_str())
15 .unwrap_or_else(|| sess
.fatal("couldn't extract file name from specified linker"));
17 if linker_file_name
== "ld.lld" {
19 linker
.set_file_name(tool
)
22 let tool_file_name
= linker_file_name
25 .replace("clang", tool
)
28 linker
.set_file_name(tool_file_name
)
34 // Adapted from https://github.com/rust-lang/rust/blob/5db778affee7c6600c8e7a177c48282dab3f6292/src/librustc_codegen_ssa/back/link.rs#L848-L931
35 fn linker_and_flavor(sess
: &Session
) -> (PathBuf
, LinkerFlavor
) {
38 linker
: Option
<PathBuf
>,
39 flavor
: Option
<LinkerFlavor
>,
40 ) -> Option
<(PathBuf
, LinkerFlavor
)> {
41 match (linker
, flavor
) {
42 (Some(linker
), Some(flavor
)) => Some((linker
, flavor
)),
43 // only the linker flavor is known; use the default linker for the selected flavor
44 (None
, Some(flavor
)) => Some((
45 PathBuf
::from(match flavor
{
53 LinkerFlavor
::Gcc
=> {
54 if cfg
!(any(target_os
= "solaris", target_os
= "illumos")) {
55 // On historical Solaris systems, "cc" may have
56 // been Sun Studio, which is not flag-compatible
57 // with "gcc". This history casts a long shadow,
58 // and many modern illumos distributions today
59 // ship GCC as "gcc" without also making it
66 LinkerFlavor
::Ld
=> "ld",
67 LinkerFlavor
::Msvc
=> "link.exe",
68 LinkerFlavor
::Lld(_
) => "lld",
69 LinkerFlavor
::PtxLinker
=> "rust-ptx-linker",
73 (Some(linker
), None
) => {
74 let stem
= linker
.file_stem().and_then(|stem
| stem
.to_str()).unwrap_or_else(|| {
75 sess
.fatal("couldn't extract file stem from specified linker")
78 let flavor
= if stem
== "emcc" {
80 } else if stem
== "gcc"
81 || stem
.ends_with("-gcc")
83 || stem
.ends_with("-clang")
86 } else if stem
== "ld" || stem
== "ld.lld" || stem
.ends_with("-ld") {
88 } else if stem
== "link" || stem
== "lld-link" {
90 } else if stem
== "lld" || stem
== "rust-lld" {
91 LinkerFlavor
::Lld(sess
.target
.lld_flavor
)
93 // fall back to the value in the target spec
94 sess
.target
.linker_flavor
97 Some((linker
, flavor
))
103 // linker and linker flavor specified via command line have precedence over what the target
104 // specification specifies
105 if let Some(ret
) = infer_from(sess
, sess
.opts
.cg
.linker
.clone(), sess
.opts
.cg
.linker_flavor
) {
109 if let Some(ret
) = infer_from(
111 sess
.target
.linker
.clone().map(PathBuf
::from
),
112 Some(sess
.target
.linker_flavor
),
117 bug
!("Not enough information provided to determine how to invoke the linker");