authorgravatar for spexguy070@gmail.comMartin Wickham <spexguy070@gmail.com> 2021-09-07 14:11:28-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-09-07 15:11:28-04:00
log3d5ff91441040d11cca814f298231a501700da9e
tree706a7c116a1be0dffa72819394e0403a5041efaa
parent88e0f81eefc84feaba3ea3b146c92a62efeb9c3f
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Fix libc file to check against compilation target instead of native (#9670)


2 files changed, 75 insertions(+), 42 deletions(-)

src/libc_installation.zig+16-10
......@@ -41,6 +41,7 @@ pub const LibCInstallation = struct {
4141 pub fn parse(
4242 allocator: *Allocator,
4343 libc_file: []const u8,
44 target: std.zig.CrossTarget,
4445 ) !LibCInstallation {
4546 var self: LibCInstallation = .{};
4647
......@@ -96,26 +97,31 @@ pub const LibCInstallation = struct {
9697 log.err("sys_include_dir may not be empty\n", .{});
9798 return error.ParseError;
9899 }
99 if (self.crt_dir == null and !is_darwin) {
100 log.err("crt_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)});
100
101 const os_tag = target.getOsTag();
102 if (self.crt_dir == null and !target.isDarwin()) {
103 log.err("crt_dir may not be empty for {s}\n", .{@tagName(os_tag)});
101104 return error.ParseError;
102105 }
103 if (self.msvc_lib_dir == null and is_windows) {
106
107 const abi = target.getAbi();
108 if (self.msvc_lib_dir == null and target.isWindows() and abi == .msvc) {
104109 log.err("msvc_lib_dir may not be empty for {s}-{s}\n", .{
105 @tagName(Target.current.os.tag),
106 @tagName(Target.current.abi),
110 @tagName(os_tag),
111 @tagName(abi),
107112 });
108113 return error.ParseError;
109114 }
110 if (self.kernel32_lib_dir == null and is_windows) {
115 if (self.kernel32_lib_dir == null and target.isWindows() and abi == .msvc) {
111116 log.err("kernel32_lib_dir may not be empty for {s}-{s}\n", .{
112 @tagName(Target.current.os.tag),
113 @tagName(Target.current.abi),
117 @tagName(os_tag),
118 @tagName(abi),
114119 });
115120 return error.ParseError;
116121 }
117 if (self.gcc_dir == null and is_haiku) {
118 log.err("gcc_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)});
122
123 if (self.gcc_dir == null and os_tag == .haiku) {
124 log.err("gcc_dir may not be empty for {s}\n", .{@tagName(os_tag)});
119125 return error.ParseError;
120126 }
121127
src/main.zig+59-32
......@@ -1593,39 +1593,11 @@ fn buildOutputType(
15931593 }
15941594 };
15951595
1596 var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{};
1597 const cross_target = std.zig.CrossTarget.parse(.{
1596 const cross_target = try parseCrossTargetOrReportFatalError(arena, .{
15981597 .arch_os_abi = target_arch_os_abi,
15991598 .cpu_features = target_mcpu,
16001599 .dynamic_linker = target_dynamic_linker,
1601 .diagnostics = &diags,
1602 }) catch |err| switch (err) {
1603 error.UnknownCpuModel => {
1604 help: {
1605 var help_text = std.ArrayList(u8).init(arena);
1606 for (diags.arch.?.allCpuModels()) |cpu| {
1607 help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help;
1608 }
1609 std.log.info("Available CPUs for architecture '{s}':\n{s}", .{
1610 @tagName(diags.arch.?), help_text.items,
1611 });
1612 }
1613 fatal("Unknown CPU: '{s}'", .{diags.cpu_name.?});
1614 },
1615 error.UnknownCpuFeature => {
1616 help: {
1617 var help_text = std.ArrayList(u8).init(arena);
1618 for (diags.arch.?.allFeaturesList()) |feature| {
1619 help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help;
1620 }
1621 std.log.info("Available CPU features for architecture '{s}':\n{s}", .{
1622 @tagName(diags.arch.?), help_text.items,
1623 });
1624 }
1625 fatal("Unknown CPU feature: '{s}'", .{diags.unknown_feature_name});
1626 },
1627 else => |e| return e,
1628 };
1600 });
16291601
16301602 const target_info = try detectNativeTargetInfo(gpa, cross_target);
16311603
......@@ -1972,7 +1944,7 @@ fn buildOutputType(
19721944 defer if (libc_installation) |*l| l.deinit(gpa);
19731945
19741946 if (libc_paths_file) |paths_file| {
1975 libc_installation = LibCInstallation.parse(gpa, paths_file) catch |err| {
1947 libc_installation = LibCInstallation.parse(gpa, paths_file, cross_target) catch |err| {
19761948 fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) });
19771949 };
19781950 }
......@@ -2289,6 +2261,43 @@ fn buildOutputType(
22892261 return cleanExit();
22902262}
22912263
2264fn parseCrossTargetOrReportFatalError(allocator: *Allocator, opts: std.zig.CrossTarget.ParseOptions) !std.zig.CrossTarget {
2265 var opts_with_diags = opts;
2266 var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{};
2267 if (opts_with_diags.diagnostics == null) {
2268 opts_with_diags.diagnostics = &diags;
2269 }
2270 return std.zig.CrossTarget.parse(opts_with_diags) catch |err| switch (err) {
2271 error.UnknownCpuModel => {
2272 help: {
2273 var help_text = std.ArrayList(u8).init(allocator);
2274 defer help_text.deinit();
2275 for (diags.arch.?.allCpuModels()) |cpu| {
2276 help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help;
2277 }
2278 std.log.info("Available CPUs for architecture '{s}':\n{s}", .{
2279 @tagName(diags.arch.?), help_text.items,
2280 });
2281 }
2282 fatal("Unknown CPU: '{s}'", .{diags.cpu_name.?});
2283 },
2284 error.UnknownCpuFeature => {
2285 help: {
2286 var help_text = std.ArrayList(u8).init(allocator);
2287 defer help_text.deinit();
2288 for (diags.arch.?.allFeaturesList()) |feature| {
2289 help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help;
2290 }
2291 std.log.info("Available CPU features for architecture '{s}':\n{s}", .{
2292 @tagName(diags.arch.?), help_text.items,
2293 });
2294 }
2295 fatal("Unknown CPU feature: '{s}'", .{diags.unknown_feature_name});
2296 },
2297 else => |e| return e,
2298 };
2299}
2300
22922301fn runOrTest(
22932302 comp: *Compilation,
22942303 gpa: *Allocator,
......@@ -2630,10 +2639,15 @@ pub const usage_libc =
26302639 \\
26312640 \\ Parse a libc installation text file and validate it.
26322641 \\
2642 \\Options:
2643 \\ -h, --help Print this help and exit
2644 \\ -target [name] <arch><sub>-<os>-<abi> see the targets command
2645 \\
26332646;
26342647
26352648pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
26362649 var input_file: ?[]const u8 = null;
2650 var target_arch_os_abi: []const u8 = "native";
26372651 {
26382652 var i: usize = 0;
26392653 while (i < args.len) : (i += 1) {
......@@ -2643,6 +2657,10 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
26432657 const stdout = io.getStdOut().writer();
26442658 try stdout.writeAll(usage_libc);
26452659 return cleanExit();
2660 } else if (mem.eql(u8, arg, "-target")) {
2661 if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});
2662 i += 1;
2663 target_arch_os_abi = args[i];
26462664 } else {
26472665 fatal("unrecognized parameter: '{s}'", .{arg});
26482666 }
......@@ -2653,12 +2671,21 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
26532671 }
26542672 }
26552673 }
2674
2675 const cross_target = try parseCrossTargetOrReportFatalError(gpa, .{
2676 .arch_os_abi = target_arch_os_abi,
2677 });
2678
26562679 if (input_file) |libc_file| {
2657 var libc = LibCInstallation.parse(gpa, libc_file) catch |err| {
2680 var libc = LibCInstallation.parse(gpa, libc_file, cross_target) catch |err| {
26582681 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });
26592682 };
26602683 defer libc.deinit(gpa);
26612684 } else {
2685 if (!cross_target.isNative()) {
2686 fatal("unable to detect libc for non-native target", .{});
2687 }
2688
26622689 var libc = LibCInstallation.findNative(.{
26632690 .allocator = gpa,
26642691 .verbose = true,