From 0912484c4f1a8b278a4f04b3baa76cfa38daef6e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 26 Feb 2020 15:35:48 -0500 Subject: [PATCH] improve the "external executor" detection logic --- lib/std/build.zig | 3 +-- lib/std/zig/cross_target.zig | 36 +++++++++++++++++------------------- src-self-hosted/stage2.zig | 6 +++--- test/stack_traces.zig | 2 +- 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/lib/std/build.zig b/lib/std/build.zig index 792781df85..23db4c3f8e 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1141,7 +1141,7 @@ pub const LibExeObjStep = struct { out_pdb_filename: []const u8, packages: ArrayList(Pkg), build_options_contents: std.Buffer, - system_linker_hack: bool, + system_linker_hack: bool = false, object_src: []const u8, @@ -1273,7 +1273,6 @@ pub const LibExeObjStep = struct { .object_src = undefined, .build_options_contents = std.Buffer.initSize(builder.allocator, 0) catch unreachable, .c_std = Builder.CStd.C99, - .system_linker_hack = false, .override_lib_dir = null, .main_pkg_path = null, .exec_cmd_args = null, diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig index 6654635b89..1e16072815 100644 --- a/lib/std/zig/cross_target.zig +++ b/lib/std/zig/cross_target.zig @@ -383,7 +383,7 @@ pub const CrossTarget = struct { pub fn getAbi(self: CrossTarget) Target.Abi { if (self.abi) |abi| return abi; - if (self.isNativeOs()) { + if (self.os_tag == null) { // This works when doing `zig build` because Zig generates a build executable using // native CPU model & features. However this will not be accurate otherwise, and // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. @@ -441,21 +441,11 @@ pub const CrossTarget = struct { return Target.libPrefix_cpu_arch_abi(self.getCpuArch(), self.getAbi()); } - pub fn isNativeCpu(self: CrossTarget) bool { - return self.cpu_arch == null and self.cpu_model == null and - self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty(); - } - - pub fn isNativeOs(self: CrossTarget) bool { - return self.os_tag == null and self.os_version_min == null and self.os_version_max == null; - } - - pub fn isNativeAbi(self: CrossTarget) bool { - return self.abi == null and self.glibc_version == null; - } - pub fn isNative(self: CrossTarget) bool { - return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi(); + return self.cpu_arch == null and self.cpu_model == null and + self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty() and + self.os_tag == null and self.os_version_min == null and self.os_version_max == null and + self.abi == null; } pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![:0]u8 { @@ -463,7 +453,7 @@ pub const CrossTarget = struct { return mem.dupeZ(allocator, u8, "native"); } - const arch_name = if (self.isNativeCpu()) "native" else @tagName(self.getCpuArch()); + const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native"; const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native"; var result = try std.Buffer.allocPrint(allocator, "{}-{}", .{ arch_name, os_name }); @@ -557,12 +547,20 @@ pub const CrossTarget = struct { unavailable, }; + /// Note that even a `CrossTarget` which returns `false` for `isNative` could still be natively executed. + /// For example `-target arm-native` running on an aarch64 host. pub fn getExternalExecutor(self: CrossTarget) Executor { - const os_tag = self.getOsTag(); const cpu_arch = self.getCpuArch(); + const os_tag = self.getOsTag(); + const os_match = os_tag == Target.current.os.tag; - // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture. - if (os_tag == Target.current.os.tag) { + // If the OS matches, and the CPU arch matches, the binary is considered native. + if (self.os_tag == null and cpu_arch == Target.current.cpu.arch) { + return .native; + } + + // If the OS matches, we can use QEMU to emulate a foreign architecture. + if (os_match) { return switch (cpu_arch) { .aarch64 => Executor{ .qemu = "qemu-aarch64" }, .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" }, diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index b2963c8a71..351c6c5357 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -1137,9 +1137,9 @@ fn enumInt(comptime Enum: type, int: c_int) Enum { /// TODO self-host this function fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) !Target { var adjusted_target = cross_target.toTarget(); - if (cross_target.isNativeCpu() or cross_target.isNativeOs()) { + if (cross_target.cpu_arch == null or cross_target.os_tag == null) { const detected_info = try std.zig.system.NativeTargetInfo.detect(std.heap.c_allocator); - if (cross_target.isNativeCpu()) { + if (cross_target.cpu_arch == null) { adjusted_target.cpu = detected_info.target.cpu; // TODO We want to just use detected_info.target but implementing @@ -1151,7 +1151,7 @@ fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) const arch = std.Target.current.cpu.arch; adjusted_target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features); } - if (cross_target.isNativeOs()) { + if (cross_target.os_tag == null) { adjusted_target.os = detected_info.target.os; if (detected_info.dynamic_linker) |dl| { diff --git a/test/stack_traces.zig b/test/stack_traces.zig index ab1156c3cb..b16bf485c0 100644 --- a/test/stack_traces.zig +++ b/test/stack_traces.zig @@ -42,7 +42,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\} ; - switch (builtin.os.tag) { + switch (std.Target.current.os.tag) { .freebsd => { cases.addCase( "return",