|
1 |
| -use std::{env, io, path::Path, process::Command}; |
| 1 | +use std::{env, path::Path}; |
2 | 2 |
|
3 | 3 | use crate::spec::{LinkArgs, TargetOptions};
|
4 | 4 |
|
@@ -52,43 +52,60 @@ pub fn macos_llvm_target(arch: &str) -> String {
|
52 | 52 | format!("{}-apple-macosx{}.{}.0", arch, major, minor)
|
53 | 53 | }
|
54 | 54 |
|
55 |
| -pub fn sysroot(sdk: &str) -> Result<String, String> { |
56 |
| - let actual_sdk_path = sdk_path(sdk)?; |
| 55 | +#[cfg(target_os = "macos")] |
| 56 | +pub fn sysroot(sdk: &str) -> Result<Option<String>, String> { |
57 | 57 | // Like Clang, allow the `SDKROOT` environment variable used by Xcode to define the sysroot.
|
58 | 58 | if let Some(sdk_root) = env::var("SDKROOT").ok() {
|
| 59 | + let actual_sdk_path = sdk_path(sdk)?; |
59 | 60 | let sdk_root_p = Path::new(&sdk_root);
|
60 | 61 | // Ignore `SDKROOT` if it's not a valid path.
|
61 | 62 | if !sdk_root_p.is_absolute() || sdk_root_p == Path::new("/") || !sdk_root_p.exists() {
|
62 |
| - return Ok(actual_sdk_path); |
| 63 | + return Ok(Some(actual_sdk_path)); |
63 | 64 | }
|
64 | 65 | // Ignore `SDKROOT` if it's clearly set for the wrong platform, which may occur when we're
|
65 | 66 | // compiling a custom build script while targeting iOS for example.
|
66 |
| - return Ok(match sdk { |
| 67 | + return Ok(Some(match sdk { |
67 | 68 | "iphoneos" if sdk_root.contains("iPhoneSimulator.platform")
|
68 | 69 | || sdk_root.contains("MacOSX.platform") => actual_sdk_path,
|
69 | 70 | "iphonesimulator" if sdk_root.contains("iPhoneOS.platform")
|
70 | 71 | || sdk_root.contains("MacOSX.platform") => actual_sdk_path,
|
71 | 72 | "macosx" | "macosx10.15" if sdk_root.contains("iPhoneOS.platform")
|
72 | 73 | || sdk_root.contains("iPhoneSimulator.platform") => actual_sdk_path,
|
73 | 74 | _ => sdk_root,
|
74 |
| - }) |
| 75 | + })) |
75 | 76 | }
|
76 |
| - Ok(actual_sdk_path) |
| 77 | + Ok(None) |
77 | 78 | }
|
78 | 79 |
|
| 80 | +// `xcrun` is only available on macOS. |
| 81 | +#[cfg(not(target_os = "macos"))] |
| 82 | +pub fn sysroot(_sdk: &str) -> Result<Option<String>, String> { |
| 83 | + if let Some(sdk_root) = env::var("SDKROOT").ok() { |
| 84 | + let sdk_root_p = Path::new(&sdk_root); |
| 85 | + // Use `SDKROOT` only if it's a valid path. |
| 86 | + if sdk_root_p.is_absolute() && sdk_root_p != Path::new("/") && sdk_root_p.exists() { |
| 87 | + return Ok(Some(sdk_root)); |
| 88 | + } |
| 89 | + } |
| 90 | + Ok(None) |
| 91 | +} |
| 92 | + |
| 93 | +#[cfg(target_os = "macos")] |
79 | 94 | fn sdk_path(sdk_name: &str) -> Result<String, String> {
|
80 |
| - let res = |
81 |
| - Command::new("xcrun").arg("--show-sdk-path").arg("-sdk").arg(sdk_name).output().and_then( |
82 |
| - |output| { |
83 |
| - if output.status.success() { |
84 |
| - Ok(String::from_utf8(output.stdout).unwrap()) |
85 |
| - } else { |
86 |
| - let error = String::from_utf8(output.stderr); |
87 |
| - let error = format!("process exit with error: {}", error.unwrap()); |
88 |
| - Err(io::Error::new(io::ErrorKind::Other, &error[..])) |
89 |
| - } |
90 |
| - }, |
91 |
| - ); |
| 95 | + let res = std::process::Command::new("xcrun") |
| 96 | + .arg("--show-sdk-path") |
| 97 | + .arg("-sdk") |
| 98 | + .arg(sdk_name) |
| 99 | + .output() |
| 100 | + .and_then(|output| { |
| 101 | + if output.status.success() { |
| 102 | + Ok(String::from_utf8(output.stdout).unwrap()) |
| 103 | + } else { |
| 104 | + let error = String::from_utf8(output.stderr); |
| 105 | + let error = format!("process exit with error: {}", error.unwrap()); |
| 106 | + Err(std::io::Error::new(std::io::ErrorKind::Other, &error[..])) |
| 107 | + } |
| 108 | + }); |
92 | 109 | match res {
|
93 | 110 | Ok(output) => Ok(output.trim().to_string()),
|
94 | 111 | Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
|
|
0 commit comments