Skip to content

Commit a38bb81

Browse files
committed
zig rc: Fix include directory detection when cross-compiling from certain host archs
Previously, resinator would use the host arch as the target arch when looking for windows-gnu include directories. However, Zig only thinks it can provide a libc for targets specified in the `std.zig.target.available_libcs` array, which only includes a few for windows-gnu. Therefore, when cross-compiling from a host architecture that doesn't have a windows-gnu target in the available_libcs list, resinator would fail to detect the MinGW include directories. Now, the custom option `/:target` is passed to `zig rc` which is intended for the COFF object file target, but can be re-used for the include directory target as well. For the include directory target, resinator can get away with being a bit lossy in its conversion from coff.MachineType to Target.Cpu.Arch (to ensure that the target arch is within the set of available_libcs) since the include directories all resolve to `any-windows-any` in the end anyway (which is what Zig actually ships for MinGW). Fixes the `windows_resources` standalone test failing when the host is, for example, `risc64-linux`.
1 parent 0adcfd6 commit a38bb81

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

lib/compiler/resinator/main.zig

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,26 @@ pub fn main() !void {
104104
}
105105
const maybe_dependencies_list: ?*std.ArrayList([]const u8) = if (options.depfile_path != null) &dependencies_list else null;
106106

107-
const include_paths = getIncludePaths(arena, options.auto_includes, zig_lib_dir) catch |err| switch (err) {
107+
// Use the COFF target to inform which architecture to target for the includes, too.
108+
//
109+
// Note: This is more of a "best fit" mapping to architectures that Zig recognizes
110+
// and considers valid for providing a libc for. For the purposes of include directories,
111+
// when targeting `gnu` the same set of headers will be used for each target arch so we're
112+
// really just trying to avoid Zig thinking that it can't provide a libc for the target
113+
// so we can get the path to the MinGW include directories shipped with Zig.
114+
const includes_arch: std.Target.Cpu.Arch = switch (options.coff_options.target) {
115+
.X64 => .x86_64,
116+
.I386 => .x86,
117+
.ARMNT => .thumb,
118+
.ARM64 => .aarch64,
119+
.ARM64EC => .aarch64,
120+
.ARM64X => .aarch64,
121+
.IA64 => .x86_64,
122+
.EBC => .x86_64,
123+
// the above cases are exhaustive of all the `MachineType`s supported (see supported_targets in cvtres.zig)
124+
else => unreachable,
125+
};
126+
const include_paths = getIncludePaths(arena, options.auto_includes, zig_lib_dir, includes_arch) catch |err| switch (err) {
108127
error.OutOfMemory => |e| return e,
109128
else => |e| {
110129
switch (e) {
@@ -498,7 +517,7 @@ const IoStream = struct {
498517
};
499518
};
500519

501-
fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.AutoIncludes, zig_lib_dir: []const u8) ![]const []const u8 {
520+
fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.AutoIncludes, zig_lib_dir: []const u8, target_arch: std.Target.Cpu.Arch) ![]const []const u8 {
502521
var includes = auto_includes_option;
503522
if (builtin.target.os.tag != .windows) {
504523
switch (includes) {
@@ -521,6 +540,7 @@ fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.A
521540

522541
const target_query: std.Target.Query = .{
523542
.os_tag = .windows,
543+
.cpu_arch = target_arch,
524544
.abi = .msvc,
525545
};
526546
const target = std.zig.resolveTargetQueryOrFatal(target_query);
@@ -546,6 +566,7 @@ fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.A
546566
.gnu => {
547567
const target_query: std.Target.Query = .{
548568
.os_tag = .windows,
569+
.cpu_arch = target_arch,
549570
.abi = .gnu,
550571
};
551572
const target = std.zig.resolveTargetQueryOrFatal(target_query);

src/Compilation.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6058,6 +6058,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
60586058
self_exe_path,
60596059
"rc",
60606060
"--zig-integration",
6061+
// Note: Don't need to pass target here since no preprocessing is done
60616062
"/:no-preprocess",
60626063
"/x", // ignore INCLUDE environment variable
60636064
"/c65001", // UTF-8 codepage
@@ -6115,6 +6116,8 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
61156116
self_exe_path,
61166117
"rc",
61176118
"--zig-integration",
6119+
"/:target",
6120+
@tagName(comp.getTarget().cpu.arch),
61186121
"/:depfile",
61196122
out_dep_path,
61206123
"/:depfile-fmt",

0 commit comments

Comments
 (0)