Rollup merge of #134999 - Berrysoft:dev/new-cygwin-target, r=chenyukang,workingjubilee

Add cygwin target.

This PR simply adds cygwin target together with msys2 target, based on ````@ookiineko```` 's (the account has been deleted) [work](https://github.com/ookiineko-cygport/rust) on cygwin target. My full work is here: https://github.com/rust-lang/rust/compare/master...Berrysoft:rust:dev/cygwin

I have succeeded in building a new rustc for cygwin target, and eventually distributed a new version of [fish-shell](https://github.com/Berrysoft/fish-shell/releases) (rewritten by Rust) for MSYS2.

I will open a new PR to fix std if this PR is accepted.
This commit is contained in:
Jacob Pratt 2025-02-13 03:53:28 -05:00 committed by GitHub
commit 6f671ad6c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 125 additions and 5 deletions

View file

@ -0,0 +1,46 @@
use std::borrow::Cow;
use crate::spec::{Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs};
pub(crate) fn opts() -> TargetOptions {
let mut pre_link_args = TargetOptions::link_args(
LinkerFlavor::Gnu(Cc::No, Lld::No),
&["--disable-dynamicbase", "--enable-auto-image-base"],
);
crate::spec::add_link_args(
&mut pre_link_args,
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
&["-Wl,--disable-dynamicbase", "-Wl,--enable-auto-image-base"],
);
let cygwin_libs = &["-lcygwin", "-lgcc", "-lcygwin", "-luser32", "-lkernel32", "-lgcc_s"];
let mut late_link_args =
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), cygwin_libs);
crate::spec::add_link_args(
&mut late_link_args,
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
cygwin_libs,
);
TargetOptions {
os: "cygwin".into(),
vendor: "pc".into(),
// FIXME(#13846) this should be enabled for cygwin
function_sections: false,
linker: Some("gcc".into()),
dynamic_linking: true,
dll_prefix: "".into(),
dll_suffix: ".dll".into(),
exe_suffix: ".exe".into(),
families: cvs!["unix"],
is_like_windows: true,
allows_weak_linkage: false,
pre_link_args,
late_link_args,
abi_return_struct_as_int: true,
emit_debug_gdb_scripts: false,
requires_uwtable: true,
eh_frame_header: false,
debuginfo_kind: DebuginfoKind::Dwarf,
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
..Default::default()
}
}

View file

@ -3,6 +3,7 @@ pub(crate) mod android;
pub(crate) mod apple;
pub(crate) mod avr_gnu;
pub(crate) mod bpf;
pub(crate) mod cygwin;
pub(crate) mod dragonfly;
pub(crate) mod freebsd;
pub(crate) mod fuchsia;

View file

@ -2013,6 +2013,7 @@ supported_targets! {
("riscv64imac-unknown-nuttx-elf", riscv64imac_unknown_nuttx_elf),
("riscv64gc-unknown-nuttx-elf", riscv64gc_unknown_nuttx_elf),
("x86_64-pc-cygwin", x86_64_pc_cygwin),
}
/// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]>
@ -2994,8 +2995,8 @@ impl Target {
);
check_eq!(
self.is_like_windows,
self.os == "windows" || self.os == "uefi",
"`is_like_windows` must be set if and only if `os` is `windows` or `uefi`"
self.os == "windows" || self.os == "uefi" || self.os == "cygwin",
"`is_like_windows` must be set if and only if `os` is `windows`, `uefi` or `cygwin`"
);
check_eq!(
self.is_like_wasm,

View file

@ -0,0 +1,24 @@
use crate::spec::{Cc, LinkerFlavor, Lld, Target, base};
pub(crate) fn target() -> Target {
let mut base = base::cygwin::opts();
base.cpu = "x86-64".into();
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "i386pep"]);
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
base.max_atomic_width = Some(64);
base.linker = Some("x86_64-pc-cygwin-gcc".into());
Target {
llvm_target: "x86_64-pc-cygwin".into(),
pointer_width: 64,
data_layout:
"e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
arch: "x86_64".into(),
options: base,
metadata: crate::spec::TargetMetadata {
description: Some("64-bit x86 Cygwin".into()),
tier: Some(3),
host_tools: Some(false),
std: None,
},
}
}

View file

@ -245,7 +245,11 @@ impl Cargo {
// flesh out rpath support more fully in the future.
self.rustflags.arg("-Zosx-rpath-install-name");
Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
} else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
} else if !target.is_windows()
&& !target.contains("cygwin")
&& !target.contains("aix")
&& !target.contains("xous")
{
self.rustflags.arg("-Clink-args=-Wl,-z,origin");
Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
} else {

View file

@ -102,6 +102,7 @@
- [\*-win7-windows-gnu](platform-support/win7-windows-gnu.md)
- [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md)
- [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md)
- [x86_64-pc-cygwin](platform-support/x86_64-pc-cygwin.md)
- [x86_64-pc-solaris](platform-support/solaris.md)
- [x86_64-unknown-linux-none.md](platform-support/x86_64-unknown-linux-none.md)
- [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)

View file

@ -407,6 +407,7 @@ target | std | host | notes
[`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly
[`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS
[`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator
[`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ? | | 64-bit x86 Cygwin |
[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) |
[`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) |
[`x86_64-pc-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 8.0 RTOS |

View file

@ -0,0 +1,39 @@
# `x86_64-pc-cygwin`
**Tier: 3**
Windows targets supporting Cygwin.
The `*-cygwin` targets are **not** intended as native target for applications,
a developer writing Windows applications should use the `*-pc-windows-*` targets instead, which are *native* Windows.
Cygwin is only intended as an emulation layer for Unix-only programs which do not support the native Windows targets.
## Target maintainers
- [Berrysoft](https://github.com/Berrysoft)
## Requirements
This target is cross compiled. It needs `x86_64-pc-cygwin-gcc` as linker.
The `target_os` of the target is `cygwin`, and it is `unix`.
## Building the target
For cross-compilation you want LLVM with [llvm/llvm-project#121439 (merged)](https://github.com/llvm/llvm-project/pull/121439) applied to fix the LLVM codegen on importing external global variables from DLLs.
No native builds on Cygwin now. It should be possible theoretically though, but might need a lot of patches.
## Building Rust programs
Rust does not yet ship pre-compiled artifacts for this target. To compile for
this target, you will either need to build Rust with the target enabled (see
"Building the target" above), or build your own copy of `core` by using
`build-std` or similar.
## Testing
Created binaries work fine on Windows with Cygwin.
## Cross-compilation toolchains and C code
Compatible C code can be built with GCC shipped with Cygwin. Clang is untested.

View file

@ -84,6 +84,9 @@
//@ revisions: x86_64_win7_windows_msvc
//@ [x86_64_win7_windows_msvc] compile-flags: --target x86_64-win7-windows-msvc
//@ [x86_64_win7_windows_msvc] needs-llvm-components: x86
//@ revisions: x86_64_pc_cygwin
//@ [x86_64_pc_cygwin] compile-flags: --target x86_64-pc-cygwin
//@ [x86_64_pc_cygwin] needs-llvm-components: x86
// Sanity-check that each target can produce assembly code.

View file

@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
LL | target_os = "_UNEXPECTED_VALUE",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@ -274,7 +274,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
| |
| help: there is a expected value with a similar name: `"linux"`
|
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
warning: 28 warnings emitted