aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlex Rønne Petersen <alex@alexrp.com>2025-06-29 09:59:38 +0200
committerGitHub <noreply@github.com>2025-06-29 09:59:38 +0200
commite8377659560497beb36ec1f981b024f74292c1b9 (patch)
treea2c00b2800368763c7ef6710f6c2e55c795bdac2 /lib
parentd3363b7a61cc0833d6eb60077b90cf12b95155f0 (diff)
parent09f4e2d9d138d313b93ab10cbac1fee2a8f4e9f0 (diff)
downloadzig-e8377659560497beb36ec1f981b024f74292c1b9.tar.gz
zig-e8377659560497beb36ec1f981b024f74292c1b9.zip
zig rc: Fix include directory detection when cross-compiling from certain host archs (#24288)
* resinator: Only preprocess when the input is an .rc file * resinator: 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 will convert the MachineType to the relevant arch, or fail if there is no equivalent arch/no support for detecting the includes for the MachineType (currently 64-bit Itanium and EBC). Fixes the `windows_resources` standalone test failing when the host is, for example, `riscv64-linux`.
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/resinator/main.zig84
1 files changed, 64 insertions, 20 deletions
diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig
index a96289ceec..8344a16b25 100644
--- a/lib/compiler/resinator/main.zig
+++ b/lib/compiler/resinator/main.zig
@@ -104,24 +104,15 @@ pub fn main() !void {
}
const maybe_dependencies_list: ?*std.ArrayList([]const u8) = if (options.depfile_path != null) &dependencies_list else null;
- const include_paths = getIncludePaths(arena, options.auto_includes, zig_lib_dir) catch |err| switch (err) {
- error.OutOfMemory => |e| return e,
- else => |e| {
- switch (e) {
- error.MsvcIncludesNotFound => {
- try error_handler.emitMessage(allocator, .err, "MSVC include paths could not be automatically detected", .{});
- },
- error.MingwIncludesNotFound => {
- try error_handler.emitMessage(allocator, .err, "MinGW include paths could not be automatically detected", .{});
- },
- }
- try error_handler.emitMessage(allocator, .note, "to disable auto includes, use the option /:auto-includes none", .{});
- std.process.exit(1);
- },
+ var include_paths = LazyIncludePaths{
+ .arena = arena,
+ .auto_includes_option = options.auto_includes,
+ .zig_lib_dir = zig_lib_dir,
+ .target_machine_type = options.coff_options.target,
};
const full_input = full_input: {
- if (options.preprocess != .no) {
+ if (options.input_format == .rc and options.preprocess != .no) {
var preprocessed_buf = std.ArrayList(u8).init(allocator);
errdefer preprocessed_buf.deinit();
@@ -138,7 +129,8 @@ pub fn main() !void {
defer argv.deinit();
try argv.append("arocc"); // dummy command name
- try preprocess.appendAroArgs(aro_arena, &argv, options, include_paths);
+ const resolved_include_paths = try include_paths.get(&error_handler);
+ try preprocess.appendAroArgs(aro_arena, &argv, options, resolved_include_paths);
try argv.append(switch (options.input_source) {
.stdio => "-",
.filename => |filename| filename,
@@ -264,7 +256,7 @@ pub fn main() !void {
.dependencies_list = maybe_dependencies_list,
.ignore_include_env_var = options.ignore_include_env_var,
.extra_include_paths = options.extra_include_paths.items,
- .system_include_paths = include_paths,
+ .system_include_paths = try include_paths.get(&error_handler),
.default_language_id = options.default_language_id,
.default_code_page = default_code_page,
.disjoint_code_page = has_disjoint_code_page,
@@ -498,21 +490,71 @@ const IoStream = struct {
};
};
-fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.AutoIncludes, zig_lib_dir: []const u8) ![]const []const u8 {
+const LazyIncludePaths = struct {
+ arena: std.mem.Allocator,
+ auto_includes_option: cli.Options.AutoIncludes,
+ zig_lib_dir: []const u8,
+ target_machine_type: std.coff.MachineType,
+ resolved_include_paths: ?[]const []const u8 = null,
+
+ pub fn get(self: *LazyIncludePaths, error_handler: *ErrorHandler) ![]const []const u8 {
+ if (self.resolved_include_paths) |include_paths|
+ return include_paths;
+
+ return getIncludePaths(self.arena, self.auto_includes_option, self.zig_lib_dir, self.target_machine_type) catch |err| switch (err) {
+ error.OutOfMemory => |e| return e,
+ else => |e| {
+ switch (e) {
+ error.UnsupportedAutoIncludesMachineType => {
+ try error_handler.emitMessage(self.arena, .err, "automatic include path detection is not supported for target '{s}'", .{@tagName(self.target_machine_type)});
+ },
+ error.MsvcIncludesNotFound => {
+ try error_handler.emitMessage(self.arena, .err, "MSVC include paths could not be automatically detected", .{});
+ },
+ error.MingwIncludesNotFound => {
+ try error_handler.emitMessage(self.arena, .err, "MinGW include paths could not be automatically detected", .{});
+ },
+ }
+ try error_handler.emitMessage(self.arena, .note, "to disable auto includes, use the option /:auto-includes none", .{});
+ std.process.exit(1);
+ },
+ };
+ }
+};
+
+fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.AutoIncludes, zig_lib_dir: []const u8, target_machine_type: std.coff.MachineType) ![]const []const u8 {
+ if (auto_includes_option == .none) return &[_][]const u8{};
+
+ const includes_arch: std.Target.Cpu.Arch = switch (target_machine_type) {
+ .X64 => .x86_64,
+ .I386 => .x86,
+ .ARMNT => .thumb,
+ .ARM64 => .aarch64,
+ .ARM64EC => .aarch64,
+ .ARM64X => .aarch64,
+ .IA64, .EBC => {
+ return error.UnsupportedAutoIncludesMachineType;
+ },
+ // The above cases are exhaustive of all the `MachineType`s supported (see supported_targets in cvtres.zig)
+ // This is enforced by the argument parser in cli.zig.
+ else => unreachable,
+ };
+
var includes = auto_includes_option;
if (builtin.target.os.tag != .windows) {
switch (includes) {
+ .none => unreachable,
// MSVC can't be found when the host isn't Windows, so short-circuit.
.msvc => return error.MsvcIncludesNotFound,
// Skip straight to gnu since we won't be able to detect MSVC on non-Windows hosts.
.any => includes = .gnu,
- .none, .gnu => {},
+ .gnu => {},
}
}
while (true) {
switch (includes) {
- .none => return &[_][]const u8{},
+ .none => unreachable,
.any, .msvc => {
// MSVC is only detectable on Windows targets. This unreachable is to signify
// that .any and .msvc should be dealt with on non-Windows targets before this point,
@@ -521,6 +563,7 @@ fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.A
const target_query: std.Target.Query = .{
.os_tag = .windows,
+ .cpu_arch = includes_arch,
.abi = .msvc,
};
const target = std.zig.resolveTargetQueryOrFatal(target_query);
@@ -546,6 +589,7 @@ fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.A
.gnu => {
const target_query: std.Target.Query = .{
.os_tag = .windows,
+ .cpu_arch = includes_arch,
.abi = .gnu,
};
const target = std.zig.resolveTargetQueryOrFatal(target_query);