mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
CLI: always try to exec binaries
Previously when using `zig run` or `zig test`, zig would try to guess whether the host system was capable of running the target binaries. Now, it will always try. If it fails, then Zig emits a helpful warning to explain the probable cause.
This commit is contained in:
parent
b24cbecdb2
commit
0cd8710222
@ -2527,45 +2527,56 @@ pub const LibExeObjStep = struct {
|
||||
}
|
||||
}
|
||||
} else switch (self.target.getExternalExecutor()) {
|
||||
.native, .unavailable => {},
|
||||
.native => {},
|
||||
.unavailable => {
|
||||
try zig_args.append("--test-no-exec");
|
||||
},
|
||||
.rosetta => if (builder.enable_rosetta) {
|
||||
try zig_args.append("--test-cmd-bin");
|
||||
} else {
|
||||
try zig_args.append("--test-no-exec");
|
||||
},
|
||||
.qemu => |bin_name| if (builder.enable_qemu) qemu: {
|
||||
const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc;
|
||||
const glibc_dir_arg = if (need_cross_glibc)
|
||||
builder.glibc_runtimes_dir orelse break :qemu
|
||||
else
|
||||
null;
|
||||
try zig_args.append("--test-cmd");
|
||||
try zig_args.append(bin_name);
|
||||
if (glibc_dir_arg) |dir| {
|
||||
// TODO look into making this a call to `linuxTriple`. This
|
||||
// needs the directory to be called "i686" rather than
|
||||
// "i386" which is why we do it manually here.
|
||||
const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}";
|
||||
const cpu_arch = self.target.getCpuArch();
|
||||
const os_tag = self.target.getOsTag();
|
||||
const abi = self.target.getAbi();
|
||||
const cpu_arch_name: []const u8 = if (cpu_arch == .i386)
|
||||
"i686"
|
||||
.qemu => |bin_name| ok: {
|
||||
if (builder.enable_qemu) qemu: {
|
||||
const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc;
|
||||
const glibc_dir_arg = if (need_cross_glibc)
|
||||
builder.glibc_runtimes_dir orelse break :qemu
|
||||
else
|
||||
@tagName(cpu_arch);
|
||||
const full_dir = try std.fmt.allocPrint(builder.allocator, fmt_str, .{
|
||||
dir, cpu_arch_name, @tagName(os_tag), @tagName(abi),
|
||||
});
|
||||
null;
|
||||
try zig_args.append("--test-cmd");
|
||||
try zig_args.append(bin_name);
|
||||
if (glibc_dir_arg) |dir| {
|
||||
// TODO look into making this a call to `linuxTriple`. This
|
||||
// needs the directory to be called "i686" rather than
|
||||
// "i386" which is why we do it manually here.
|
||||
const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}";
|
||||
const cpu_arch = self.target.getCpuArch();
|
||||
const os_tag = self.target.getOsTag();
|
||||
const abi = self.target.getAbi();
|
||||
const cpu_arch_name: []const u8 = if (cpu_arch == .i386)
|
||||
"i686"
|
||||
else
|
||||
@tagName(cpu_arch);
|
||||
const full_dir = try std.fmt.allocPrint(builder.allocator, fmt_str, .{
|
||||
dir, cpu_arch_name, @tagName(os_tag), @tagName(abi),
|
||||
});
|
||||
|
||||
try zig_args.append("--test-cmd");
|
||||
try zig_args.append("-L");
|
||||
try zig_args.append("--test-cmd");
|
||||
try zig_args.append(full_dir);
|
||||
try zig_args.append("--test-cmd");
|
||||
try zig_args.append("-L");
|
||||
try zig_args.append("--test-cmd");
|
||||
try zig_args.append(full_dir);
|
||||
}
|
||||
try zig_args.append("--test-cmd-bin");
|
||||
break :ok;
|
||||
}
|
||||
try zig_args.append("--test-cmd-bin");
|
||||
try zig_args.append("--test-no-exec");
|
||||
},
|
||||
.wine => |bin_name| if (builder.enable_wine) {
|
||||
try zig_args.append("--test-cmd");
|
||||
try zig_args.append(bin_name);
|
||||
try zig_args.append("--test-cmd-bin");
|
||||
} else {
|
||||
try zig_args.append("--test-no-exec");
|
||||
},
|
||||
.wasmtime => |bin_name| if (builder.enable_wasmtime) {
|
||||
try zig_args.append("--test-cmd");
|
||||
@ -2573,11 +2584,15 @@ pub const LibExeObjStep = struct {
|
||||
try zig_args.append("--test-cmd");
|
||||
try zig_args.append("--dir=.");
|
||||
try zig_args.append("--test-cmd-bin");
|
||||
} else {
|
||||
try zig_args.append("--test-no-exec");
|
||||
},
|
||||
.darling => |bin_name| if (builder.enable_darling) {
|
||||
try zig_args.append("--test-cmd");
|
||||
try zig_args.append(bin_name);
|
||||
try zig_args.append("--test-cmd-bin");
|
||||
} else {
|
||||
try zig_args.append("--test-no-exec");
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
66
src/main.zig
66
src/main.zig
@ -2534,7 +2534,7 @@ fn buildOutputType(
|
||||
test_exec_args.items,
|
||||
self_exe_path,
|
||||
arg_mode,
|
||||
target_info.target,
|
||||
target_info,
|
||||
watch,
|
||||
&comp_destroyed,
|
||||
all_args,
|
||||
@ -2606,7 +2606,7 @@ fn buildOutputType(
|
||||
test_exec_args.items,
|
||||
self_exe_path,
|
||||
arg_mode,
|
||||
target_info.target,
|
||||
target_info,
|
||||
watch,
|
||||
&comp_destroyed,
|
||||
all_args,
|
||||
@ -2631,7 +2631,7 @@ fn buildOutputType(
|
||||
test_exec_args.items,
|
||||
self_exe_path,
|
||||
arg_mode,
|
||||
target_info.target,
|
||||
target_info,
|
||||
watch,
|
||||
&comp_destroyed,
|
||||
all_args,
|
||||
@ -2695,7 +2695,7 @@ fn runOrTest(
|
||||
test_exec_args: []const ?[]const u8,
|
||||
self_exe_path: []const u8,
|
||||
arg_mode: ArgMode,
|
||||
target: std.Target,
|
||||
target_info: std.zig.system.NativeTargetInfo,
|
||||
watch: bool,
|
||||
comp_destroyed: *bool,
|
||||
all_args: []const []const u8,
|
||||
@ -2711,20 +2711,6 @@ fn runOrTest(
|
||||
defer argv.deinit();
|
||||
|
||||
if (test_exec_args.len == 0) {
|
||||
if (!builtin.target.canExecBinariesOf(target)) {
|
||||
switch (arg_mode) {
|
||||
.zig_test => {
|
||||
warn("created {s} but skipping execution because it is non-native", .{exe_path});
|
||||
if (!watch) return cleanExit();
|
||||
return;
|
||||
},
|
||||
else => {
|
||||
std.log.err("unable to execute {s}: non-native", .{exe_path});
|
||||
if (!watch) process.exit(1);
|
||||
return;
|
||||
},
|
||||
}
|
||||
}
|
||||
// when testing pass the zig_exe_path to argv
|
||||
if (arg_mode == .zig_test)
|
||||
try argv.appendSlice(&[_][]const u8{
|
||||
@ -2754,6 +2740,7 @@ fn runOrTest(
|
||||
if (std.process.can_execv and arg_mode == .run and !watch) {
|
||||
// execv releases the locks; no need to destroy the Compilation here.
|
||||
const err = std.process.execv(gpa, argv.items);
|
||||
try warnAboutForeignBinaries(gpa, arena, arg_mode, target_info);
|
||||
const cmd = try argvCmd(arena, argv.items);
|
||||
fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd });
|
||||
} else {
|
||||
@ -2771,7 +2758,11 @@ fn runOrTest(
|
||||
comp_destroyed.* = true;
|
||||
}
|
||||
|
||||
const term = try child.spawnAndWait();
|
||||
const term = child.spawnAndWait() catch |err| {
|
||||
try warnAboutForeignBinaries(gpa, arena, arg_mode, target_info);
|
||||
const cmd = try argvCmd(arena, argv.items);
|
||||
fatal("the following command failed with '{s}':\n{s}", .{ @errorName(err), cmd });
|
||||
};
|
||||
switch (arg_mode) {
|
||||
.run, .build => {
|
||||
switch (term) {
|
||||
@ -4665,3 +4656,40 @@ fn parseIntSuffix(arg: []const u8, prefix_len: usize) u64 {
|
||||
fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
|
||||
};
|
||||
}
|
||||
|
||||
fn warnAboutForeignBinaries(
|
||||
gpa: Allocator,
|
||||
arena: Allocator,
|
||||
arg_mode: ArgMode,
|
||||
target_info: std.zig.system.NativeTargetInfo,
|
||||
) !void {
|
||||
const host_cross_target: std.zig.CrossTarget = .{};
|
||||
const host_target_info = try detectNativeTargetInfo(gpa, host_cross_target);
|
||||
|
||||
if (!host_target_info.target.canExecBinariesOf(target_info.target)) {
|
||||
const host_name = try host_target_info.target.zigTriple(arena);
|
||||
const foreign_name = try target_info.target.zigTriple(arena);
|
||||
const tip_suffix = switch (arg_mode) {
|
||||
.zig_test => ". Consider using --test-no-exec or --test-cmd",
|
||||
else => "",
|
||||
};
|
||||
warn("the host system ({s}) does not appear to be capable of executing binaries from the target ({s}){s}", .{
|
||||
host_name, foreign_name, tip_suffix,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (target_info.dynamic_linker.get()) |foreign_dl| {
|
||||
std.fs.cwd().access(foreign_dl, .{}) catch {
|
||||
const host_dl = host_target_info.dynamic_linker.get() orelse "(none)";
|
||||
const tip_suffix = switch (arg_mode) {
|
||||
.zig_test => ", --test-no-exec, or --test-cmd",
|
||||
else => "",
|
||||
};
|
||||
warn("the host system does not appear to be capable of executing binaries from the target because the host dynamic linker is located at '{s}', while the target dynamic linker path is '{s}'. Consider using --dynamic-linker{s}", .{
|
||||
host_dl, foreign_dl, tip_suffix,
|
||||
});
|
||||
return;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user