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

This commit is contained in:
Martin Wickham 2021-09-07 14:11:28 -05:00 committed by GitHub
parent 88e0f81eef
commit 3d5ff91441
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 75 additions and 42 deletions

View File

@ -41,6 +41,7 @@ pub const LibCInstallation = struct {
pub fn parse(
allocator: *Allocator,
libc_file: []const u8,
target: std.zig.CrossTarget,
) !LibCInstallation {
var self: LibCInstallation = .{};
@ -96,26 +97,31 @@ pub const LibCInstallation = struct {
log.err("sys_include_dir may not be empty\n", .{});
return error.ParseError;
}
if (self.crt_dir == null and !is_darwin) {
log.err("crt_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)});
const os_tag = target.getOsTag();
if (self.crt_dir == null and !target.isDarwin()) {
log.err("crt_dir may not be empty for {s}\n", .{@tagName(os_tag)});
return error.ParseError;
}
if (self.msvc_lib_dir == null and is_windows) {
const abi = target.getAbi();
if (self.msvc_lib_dir == null and target.isWindows() and abi == .msvc) {
log.err("msvc_lib_dir may not be empty for {s}-{s}\n", .{
@tagName(Target.current.os.tag),
@tagName(Target.current.abi),
@tagName(os_tag),
@tagName(abi),
});
return error.ParseError;
}
if (self.kernel32_lib_dir == null and is_windows) {
if (self.kernel32_lib_dir == null and target.isWindows() and abi == .msvc) {
log.err("kernel32_lib_dir may not be empty for {s}-{s}\n", .{
@tagName(Target.current.os.tag),
@tagName(Target.current.abi),
@tagName(os_tag),
@tagName(abi),
});
return error.ParseError;
}
if (self.gcc_dir == null and is_haiku) {
log.err("gcc_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)});
if (self.gcc_dir == null and os_tag == .haiku) {
log.err("gcc_dir may not be empty for {s}\n", .{@tagName(os_tag)});
return error.ParseError;
}

View File

@ -1593,39 +1593,11 @@ fn buildOutputType(
}
};
var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{};
const cross_target = std.zig.CrossTarget.parse(.{
const cross_target = try parseCrossTargetOrReportFatalError(arena, .{
.arch_os_abi = target_arch_os_abi,
.cpu_features = target_mcpu,
.dynamic_linker = target_dynamic_linker,
.diagnostics = &diags,
}) catch |err| switch (err) {
error.UnknownCpuModel => {
help: {
var help_text = std.ArrayList(u8).init(arena);
for (diags.arch.?.allCpuModels()) |cpu| {
help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help;
}
std.log.info("Available CPUs for architecture '{s}':\n{s}", .{
@tagName(diags.arch.?), help_text.items,
});
}
fatal("Unknown CPU: '{s}'", .{diags.cpu_name.?});
},
error.UnknownCpuFeature => {
help: {
var help_text = std.ArrayList(u8).init(arena);
for (diags.arch.?.allFeaturesList()) |feature| {
help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help;
}
std.log.info("Available CPU features for architecture '{s}':\n{s}", .{
@tagName(diags.arch.?), help_text.items,
});
}
fatal("Unknown CPU feature: '{s}'", .{diags.unknown_feature_name});
},
else => |e| return e,
};
});
const target_info = try detectNativeTargetInfo(gpa, cross_target);
@ -1972,7 +1944,7 @@ fn buildOutputType(
defer if (libc_installation) |*l| l.deinit(gpa);
if (libc_paths_file) |paths_file| {
libc_installation = LibCInstallation.parse(gpa, paths_file) catch |err| {
libc_installation = LibCInstallation.parse(gpa, paths_file, cross_target) catch |err| {
fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) });
};
}
@ -2289,6 +2261,43 @@ fn buildOutputType(
return cleanExit();
}
fn parseCrossTargetOrReportFatalError(allocator: *Allocator, opts: std.zig.CrossTarget.ParseOptions) !std.zig.CrossTarget {
var opts_with_diags = opts;
var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{};
if (opts_with_diags.diagnostics == null) {
opts_with_diags.diagnostics = &diags;
}
return std.zig.CrossTarget.parse(opts_with_diags) catch |err| switch (err) {
error.UnknownCpuModel => {
help: {
var help_text = std.ArrayList(u8).init(allocator);
defer help_text.deinit();
for (diags.arch.?.allCpuModels()) |cpu| {
help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help;
}
std.log.info("Available CPUs for architecture '{s}':\n{s}", .{
@tagName(diags.arch.?), help_text.items,
});
}
fatal("Unknown CPU: '{s}'", .{diags.cpu_name.?});
},
error.UnknownCpuFeature => {
help: {
var help_text = std.ArrayList(u8).init(allocator);
defer help_text.deinit();
for (diags.arch.?.allFeaturesList()) |feature| {
help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help;
}
std.log.info("Available CPU features for architecture '{s}':\n{s}", .{
@tagName(diags.arch.?), help_text.items,
});
}
fatal("Unknown CPU feature: '{s}'", .{diags.unknown_feature_name});
},
else => |e| return e,
};
}
fn runOrTest(
comp: *Compilation,
gpa: *Allocator,
@ -2630,10 +2639,15 @@ pub const usage_libc =
\\
\\ Parse a libc installation text file and validate it.
\\
\\Options:
\\ -h, --help Print this help and exit
\\ -target [name] <arch><sub>-<os>-<abi> see the targets command
\\
;
pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
var input_file: ?[]const u8 = null;
var target_arch_os_abi: []const u8 = "native";
{
var i: usize = 0;
while (i < args.len) : (i += 1) {
@ -2643,6 +2657,10 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
const stdout = io.getStdOut().writer();
try stdout.writeAll(usage_libc);
return cleanExit();
} else if (mem.eql(u8, arg, "-target")) {
if (i + 1 >= args.len) fatal("expected parameter after {s}", .{arg});
i += 1;
target_arch_os_abi = args[i];
} else {
fatal("unrecognized parameter: '{s}'", .{arg});
}
@ -2653,12 +2671,21 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
}
}
}
const cross_target = try parseCrossTargetOrReportFatalError(gpa, .{
.arch_os_abi = target_arch_os_abi,
});
if (input_file) |libc_file| {
var libc = LibCInstallation.parse(gpa, libc_file) catch |err| {
var libc = LibCInstallation.parse(gpa, libc_file, cross_target) catch |err| {
fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });
};
defer libc.deinit(gpa);
} else {
if (!cross_target.isNative()) {
fatal("unable to detect libc for non-native target", .{});
}
var libc = LibCInstallation.findNative(.{
.allocator = gpa,
.verbose = true,