From 1f862a82e2ed32a0c9a6dc33fb7cf32ed7195653 Mon Sep 17 00:00:00 2001 From: Jeremy Drake Date: Wed, 21 May 2025 22:10:28 -0700 Subject: [PATCH] make shared_helpers exe function work for both cygwin and non-cygwin hosts On Cygwin, it needs to not append .exe, because /proc/self/exe (and therefore std::env::current_exe) does not include the .exe extension, breaking bootstrap's rustc wrapper. On hosts other than Cygwin, it *does* need to append .exe because the file really does have a .exe extension, and non-Cygwin hosts won't be doing the same filename rewriting that Cygwin does when looking for a file X but finding only X.exe in its place. --- src/bootstrap/src/utils/shared_helpers.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/utils/shared_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs index 08e1c21e58e7c..561af34a4478b 100644 --- a/src/bootstrap/src/utils/shared_helpers.rs +++ b/src/bootstrap/src/utils/shared_helpers.rs @@ -46,7 +46,16 @@ pub fn dylib_path() -> Vec { /// Given an executable called `name`, return the filename for the /// executable for a particular target. pub fn exe(name: &str, target: &str) -> String { - if target.contains("windows") { + // On Cygwin, the decision to append .exe or not is not as straightforward. + // Executable files do actually have .exe extensions so on hosts other than + // Cygwin it is necessary. But on a Cygwin host there is magic happening + // that redirects requests for file X to file X.exe if it exists, and + // furthermore /proc/self/exe (and thus std::env::current_exe) always + // returns the name *without* the .exe extension. For comparisons against + // that to match, we therefore do not append .exe for Cygwin targets on + // a Cygwin host. + if target.contains("windows") || (cfg!(not(target_os = "cygwin")) && target.contains("cygwin")) + { format!("{name}.exe") } else if target.contains("uefi") { format!("{name}.efi")