Commit 537a873b17

Alex Rønne Petersen <alex@alexrp.com>
2024-09-27 02:01:07
Initial port work for `*-windows-itanium` support.
https://llvm.org/docs/HowToBuildWindowsItaniumPrograms.html This is a weird middle ground between `*-windows-gnu` and `*-windows-msvc`. It uses the C++ ABI of the former while using the system libraries of the latter.
1 parent 4ceefca
lib/compiler_rt/aulldiv.zig
@@ -1,13 +1,14 @@
 const std = @import("std");
 const builtin = @import("builtin");
 const arch = builtin.cpu.arch;
+const os = builtin.os.tag;
 const abi = builtin.abi;
 const common = @import("common.zig");
 
 pub const panic = common.panic;
 
 comptime {
-    if (arch == .x86 and abi == .msvc and builtin.zig_backend != .stage2_c) {
+    if (arch == .x86 and os == .windows and (abi == .msvc or abi == .itanium) and builtin.zig_backend != .stage2_c) {
         // Don't let LLVM apply the stdcall name mangling on those MSVC builtins
         @export(&_alldiv, .{ .name = "\x01__alldiv", .linkage = common.linkage, .visibility = common.visibility });
         @export(&_aulldiv, .{ .name = "\x01__aulldiv", .linkage = common.linkage, .visibility = common.visibility });
lib/compiler_rt/aullrem.zig
@@ -1,13 +1,14 @@
 const std = @import("std");
 const builtin = @import("builtin");
 const arch = builtin.cpu.arch;
+const os = builtin.os.tag;
 const abi = builtin.abi;
 const common = @import("common.zig");
 
 pub const panic = common.panic;
 
 comptime {
-    if (arch == .x86 and abi == .msvc and builtin.zig_backend != .stage2_c) {
+    if (arch == .x86 and os == .windows and (abi == .msvc or abi == .itanium) and builtin.zig_backend != .stage2_c) {
         // Don't let LLVM apply the stdcall name mangling on those MSVC builtins
         @export(&_allrem, .{ .name = "\x01__allrem", .linkage = common.linkage, .visibility = common.visibility });
         @export(&_aullrem, .{ .name = "\x01__aullrem", .linkage = common.linkage, .visibility = common.visibility });
lib/std/os/windows/tls.zig
@@ -9,7 +9,7 @@ export var __xl_a: windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLA") = null;
 export var __xl_z: windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLZ") = null;
 
 comptime {
-    if (builtin.cpu.arch == .x86 and builtin.abi == .msvc and builtin.zig_backend != .stage2_c) {
+    if (builtin.cpu.arch == .x86 and !builtin.abi.isGnu() and builtin.zig_backend != .stage2_c) {
         // The __tls_array is the offset of the ThreadLocalStoragePointer field
         // in the TEB block whose base address held in the %fs segment.
         asm (
lib/std/zig/LibCDirs.zig
@@ -69,7 +69,7 @@ pub fn detect(
     // On windows, instead of the native (mingw) abi, we want to check
     // for the MSVC abi as a fallback.
     const use_system_abi = if (builtin.os.tag == .windows)
-        target.abi == .msvc
+        target.abi == .msvc or target.abi == .itanium
     else
         is_native_abi;
 
lib/std/zig/LibCInstallation.zig
@@ -86,14 +86,14 @@ pub fn parse(
         return error.ParseError;
     }
 
-    if (self.msvc_lib_dir == null and os_tag == .windows and target.abi == .msvc) {
+    if (self.msvc_lib_dir == null and os_tag == .windows and (target.abi == .msvc or target.abi == .itanium)) {
         log.err("msvc_lib_dir may not be empty for {s}-{s}", .{
             @tagName(os_tag),
             @tagName(target.abi),
         });
         return error.ParseError;
     }
-    if (self.kernel32_lib_dir == null and os_tag == .windows and target.abi == .msvc) {
+    if (self.kernel32_lib_dir == null and os_tag == .windows and (target.abi == .msvc or target.abi == .itanium)) {
         log.err("kernel32_lib_dir may not be empty for {s}-{s}", .{
             @tagName(os_tag),
             @tagName(target.abi),
lib/std/c.zig
@@ -9506,7 +9506,7 @@ else if (native_os == .linux and builtin.target.isMusl())
 else
     private.getcontext;
 
-pub const max_align_t = if (native_abi == .msvc)
+pub const max_align_t = if (native_abi == .msvc or native_abi == .itanium)
     f64
 else if (builtin.target.isDarwin())
     c_longdouble
lib/std/Target.zig
@@ -113,7 +113,7 @@ pub const Os = struct {
 
         pub fn staticLibSuffix(tag: Tag, abi: Abi) [:0]const u8 {
             return switch (abi) {
-                .msvc => ".lib",
+                .msvc, .itanium => ".lib",
                 else => switch (tag) {
                     .windows, .uefi => ".lib",
                     else => ".a",
@@ -138,7 +138,7 @@ pub const Os = struct {
 
         pub fn libPrefix(tag: Os.Tag, abi: Abi) [:0]const u8 {
             return switch (abi) {
-                .msvc => "",
+                .msvc, .itanium => "",
                 else => switch (tag) {
                     .windows, .uefi => "",
                     else => "lib",
src/link/Coff/lld.zig
@@ -93,7 +93,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
             man.hash.add(comp.libc_installation != null);
             if (comp.libc_installation) |libc_installation| {
                 man.hash.addBytes(libc_installation.crt_dir.?);
-                if (target.abi == .msvc) {
+                if (target.abi == .msvc or target.abi == .itanium) {
                     man.hash.addBytes(libc_installation.msvc_lib_dir.?);
                     man.hash.addBytes(libc_installation.kernel32_lib_dir.?);
                 }
@@ -256,7 +256,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
             if (comp.libc_installation) |libc_installation| {
                 try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?}));
 
-                if (target.abi == .msvc) {
+                if (target.abi == .msvc or target.abi == .itanium) {
                     try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.msvc_lib_dir.?}));
                     try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.kernel32_lib_dir.?}));
                 }
@@ -499,7 +499,7 @@ pub fn linkWithLLD(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no
                     continue;
                 }
             }
-            if (target.abi == .msvc) {
+            if (target.abi == .msvc or target.abi == .itanium) {
                 argv.appendAssumeCapacity(lib_basename);
                 continue;
             }
src/link/C.zig
@@ -398,7 +398,7 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {
     errdefer defines.deinit();
     const writer = defines.writer();
     switch (target.abi) {
-        .msvc => try writer.writeAll("#define ZIG_TARGET_ABI_MSVC\n"),
+        .msvc, .itanium => try writer.writeAll("#define ZIG_TARGET_ABI_MSVC\n"),
         else => {},
     }
     try writer.print("#define ZIG_TARGET_MAX_INT_ALIGNMENT {d}\n", .{
src/clang.zig
@@ -64,7 +64,7 @@ pub const APValueKind = enum(c_int) {
 
 pub const APValue = extern struct {
     Kind: APValueKind,
-    Data: if (builtin.os.tag == .windows and builtin.abi == .msvc) [52]u8 else [68]u8,
+    Data: if (builtin.os.tag == .windows and (builtin.abi == .msvc or builtin.abi == .itanium)) [52]u8 else [68]u8,
 
     pub const getKind = ZigClangAPValue_getKind;
     extern fn ZigClangAPValue_getKind(*const APValue) APValueKind;
src/Compilation.zig
@@ -2639,7 +2639,7 @@ fn addNonIncrementalStuffToCacheManifest(
         const target = comp.root_mod.resolved_target.result;
         if (comp.libc_installation) |libc_installation| {
             man.hash.addOptionalBytes(libc_installation.crt_dir);
-            if (target.abi == .msvc) {
+            if (target.abi == .msvc or target.abi == .itanium) {
                 man.hash.addOptionalBytes(libc_installation.msvc_lib_dir);
                 man.hash.addOptionalBytes(libc_installation.kernel32_lib_dir);
             }
src/libcxx.zig
@@ -221,7 +221,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
     for (libcxx_files) |cxx_src| {
         var cflags = std.ArrayList([]const u8).init(arena);
 
-        if ((target.os.tag == .windows and target.abi == .msvc) or target.os.tag == .wasi) {
+        if ((target.os.tag == .windows and (target.abi == .msvc or target.abi == .itanium)) or target.os.tag == .wasi) {
             // Filesystem stuff isn't supported on WASI and Windows (MSVC).
             if (std.mem.startsWith(u8, cxx_src, "src/filesystem/"))
                 continue;
src/main.zig
@@ -3874,7 +3874,7 @@ fn createModule(
             };
         }
 
-        if (builtin.target.os.tag == .windows and target.abi == .msvc and
+        if (builtin.target.os.tag == .windows and (target.abi == .msvc or target.abi == .itanium) and
             external_system_libs.len != 0)
         {
             if (create_module.libc_installation == null) {
src/target.zig
@@ -31,7 +31,7 @@ pub fn libcNeedsLibUnwind(target: std.Target) bool {
         .wasi, // Wasm/WASI currently doesn't offer support for libunwind, so don't link it.
         => false,
 
-        .windows => target.abi != .msvc,
+        .windows => target.abi.isGnu(),
         else => true,
     };
 }
@@ -87,7 +87,7 @@ pub fn hasValgrindSupport(target: std.Target) bool {
         .aarch64_be,
         => {
             return target.os.tag == .linux or target.os.tag == .solaris or target.os.tag == .illumos or
-                (target.os.tag == .windows and target.abi != .msvc);
+                (target.os.tag == .windows and target.abi.isGnu());
         },
         else => return false,
     }