Skip to content

Commit 5ade657

Browse files
committed
Allow the SDK to be missing on non host macOS
1 parent e77a8f4 commit 5ade657

File tree

2 files changed

+63
-13
lines changed

2 files changed

+63
-13
lines changed

compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,26 @@ codegen_ssa_visual_studio_not_installed = you may need to install Visual Studio
402402
codegen_ssa_xcrun_command_line_tools_insufficient =
403403
when compiling for iOS, tvOS, visionOS or watchOS, you need a full installation of Xcode
404404
405+
codegen_ssa_xcrun_cross_about =
406+
the SDK is needed by the linker to know where to find symbols in system libraries and for embedding the SDK version in the final object file
407+
408+
codegen_ssa_xcrun_cross_download_sdk =
409+
the SDK can be downloaded and extracted from https://developer.apple.com/download/all/?q=xcode (requires an Apple ID).
410+
411+
The full Xcode bundle should contain the SDK in Xcode.app/Contents/Developer/Platforms/{$sdk_name}.platform/Developer/SDKs/{$sdk_name}.sdk{ $sdk_name ->
412+
[MacOSX] , but downloading just the "Command Line Tools for Xcode" should also be sufficient to obtain the macOS SDK.
413+
*[other] .
414+
}
415+
416+
codegen_ssa_xcrun_cross_env_var =
417+
pass the path to the SDK using the SDKROOT environment variable
418+
419+
codegen_ssa_xcrun_cross_ill_supported_target =
420+
cross-compiling on iOS, tvOS, visionOS or watchOS (in particular the linking step) is ill supported on non-macOS hosts
421+
422+
codegen_ssa_xcrun_cross_linker_not_explicitly_set =
423+
you will also need to use a linker capable of linking Mach-O files, consider using the bundled `lld` with `-Clinker=rust-lld`
424+
405425
codegen_ssa_xcrun_failed_invoking = invoking `{$command_formatted}` to find {$sdk_name}.sdk failed: {$error}
406426
407427
codegen_ssa_xcrun_found_developer_dir = found active developer directory at "{$developer_dir}"

compiler/rustc_codegen_ssa/src/back/apple.rs

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -290,22 +290,50 @@ pub(super) fn get_sdk_root(sess: &Session) -> Option<PathBuf> {
290290
Some(path)
291291
}
292292
Err(err) => {
293-
let mut diag = sess.dcx().create_err(err);
294-
295-
// Recognize common error cases, and give more Rust-specific error messages for those.
296-
if let Some(developer_dir) = xcode_select_developer_dir() {
297-
diag.arg("developer_dir", &developer_dir);
298-
diag.note(fluent::codegen_ssa_xcrun_found_developer_dir);
299-
if developer_dir.as_os_str().to_string_lossy().contains("CommandLineTools") {
300-
if sdk_name != "MacOSX" {
301-
diag.help(fluent::codegen_ssa_xcrun_command_line_tools_insufficient);
293+
if sess.host.os == "macos" {
294+
// On host macOS, we require the SDK to be available, either via the `SDKROOT` env
295+
// var, or from the invocation of `xcrun`.
296+
let mut diag = sess.dcx().create_err(err);
297+
298+
// Recognize common error cases, and give more Rust-specific error messages for those.
299+
if let Some(developer_dir) = xcode_select_developer_dir() {
300+
diag.arg("developer_dir", &developer_dir);
301+
diag.note(fluent::codegen_ssa_xcrun_found_developer_dir);
302+
if developer_dir.as_os_str().to_string_lossy().contains("CommandLineTools") {
303+
if sdk_name != "MacOSX" {
304+
diag.help(fluent::codegen_ssa_xcrun_command_line_tools_insufficient);
305+
}
302306
}
307+
} else {
308+
diag.help(fluent::codegen_ssa_xcrun_no_developer_dir);
303309
}
310+
311+
diag.emit();
304312
} else {
305-
diag.help(fluent::codegen_ssa_xcrun_no_developer_dir);
313+
// When cross-compiling from e.g. Linux, while the `xcrun` binary _may_ sometimes be
314+
// provided as a shim by a cross-compilation helper tool, it usually isn't.
315+
//
316+
// In that case, we treat failing to find and/or invoke the `xcrun` binary as a
317+
// warning, allow the SDK to be missing, and assume that the compiler driver
318+
// / linker is properly configured to be able to link with an internal SDK (like in
319+
// `zig cc`).
320+
let mut diag = sess.dcx().create_warn(err);
321+
322+
diag.note(fluent::codegen_ssa_xcrun_cross_about);
323+
diag.help(fluent::codegen_ssa_xcrun_cross_env_var);
324+
diag.help(fluent::codegen_ssa_xcrun_cross_download_sdk);
325+
326+
if sess.opts.cg.linker.is_none() {
327+
diag.warn(fluent::codegen_ssa_xcrun_cross_linker_not_explicitly_set);
328+
}
329+
330+
if sess.target.os != "macos" {
331+
diag.warn(fluent::codegen_ssa_xcrun_cross_ill_supported_target);
332+
}
333+
334+
diag.emit();
306335
}
307336

308-
diag.emit();
309337
None
310338
}
311339
}
@@ -330,6 +358,8 @@ fn xcrun_show_sdk_path(
330358
sdk_name: &'static str,
331359
verbose: bool,
332360
) -> Result<(PathBuf, String), XcrunError> {
361+
// Intentionally invoke the `xcrun` in PATH (e.g. nixpkgs provides an `xcrun` shim, so we don't
362+
// want to require `/usr/bin/xcrun`).
333363
let mut cmd = Command::new("xcrun");
334364
if verbose {
335365
cmd.arg("--verbose");
@@ -401,7 +431,7 @@ fn stdout_to_path(mut stdout: Vec<u8>) -> PathBuf {
401431
}
402432
#[cfg(unix)]
403433
let path = <OsString as std::os::unix::ffi::OsStringExt>::from_vec(stdout);
404-
#[cfg(not(unix))] // Unimportant, this is only used on macOS
405-
let path = OsString::from(String::from_utf8(stdout).unwrap());
434+
#[cfg(not(unix))] // Not so important, this is mostly used on macOS
435+
let path = OsString::from(String::from_utf8(stdout).expect("stdout must be UTF-8"));
406436
PathBuf::from(path)
407437
}

0 commit comments

Comments
 (0)