commit 85fe35d246d0076d403fc5ee90f4434da7206fd5 (tree)
parent f28802a9c6c3bd36368101981243aab7cf4f453f
Author: Andrew Kelley <andrew@ziglang.org>
Date: Thu, 1 Jan 2026 20:39:16 -0800
compiler: fix -Denable-llvm compilation failures
Diffstat:
11 files changed, 67 insertions(+), 54 deletions(-)
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
@@ -14279,17 +14279,6 @@ fn testArgvToCommandLineWindows(argv: []const []const u8, expected_cmd_line: []c
try std.testing.expectEqualStrings(expected_cmd_line, cmd_line);
}
-/// Replaces the current process image with the executed process. If this
-/// function succeeds, it does not return.
-///
-/// This operation is not available on all targets. `can_execv`
-///
-/// This function also uses the PATH environment variable to get the full path to the executable.
-/// If `file` is an absolute path, this is the same as `execveZ`.
-///
-/// Like `execvpeZ` except if `arg0_expand` is `.expand`, then `argv` is mutable,
-/// and `argv[0]` is expanded to be the same absolute path that is passed to the execve syscall.
-/// If this function returns with an error, `argv[0]` will be restored to the value it was when it was passed in.
fn execvpeZ_expandArg0(
arg0_expand: process.ArgExpansion,
file: [*:0]const u8,
diff --git a/src/Compilation.zig b/src/Compilation.zig
@@ -54,7 +54,7 @@ gpa: Allocator,
/// threads at once.
arena: Allocator,
io: Io,
-environ_map: *std.process.Environ.Map,
+environ_map: *const std.process.Environ.Map,
thread_limit: usize,
/// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.
zcu: ?*Zcu,
@@ -762,12 +762,12 @@ pub const Directories = struct {
.wasi => void,
else => []const u8,
},
- env_map: *std.process.Environ.Map,
+ env_map: *const std.process.Environ.Map,
) Directories {
const wasi = builtin.target.os.tag == .wasi;
const cwd = introspect.getResolvedCwd(arena) catch |err| {
- fatal("unable to get cwd: {s}", .{@errorName(err)});
+ fatal("unable to get cwd: {t}", .{err});
};
const zig_lib: Cache.Directory = d: {
@@ -1799,7 +1799,7 @@ pub const CreateOptions = struct {
parent_whole_cache: ?ParentWholeCache = null,
- environ_map: *std.process.Environ.Map,
+ environ_map: *const std.process.Environ.Map,
pub const Entry = link.File.OpenOptions.Entry;
@@ -5713,7 +5713,7 @@ pub fn translateC(
translated_basename: []const u8,
owner_mod: *Package.Module,
prog_node: std.Progress.Node,
- env_map: *std.process.Environ.Map,
+ env_map: *const std.process.Environ.Map,
) !CImportResult {
dev.check(.translate_c_command);
@@ -6260,7 +6260,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
// that we could "tail call" clang by doing an execve, and any use of
// the caching system would actually be problematic since the user is
// presumably doing their own caching by using dep file flags.
- if (std.process.can_execv and direct_o and
+ if (std.process.can_replace and direct_o and
comp.disable_c_depfile and comp.clang_passthrough_mode)
{
try comp.addCCArgs(arena, &argv, ext, null, c_object.src.owner);
@@ -6292,8 +6292,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
try dumpArgv(io, argv.items);
}
- const err = std.process.execv(arena, argv.items);
- fatal("unable to execv clang: {s}", .{@errorName(err)});
+ const err = std.process.replace(io, .{ .argv = argv.items });
+ fatal("unable to replace process with clang: {t}", .{err});
}
// We can't know the digest until we do the C compiler invocation,
@@ -6348,14 +6348,21 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
else => log.warn("failed to delete '{s}': {s}", .{ dep_file_path, @errorName(err) }),
};
if (std.process.can_spawn) {
- var child = std.process.Child.init(argv.items, arena);
if (comp.clang_passthrough_mode) {
- child.stdin_behavior = .inherit;
- child.stdout_behavior = .inherit;
- child.stderr_behavior = .inherit;
-
- const term = child.spawnAndWait(io) catch |err| {
- return comp.failCObj(c_object, "failed to spawn zig clang (passthrough mode) {s}: {s}", .{ argv.items[0], @errorName(err) });
+ var child = std.process.spawn(io, .{
+ .argv = argv.items,
+ .stdin = .inherit,
+ .stdout = .inherit,
+ .stderr = .inherit,
+ }) catch |err| {
+ return comp.failCObj(c_object, "failed to spawn zig clang (passthrough mode) {s}: {t}", .{
+ argv.items[0], err,
+ });
+ };
+ const term = child.wait(io) catch |err| {
+ return comp.failCObj(c_object, "failed to wait zig clang (passthrough mode) {s}: {t}", .{
+ argv.items[0], err,
+ });
};
switch (term) {
.exited => |code| {
@@ -6367,36 +6374,41 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
},
else => std.process.abort(),
}
- } else {
- child.stdin_behavior = .ignore;
- child.stdout_behavior = .ignore;
- child.stderr_behavior = .pipe;
+ unreachable;
+ }
- try child.spawn(io);
+ var child = try std.process.spawn(io, .{
+ .argv = argv.items,
+ .stdin = .ignore,
+ .stdout = .ignore,
+ .stderr = .pipe,
+ });
- var stderr_reader = child.stderr.?.readerStreaming(io, &.{});
- const stderr = try stderr_reader.interface.allocRemaining(arena, .limited(std.math.maxInt(u32)));
+ var stderr_reader = child.stderr.?.readerStreaming(io, &.{});
+ const stderr = try stderr_reader.interface.allocRemaining(arena, .limited(std.math.maxInt(u32)));
- const term = child.wait(io) catch |err| {
- return comp.failCObj(c_object, "failed to spawn zig clang {s}: {s}", .{ argv.items[0], @errorName(err) });
- };
+ const term = child.wait(io) catch |err|
+ return comp.failCObj(c_object, "failed to spawn zig clang {s}: {t}", .{ argv.items[0], err });
- switch (term) {
- .exited => |code| if (code != 0) if (out_diag_path) |diag_file_path| {
- const bundle = CObject.Diag.Bundle.parse(gpa, io, diag_file_path) catch |err| {
- log.err("{}: failed to parse clang diagnostics: {s}", .{ err, stderr });
- return comp.failCObj(c_object, "clang exited with code {d}", .{code});
- };
- return comp.failCObjWithOwnedDiagBundle(c_object, bundle);
- } else {
- log.err("clang failed with stderr: {s}", .{stderr});
+ switch (term) {
+ .exited => |code| if (code != 0) if (out_diag_path) |diag_file_path| {
+ const bundle = CObject.Diag.Bundle.parse(gpa, io, diag_file_path) catch |err| {
+ log.err("{}: failed to parse clang diagnostics: {s}", .{ err, stderr });
return comp.failCObj(c_object, "clang exited with code {d}", .{code});
- },
- else => {
- log.err("clang terminated with stderr: {s}", .{stderr});
- return comp.failCObj(c_object, "clang terminated unexpectedly", .{});
- },
- }
+ };
+ return comp.failCObjWithOwnedDiagBundle(c_object, bundle);
+ } else {
+ log.err("clang failed with stderr: {s}", .{stderr});
+ return comp.failCObj(c_object, "clang exited with code {d}", .{code});
+ },
+ .signal => |sig| {
+ log.err("clang failed with stderr: {s}", .{stderr});
+ return comp.failCObj(c_object, "clang terminated with signal {t}", .{sig});
+ },
+ else => {
+ log.err("clang terminated with stderr: {s}", .{stderr});
+ return comp.failCObj(c_object, "clang terminated unexpectedly", .{});
+ },
}
} else {
const exit_code = try clangMain(arena, argv.items);
@@ -8113,6 +8125,7 @@ pub fn build_crt_file(
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
.clang_passthrough_mode = comp.clang_passthrough_mode,
.skip_linker_dependencies = true,
+ .environ_map = comp.environ_map,
}) catch |err| switch (err) {
error.CreateFail => {
comp.lockAndSetMiscFailure(misc_task_tag, "sub-compilation of {t} failed: {f}", .{ misc_task_tag, sub_create_diag });
diff --git a/src/introspect.zig b/src/introspect.zig
@@ -102,7 +102,7 @@ pub fn findZigLibDirFromSelfExe(
return error.FileNotFound;
}
-pub fn resolveGlobalCacheDir(arena: Allocator, env_map: *std.process.Environ.Map) ![]const u8 {
+pub fn resolveGlobalCacheDir(arena: Allocator, env_map: *const std.process.Environ.Map) ![]const u8 {
if (std.zig.EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map)) |value| return value;
const app_name = "zig";
diff --git a/src/libs/freebsd.zig b/src/libs/freebsd.zig
@@ -445,6 +445,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
.gpa = gpa,
.io = io,
.manifest_dir = try comp.dirs.global_cache.handle.createDirPathOpen(io, "h", .{}),
+ .cwd = comp.dirs.cwd,
};
cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() });
cache.addPrefix(comp.dirs.zig_lib);
@@ -1119,6 +1120,7 @@ fn buildSharedLib(
.soname = soname,
.c_source_files = &c_source_files,
.skip_linker_dependencies = true,
+ .environ_map = comp.environ_map,
}) catch |err| switch (err) {
error.CreateFail => {
comp.lockAndSetMiscFailure(misc_task, "sub-compilation of {t} failed: {f}", .{ misc_task, sub_create_diag });
diff --git a/src/libs/glibc.zig b/src/libs/glibc.zig
@@ -680,6 +680,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
.gpa = gpa,
.io = io,
.manifest_dir = try comp.dirs.global_cache.handle.createDirPathOpen(io, "h", .{}),
+ .cwd = comp.dirs.cwd,
};
cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() });
cache.addPrefix(comp.dirs.zig_lib);
@@ -1258,6 +1259,7 @@ fn buildSharedLib(
.soname = soname,
.c_source_files = &c_source_files,
.skip_linker_dependencies = true,
+ .environ_map = comp.environ_map,
}) catch |err| switch (err) {
error.CreateFail => {
comp.lockAndSetMiscFailure(misc_task, "sub-compilation of {t} failed: {f}", .{ misc_task, sub_create_diag });
diff --git a/src/libs/libcxx.zig b/src/libs/libcxx.zig
@@ -275,6 +275,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
.clang_passthrough_mode = comp.clang_passthrough_mode,
.skip_linker_dependencies = true,
+ .environ_map = comp.environ_map,
}) catch |err| {
switch (err) {
else => comp.lockAndSetMiscFailure(misc_task, "unable to build libc++: create compilation failed: {t}", .{err}),
@@ -468,6 +469,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
.clang_passthrough_mode = comp.clang_passthrough_mode,
.skip_linker_dependencies = true,
+ .environ_map = comp.environ_map,
}) catch |err| {
switch (err) {
else => comp.lockAndSetMiscFailure(misc_task, "unable to build libc++abi: create compilation failed: {t}", .{err}),
diff --git a/src/libs/libtsan.zig b/src/libs/libtsan.zig
@@ -301,6 +301,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
.linker_allow_shlib_undefined = linker_allow_shlib_undefined,
.install_name = install_name,
.headerpad_size = headerpad_size,
+ .environ_map = comp.environ_map,
}) catch |err| {
switch (err) {
else => comp.lockAndSetMiscFailure(misc_task, "unable to build {t}: create compilation failed: {t}", .{ misc_task, err }),
diff --git a/src/libs/libunwind.zig b/src/libs/libunwind.zig
@@ -166,6 +166,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
.clang_passthrough_mode = comp.clang_passthrough_mode,
.skip_linker_dependencies = true,
+ .environ_map = comp.environ_map,
}) catch |err| {
switch (err) {
else => comp.lockAndSetMiscFailure(misc_task, "unable to build {t}: create compilation failed: {t}", .{ misc_task, err }),
diff --git a/src/libs/musl.zig b/src/libs/musl.zig
@@ -272,6 +272,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
},
.skip_linker_dependencies = true,
.soname = "libc.so",
+ .environ_map = comp.environ_map,
}) catch |err| switch (err) {
error.CreateFail => {
comp.lockAndSetMiscFailure(misc_task, "sub-compilation of {t} failed: {f}", .{ misc_task, sub_create_diag });
diff --git a/src/libs/netbsd.zig b/src/libs/netbsd.zig
@@ -386,6 +386,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye
.gpa = gpa,
.io = io,
.manifest_dir = try comp.dirs.global_cache.handle.createDirPathOpen(io, "h", .{}),
+ .cwd = comp.dirs.cwd,
};
cache.addPrefix(.{ .path = null, .handle = Io.Dir.cwd() });
cache.addPrefix(comp.dirs.zig_lib);
@@ -761,6 +762,7 @@ fn buildSharedLib(
.soname = soname,
.c_source_files = &c_source_files,
.skip_linker_dependencies = true,
+ .environ_map = comp.environ_map,
}) catch |err| switch (err) {
error.CreateFail => {
comp.lockAndSetMiscFailure(misc_task, "sub-compilation of {t} failed: {f}", .{ misc_task, sub_create_diag });
diff --git a/src/main.zig b/src/main.zig
@@ -4708,7 +4708,7 @@ pub fn translateC(
arena: Allocator,
io: Io,
argv: []const []const u8,
- env_map: *process.Environ.Map,
+ env_map: *const process.Environ.Map,
prog_node: std.Progress.Node,
capture: ?*[]u8,
) !void {
@@ -5516,7 +5516,7 @@ fn jitCmd(
arena: Allocator,
io: Io,
args: []const []const u8,
- env_map: *process.Environ.Map,
+ env_map: *const process.Environ.Map,
options: JitCmdOptions,
) !void {
dev.check(.jit_command);