diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 6692ea735401a..66d8b339cdc8b 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -191,6 +191,10 @@ fn main() { cfg.flag(flag); } + if target.contains("cygwin") { + cfg.define("_GNU_SOURCE", None); + } + for component in &components { let mut flag = String::from("LLVM_COMPONENT_"); flag.push_str(&component.to_uppercase()); @@ -255,6 +259,7 @@ fn main() { } else if target.contains("haiku") || target.contains("darwin") || (is_crossed && (target.contains("dragonfly") || target.contains("solaris"))) + || target.contains("cygwin") { println!("cargo:rustc-link-lib=z"); } else if target.contains("netbsd") { diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index bdeca91eb64a4..2a85f44278a03 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -58,7 +58,7 @@ pub fn make_target_bin_path(sysroot: &Path, target_triple: &str) -> PathBuf { sysroot.join(rustlib_path).join("bin") } -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "cygwin")))] fn current_dll_path() -> Result { use std::sync::OnceLock; @@ -132,6 +132,23 @@ fn current_dll_path() -> Result { .clone() } +#[cfg(target_os = "cygwin")] +fn current_dll_path() -> Result { + use std::ffi::{CStr, OsStr}; + use std::os::unix::prelude::*; + + unsafe { + let addr = current_dll_path as usize as *mut _; + let mut info = std::mem::zeroed(); + if libc::dladdr(addr, &mut info) == 0 { + return Err("dladdr failed".into()); + } + let bytes = CStr::from_ptr(info.dli_fname.as_ptr()).to_bytes(); + let os = OsStr::from_bytes(bytes); + Ok(PathBuf::from(os)) + } +} + #[cfg(windows)] fn current_dll_path() -> Result { use std::ffi::OsString; diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index c32d9c2870cfa..b92870f618e97 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1386,7 +1386,7 @@ impl<'a> Builder<'a> { // Windows doesn't need dylib path munging because the dlls for the // compiler live next to the compiler and the system will find them // automatically. - if cfg!(windows) { + if cfg!(any(windows, target_os = "cygwin")) { return; } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 1299fbb7d6291..e80003ad3f81d 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -110,7 +110,7 @@ pub fn is_debug_info(name: &str) -> bool { /// Returns the corresponding relative library directory that the compiler's /// dylibs will be found in. pub fn libdir(target: TargetSelection) -> &'static str { - if target.is_windows() { "bin" } else { "lib" } + if target.is_windows() || target.contains("cygwin") { "bin" } else { "lib" } } /// Adds a list of lookup paths to `cmd`'s dynamic library lookup path. diff --git a/src/bootstrap/src/utils/shared_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs index 7b206c3ffe826..466ac96e22e6e 100644 --- a/src/bootstrap/src/utils/shared_helpers.rs +++ b/src/bootstrap/src/utils/shared_helpers.rs @@ -20,7 +20,7 @@ use std::str::FromStr; /// Returns the environment variable which the dynamic library lookup path /// resides in for this platform. pub fn dylib_path_var() -> &'static str { - if cfg!(target_os = "windows") { + if cfg!(any(target_os = "windows", target_os = "cygwin")) { "PATH" } else if cfg!(target_vendor = "apple") { "DYLD_LIBRARY_PATH" @@ -46,7 +46,7 @@ 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") { + if target.contains("windows") || target.contains("cygwin") { format!("{name}.exe") } else if target.contains("uefi") { format!("{name}.efi")