From 3ec6d655dd61ed5fd0a0d33e33e58b12d5b658f5 Mon Sep 17 00:00:00 2001 From: Techatrix Date: Wed, 12 Aug 2026 20:36:27 +0200 Subject: [PATCH] fix compilation errors when building compiler for wasm32-wasi --- src/link.zig | 2 +- src/main.zig | 100 +++++++++++++++++++++++++++++++++--------- src/print_env.zig | 30 +------------ src/print_targets.zig | 7 +-- 4 files changed, 84 insertions(+), 55 deletions(-) diff --git a/src/link.zig b/src/link.zig index 58534f63f8b6e2e2840201eebbe4fd69af07ac33..04f642e4f988ba9147a04152f407cb1a5a47a315 100644 --- a/src/link.zig +++ b/src/link.zig @@ -1337,7 +1337,7 @@ pub const File = struct { // with 0o755 permissions, but it works appropriately if the system is configured // more leniently. As another data point, C's fopen seems to open files with the // 666 mode. - const executable_mode: Io.File.Permissions = if (builtin.target.os.tag == .windows) + const executable_mode: Io.File.Permissions = if (builtin.target.os.tag == .windows or std.posix.mode_t == u0) .default_file else .fromMode(0o777); diff --git a/src/main.zig b/src/main.zig index 4ef9537109d9adf1f09048d8e7f28f5aa2780d9b..f0850ffa08462b1841362e76b602ad11d8012529 100644 --- a/src/main.zig +++ b/src/main.zig @@ -419,9 +419,32 @@ fn mainArgs( }, .targets => { dev.check(.targets_command); + const self_exe_path = switch (native_os) { + .wasi => {}, + else => process.executablePathAlloc(io, arena) catch |err| fatal("unable to find zig self exe path: {t}", .{err}), + }; + var dirs: std.zig.Directories = .init( + arena, + io, + EnvVar.ZIG_LIB_DIR.get(environ_map), + EnvVar.ZIG_GLOBAL_CACHE_DIR.get(environ_map), + .global, + preopens, + self_exe_path, + environ_map, + try std.zig.getResolvedCwd(io, arena), + ); + defer dirs.deinit(io); const host = std.zig.resolveTargetQueryOrFatal(io, .{}); var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); - try @import("print_targets.zig").cmdTargets(arena, io, cmd_args, &stdout_writer.interface, &host); + try @import("print_targets.zig").cmdTargets( + arena, + io, + &dirs, + cmd_args, + &stdout_writer.interface, + &host, + ); return stdout_writer.interface.flush(); }, .version => { @@ -431,16 +454,31 @@ fn mainArgs( }, .env => { dev.check(.env_command); + const self_exe_path = switch (native_os) { + .wasi => args[0], + else => process.executablePathAlloc(io, arena) catch |err| fatal("unable to find zig self exe path: {t}", .{err}), + }; + var dirs: std.zig.Directories = .init( + arena, + io, + EnvVar.ZIG_LIB_DIR.get(environ_map), + EnvVar.ZIG_GLOBAL_CACHE_DIR.get(environ_map), + .global, + preopens, + if (native_os != .wasi) self_exe_path, + environ_map, + try std.zig.getResolvedCwd(io, arena), + ); + defer dirs.deinit(io); const host = std.zig.resolveTargetQueryOrFatal(io, .{}); var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer); try @import("print_env.zig").cmdEnv( arena, - io, &stdout_writer.interface, - args, - preopens, &host, environ_map, + &dirs, + self_exe_path, ); return stdout_writer.interface.flush(); }, @@ -3813,9 +3851,14 @@ fn buildOutputType( }) { dev.checkAny(&.{ .run_command, .test_command }); + const self_exe_path_or_argv0 = switch (native_os) { + .wasi => all_args[0], // Will error because of `!process.can_spawn` + else => self_exe_path, + }; + if (test_exec_args.items.len == 0 and target.ofmt == .c and emit_bin_resolved != .no) { // Default to using `zig run` to execute the produced .c code from `zig test`. - try test_exec_args.appendSlice(arena, &.{ self_exe_path, "run" }); + try test_exec_args.appendSlice(arena, &.{ self_exe_path_or_argv0, "run" }); // Skip passing `-ofmt`, we want the default for the target, not `.c` anymore. var prev_has_cflags = false; @@ -3896,7 +3939,7 @@ fn buildOutputType( arena, io, test_exec_args.items, - self_exe_path, + self_exe_path_or_argv0, arg_mode, target, &comp_destroyed, @@ -4287,7 +4330,10 @@ fn serve( in: *Io.Reader, out: *Io.Writer, test_exec_args: []const ?[]const u8, - self_exe_path: ?[]const u8, + self_exe_path: switch (native_os) { + .wasi => void, + else => []const u8, + }, arg_mode: ArgMode, all_args: []const []const u8, runtime_args_start: ?usize, @@ -4400,7 +4446,7 @@ fn serve( comp, gpa, test_exec_args, - self_exe_path.?, + self_exe_path, arg_mode, all_args, runtime_args_start, @@ -4585,9 +4631,8 @@ fn runOrTest( const cmd = try std.mem.join(arena, " ", argv.items); fatal("the following command failed to execve with '{t}':\n{s}", .{ err, cmd }); } else if (!process.can_spawn) { - const cmd = try std.mem.join(arena, " ", argv.items); - fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{s}", .{ - native_os, cmd, + fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{f}", .{ + native_os, std.zig.SubprocessCommand{ .argv = argv.items }, }); } const term_result = (term: { @@ -4667,7 +4712,10 @@ fn runOrTestHotSwap( comp: *Compilation, gpa: Allocator, test_exec_args: []const ?[]const u8, - self_exe_path: []const u8, + self_exe_path: switch (native_os) { + .wasi => void, + else => []const u8, + }, arg_mode: ArgMode, all_args: []const []const u8, runtime_args_start: ?usize, @@ -4675,6 +4723,11 @@ fn runOrTestHotSwap( const io = comp.io; const lf = comp.bin_file.?; + const self_exe_path_or_argv0 = switch (native_os) { + .wasi => all_args[0], // Will error because of `!process.can_spawn` + else => self_exe_path, + }; + const exe_path = switch (builtin.target.os.tag) { // On Windows it seems impossible to perform an atomic rename of a file that is currently // running in a process. Therefore, we do the opposite. We create a copy of the file in @@ -4700,7 +4753,7 @@ fn runOrTestHotSwap( // when testing pass the zig_exe_path to argv if (arg_mode == .zig_test) try argv.appendSlice(&[_][]const u8{ - exe_path, self_exe_path, + exe_path, self_exe_path_or_argv0, }) // when running just pass the current exe else @@ -4713,7 +4766,7 @@ fn runOrTestHotSwap( try argv.append(a); } else { try argv.appendSlice(&[_][]const u8{ - exe_path, self_exe_path, + exe_path, self_exe_path_or_argv0, }); } } @@ -4722,6 +4775,12 @@ fn runOrTestHotSwap( try argv.appendSlice(all_args[i..]); } + if (!process.can_spawn) { + fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{f}", .{ + native_os, std.zig.SubprocessCommand{ .argv = argv.items }, + }); + } + const child = try std.process.spawn(io, .{ .argv = argv.items, .stdin = .inherit, @@ -4902,6 +4961,12 @@ fn jitCmdInner( thread_limit: usize, options: JitCmdOptions, ) !void { + if (!std.process.can_spawn) { + fatal("The {s} command cannot be executed ({t} does not support spawning a child process)", .{ + options.cmd_name, native_os, + }); + } + const target_query: std.Target.Query = .{}; const resolved_target: Module.ResolvedTarget = .{ .result = std.zig.resolveTargetQueryOrFatal(io, target_query), @@ -5074,13 +5139,6 @@ fn jitCmdInner( fatal("the following command failed to execve with {t}:\n{s}", .{ err, cmd }); } - if (!process.can_spawn) { - const cmd = try std.mem.join(arena, " ", child_argv.items); - fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{s}", .{ - native_os, cmd, - }); - } - const term = t: { _ = try io.lockStderr(&.{}, .no_color); defer io.unlockStderr(); diff --git a/src/print_env.zig b/src/print_env.zig index 34264234ad234faf38bf5bd744e67b833899ce7d..6c5fd6fc6aa9abdb1a58ce6a993b1adba04c8f94 100644 --- a/src/print_env.zig +++ b/src/print_env.zig @@ -11,38 +11,12 @@ const Compilation = @import("Compilation.zig"); pub fn cmdEnv( arena: Allocator, - io: Io, out: *std.Io.Writer, - args: []const []const u8, - preopens: std.process.Preopens, host: *const std.Target, environ_map: *std.process.Environ.Map, + dirs: *const std.zig.Directories, + self_exe_path: []const u8, ) !void { - const override_lib_dir: ?[]const u8 = EnvVar.ZIG_LIB_DIR.get(environ_map); - const override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(environ_map); - - const self_exe_path = switch (builtin.target.os.tag) { - .wasi => args[0], - else => std.process.executablePathAlloc(io, arena) catch |err| { - fatal("unable to find zig self exe path: {t}", .{err}); - }, - }; - - const cwd_path = try std.zig.getResolvedCwd(io, arena); - - var dirs: std.zig.Directories = .init( - arena, - io, - override_lib_dir, - override_global_cache_dir, - .global, - preopens, - if (builtin.target.os.tag != .wasi) self_exe_path, - environ_map, - cwd_path, - ); - defer dirs.deinit(io); - const zig_lib_dir = dirs.zig_lib.path orelse ""; const zig_std_dir = try dirs.zig_lib.join(arena, &.{"std"}); const global_cache_dir = dirs.global_cache.path orelse ""; diff --git a/src/print_targets.zig b/src/print_targets.zig index 695a9a5ef4dc168b85d479f691073d4008efa3a8..526f16f39ac72a2c26f88a4c6449bc4b655d7e52 100644 --- a/src/print_targets.zig +++ b/src/print_targets.zig @@ -14,16 +14,13 @@ const target = @import("target.zig"); pub fn cmdTargets( allocator: Allocator, io: Io, + directories: *const std.zig.Directories, args: []const []const u8, out: *std.Io.Writer, native_target: *const Target, ) !void { _ = args; - var zig_lib_directory = std.zig.findZigLibDir(allocator, io) catch |err| - fatal("unable to find zig installation directory: {t}", .{err}); - defer zig_lib_directory.handle.close(io); - defer allocator.free(zig_lib_directory.path.?); - + const zig_lib_directory = directories.zig_lib; const abilists_contents = zig_lib_directory.handle.readFileAlloc( io, glibc.abilists_path, -- 2.54.0