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 {...@@ -41,6 +41,7 @@ pub const LibCInstallation = struct {
41 pub fn parse(41 pub fn parse(
42 allocator: *Allocator,42 allocator: *Allocator,
43 libc_file: []const u8,43 libc_file: []const u8,
44 target: std.zig.CrossTarget,
44 ) !LibCInstallation {45 ) !LibCInstallation {
45 var self: LibCInstallation = .{};46 var self: LibCInstallation = .{};
4647
...@@ -96,26 +97,31 @@ pub const LibCInstallation = struct {...@@ -96,26 +97,31 @@ pub const LibCInstallation = struct {
96 log.err("sys_include_dir may not be empty\n", .{});97 log.err("sys_include_dir may not be empty\n", .{});
97 return error.ParseError;98 return error.ParseError;
98 }99 }
99 if (self.crt_dir == null and !is_darwin) {100
100 log.err("crt_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)});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)});
101 return error.ParseError;104 return error.ParseError;
102 }105 }
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) {
104 log.err("msvc_lib_dir may not be empty for {s}-{s}\n", .{109 log.err("msvc_lib_dir may not be empty for {s}-{s}\n", .{
105 @tagName(Target.current.os.tag),110 @tagName(os_tag),
106 @tagName(Target.current.abi),111 @tagName(abi),
107 });112 });
108 return error.ParseError;113 return error.ParseError;
109 }114 }
110 if (self.kernel32_lib_dir == null and is_windows) {115 if (self.kernel32_lib_dir == null and target.isWindows() and abi == .msvc) {
111 log.err("kernel32_lib_dir may not be empty for {s}-{s}\n", .{116 log.err("kernel32_lib_dir may not be empty for {s}-{s}\n", .{
112 @tagName(Target.current.os.tag),117 @tagName(os_tag),
113 @tagName(Target.current.abi),118 @tagName(abi),
114 });119 });
115 return error.ParseError;120 return error.ParseError;
116 }121 }
117 if (self.gcc_dir == null and is_haiku) {122
118 log.err("gcc_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)});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)});
119 return error.ParseError;125 return error.ParseError;
120 }126 }
121127
src/main.zig+59-32
...@@ -1593,39 +1593,11 @@ fn buildOutputType(...@@ -1593,39 +1593,11 @@ fn buildOutputType(
1593 }1593 }
1594 };1594 };
15951595
1596 var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{};1596 const cross_target = try parseCrossTargetOrReportFatalError(arena, .{
1597 const cross_target = std.zig.CrossTarget.parse(.{
1598 .arch_os_abi = target_arch_os_abi,1597 .arch_os_abi = target_arch_os_abi,
1599 .cpu_features = target_mcpu,1598 .cpu_features = target_mcpu,
1600 .dynamic_linker = target_dynamic_linker,1599 .dynamic_linker = target_dynamic_linker,
1601 .diagnostics = &diags,1600 });
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 };
16291601
1630 const target_info = try detectNativeTargetInfo(gpa, cross_target);1602 const target_info = try detectNativeTargetInfo(gpa, cross_target);
16311603
...@@ -1972,7 +1944,7 @@ fn buildOutputType(...@@ -1972,7 +1944,7 @@ fn buildOutputType(
1972 defer if (libc_installation) |*l| l.deinit(gpa);1944 defer if (libc_installation) |*l| l.deinit(gpa);
19731945
1974 if (libc_paths_file) |paths_file| {1946 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| {
1976 fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) });1948 fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) });
1977 };1949 };
1978 }1950 }
...@@ -2289,6 +2261,43 @@ fn buildOutputType(...@@ -2289,6 +2261,43 @@ fn buildOutputType(
2289 return cleanExit();2261 return cleanExit();
2290}2262}
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
2292fn runOrTest(2301fn runOrTest(
2293 comp: *Compilation,2302 comp: *Compilation,
2294 gpa: *Allocator,2303 gpa: *Allocator,
...@@ -2630,10 +2639,15 @@ pub const usage_libc =...@@ -2630,10 +2639,15 @@ pub const usage_libc =
2630 \\2639 \\
2631 \\ Parse a libc installation text file and validate it.2640 \\ Parse a libc installation text file and validate it.
2632 \\2641 \\
2642 \\Options:
2643 \\ -h, --help Print this help and exit
2644 \\ -target [name] <arch><sub>-<os>-<abi> see the targets command
2645 \\
2633;2646;
26342647
2635pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {2648pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
2636 var input_file: ?[]const u8 = null;2649 var input_file: ?[]const u8 = null;
2650 var target_arch_os_abi: []const u8 = "native";
2637 {2651 {
2638 var i: usize = 0;2652 var i: usize = 0;
2639 while (i < args.len) : (i += 1) {2653 while (i < args.len) : (i += 1) {
...@@ -2643,6 +2657,10 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {...@@ -2643,6 +2657,10 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
2643 const stdout = io.getStdOut().writer();2657 const stdout = io.getStdOut().writer();
2644 try stdout.writeAll(usage_libc);2658 try stdout.writeAll(usage_libc);
2645 return cleanExit();2659 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];
2646 } else {2664 } else {
2647 fatal("unrecognized parameter: '{s}'", .{arg});2665 fatal("unrecognized parameter: '{s}'", .{arg});
2648 }2666 }
...@@ -2653,12 +2671,21 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {...@@ -2653,12 +2671,21 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
2653 }2671 }
2654 }2672 }
2655 }2673 }
2674
2675 const cross_target = try parseCrossTargetOrReportFatalError(gpa, .{
2676 .arch_os_abi = target_arch_os_abi,
2677 });
2678
2656 if (input_file) |libc_file| {2679 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| {
2658 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });2681 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });
2659 };2682 };
2660 defer libc.deinit(gpa);2683 defer libc.deinit(gpa);
2661 } else {2684 } else {
2685 if (!cross_target.isNative()) {
2686 fatal("unable to detect libc for non-native target", .{});
2687 }
2688
2662 var libc = LibCInstallation.findNative(.{2689 var libc = LibCInstallation.findNative(.{
2663 .allocator = gpa,2690 .allocator = gpa,
2664 .verbose = true,2691 .verbose = true,