aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-12-02 21:51:14 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-12-02 21:51:14 -0700
commitf3edff439e2dd8e4055d21507b352141cd5b1718 (patch)
tree160b6397c84011c008c0a5671bbdbbcf41c4b5fd /doc
parent0cd87102221233c2885faccfcaaac297b8d3b656 (diff)
downloadzig-f3edff439e2dd8e4055d21507b352141cd5b1718.tar.gz
zig-f3edff439e2dd8e4055d21507b352141cd5b1718.zip
improve detection of how to execute binaries on the host
`getExternalExecutor` is moved from `std.zig.CrossTarget` to `std.zig.system.NativeTargetInfo.getExternalExecutor`. The function also now communicates a bit more information about *why* the host is unable to execute a binary. The CLI is updated to report this information in a useful manner. `getExternalExecutor` is also improved to detect such patterns as: * x86_64 is able to execute x86 binaries * aarch64 is able to execute arm binaries * etc. Added qemu-hexagon support to `getExternalExecutor`. `std.Target.canExecBinaries` of is removed; callers should use the more powerful `getExternalExecutor` instead. Now that `zig test` tries to run the resulting binary no matter what, this commit has a follow-up change to the build system and docgen to utilize the `getExternalExecutor` function and pass `--test-no-exec` in some cases to avoid getting the error. Additionally: * refactor: extract NativePaths and NativeTargetInfo into their own files named after the structs. * small improvement to langref to reduce the complexity of the `callconv` expression in a couple examples.
Diffstat (limited to 'doc')
-rw-r--r--doc/docgen.zig33
-rw-r--r--doc/langref.html.in18
2 files changed, 41 insertions, 10 deletions
diff --git a/doc/docgen.zig b/doc/docgen.zig
index 08502f0b79..29cb8bda5f 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -1202,6 +1202,7 @@ fn genHtml(
var env_map = try process.getEnvMap(allocator);
try env_map.put("ZIG_DEBUG_COLOR", "1");
+ const host = try std.zig.system.NativeTargetInfo.detect(allocator, .{});
const builtin_code = try getBuiltinCode(allocator, &env_map, zig_exe);
for (toc.nodes) |node| {
@@ -1424,13 +1425,17 @@ fn genHtml(
var test_args = std.ArrayList([]const u8).init(allocator);
defer test_args.deinit();
- try test_args.appendSlice(&[_][]const u8{ zig_exe, "test", tmp_source_file_name });
+ try test_args.appendSlice(&[_][]const u8{
+ zig_exe, "test", tmp_source_file_name,
+ });
try shell_out.print("$ zig test {s}.zig ", .{code.name});
switch (code.mode) {
.Debug => {},
else => {
- try test_args.appendSlice(&[_][]const u8{ "-O", @tagName(code.mode) });
+ try test_args.appendSlice(&[_][]const u8{
+ "-O", @tagName(code.mode),
+ });
try shell_out.print("-O {s} ", .{@tagName(code.mode)});
},
}
@@ -1441,8 +1446,26 @@ fn genHtml(
if (code.target_str) |triple| {
try test_args.appendSlice(&[_][]const u8{ "-target", triple });
try shell_out.print("-target {s} ", .{triple});
+
+ const cross_target = try std.zig.CrossTarget.parse(.{
+ .arch_os_abi = triple,
+ });
+ const target_info = try std.zig.system.NativeTargetInfo.detect(
+ allocator,
+ cross_target,
+ );
+ switch (host.getExternalExecutor(target_info, .{
+ .link_libc = code.link_libc,
+ })) {
+ .native => {},
+ else => {
+ try test_args.appendSlice(&[_][]const u8{"--test-no-exec"});
+ try shell_out.writeAll("--test-no-exec");
+ },
+ }
}
- const result = exec(allocator, &env_map, test_args.items) catch return parseError(tokenizer, code.source_token, "test failed", .{});
+ const result = exec(allocator, &env_map, test_args.items) catch
+ return parseError(tokenizer, code.source_token, "test failed", .{});
const escaped_stderr = try escapeHtml(allocator, result.stderr);
const escaped_stdout = try escapeHtml(allocator, result.stdout);
try shell_out.print("\n{s}{s}\n", .{ escaped_stderr, escaped_stdout });
@@ -1504,9 +1527,7 @@ fn genHtml(
defer test_args.deinit();
try test_args.appendSlice(&[_][]const u8{
- zig_exe,
- "test",
- tmp_source_file_name,
+ zig_exe, "test", tmp_source_file_name,
});
var mode_arg: []const u8 = "";
switch (code.mode) {
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 117c533f40..db68f8eb08 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -4763,7 +4763,13 @@ test "noreturn" {
<p>Another use case for {#syntax#}noreturn{#endsyntax#} is the {#syntax#}exit{#endsyntax#} function:</p>
{#code_begin|test|noreturn_from_exit#}
{#target_windows#}
-pub extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(if (@import("builtin").target.cpu.arch == .i386) .Stdcall else .C) noreturn;
+const std = @import("std");
+const builtin = @import("builtin");
+const native_arch = builtin.cpu.arch;
+const expect = std.testing.expect;
+
+const WINAPI: std.builtin.CallingConvention = if (native_arch == .i386) .Stdcall else .C;
+extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(WINAPI) noreturn;
test "foo" {
const value = bar() catch ExitProcess(1);
@@ -4774,12 +4780,15 @@ fn bar() anyerror!u32 {
return 1234;
}
-const expect = @import("std").testing.expect;
{#code_end#}
{#header_close#}
+
{#header_open|Functions#}
{#code_begin|test|functions#}
-const expect = @import("std").testing.expect;
+const std = @import("std");
+const builtin = @import("builtin");
+const native_arch = builtin.cpu.arch;
+const expect = std.testing.expect;
// Functions are declared like this
fn add(a: i8, b: i8) i8 {
@@ -4798,7 +4807,8 @@ export fn sub(a: i8, b: i8) i8 { return a - b; }
// at link time, when linking statically, or at runtime, when linking
// dynamically.
// The callconv specifier changes the calling convention of the function.
-extern "kernel32" fn ExitProcess(exit_code: u32) callconv(if (@import("builtin").target.cpu.arch == .i386) .Stdcall else .C) noreturn;
+const WINAPI: std.builtin.CallingConvention = if (native_arch == .i386) .Stdcall else .C;
+extern "kernel32" fn ExitProcess(exit_code: u32) callconv(WINAPI) noreturn;
extern "c" fn atan2(a: f64, b: f64) f64;
// The @setCold builtin tells the optimizer that a function is rarely called.