Add LLVM based mingw-w64 targets
This commit is contained in:
parent
a7d6408b05
commit
60361f2ca3
14 changed files with 175 additions and 18 deletions
|
@ -152,8 +152,10 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
|
|||
};
|
||||
|
||||
let target = &self.config.sess.target;
|
||||
let mingw_gnu_toolchain =
|
||||
target.vendor == "pc" && target.os == "windows" && target.env == "gnu";
|
||||
let mingw_gnu_toolchain = target.vendor == "pc"
|
||||
&& target.os == "windows"
|
||||
&& target.env == "gnu"
|
||||
&& target.abi.is_empty();
|
||||
|
||||
let import_name_and_ordinal_vector: Vec<(String, Option<u16>)> = dll_imports
|
||||
.iter()
|
||||
|
|
|
@ -324,9 +324,10 @@ fn main() {
|
|||
|
||||
let stdcppname = if target.contains("openbsd") {
|
||||
if target.contains("sparc64") { "estdc++" } else { "c++" }
|
||||
} else if target.contains("freebsd") {
|
||||
"c++"
|
||||
} else if target.contains("darwin") {
|
||||
} else if target.contains("darwin")
|
||||
|| target.contains("freebsd")
|
||||
|| target.contains("windows-gnullvm")
|
||||
{
|
||||
"c++"
|
||||
} else if target.contains("netbsd") && llvm_static_stdcpp.is_some() {
|
||||
// NetBSD uses a separate library when relocation is required
|
||||
|
@ -365,7 +366,7 @@ fn main() {
|
|||
|
||||
// Libstdc++ depends on pthread which Rust doesn't link on MinGW
|
||||
// since nothing else requires it.
|
||||
if target.contains("windows-gnu") {
|
||||
if target.ends_with("windows-gnu") {
|
||||
println!("cargo:rustc-link-lib=static:-bundle=pthread");
|
||||
}
|
||||
}
|
||||
|
|
16
compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs
Normal file
16
compiler/rustc_target/src/spec/aarch64_pc_windows_gnullvm.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
use crate::spec::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::windows_gnullvm_base::opts();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.features = "+neon,+fp-armv8".into();
|
||||
base.linker = Some("aarch64-w64-mingw32-clang".into());
|
||||
|
||||
Target {
|
||||
llvm_target: "aarch64-pc-windows-gnu".into(),
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: base,
|
||||
}
|
||||
}
|
|
@ -82,6 +82,7 @@ mod uefi_msvc_base;
|
|||
mod vxworks_base;
|
||||
mod wasm_base;
|
||||
mod windows_gnu_base;
|
||||
mod windows_gnullvm_base;
|
||||
mod windows_msvc_base;
|
||||
mod windows_uwp_gnu_base;
|
||||
mod windows_uwp_msvc_base;
|
||||
|
@ -939,6 +940,9 @@ supported_targets! {
|
|||
("i686-uwp-windows-gnu", i686_uwp_windows_gnu),
|
||||
("x86_64-uwp-windows-gnu", x86_64_uwp_windows_gnu),
|
||||
|
||||
("aarch64-pc-windows-gnullvm", aarch64_pc_windows_gnullvm),
|
||||
("x86_64-pc-windows-gnullvm", x86_64_pc_windows_gnullvm),
|
||||
|
||||
("aarch64-pc-windows-msvc", aarch64_pc_windows_msvc),
|
||||
("aarch64-uwp-windows-msvc", aarch64_uwp_windows_msvc),
|
||||
("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc),
|
||||
|
|
52
compiler/rustc_target/src/spec/windows_gnullvm_base.rs
Normal file
52
compiler/rustc_target/src/spec/windows_gnullvm_base.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use crate::spec::{cvs, LinkArgs, LinkerFlavor, TargetOptions};
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let pre_link_args = LinkArgs::from([(
|
||||
LinkerFlavor::Gcc,
|
||||
vec![
|
||||
// We cannot use `-nodefaultlibs` because compiler-rt has to be passed
|
||||
// as a path since it's not added to linker search path by the default.
|
||||
// There were attemts to make it behave like libgcc (so one can just use -l<name>)
|
||||
// but LLVM maintainers rejected it: https://reviews.llvm.org/D51440
|
||||
"-nolibc".into(),
|
||||
"--unwindlib=none".into(),
|
||||
],
|
||||
)]);
|
||||
let late_link_args = LinkArgs::from([(
|
||||
LinkerFlavor::Gcc,
|
||||
// Order of `late_link_args*` does not matter with LLD.
|
||||
vec![
|
||||
"-lmingw32".into(),
|
||||
"-lmingwex".into(),
|
||||
"-lmsvcrt".into(),
|
||||
"-lkernel32".into(),
|
||||
"-luser32".into(),
|
||||
],
|
||||
)]);
|
||||
|
||||
TargetOptions {
|
||||
os: "windows".into(),
|
||||
env: "gnu".into(),
|
||||
vendor: "pc".into(),
|
||||
abi: "llvm".into(),
|
||||
linker: Some("clang".into()),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
dll_prefix: "".into(),
|
||||
dll_suffix: ".dll".into(),
|
||||
exe_suffix: ".exe".into(),
|
||||
families: cvs!["windows"],
|
||||
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,
|
||||
no_default_libraries: false,
|
||||
has_thread_local: true,
|
||||
|
||||
..Default::default()
|
||||
}
|
||||
}
|
19
compiler/rustc_target/src/spec/x86_64_pc_windows_gnullvm.rs
Normal file
19
compiler/rustc_target/src/spec/x86_64_pc_windows_gnullvm.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
use crate::spec::{LinkerFlavor, Target};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::windows_gnullvm_base::opts();
|
||||
base.cpu = "x86-64".into();
|
||||
let gcc_pre_link_args = base.pre_link_args.entry(LinkerFlavor::Gcc).or_default();
|
||||
gcc_pre_link_args.push("-m64".into());
|
||||
base.max_atomic_width = Some(64);
|
||||
base.linker = Some("x86_64-w64-mingw32-clang".into());
|
||||
|
||||
Target {
|
||||
llvm_target: "x86_64-pc-windows-gnu".into(),
|
||||
pointer_width: 64,
|
||||
data_layout: "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
.into(),
|
||||
arch: "x86_64".into(),
|
||||
options: base,
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ fn main() {
|
|||
println!("cargo:rustc-link-lib=gcc_s");
|
||||
} else if target.contains("dragonfly") {
|
||||
println!("cargo:rustc-link-lib=gcc_pic");
|
||||
} else if target.contains("pc-windows-gnu") {
|
||||
} else if target.ends_with("pc-windows-gnu") {
|
||||
// This is handled in the target spec with late_link_args_[static|dynamic]
|
||||
} else if target.contains("uwp-windows-gnu") {
|
||||
println!("cargo:rustc-link-lib=unwind");
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#![feature(nll)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(c_unwind)]
|
||||
#![feature(cfg_target_abi)]
|
||||
#![cfg_attr(not(target_env = "msvc"), feature(libc))]
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
|
@ -85,3 +86,7 @@ extern "C" {}
|
|||
#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
|
||||
#[link(name = "unwind", kind = "static", modifiers = "-bundle")]
|
||||
extern "C" {}
|
||||
|
||||
#[cfg(all(target_os = "windows", target_env = "gnu", target_abi = "llvm"))]
|
||||
#[link(name = "unwind", kind = "static", modifiers = "-bundle")]
|
||||
extern "C" {}
|
||||
|
|
|
@ -175,6 +175,7 @@ fn copy_third_party_objects(
|
|||
}
|
||||
|
||||
if target == "x86_64-fortanix-unknown-sgx"
|
||||
|| target.contains("pc-windows-gnullvm")
|
||||
|| builder.config.llvm_libunwind == LlvmLibunwind::InTree
|
||||
&& (target.contains("linux") || target.contains("fuchsia"))
|
||||
{
|
||||
|
@ -246,7 +247,7 @@ fn copy_self_contained_objects(
|
|||
DependencyType::TargetSelfContained,
|
||||
);
|
||||
}
|
||||
} else if target.contains("windows-gnu") {
|
||||
} else if target.ends_with("windows-gnu") {
|
||||
for obj in ["crt2.o", "dllcrt2.o"].iter() {
|
||||
let src = compiler_file(builder, builder.cc(target), target, CLang::C, obj);
|
||||
let target = libdir_self_contained.join(obj);
|
||||
|
@ -477,7 +478,7 @@ impl Step for StartupObjects {
|
|||
fn run(self, builder: &Builder<'_>) -> Vec<(PathBuf, DependencyType)> {
|
||||
let for_compiler = self.compiler;
|
||||
let target = self.target;
|
||||
if !target.contains("windows-gnu") {
|
||||
if !target.ends_with("windows-gnu") {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
|
|
|
@ -285,7 +285,7 @@ impl Step for Mingw {
|
|||
/// without any extra installed software (e.g., we bundle gcc, libraries, etc).
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let host = self.host;
|
||||
if !host.contains("pc-windows-gnu") {
|
||||
if !host.ends_with("pc-windows-gnu") {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -341,7 +341,7 @@ impl Step for Rustc {
|
|||
// anything requiring us to distribute a license, but it's likely the
|
||||
// install will *also* include the rust-mingw package, which also needs
|
||||
// licenses, so to be safe we just include it here in all MinGW packages.
|
||||
if host.contains("pc-windows-gnu") {
|
||||
if host.ends_with("pc-windows-gnu") {
|
||||
make_win_dist(tarball.image_dir(), &tmpdir(builder), host, builder);
|
||||
tarball.add_dir(builder.src.join("src/etc/third-party"), "share/doc");
|
||||
}
|
||||
|
@ -1352,7 +1352,7 @@ impl Step for Extended {
|
|||
tarballs.push(builder.ensure(Rustc { compiler: builder.compiler(stage, target) }));
|
||||
tarballs.push(builder.ensure(Std { compiler, target }).expect("missing std"));
|
||||
|
||||
if target.contains("windows-gnu") {
|
||||
if target.ends_with("windows-gnu") {
|
||||
tarballs.push(builder.ensure(Mingw { host: target }).expect("missing mingw"));
|
||||
}
|
||||
|
||||
|
@ -1522,7 +1522,7 @@ impl Step for Extended {
|
|||
prepare(tool);
|
||||
}
|
||||
}
|
||||
if target.contains("windows-gnu") {
|
||||
if target.ends_with("windows-gnu") {
|
||||
prepare("rust-mingw");
|
||||
}
|
||||
|
||||
|
@ -1711,7 +1711,7 @@ impl Step for Extended {
|
|||
.arg("-t")
|
||||
.arg(etc.join("msi/remove-duplicates.xsl")),
|
||||
);
|
||||
if target.contains("windows-gnu") {
|
||||
if target.ends_with("windows-gnu") {
|
||||
builder.run(
|
||||
Command::new(&heat)
|
||||
.current_dir(&exe)
|
||||
|
@ -1760,7 +1760,7 @@ impl Step for Extended {
|
|||
if built_tools.contains("miri") {
|
||||
cmd.arg("-dMiriDir=miri");
|
||||
}
|
||||
if target.contains("windows-gnu") {
|
||||
if target.ends_with("windows-gnu") {
|
||||
cmd.arg("-dGccDir=rust-mingw");
|
||||
}
|
||||
builder.run(&mut cmd);
|
||||
|
@ -1787,7 +1787,7 @@ impl Step for Extended {
|
|||
}
|
||||
candle("AnalysisGroup.wxs".as_ref());
|
||||
|
||||
if target.contains("windows-gnu") {
|
||||
if target.ends_with("windows-gnu") {
|
||||
candle("GccGroup.wxs".as_ref());
|
||||
}
|
||||
|
||||
|
@ -1829,7 +1829,7 @@ impl Step for Extended {
|
|||
cmd.arg("MiriGroup.wixobj");
|
||||
}
|
||||
|
||||
if target.contains("windows-gnu") {
|
||||
if target.ends_with("windows-gnu") {
|
||||
cmd.arg("GccGroup.wixobj");
|
||||
}
|
||||
// ICE57 wrongly complains about the shortcuts
|
||||
|
@ -1859,7 +1859,9 @@ fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) {
|
|||
.env("CFG_BUILD", target.triple)
|
||||
.env("CFG_CHANNEL", &builder.config.channel);
|
||||
|
||||
if target.contains("windows-gnu") {
|
||||
if target.contains("windows-gnullvm") {
|
||||
cmd.env("CFG_MINGW", "1").env("CFG_ABI", "LLVM");
|
||||
} else if target.contains("windows-gnu") {
|
||||
cmd.env("CFG_MINGW", "1").env("CFG_ABI", "GNU");
|
||||
} else {
|
||||
cmd.env("CFG_MINGW", "0").env("CFG_ABI", "MSVC");
|
||||
|
|
|
@ -1372,6 +1372,10 @@ impl Step for Libunwind {
|
|||
cfg.define("__LIBUNWIND_IS_NATIVE_ONLY", None);
|
||||
cfg.define("NDEBUG", None);
|
||||
}
|
||||
if self.target.contains("windows") {
|
||||
cfg.define("_LIBUNWIND_HIDE_SYMBOLS", "1");
|
||||
cfg.define("_LIBUNWIND_IS_NATIVE_ONLY", "1");
|
||||
}
|
||||
}
|
||||
|
||||
cc_cfg.compiler(builder.cc(self.target));
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
- [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
|
||||
- [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
|
||||
- [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md)
|
||||
- [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
|
||||
- [*-unknown-openbsd](platform-support/openbsd.md)
|
||||
- [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
|
||||
- [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
|
||||
|
|
|
@ -208,6 +208,7 @@ target | std | host | notes
|
|||
`aarch64-apple-ios-macabi` | ? | | Apple Catalyst on ARM64
|
||||
`aarch64-apple-tvos` | * | | ARM64 tvOS
|
||||
[`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3
|
||||
[`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
|
||||
`aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
|
||||
`aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore
|
||||
`aarch64-unknown-uefi` | * | | ARM64 UEFI
|
||||
|
@ -288,6 +289,7 @@ target | std | host | notes
|
|||
[`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly
|
||||
`x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64
|
||||
`x86_64-apple-tvos` | * | | x86 64-bit tvOS
|
||||
[`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
|
||||
`x86_64-pc-windows-msvc` | * | | 64-bit Windows XP support
|
||||
`x86_64-sun-solaris` | ? | | Deprecated target for 64-bit Solaris 10/11, illumos
|
||||
`x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD
|
||||
|
|
48
src/doc/rustc/src/platform-support/pc-windows-gnullvm.md
Normal file
48
src/doc/rustc/src/platform-support/pc-windows-gnullvm.md
Normal file
|
@ -0,0 +1,48 @@
|
|||
# \*-pc-windows-gnullvm
|
||||
|
||||
**Tier: 3**
|
||||
|
||||
Windows targets similar to `*-pc-windows-gnu` but using UCRT as the runtime and various LLVM tools/libraries instead of GCC/Binutils.
|
||||
|
||||
Target triples avaiable so far:
|
||||
- `aarch64-pc-windows-gnullvm`
|
||||
- `x86_64-pc-windows-gnullvm`
|
||||
|
||||
## Target maintainers
|
||||
|
||||
- [@mati865](https://github.com/mati865)
|
||||
|
||||
## Requirements
|
||||
|
||||
The easiest way to obtain these targets is cross-compilation but native build from `x86_64-pc-windows-gnu` is possible with few hacks which I don't recommend.
|
||||
Std support is expected to be on pair with `*-pc-windows-gnu`.
|
||||
|
||||
Binaries for this target should be at least on pair with `*-pc-windows-gnu` in terms of requirements and functionality.
|
||||
|
||||
Those targets follow Windows calling convention for `extern "C"`.
|
||||
|
||||
Like with any other Windows target created binaries are in PE format.
|
||||
|
||||
## Building the target
|
||||
|
||||
For cross-compilation I recommend using [llvm-mingw](https://github.com/mstorsjo/llvm-mingw) toolchain, one change that seems necessary beside configuring corss compilers is disabling experimental `m86k` target. Otherwise LLVM build fails with `multiple definition ...` errors.
|
||||
Native bootstrapping builds require rather fragile hacks until host artifacts are avaiable so I won't describe them here.
|
||||
|
||||
## 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 or Wine using native hardware. Testing AArch64 on x86_64 is problematic though and requires spending some time with QEMU.
|
||||
Once these targets bootstrap themselves on native hardware they should pass Rust testsuite.
|
||||
|
||||
## Cross-compilation toolchains and C code
|
||||
|
||||
Compatible C code can be built with Clang's `aarch64-pc-windows-gnu` and `x86_64-pc-windows-gnu` targets as long as LLVM based C toolchains are used.
|
||||
Those include:
|
||||
- [llvm-mingw](https://github.com/mstorsjo/llvm-mingw)
|
||||
- [MSYS2 with CLANG* environment](https://www.msys2.org/docs/environments)
|
Loading…
Add table
Add a link
Reference in a new issue