2019-09-10 09:53:59 +03:00
|
|
|
use std::env;
|
2015-12-10 12:21:55 -08:00
|
|
|
|
2019-02-08 21:00:07 +09:00
|
|
|
use crate::spec::{LinkArgs, TargetOptions};
|
2014-07-23 11:56:36 -07:00
|
|
|
|
2020-10-08 20:54:45 +03:00
|
|
|
pub fn opts(os: &str) -> TargetOptions {
|
2017-03-12 14:13:35 -04:00
|
|
|
// ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
|
2015-12-10 12:21:55 -08:00
|
|
|
// either the linker will complain if it is used or the binary will end up
|
2017-03-12 14:13:35 -04:00
|
|
|
// segfaulting at runtime when run on 10.6. Rust by default supports macOS
|
2015-12-10 12:21:55 -08:00
|
|
|
// 10.7+, but there is a standard environment variable,
|
|
|
|
// MACOSX_DEPLOYMENT_TARGET, which is used to signal targeting older
|
2017-03-12 14:13:35 -04:00
|
|
|
// versions of macOS. For example compiling on 10.10 with
|
2015-12-10 12:21:55 -08:00
|
|
|
// MACOSX_DEPLOYMENT_TARGET set to 10.6 will cause the linker to generate
|
|
|
|
// warnings about the usage of ELF TLS.
|
|
|
|
//
|
|
|
|
// Here we detect what version is being requested, defaulting to 10.7. ELF
|
|
|
|
// TLS is flagged as enabled if it looks to be supported.
|
default to $ARCH-apple-macosx10.7.0 LLVM triple for darwin targets
Over in #60378, we made `rustc` switch LLVM target triples dynamically
based on the `MACOSX_DEPLOYMENT_TARGET` environment variable. This
change was made to align with `clang`'s behavior, and therefore make
cross-language LTO feasible on OS X. Otherwise, `rustc` would produce
LLVM bitcode files with a target triple of `x86_64-apple-darwin`,
`clang` would produce LLVM bitcode files with a target triple of
`x86_64-apple-macosx$VERSION`, and the linker would complain.
This change worked fine, except for one corner case: if you didn't have
`MACOSX_DEPLOYMENT_TARGET` set, and you wanted to do LTO on just Rust
code, you'd get warning messages similar to:
```
warning: Linking two modules of different target triples: ' is 'x86_64-apple-macosx10.7.0' whereas 'main.7rcbfp3g-cgu.4' is 'x86_64-apple-darwin'
```
This message occurs because libstd is compiled with
`MACOSX_DEPLOYMENT_TARGET` set to 10.7. The LLVM bitcode distributed in
libstd's rlibs, then, is tagged with the target triple of
`x86_64-apple-macosx10.7.0`, while the bitcode `rustc` produces for
"user" code is tagged with the target triple of `x86_64-apple-darwin`.
It's not good to have LTO on just Rust code (probably much more common
than cross-language LTO) warn by default. These warnings also break
Cargo's testsuite.
This change defaults to acting as though `MACOSX_DEPLOYMENT_TARGET` was
set to 10.7. "user" code will then be given a target triple that is
equivalent to the target triple libstd bitcode is already using. The
above warning will therefore go away.
`rustc` already assumes that compiling without
`MACOSX_DEPLOYMENT_TARGET` means that we're compiling for a target
compatible with OS X 10.7 (e.g. that things like TLS work properly). So
this change is really just making things conform more closely to the
status quo.
(It's also worth noting that before and after this patch, compiling with
`MACOSX_DEPLOYMENT_TARGET` set to, say, 10.9, works just fine: target
triples with an "apple" version ignore OS versions when checking
compatibility, so bitcode with a `x86_64-apple-macosx10.7.0` triple works just
fine with bitcode with a `x86_64-apple-macosx10.9.0` triple.)
2019-05-13 11:03:48 -04:00
|
|
|
let version = macos_deployment_target();
|
2015-12-10 12:21:55 -08:00
|
|
|
|
2014-07-23 11:56:36 -07:00
|
|
|
TargetOptions {
|
2020-10-08 20:54:45 +03:00
|
|
|
target_os: os.to_string(),
|
2020-10-08 22:10:13 +03:00
|
|
|
target_vendor: "apple".to_string(),
|
2017-03-12 14:13:35 -04:00
|
|
|
// macOS has -dead_strip, which doesn't rely on function_sections
|
2014-07-23 11:56:36 -07:00
|
|
|
function_sections: false,
|
|
|
|
dynamic_linking: true,
|
|
|
|
executables: true,
|
2016-12-22 22:20:47 -07:00
|
|
|
target_family: Some("unix".to_string()),
|
2014-07-23 11:56:36 -07:00
|
|
|
is_like_osx: true,
|
2020-10-09 15:08:18 -04:00
|
|
|
dwarf_version: Some(2),
|
2014-07-23 11:56:36 -07:00
|
|
|
has_rpath: true,
|
|
|
|
dll_prefix: "lib".to_string(),
|
|
|
|
dll_suffix: ".dylib".to_string(),
|
2020-02-12 12:06:14 +01:00
|
|
|
archive_format: "darwin".to_string(),
|
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
2017-02-21 14:47:15 -05:00
|
|
|
pre_link_args: LinkArgs::new(),
|
2015-12-10 12:21:55 -08:00
|
|
|
has_elf_tls: version >= (10, 7),
|
2018-02-26 10:20:14 -08:00
|
|
|
abi_return_struct_as_int: true,
|
2018-04-06 15:44:08 +02:00
|
|
|
emit_debug_gdb_scripts: false,
|
2020-07-22 15:49:04 +03:00
|
|
|
eh_frame_header: false,
|
2020-05-05 14:25:58 -07:00
|
|
|
|
|
|
|
// This environment variable is pretty magical but is intended for
|
|
|
|
// producing deterministic builds. This was first discovered to be used
|
|
|
|
// by the `ar` tool as a way to control whether or not mtime entries in
|
|
|
|
// the archive headers were set to zero or not. It appears that
|
|
|
|
// eventually the linker got updated to do the same thing and now reads
|
|
|
|
// this environment variable too in recent versions.
|
|
|
|
//
|
|
|
|
// For some more info see the commentary on #47086
|
|
|
|
link_env: vec![("ZERO_AR_DATE".to_string(), "1".to_string())],
|
|
|
|
|
2019-12-22 17:42:04 -05:00
|
|
|
..Default::default()
|
2014-07-23 11:56:36 -07:00
|
|
|
}
|
|
|
|
}
|
2019-04-25 16:04:37 -04:00
|
|
|
|
default to $ARCH-apple-macosx10.7.0 LLVM triple for darwin targets
Over in #60378, we made `rustc` switch LLVM target triples dynamically
based on the `MACOSX_DEPLOYMENT_TARGET` environment variable. This
change was made to align with `clang`'s behavior, and therefore make
cross-language LTO feasible on OS X. Otherwise, `rustc` would produce
LLVM bitcode files with a target triple of `x86_64-apple-darwin`,
`clang` would produce LLVM bitcode files with a target triple of
`x86_64-apple-macosx$VERSION`, and the linker would complain.
This change worked fine, except for one corner case: if you didn't have
`MACOSX_DEPLOYMENT_TARGET` set, and you wanted to do LTO on just Rust
code, you'd get warning messages similar to:
```
warning: Linking two modules of different target triples: ' is 'x86_64-apple-macosx10.7.0' whereas 'main.7rcbfp3g-cgu.4' is 'x86_64-apple-darwin'
```
This message occurs because libstd is compiled with
`MACOSX_DEPLOYMENT_TARGET` set to 10.7. The LLVM bitcode distributed in
libstd's rlibs, then, is tagged with the target triple of
`x86_64-apple-macosx10.7.0`, while the bitcode `rustc` produces for
"user" code is tagged with the target triple of `x86_64-apple-darwin`.
It's not good to have LTO on just Rust code (probably much more common
than cross-language LTO) warn by default. These warnings also break
Cargo's testsuite.
This change defaults to acting as though `MACOSX_DEPLOYMENT_TARGET` was
set to 10.7. "user" code will then be given a target triple that is
equivalent to the target triple libstd bitcode is already using. The
above warning will therefore go away.
`rustc` already assumes that compiling without
`MACOSX_DEPLOYMENT_TARGET` means that we're compiling for a target
compatible with OS X 10.7 (e.g. that things like TLS work properly). So
this change is really just making things conform more closely to the
status quo.
(It's also worth noting that before and after this patch, compiling with
`MACOSX_DEPLOYMENT_TARGET` set to, say, 10.9, works just fine: target
triples with an "apple" version ignore OS versions when checking
compatibility, so bitcode with a `x86_64-apple-macosx10.7.0` triple works just
fine with bitcode with a `x86_64-apple-macosx10.9.0` triple.)
2019-05-13 11:03:48 -04:00
|
|
|
fn macos_deployment_target() -> (u32, u32) {
|
2019-04-25 16:04:37 -04:00
|
|
|
let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok();
|
2019-12-22 17:42:04 -05:00
|
|
|
let version = deployment_target
|
|
|
|
.as_ref()
|
|
|
|
.and_then(|s| {
|
|
|
|
let mut i = s.splitn(2, '.');
|
|
|
|
i.next().and_then(|a| i.next().map(|b| (a, b)))
|
|
|
|
})
|
|
|
|
.and_then(|(a, b)| a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok());
|
2019-04-25 16:04:37 -04:00
|
|
|
|
default to $ARCH-apple-macosx10.7.0 LLVM triple for darwin targets
Over in #60378, we made `rustc` switch LLVM target triples dynamically
based on the `MACOSX_DEPLOYMENT_TARGET` environment variable. This
change was made to align with `clang`'s behavior, and therefore make
cross-language LTO feasible on OS X. Otherwise, `rustc` would produce
LLVM bitcode files with a target triple of `x86_64-apple-darwin`,
`clang` would produce LLVM bitcode files with a target triple of
`x86_64-apple-macosx$VERSION`, and the linker would complain.
This change worked fine, except for one corner case: if you didn't have
`MACOSX_DEPLOYMENT_TARGET` set, and you wanted to do LTO on just Rust
code, you'd get warning messages similar to:
```
warning: Linking two modules of different target triples: ' is 'x86_64-apple-macosx10.7.0' whereas 'main.7rcbfp3g-cgu.4' is 'x86_64-apple-darwin'
```
This message occurs because libstd is compiled with
`MACOSX_DEPLOYMENT_TARGET` set to 10.7. The LLVM bitcode distributed in
libstd's rlibs, then, is tagged with the target triple of
`x86_64-apple-macosx10.7.0`, while the bitcode `rustc` produces for
"user" code is tagged with the target triple of `x86_64-apple-darwin`.
It's not good to have LTO on just Rust code (probably much more common
than cross-language LTO) warn by default. These warnings also break
Cargo's testsuite.
This change defaults to acting as though `MACOSX_DEPLOYMENT_TARGET` was
set to 10.7. "user" code will then be given a target triple that is
equivalent to the target triple libstd bitcode is already using. The
above warning will therefore go away.
`rustc` already assumes that compiling without
`MACOSX_DEPLOYMENT_TARGET` means that we're compiling for a target
compatible with OS X 10.7 (e.g. that things like TLS work properly). So
this change is really just making things conform more closely to the
status quo.
(It's also worth noting that before and after this patch, compiling with
`MACOSX_DEPLOYMENT_TARGET` set to, say, 10.9, works just fine: target
triples with an "apple" version ignore OS versions when checking
compatibility, so bitcode with a `x86_64-apple-macosx10.7.0` triple works just
fine with bitcode with a `x86_64-apple-macosx10.9.0` triple.)
2019-05-13 11:03:48 -04:00
|
|
|
version.unwrap_or((10, 7))
|
2019-04-25 16:04:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn macos_llvm_target(arch: &str) -> String {
|
default to $ARCH-apple-macosx10.7.0 LLVM triple for darwin targets
Over in #60378, we made `rustc` switch LLVM target triples dynamically
based on the `MACOSX_DEPLOYMENT_TARGET` environment variable. This
change was made to align with `clang`'s behavior, and therefore make
cross-language LTO feasible on OS X. Otherwise, `rustc` would produce
LLVM bitcode files with a target triple of `x86_64-apple-darwin`,
`clang` would produce LLVM bitcode files with a target triple of
`x86_64-apple-macosx$VERSION`, and the linker would complain.
This change worked fine, except for one corner case: if you didn't have
`MACOSX_DEPLOYMENT_TARGET` set, and you wanted to do LTO on just Rust
code, you'd get warning messages similar to:
```
warning: Linking two modules of different target triples: ' is 'x86_64-apple-macosx10.7.0' whereas 'main.7rcbfp3g-cgu.4' is 'x86_64-apple-darwin'
```
This message occurs because libstd is compiled with
`MACOSX_DEPLOYMENT_TARGET` set to 10.7. The LLVM bitcode distributed in
libstd's rlibs, then, is tagged with the target triple of
`x86_64-apple-macosx10.7.0`, while the bitcode `rustc` produces for
"user" code is tagged with the target triple of `x86_64-apple-darwin`.
It's not good to have LTO on just Rust code (probably much more common
than cross-language LTO) warn by default. These warnings also break
Cargo's testsuite.
This change defaults to acting as though `MACOSX_DEPLOYMENT_TARGET` was
set to 10.7. "user" code will then be given a target triple that is
equivalent to the target triple libstd bitcode is already using. The
above warning will therefore go away.
`rustc` already assumes that compiling without
`MACOSX_DEPLOYMENT_TARGET` means that we're compiling for a target
compatible with OS X 10.7 (e.g. that things like TLS work properly). So
this change is really just making things conform more closely to the
status quo.
(It's also worth noting that before and after this patch, compiling with
`MACOSX_DEPLOYMENT_TARGET` set to, say, 10.9, works just fine: target
triples with an "apple" version ignore OS versions when checking
compatibility, so bitcode with a `x86_64-apple-macosx10.7.0` triple works just
fine with bitcode with a `x86_64-apple-macosx10.9.0` triple.)
2019-05-13 11:03:48 -04:00
|
|
|
let (major, minor) = macos_deployment_target();
|
|
|
|
format!("{}-apple-macosx{}.{}.0", arch, major, minor)
|
2019-04-25 16:04:37 -04:00
|
|
|
}
|
2019-09-07 17:18:10 +03:00
|
|
|
|
2019-09-12 13:47:17 +03:00
|
|
|
pub fn macos_link_env_remove() -> Vec<String> {
|
|
|
|
let mut env_remove = Vec::with_capacity(2);
|
|
|
|
// Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
|
2019-09-10 09:53:59 +03:00
|
|
|
// may occur when we're linking a custom build script while targeting iOS for example.
|
2020-03-21 12:50:22 +01:00
|
|
|
if let Ok(sdkroot) = env::var("SDKROOT") {
|
2019-09-10 09:53:59 +03:00
|
|
|
if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform") {
|
2019-09-12 13:47:17 +03:00
|
|
|
env_remove.push("SDKROOT".to_string())
|
2019-09-07 17:18:10 +03:00
|
|
|
}
|
|
|
|
}
|
2019-09-10 09:53:59 +03:00
|
|
|
// Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
|
|
|
|
// "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
|
|
|
|
// although this is apparently ignored when using the linker at "/usr/bin/ld".
|
2019-09-12 13:47:17 +03:00
|
|
|
env_remove.push("IPHONEOS_DEPLOYMENT_TARGET".to_string());
|
|
|
|
env_remove
|
2019-09-07 17:18:10 +03:00
|
|
|
}
|