mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
std.zig.system.NativeTargetInfo: detection ignores self exe
Before, native glibc and dynamic linker detection attempted to use the executable's own binary if it was dynamically linked to answer both the C ABI question and the dynamic linker question. However, this could be problematic on a system that uses a RUNPATH for the compiler binary, locking it to an older glibc version, while system binaries such as /usr/bin/env use a newer glibc version. The problem is that libc.so.6 glibc version will match that of the system while the dynamic linker will match that of the compiler binary. Executables with these versions mismatching will fail to run. Therefore, this commit changes the logic to be the same regardless of whether the compiler binary is dynamically or statically linked. It inspects `/usr/bin/env` as an ELF file to find the answer to these questions, or if there is a shebang line, then it chases the referenced file recursively. If that does not provide the answer, then the function falls back to defaults. This commit also solves a TODO to remove an Allocator parameter to the detect() function.
This commit is contained in:
parent
fa940bafa2
commit
3ee01c14ee
@ -1210,7 +1210,7 @@ fn genHtml(
|
|||||||
var env_map = try process.getEnvMap(allocator);
|
var env_map = try process.getEnvMap(allocator);
|
||||||
try env_map.put("ZIG_DEBUG_COLOR", "1");
|
try env_map.put("ZIG_DEBUG_COLOR", "1");
|
||||||
|
|
||||||
const host = try std.zig.system.NativeTargetInfo.detect(allocator, .{});
|
const host = try std.zig.system.NativeTargetInfo.detect(.{});
|
||||||
const builtin_code = try getBuiltinCode(allocator, &env_map, zig_exe);
|
const builtin_code = try getBuiltinCode(allocator, &env_map, zig_exe);
|
||||||
|
|
||||||
for (toc.nodes) |node| {
|
for (toc.nodes) |node| {
|
||||||
@ -1474,7 +1474,6 @@ fn genHtml(
|
|||||||
.arch_os_abi = triple,
|
.arch_os_abi = triple,
|
||||||
});
|
});
|
||||||
const target_info = try std.zig.system.NativeTargetInfo.detect(
|
const target_info = try std.zig.system.NativeTargetInfo.detect(
|
||||||
allocator,
|
|
||||||
cross_target,
|
cross_target,
|
||||||
);
|
);
|
||||||
switch (host.getExternalExecutor(target_info, .{
|
switch (host.getExternalExecutor(target_info, .{
|
||||||
|
|||||||
@ -171,7 +171,7 @@ pub const Builder = struct {
|
|||||||
const env_map = try allocator.create(EnvMap);
|
const env_map = try allocator.create(EnvMap);
|
||||||
env_map.* = try process.getEnvMap(allocator);
|
env_map.* = try process.getEnvMap(allocator);
|
||||||
|
|
||||||
const host = try NativeTargetInfo.detect(allocator, .{});
|
const host = try NativeTargetInfo.detect(.{});
|
||||||
|
|
||||||
const self = try allocator.create(Builder);
|
const self = try allocator.create(Builder);
|
||||||
self.* = Builder{
|
self.* = Builder{
|
||||||
@ -1798,7 +1798,7 @@ pub const LibExeObjStep = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn computeOutFileNames(self: *LibExeObjStep) void {
|
fn computeOutFileNames(self: *LibExeObjStep) void {
|
||||||
self.target_info = NativeTargetInfo.detect(self.builder.allocator, self.target) catch
|
self.target_info = NativeTargetInfo.detect(self.target) catch
|
||||||
unreachable;
|
unreachable;
|
||||||
|
|
||||||
const target = self.target_info.target;
|
const target = self.target_info.target;
|
||||||
|
|||||||
@ -158,7 +158,7 @@ fn warnAboutForeignBinaries(step: *EmulatableRunStep) void {
|
|||||||
|
|
||||||
const host_name = builder.host.target.zigTriple(builder.allocator) catch unreachable;
|
const host_name = builder.host.target.zigTriple(builder.allocator) catch unreachable;
|
||||||
const foreign_name = artifact.target.zigTriple(builder.allocator) catch unreachable;
|
const foreign_name = artifact.target.zigTriple(builder.allocator) catch unreachable;
|
||||||
const target_info = std.zig.system.NativeTargetInfo.detect(builder.allocator, artifact.target) catch unreachable;
|
const target_info = std.zig.system.NativeTargetInfo.detect(artifact.target) catch unreachable;
|
||||||
const need_cross_glibc = artifact.target.isGnuLibC() and artifact.is_linking_libc;
|
const need_cross_glibc = artifact.target.isGnuLibC() and artifact.is_linking_libc;
|
||||||
switch (builder.host.getExternalExecutor(target_info, .{
|
switch (builder.host.getExternalExecutor(target_info, .{
|
||||||
.qemu_fixes_dl = need_cross_glibc and builder.glibc_runtimes_dir != null,
|
.qemu_fixes_dl = need_cross_glibc and builder.glibc_runtimes_dir != null,
|
||||||
|
|||||||
@ -37,8 +37,7 @@ pub const DetectError = error{
|
|||||||
/// relative to that.
|
/// relative to that.
|
||||||
/// Any resources this function allocates are released before returning, and so there is no
|
/// Any resources this function allocates are released before returning, and so there is no
|
||||||
/// deinitialization method.
|
/// deinitialization method.
|
||||||
/// TODO Remove the Allocator requirement from this function.
|
pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {
|
||||||
pub fn detect(allocator: Allocator, cross_target: CrossTarget) DetectError!NativeTargetInfo {
|
|
||||||
var os = cross_target.getOsTag().defaultVersionRange(cross_target.getCpuArch());
|
var os = cross_target.getOsTag().defaultVersionRange(cross_target.getCpuArch());
|
||||||
if (cross_target.os_tag == null) {
|
if (cross_target.os_tag == null) {
|
||||||
switch (builtin.target.os.tag) {
|
switch (builtin.target.os.tag) {
|
||||||
@ -199,7 +198,7 @@ pub fn detect(allocator: Allocator, cross_target: CrossTarget) DetectError!Nativ
|
|||||||
} orelse backup_cpu_detection: {
|
} orelse backup_cpu_detection: {
|
||||||
break :backup_cpu_detection Target.Cpu.baseline(cpu_arch);
|
break :backup_cpu_detection Target.Cpu.baseline(cpu_arch);
|
||||||
};
|
};
|
||||||
var result = try detectAbiAndDynamicLinker(allocator, cpu, os, cross_target);
|
var result = try detectAbiAndDynamicLinker(cpu, os, cross_target);
|
||||||
// For x86, we need to populate some CPU feature flags depending on architecture
|
// For x86, we need to populate some CPU feature flags depending on architecture
|
||||||
// and mode:
|
// and mode:
|
||||||
// * 16bit_mode => if the abi is code16
|
// * 16bit_mode => if the abi is code16
|
||||||
@ -236,13 +235,20 @@ pub fn detect(allocator: Allocator, cross_target: CrossTarget) DetectError!Nativ
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// First we attempt to use the executable's own binary. If it is dynamically
|
/// In the past, this function attempted to use the executable's own binary if it was dynamically
|
||||||
/// linked, then it should answer both the C ABI question and the dynamic linker question.
|
/// linked to answer both the C ABI question and the dynamic linker question. However, this
|
||||||
/// If it is statically linked, then we try /usr/bin/env (or the file it references in shebang). If that does not provide the answer, then
|
/// could be problematic on a system that uses a RUNPATH for the compiler binary, locking
|
||||||
/// we fall back to the defaults.
|
/// it to an older glibc version, while system binaries such as /usr/bin/env use a newer glibc
|
||||||
/// TODO Remove the Allocator requirement from this function.
|
/// version. The problem is that libc.so.6 glibc version will match that of the system while
|
||||||
|
/// the dynamic linker will match that of the compiler binary. Executables with these versions
|
||||||
|
/// mismatching will fail to run.
|
||||||
|
///
|
||||||
|
/// Therefore, this function works the same regardless of whether the compiler binary is
|
||||||
|
/// dynamically or statically linked. It inspects `/usr/bin/env` as an ELF file to find the
|
||||||
|
/// answer to these questions, or if there is a shebang line, then it chases the referenced
|
||||||
|
/// file recursively. If that does not provide the answer, then the function falls back to
|
||||||
|
/// defaults.
|
||||||
fn detectAbiAndDynamicLinker(
|
fn detectAbiAndDynamicLinker(
|
||||||
allocator: Allocator,
|
|
||||||
cpu: Target.Cpu,
|
cpu: Target.Cpu,
|
||||||
os: Target.Os,
|
os: Target.Os,
|
||||||
cross_target: CrossTarget,
|
cross_target: CrossTarget,
|
||||||
@ -280,8 +286,8 @@ fn detectAbiAndDynamicLinker(
|
|||||||
const ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch);
|
const ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch);
|
||||||
|
|
||||||
for (all_abis) |abi| {
|
for (all_abis) |abi| {
|
||||||
// This may be a nonsensical parameter. We detect this with error.UnknownDynamicLinkerPath and
|
// This may be a nonsensical parameter. We detect this with
|
||||||
// skip adding it to `ld_info_list`.
|
// error.UnknownDynamicLinkerPath and skip adding it to `ld_info_list`.
|
||||||
const target: Target = .{
|
const target: Target = .{
|
||||||
.cpu = cpu,
|
.cpu = cpu,
|
||||||
.os = os,
|
.os = os,
|
||||||
@ -301,62 +307,6 @@ fn detectAbiAndDynamicLinker(
|
|||||||
|
|
||||||
// Best case scenario: the executable is dynamically linked, and we can iterate
|
// Best case scenario: the executable is dynamically linked, and we can iterate
|
||||||
// over our own shared objects and find a dynamic linker.
|
// over our own shared objects and find a dynamic linker.
|
||||||
self_exe: {
|
|
||||||
const lib_paths = try std.process.getSelfExeSharedLibPaths(allocator);
|
|
||||||
defer {
|
|
||||||
for (lib_paths) |lib_path| {
|
|
||||||
allocator.free(lib_path);
|
|
||||||
}
|
|
||||||
allocator.free(lib_paths);
|
|
||||||
}
|
|
||||||
|
|
||||||
var found_ld_info: LdInfo = undefined;
|
|
||||||
var found_ld_path: [:0]const u8 = undefined;
|
|
||||||
|
|
||||||
// Look for dynamic linker.
|
|
||||||
// This is O(N^M) but typical case here is N=2 and M=10.
|
|
||||||
find_ld: for (lib_paths) |lib_path| {
|
|
||||||
for (ld_info_list) |ld_info| {
|
|
||||||
const standard_ld_basename = fs.path.basename(ld_info.ld.get().?);
|
|
||||||
if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) {
|
|
||||||
found_ld_info = ld_info;
|
|
||||||
found_ld_path = lib_path;
|
|
||||||
break :find_ld;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else break :self_exe;
|
|
||||||
|
|
||||||
// Look for glibc version.
|
|
||||||
var os_adjusted = os;
|
|
||||||
if (builtin.target.os.tag == .linux and found_ld_info.abi.isGnu() and
|
|
||||||
cross_target.glibc_version == null)
|
|
||||||
{
|
|
||||||
for (lib_paths) |lib_path| {
|
|
||||||
if (std.mem.endsWith(u8, lib_path, glibc_so_basename)) {
|
|
||||||
os_adjusted.version_range.linux.glibc = glibcVerFromSo(lib_path) catch |err| switch (err) {
|
|
||||||
error.GnuLibCVersionUnavailable => continue,
|
|
||||||
else => |e| return e,
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var result: NativeTargetInfo = .{
|
|
||||||
.target = .{
|
|
||||||
.cpu = cpu,
|
|
||||||
.os = os_adjusted,
|
|
||||||
.abi = cross_target.abi orelse found_ld_info.abi,
|
|
||||||
.ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os_adjusted.tag, cpu.arch),
|
|
||||||
},
|
|
||||||
.dynamic_linker = if (cross_target.dynamic_linker.get() == null)
|
|
||||||
DynamicLinker.init(found_ld_path)
|
|
||||||
else
|
|
||||||
cross_target.dynamic_linker,
|
|
||||||
};
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
const elf_file = blk: {
|
const elf_file = blk: {
|
||||||
// This block looks for a shebang line in /usr/bin/env,
|
// This block looks for a shebang line in /usr/bin/env,
|
||||||
// if it finds one, then instead of using /usr/bin/env as the ELF file to examine, it uses the file it references instead,
|
// if it finds one, then instead of using /usr/bin/env as the ELF file to examine, it uses the file it references instead,
|
||||||
@ -452,56 +402,6 @@ fn detectAbiAndDynamicLinker(
|
|||||||
|
|
||||||
const glibc_so_basename = "libc.so.6";
|
const glibc_so_basename = "libc.so.6";
|
||||||
|
|
||||||
fn glibcVerFromSo(so_path: [:0]const u8) !std.builtin.Version {
|
|
||||||
const file = fs.openFileAbsolute(so_path, .{}) catch |err| switch (err) {
|
|
||||||
// Contextually impossible errors.
|
|
||||||
error.NoSpaceLeft => unreachable,
|
|
||||||
error.NameTooLong => unreachable,
|
|
||||||
error.PathAlreadyExists => unreachable,
|
|
||||||
error.SharingViolation => unreachable,
|
|
||||||
error.InvalidUtf8 => unreachable,
|
|
||||||
error.BadPathName => unreachable,
|
|
||||||
error.PipeBusy => unreachable,
|
|
||||||
error.FileLocksNotSupported => unreachable,
|
|
||||||
error.WouldBlock => unreachable,
|
|
||||||
error.FileBusy => unreachable, // opened without write permissions
|
|
||||||
error.NoDevice => unreachable, // not accessing special device
|
|
||||||
error.InvalidHandle => unreachable, // should not be in the error set
|
|
||||||
error.DeviceBusy => unreachable, // read-only
|
|
||||||
|
|
||||||
// Errors that indicate a false negative may occur if we treat this as
|
|
||||||
// not a libc shared object.
|
|
||||||
error.ProcessFdQuotaExceeded => return error.ProcessFdQuotaExceeded,
|
|
||||||
error.SystemFdQuotaExceeded => return error.SystemFdQuotaExceeded,
|
|
||||||
error.SystemResources => return error.SystemResources,
|
|
||||||
error.Unexpected => return error.Unexpected,
|
|
||||||
|
|
||||||
// Errors that indicate this file is not a libc shared object.
|
|
||||||
error.SymLinkLoop => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.IsDir => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.AccessDenied => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.FileNotFound => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.FileTooBig => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.NotDir => return error.GnuLibCVersionUnavailable,
|
|
||||||
};
|
|
||||||
defer file.close();
|
|
||||||
|
|
||||||
return glibcVerFromSoFile(file) catch |err| switch (err) {
|
|
||||||
error.InvalidElfMagic => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.InvalidElfEndian => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.InvalidElfClass => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.InvalidElfFile => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.InvalidElfVersion => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.InvalidGnuLibCVersion => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.UnexpectedEndOfFile => return error.GnuLibCVersionUnavailable,
|
|
||||||
error.UnableToReadElfFile => return error.GnuLibCVersionUnavailable,
|
|
||||||
|
|
||||||
error.SystemResources => return error.SystemResources,
|
|
||||||
error.FileSystem => return error.FileSystem,
|
|
||||||
error.Unexpected => return error.Unexpected,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn glibcVerFromSoFile(file: fs.File) !std.builtin.Version {
|
fn glibcVerFromSoFile(file: fs.File) !std.builtin.Version {
|
||||||
var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined;
|
var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined;
|
||||||
_ = try preadMin(file, &hdr_buf, 0, hdr_buf.len);
|
_ = try preadMin(file, &hdr_buf, 0, hdr_buf.len);
|
||||||
|
|||||||
17
src/main.zig
17
src/main.zig
@ -268,7 +268,7 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
|
|||||||
} else if (mem.eql(u8, cmd, "init-lib")) {
|
} else if (mem.eql(u8, cmd, "init-lib")) {
|
||||||
return cmdInit(gpa, arena, cmd_args, .Lib);
|
return cmdInit(gpa, arena, cmd_args, .Lib);
|
||||||
} else if (mem.eql(u8, cmd, "targets")) {
|
} else if (mem.eql(u8, cmd, "targets")) {
|
||||||
const info = try detectNativeTargetInfo(arena, .{});
|
const info = try detectNativeTargetInfo(.{});
|
||||||
const stdout = io.getStdOut().writer();
|
const stdout = io.getStdOut().writer();
|
||||||
return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, info.target);
|
return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, info.target);
|
||||||
} else if (mem.eql(u8, cmd, "version")) {
|
} else if (mem.eql(u8, cmd, "version")) {
|
||||||
@ -2267,7 +2267,7 @@ fn buildOutputType(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cross_target = try parseCrossTargetOrReportFatalError(arena, target_parse_options);
|
const cross_target = try parseCrossTargetOrReportFatalError(arena, target_parse_options);
|
||||||
const target_info = try detectNativeTargetInfo(gpa, cross_target);
|
const target_info = try detectNativeTargetInfo(cross_target);
|
||||||
|
|
||||||
if (target_info.target.os.tag != .freestanding) {
|
if (target_info.target.os.tag != .freestanding) {
|
||||||
if (ensure_libc_on_non_freestanding)
|
if (ensure_libc_on_non_freestanding)
|
||||||
@ -3283,7 +3283,7 @@ fn runOrTest(
|
|||||||
if (std.process.can_execv and arg_mode == .run and !watch) {
|
if (std.process.can_execv and arg_mode == .run and !watch) {
|
||||||
// execv releases the locks; no need to destroy the Compilation here.
|
// execv releases the locks; no need to destroy the Compilation here.
|
||||||
const err = std.process.execv(gpa, argv.items);
|
const err = std.process.execv(gpa, argv.items);
|
||||||
try warnAboutForeignBinaries(gpa, arena, arg_mode, target_info, link_libc);
|
try warnAboutForeignBinaries(arena, arg_mode, target_info, link_libc);
|
||||||
const cmd = try std.mem.join(arena, " ", argv.items);
|
const cmd = try std.mem.join(arena, " ", argv.items);
|
||||||
fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd });
|
fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd });
|
||||||
} else if (std.process.can_spawn) {
|
} else if (std.process.can_spawn) {
|
||||||
@ -3300,7 +3300,7 @@ fn runOrTest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const term = child.spawnAndWait() catch |err| {
|
const term = child.spawnAndWait() catch |err| {
|
||||||
try warnAboutForeignBinaries(gpa, arena, arg_mode, target_info, link_libc);
|
try warnAboutForeignBinaries(arena, arg_mode, target_info, link_libc);
|
||||||
const cmd = try std.mem.join(arena, " ", argv.items);
|
const cmd = try std.mem.join(arena, " ", argv.items);
|
||||||
fatal("the following command failed with '{s}':\n{s}", .{ @errorName(err), cmd });
|
fatal("the following command failed with '{s}':\n{s}", .{ @errorName(err), cmd });
|
||||||
};
|
};
|
||||||
@ -3914,7 +3914,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
|
|||||||
gimmeMoreOfThoseSweetSweetFileDescriptors();
|
gimmeMoreOfThoseSweetSweetFileDescriptors();
|
||||||
|
|
||||||
const cross_target: std.zig.CrossTarget = .{};
|
const cross_target: std.zig.CrossTarget = .{};
|
||||||
const target_info = try detectNativeTargetInfo(gpa, cross_target);
|
const target_info = try detectNativeTargetInfo(cross_target);
|
||||||
|
|
||||||
const exe_basename = try std.zig.binNameAlloc(arena, .{
|
const exe_basename = try std.zig.binNameAlloc(arena, .{
|
||||||
.root_name = "build",
|
.root_name = "build",
|
||||||
@ -4956,8 +4956,8 @@ test "fds" {
|
|||||||
gimmeMoreOfThoseSweetSweetFileDescriptors();
|
gimmeMoreOfThoseSweetSweetFileDescriptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn detectNativeTargetInfo(gpa: Allocator, cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo {
|
fn detectNativeTargetInfo(cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo {
|
||||||
return std.zig.system.NativeTargetInfo.detect(gpa, cross_target);
|
return std.zig.system.NativeTargetInfo.detect(cross_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicate that we are now terminating with a successful exit code.
|
/// Indicate that we are now terminating with a successful exit code.
|
||||||
@ -5320,14 +5320,13 @@ fn parseIntSuffix(arg: []const u8, prefix_len: usize) u64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn warnAboutForeignBinaries(
|
fn warnAboutForeignBinaries(
|
||||||
gpa: Allocator,
|
|
||||||
arena: Allocator,
|
arena: Allocator,
|
||||||
arg_mode: ArgMode,
|
arg_mode: ArgMode,
|
||||||
target_info: std.zig.system.NativeTargetInfo,
|
target_info: std.zig.system.NativeTargetInfo,
|
||||||
link_libc: bool,
|
link_libc: bool,
|
||||||
) !void {
|
) !void {
|
||||||
const host_cross_target: std.zig.CrossTarget = .{};
|
const host_cross_target: std.zig.CrossTarget = .{};
|
||||||
const host_target_info = try detectNativeTargetInfo(gpa, host_cross_target);
|
const host_target_info = try detectNativeTargetInfo(host_cross_target);
|
||||||
|
|
||||||
switch (host_target_info.getExternalExecutor(target_info, .{ .link_libc = link_libc })) {
|
switch (host_target_info.getExternalExecutor(target_info, .{ .link_libc = link_libc })) {
|
||||||
.native => return,
|
.native => return,
|
||||||
|
|||||||
@ -1211,7 +1211,7 @@ pub const TestContext = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(self: *TestContext) !void {
|
fn run(self: *TestContext) !void {
|
||||||
const host = try std.zig.system.NativeTargetInfo.detect(self.gpa, .{});
|
const host = try std.zig.system.NativeTargetInfo.detect(.{});
|
||||||
|
|
||||||
var progress = std.Progress{};
|
var progress = std.Progress{};
|
||||||
const root_node = progress.start("compiler", self.cases.items.len);
|
const root_node = progress.start("compiler", self.cases.items.len);
|
||||||
@ -1300,7 +1300,7 @@ pub const TestContext = struct {
|
|||||||
global_cache_directory: Compilation.Directory,
|
global_cache_directory: Compilation.Directory,
|
||||||
host: std.zig.system.NativeTargetInfo,
|
host: std.zig.system.NativeTargetInfo,
|
||||||
) !void {
|
) !void {
|
||||||
const target_info = try std.zig.system.NativeTargetInfo.detect(allocator, case.target);
|
const target_info = try std.zig.system.NativeTargetInfo.detect(case.target);
|
||||||
const target = target_info.target;
|
const target = target_info.target;
|
||||||
|
|
||||||
var arena_allocator = std.heap.ArenaAllocator.init(allocator);
|
var arena_allocator = std.heap.ArenaAllocator.init(allocator);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user