| ... | @@ -104,20 +104,11 @@ pub fn main() !void { | ... | @@ -104,20 +104,11 @@ pub fn main() !void { |
| 104 | } | 104 | } |
| 105 | const maybe_dependencies_list: ?*std.ArrayList([]const u8) = if (options.depfile_path != null) &dependencies_list else null; | 105 | const maybe_dependencies_list: ?*std.ArrayList([]const u8) = if (options.depfile_path != null) &dependencies_list else null; |
| 106 | | 106 | |
| 107 | const include_paths = getIncludePaths(arena, options.auto_includes, zig_lib_dir) catch |err| switch (err) { | 107 | var include_paths = LazyIncludePaths{ |
| 108 | error.OutOfMemory => |e| return e, | 108 | .arena = arena, |
| 109 | else => |e| { | 109 | .auto_includes_option = options.auto_includes, |
| 110 | switch (e) { | 110 | .zig_lib_dir = zig_lib_dir, |
| 111 | error.MsvcIncludesNotFound => { | 111 | .target_machine_type = options.coff_options.target, |
| 112 | try error_handler.emitMessage(allocator, .err, "MSVC include paths could not be automatically detected", .{}); | | |
| 113 | }, | | |
| 114 | error.MingwIncludesNotFound => { | | |
| 115 | try error_handler.emitMessage(allocator, .err, "MinGW include paths could not be automatically detected", .{}); | | |
| 116 | }, | | |
| 117 | } | | |
| 118 | try error_handler.emitMessage(allocator, .note, "to disable auto includes, use the option /:auto-includes none", .{}); | | |
| 119 | std.process.exit(1); | | |
| 120 | }, | | |
| 121 | }; | 112 | }; |
| 122 | | 113 | |
| 123 | const full_input = full_input: { | 114 | const full_input = full_input: { |
| ... | @@ -138,7 +129,8 @@ pub fn main() !void { | ... | @@ -138,7 +129,8 @@ pub fn main() !void { |
| 138 | defer argv.deinit(); | 129 | defer argv.deinit(); |
| 139 | | 130 | |
| 140 | try argv.append("arocc"); // dummy command name | 131 | try argv.append("arocc"); // dummy command name |
| 141 | try preprocess.appendAroArgs(aro_arena, &argv, options, include_paths); | 132 | const resolved_include_paths = try include_paths.get(&error_handler); |
| | 133 | try preprocess.appendAroArgs(aro_arena, &argv, options, resolved_include_paths); |
| 142 | try argv.append(switch (options.input_source) { | 134 | try argv.append(switch (options.input_source) { |
| 143 | .stdio => "-", | 135 | .stdio => "-", |
| 144 | .filename => |filename| filename, | 136 | .filename => |filename| filename, |
| ... | @@ -264,7 +256,7 @@ pub fn main() !void { | ... | @@ -264,7 +256,7 @@ pub fn main() !void { |
| 264 | .dependencies_list = maybe_dependencies_list, | 256 | .dependencies_list = maybe_dependencies_list, |
| 265 | .ignore_include_env_var = options.ignore_include_env_var, | 257 | .ignore_include_env_var = options.ignore_include_env_var, |
| 266 | .extra_include_paths = options.extra_include_paths.items, | 258 | .extra_include_paths = options.extra_include_paths.items, |
| 267 | .system_include_paths = include_paths, | 259 | .system_include_paths = try include_paths.get(&error_handler), |
| 268 | .default_language_id = options.default_language_id, | 260 | .default_language_id = options.default_language_id, |
| 269 | .default_code_page = default_code_page, | 261 | .default_code_page = default_code_page, |
| 270 | .disjoint_code_page = has_disjoint_code_page, | 262 | .disjoint_code_page = has_disjoint_code_page, |
| ... | @@ -498,21 +490,71 @@ const IoStream = struct { | ... | @@ -498,21 +490,71 @@ const IoStream = struct { |
| 498 | }; | 490 | }; |
| 499 | }; | 491 | }; |
| 500 | | 492 | |
| 501 | fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.AutoIncludes, zig_lib_dir: []const u8) ![]const []const u8 { | 493 | const LazyIncludePaths = struct { |
| | 494 | arena: std.mem.Allocator, |
| | 495 | auto_includes_option: cli.Options.AutoIncludes, |
| | 496 | zig_lib_dir: []const u8, |
| | 497 | target_machine_type: std.coff.MachineType, |
| | 498 | resolved_include_paths: ?[]const []const u8 = null, |
| | 499 | |
| | 500 | pub fn get(self: *LazyIncludePaths, error_handler: *ErrorHandler) ![]const []const u8 { |
| | 501 | if (self.resolved_include_paths) |include_paths| |
| | 502 | return include_paths; |
| | 503 | |
| | 504 | return getIncludePaths(self.arena, self.auto_includes_option, self.zig_lib_dir, self.target_machine_type) catch |err| switch (err) { |
| | 505 | error.OutOfMemory => |e| return e, |
| | 506 | else => |e| { |
| | 507 | switch (e) { |
| | 508 | error.UnsupportedAutoIncludesMachineType => { |
| | 509 | try error_handler.emitMessage(self.arena, .err, "automatic include path detection is not supported for target '{s}'", .{@tagName(self.target_machine_type)}); |
| | 510 | }, |
| | 511 | error.MsvcIncludesNotFound => { |
| | 512 | try error_handler.emitMessage(self.arena, .err, "MSVC include paths could not be automatically detected", .{}); |
| | 513 | }, |
| | 514 | error.MingwIncludesNotFound => { |
| | 515 | try error_handler.emitMessage(self.arena, .err, "MinGW include paths could not be automatically detected", .{}); |
| | 516 | }, |
| | 517 | } |
| | 518 | try error_handler.emitMessage(self.arena, .note, "to disable auto includes, use the option /:auto-includes none", .{}); |
| | 519 | std.process.exit(1); |
| | 520 | }, |
| | 521 | }; |
| | 522 | } |
| | 523 | }; |
| | 524 | |
| | 525 | 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 { |
| | 526 | if (auto_includes_option == .none) return &[_][]const u8{}; |
| | 527 | |
| | 528 | const includes_arch: std.Target.Cpu.Arch = switch (target_machine_type) { |
| | 529 | .X64 => .x86_64, |
| | 530 | .I386 => .x86, |
| | 531 | .ARMNT => .thumb, |
| | 532 | .ARM64 => .aarch64, |
| | 533 | .ARM64EC => .aarch64, |
| | 534 | .ARM64X => .aarch64, |
| | 535 | .IA64, .EBC => { |
| | 536 | return error.UnsupportedAutoIncludesMachineType; |
| | 537 | }, |
| | 538 | // The above cases are exhaustive of all the `MachineType`s supported (see supported_targets in cvtres.zig) |
| | 539 | // This is enforced by the argument parser in cli.zig. |
| | 540 | else => unreachable, |
| | 541 | }; |
| | 542 | |
| 502 | var includes = auto_includes_option; | 543 | var includes = auto_includes_option; |
| 503 | if (builtin.target.os.tag != .windows) { | 544 | if (builtin.target.os.tag != .windows) { |
| 504 | switch (includes) { | 545 | switch (includes) { |
| | 546 | .none => unreachable, |
| 505 | // MSVC can't be found when the host isn't Windows, so short-circuit. | 547 | // MSVC can't be found when the host isn't Windows, so short-circuit. |
| 506 | .msvc => return error.MsvcIncludesNotFound, | 548 | .msvc => return error.MsvcIncludesNotFound, |
| 507 | // Skip straight to gnu since we won't be able to detect MSVC on non-Windows hosts. | 549 | // Skip straight to gnu since we won't be able to detect MSVC on non-Windows hosts. |
| 508 | .any => includes = .gnu, | 550 | .any => includes = .gnu, |
| 509 | .none, .gnu => {}, | 551 | .gnu => {}, |
| 510 | } | 552 | } |
| 511 | } | 553 | } |
| 512 | | 554 | |
| 513 | while (true) { | 555 | while (true) { |
| 514 | switch (includes) { | 556 | switch (includes) { |
| 515 | .none => return &[_][]const u8{}, | 557 | .none => unreachable, |
| 516 | .any, .msvc => { | 558 | .any, .msvc => { |
| 517 | // MSVC is only detectable on Windows targets. This unreachable is to signify | 559 | // MSVC is only detectable on Windows targets. This unreachable is to signify |
| 518 | // that .any and .msvc should be dealt with on non-Windows targets before this point, | 560 | // 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 | ... | @@ -521,6 +563,7 @@ fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.A |
| 521 | | 563 | |
| 522 | const target_query: std.Target.Query = .{ | 564 | const target_query: std.Target.Query = .{ |
| 523 | .os_tag = .windows, | 565 | .os_tag = .windows, |
| | 566 | .cpu_arch = includes_arch, |
| 524 | .abi = .msvc, | 567 | .abi = .msvc, |
| 525 | }; | 568 | }; |
| 526 | const target = std.zig.resolveTargetQueryOrFatal(target_query); | 569 | const target = std.zig.resolveTargetQueryOrFatal(target_query); |
| ... | @@ -546,6 +589,7 @@ fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.A | ... | @@ -546,6 +589,7 @@ fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.A |
| 546 | .gnu => { | 589 | .gnu => { |
| 547 | const target_query: std.Target.Query = .{ | 590 | const target_query: std.Target.Query = .{ |
| 548 | .os_tag = .windows, | 591 | .os_tag = .windows, |
| | 592 | .cpu_arch = includes_arch, |
| 549 | .abi = .gnu, | 593 | .abi = .gnu, |
| 550 | }; | 594 | }; |
| 551 | const target = std.zig.resolveTargetQueryOrFatal(target_query); | 595 | const target = std.zig.resolveTargetQueryOrFatal(target_query); |