Skip to content

Commit a665be5

Browse files
committed
Use the linker directly on darwin,ios
Some logic to deal with macOS < 10.8 cribbed from: https://github.com/llvm-mirror/clang/blob/64309d1/lib/Driver/ToolChains/Darwin.cpp#L1910 Updates rust-lang#11937.
1 parent 4b59497 commit a665be5

11 files changed

+72
-49
lines changed

src/librustc_back/target/aarch64_apple_ios.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
2424
target_os: "ios".to_string(),
2525
target_env: "".to_string(),
2626
target_vendor: "apple".to_string(),
27-
linker_flavor: LinkerFlavor::Gcc,
27+
linker_flavor: LinkerFlavor::Ld,
2828
options: TargetOptions {
2929
features: "+neon,+fp-armv8,+cyclone".to_string(),
3030
eliminate_frame_pointer: false,

src/librustc_back/target/apple_base.rs

+40-9
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,43 @@
99
// except according to those terms.
1010

1111
use std::env;
12+
use std::io;
13+
use std::process::Command;
14+
use std::str;
1215

13-
use target::{LinkArgs, TargetOptions};
16+
use target::TargetOptions;
17+
18+
pub fn xcrun(print_arg: &str, sdk_name: &str) -> io::Result<String> {
19+
Command::new("xcrun").arg(print_arg).arg("--sdk").arg(sdk_name).output().and_then(|output| {
20+
if output.status.success() {
21+
Ok(str::from_utf8(&output.stdout[..]).unwrap().trim().to_string())
22+
} else {
23+
let error = format!(
24+
"process exit with error: {}",
25+
str::from_utf8(&output.stderr[..]).unwrap(),
26+
);
27+
Err(io::Error::new(io::ErrorKind::Other, &error[..]))
28+
}
29+
})
30+
}
31+
32+
pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> {
33+
xcrun("--show-sdk-path", sdk_name).map_err(|e| {
34+
format!("failed to get {} SDK path: {}", sdk_name, e)
35+
})
36+
}
37+
38+
pub fn get_sdk_version(sdk_name: &str) -> Result<String, String> {
39+
xcrun("--show-sdk-version", sdk_name).map_err(|e| {
40+
format!("failed to get {} SDK version: {}", sdk_name, e)
41+
})
42+
}
43+
44+
pub fn get_deployment_target() -> String {
45+
env::var("MACOSX_DEPLOYMENT_TARGET").or_else(|_e| {
46+
get_sdk_version("macosx")
47+
}).unwrap()
48+
}
1449

1550
pub fn opts() -> TargetOptions {
1651
// ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
@@ -24,13 +59,9 @@ pub fn opts() -> TargetOptions {
2459
//
2560
// Here we detect what version is being requested, defaulting to 10.7. ELF
2661
// TLS is flagged as enabled if it looks to be supported.
27-
let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok();
28-
let version = deployment_target.as_ref().and_then(|s| {
29-
let mut i = s.splitn(2, ".");
30-
i.next().and_then(|a| i.next().map(|b| (a, b)))
31-
}).and_then(|(a, b)| {
32-
a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok()
33-
}).unwrap_or((10, 7));
62+
let deployment_target = get_deployment_target();
63+
let mut i = deployment_target.splitn(2, '.').map(|s| s.parse::<u32>().unwrap());
64+
let version = (i.next().unwrap(), i.next().unwrap());
3465

3566
TargetOptions {
3667
// macOS has -dead_strip, which doesn't rely on function_sections
@@ -43,9 +74,9 @@ pub fn opts() -> TargetOptions {
4374
dll_prefix: "lib".to_string(),
4475
dll_suffix: ".dylib".to_string(),
4576
archive_format: "bsd".to_string(),
46-
pre_link_args: LinkArgs::new(),
4777
exe_allocation_crate: super::maybe_jemalloc(),
4878
has_elf_tls: version >= (10, 7),
79+
linker: "ld".to_string(),
4980
.. Default::default()
5081
}
5182
}

src/librustc_back/target/apple_ios_base.rs

+3-29
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
// except according to those terms.
1010

1111
use LinkerFlavor;
12-
use std::io;
13-
use std::process::Command;
1412
use target::{LinkArgs, TargetOptions};
1513

1614
use self::Arch::*;
@@ -37,30 +35,6 @@ impl Arch {
3735
}
3836
}
3937

40-
pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> {
41-
let res = Command::new("xcrun")
42-
.arg("--show-sdk-path")
43-
.arg("-sdk")
44-
.arg(sdk_name)
45-
.output()
46-
.and_then(|output| {
47-
if output.status.success() {
48-
Ok(String::from_utf8(output.stdout).unwrap())
49-
} else {
50-
let error = String::from_utf8(output.stderr);
51-
let error = format!("process exit with error: {}",
52-
error.unwrap());
53-
Err(io::Error::new(io::ErrorKind::Other,
54-
&error[..]))
55-
}
56-
});
57-
58-
match res {
59-
Ok(output) => Ok(output.trim().to_string()),
60-
Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e))
61-
}
62-
}
63-
6438
fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> {
6539
let sdk_name = match arch {
6640
Armv7 | Armv7s | Arm64 => "iphoneos",
@@ -69,13 +43,13 @@ fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> {
6943

7044
let arch_name = arch.to_string();
7145

72-
let sdk_root = get_sdk_root(sdk_name)?;
46+
let sdk_root = super::apple_base::get_sdk_root(sdk_name)?;
7347

7448
let mut args = LinkArgs::new();
75-
args.insert(LinkerFlavor::Gcc,
49+
args.insert(LinkerFlavor::Ld,
7650
vec!["-arch".to_string(),
7751
arch_name.to_string(),
78-
"-Wl,-syslibroot".to_string(),
52+
"-syslibroot".to_string(),
7953
sdk_root]);
8054

8155
Ok(args)

src/librustc_back/target/armv7_apple_ios.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
2424
target_os: "ios".to_string(),
2525
target_env: "".to_string(),
2626
target_vendor: "apple".to_string(),
27-
linker_flavor: LinkerFlavor::Gcc,
27+
linker_flavor: LinkerFlavor::Ld,
2828
options: TargetOptions {
2929
features: "+v7,+vfp3,+neon".to_string(),
3030
max_atomic_width: Some(64),

src/librustc_back/target/armv7s_apple_ios.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
2424
target_os: "ios".to_string(),
2525
target_env: "".to_string(),
2626
target_vendor: "apple".to_string(),
27-
linker_flavor: LinkerFlavor::Gcc,
27+
linker_flavor: LinkerFlavor::Ld,
2828
options: TargetOptions {
2929
features: "+v7,+vfp4,+neon".to_string(),
3030
max_atomic_width: Some(64),

src/librustc_back/target/i386_apple_ios.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
2424
target_os: "ios".to_string(),
2525
target_env: "".to_string(),
2626
target_vendor: "apple".to_string(),
27-
linker_flavor: LinkerFlavor::Gcc,
27+
linker_flavor: LinkerFlavor::Ld,
2828
options: TargetOptions {
2929
max_atomic_width: Some(64),
3030
stack_probes: true,

src/librustc_back/target/i686_apple_darwin.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ pub fn target() -> TargetResult {
1515
let mut base = super::apple_base::opts();
1616
base.cpu = "yonah".to_string();
1717
base.max_atomic_width = Some(64);
18-
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
1918
base.stack_probes = true;
2019

2120
Ok(Target {
@@ -28,7 +27,7 @@ pub fn target() -> TargetResult {
2827
target_os: "macos".to_string(),
2928
target_env: "".to_string(),
3029
target_vendor: "apple".to_string(),
31-
linker_flavor: LinkerFlavor::Gcc,
30+
linker_flavor: LinkerFlavor::Ld,
3231
options: base,
3332
})
3433
}

src/librustc_back/target/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use syntax::abi::{Abi, lookup as lookup_abi};
5353
use {LinkerFlavor, PanicStrategy, RelroLevel};
5454

5555
mod android_base;
56-
mod apple_base;
56+
pub mod apple_base;
5757
mod apple_ios_base;
5858
mod arm_base;
5959
mod bitrig_base;

src/librustc_back/target/x86_64_apple_darwin.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ pub fn target() -> TargetResult {
1616
base.cpu = "core2".to_string();
1717
base.max_atomic_width = Some(128); // core2 support cmpxchg16b
1818
base.eliminate_frame_pointer = false;
19-
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
2019
base.stack_probes = true;
2120

2221
Ok(Target {
@@ -29,7 +28,7 @@ pub fn target() -> TargetResult {
2928
target_os: "macos".to_string(),
3029
target_env: "".to_string(),
3130
target_vendor: "apple".to_string(),
32-
linker_flavor: LinkerFlavor::Gcc,
31+
linker_flavor: LinkerFlavor::Ld,
3332
options: base,
3433
})
3534
}

src/librustc_back/target/x86_64_apple_ios.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
2424
target_os: "ios".to_string(),
2525
target_env: "".to_string(),
2626
target_vendor: "apple".to_string(),
27-
linker_flavor: LinkerFlavor::Gcc,
27+
linker_flavor: LinkerFlavor::Ld,
2828
options: TargetOptions {
2929
max_atomic_width: Some(64),
3030
stack_probes: true,

src/librustc_trans/back/linker.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc::middle::dependency_format::Linkage;
2323
use rustc::session::Session;
2424
use rustc::session::config::{self, CrateType, OptLevel, DebugInfoLevel};
2525
use rustc::ty::TyCtxt;
26-
use rustc_back::LinkerFlavor;
26+
use rustc_back::{LinkerFlavor, target};
2727
use serialize::{json, Encoder};
2828

2929
/// For all the linkers we support, and information they might
@@ -66,6 +66,7 @@ impl LinkerInfo {
6666
info: self,
6767
hinted_static: false,
6868
is_ld: false,
69+
building_executable: true,
6970
}) as Box<Linker>
7071
}
7172
LinkerFlavor::Ld => {
@@ -75,6 +76,7 @@ impl LinkerInfo {
7576
info: self,
7677
hinted_static: false,
7778
is_ld: true,
79+
building_executable: true,
7880
}) as Box<Linker>
7981
}
8082
LinkerFlavor::Binaryen => {
@@ -126,6 +128,8 @@ pub struct GccLinker<'a> {
126128
hinted_static: bool, // Keeps track of the current hinting mode.
127129
// Link as ld
128130
is_ld: bool,
131+
// Keeps track of product being an executable.
132+
building_executable: bool,
129133
}
130134

131135
impl<'a> GccLinker<'a> {
@@ -286,6 +290,8 @@ impl<'a> Linker for GccLinker<'a> {
286290
}
287291

288292
fn build_dylib(&mut self, out_filename: &Path) {
293+
self.building_executable = false;
294+
289295
// On mac we need to tell the linker to let this library be rpathed
290296
if self.sess.target.target.options.is_like_osx {
291297
self.linker_arg("-dylib");
@@ -371,6 +377,20 @@ impl<'a> Linker for GccLinker<'a> {
371377
}
372378

373379
fn finalize(&mut self) -> Command {
380+
if self.sess.target.target.options.is_like_osx && self.is_ld {
381+
self.cmd.arg("-macosx_version_min");
382+
let deployment_target = target::apple_base::get_deployment_target();
383+
self.cmd.arg(&deployment_target);
384+
385+
if self.building_executable {
386+
let mut i = deployment_target.splitn(2, '.').map(|s| s.parse::<u32>().unwrap());
387+
let version = (i.next().unwrap(), i.next().unwrap());
388+
if version < (10, 8) {
389+
self.cmd.arg("-lcrt1.10.6.o");
390+
}
391+
}
392+
}
393+
374394
self.hint_dynamic(); // Reset to default before returning the composed command line.
375395
let mut cmd = Command::new("");
376396
::std::mem::swap(&mut cmd, &mut self.cmd);

0 commit comments

Comments
 (0)