From abd131e3367bb10a67bc4c240b87b05d1de4e42f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 25 Mar 2026 18:29:19 -0700 Subject: [PATCH] zig cc: make --version use the full clang CLI lowering code path because clang wants to parse the -target argument with clang -target syntax. closes #30178 --- lib/std/zig.zig | 1 + src/Compilation.zig | 27 ++++++++++++++++----------- src/clang_options.zon | 3 ++- src/main.zig | 27 ++++++++++++++++++++++++--- tools/update_clang_options.zig | 4 ++++ 5 files changed, 47 insertions(+), 15 deletions(-) diff --git a/lib/std/zig.zig b/lib/std/zig.zig index fdb945c7ce55781153f06d7e044f5d11f9fc9a0e..919bd9485b8de43956f153110fc15278bbe8ef70 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -1121,6 +1121,7 @@ pub const ClangCliParam = struct { rtlib, static, dynamic, + version, }; pub fn matchEql(self: @This(), arg: []const u8) u2 { diff --git a/src/Compilation.zig b/src/Compilation.zig index a82cf46fd85ce6b1c67d00d313785f3db5b4b5e4..3eb971f96b2ce0f46b4dbb65df8593c736ae4008 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1471,6 +1471,8 @@ pub const ClangPreprocessorMode = enum { stdout, /// precompiled C header pch, + /// `--version` + version, }; pub const Framework = link.File.MachO.Framework; @@ -2936,16 +2938,16 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE .none => unreachable, .manifest_create, .manifest_read, .manifest_lock => |e| return comp.setMiscFailure( .check_whole_cache, - "failed to check cache: {s} {s}", - .{ @tagName(man.diagnostic), @errorName(e) }, + "failed to check cache: {t} {t}", + .{ man.diagnostic, e }, ), .file_open, .file_stat, .file_read, .file_hash => |op| { const pp = man.files.keys()[op.file_index].prefixed_path; const prefix = man.cache.prefixes()[pp.prefix]; return comp.setMiscFailure( .check_whole_cache, - "failed to check cache: '{f}{s}' {s} {s}", - .{ prefix, pp.sub_path, @tagName(man.diagnostic), @errorName(op.err) }, + "failed to check cache: '{f}{s}' {t} {t}", + .{ prefix, pp.sub_path, man.diagnostic, op.err }, ); }, }, @@ -5739,6 +5741,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr .yes => argv.appendSliceAssumeCapacity(&.{ "-E", "-o", out_obj_path }), .pch => argv.appendSliceAssumeCapacity(&.{ "-Xclang", "-emit-pch", "-o", out_obj_path }), .stdout => argv.appendAssumeCapacity("-E"), + .version => argv.appendAssumeCapacity("--version"), } if (comp.emit_asm != null) { @@ -5782,6 +5785,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr .yes => argv.appendSliceAssumeCapacity(&.{ "-E", "-o", out_obj_path }), .pch => argv.appendSliceAssumeCapacity(&.{ "-Xclang", "-emit-pch", "-o", out_obj_path }), .stdout => argv.appendAssumeCapacity("-E"), + .version => argv.appendAssumeCapacity("--version"), } if (out_diag_path) |diag_file_path| { argv.appendSliceAssumeCapacity(&.{ "--serialize-diagnostics", diag_file_path }); @@ -5830,8 +5834,10 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr if (code != 0) { std.process.exit(code); } - if (comp.clang_preprocessor_mode == .stdout) - std.process.exit(0); + switch (comp.clang_preprocessor_mode) { + .stdout, .version => std.process.exit(0), + else => {}, + } }, else => std.process.abort(), } @@ -5879,11 +5885,10 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr return comp.failCObj(c_object, "clang exited with code {d}", .{exit_code}); } } - if (comp.clang_passthrough_mode and - comp.clang_preprocessor_mode == .stdout) - { - std.process.exit(0); - } + if (comp.clang_passthrough_mode) switch (comp.clang_preprocessor_mode) { + .stdout, .version => std.process.exit(0), + else => {}, + }; } if (out_dep_path) |dep_file_path| { diff --git a/src/clang_options.zon b/src/clang_options.zon index 0d21d903772b5681a80235812bef6ab38ad67a0c..2984aadbb3f9deb2f92b39938a1e40086b00510e 100644 --- a/src/clang_options.zon +++ b/src/clang_options.zon @@ -637,6 +637,7 @@ }, .{ .name = "version", + .ze = .version, .pd1 = false, .pd2 = true, }, @@ -3378,7 +3379,7 @@ }, .{ .name = "verify-ignore-unexpected" }, .{ .name = "verify-pch" }, -.{ .name = "version" }, +.{ .name = "version", .ze = .version }, .{ .name = "via-file-asm", .pd2 = true }, .{ .name = "w" }, .{ diff --git a/src/main.zig b/src/main.zig index f731e71dd82a9e6e5506bcc50159551b063dbcaa..5554e87c1d263fa31aec9917bde9c1794a80193a 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1889,6 +1889,7 @@ fn buildOutputType( object, assembly, preprocessor, + version, }; var c_out_mode: ?COutMode = null; var out_path: ?[]const u8 = null; @@ -1917,6 +1918,10 @@ fn buildOutputType( .c, .r => c_out_mode = .object, // -c or -r .asm_only => c_out_mode = .assembly, // -S .preprocess_only => c_out_mode = .preprocessor, // -E + .version => { + c_out_mode = .version; // --version + disable_c_depfile = true; + }, .emit_llvm => emit_llvm = true, .x => { const lang = mem.sliceTo(it.only_arg, 0); @@ -2939,9 +2944,11 @@ fn buildOutputType( } // precompiled header syntax: "zig cc -x c-header test.h -o test.pch" - const emit_pch = ((file_ext == .h or file_ext == .hpp or file_ext == .hm or file_ext == .hmm) and c_out_mode == null); - if (emit_pch) - c_out_mode = .preprocessor; + const emit_pch = if (file_ext) |fe| switch (fe) { + .h, .hpp, .hm, .hmm => c_out_mode == null, + else => false, + } else false; + if (emit_pch) c_out_mode = .preprocessor; switch (c_out_mode orelse .link) { .link => { @@ -3009,6 +3016,20 @@ fn buildOutputType( } } }, + .version => { + // We can't allow control flow to reach the simpler logic + // below because the -target argument has to be lowered to + // clang syntax in Compilation. + create_module.opts.output_mode = .Obj; + clang_preprocessor_mode = .version; + if (create_module.c_source_files.items.len == 0) { + try create_module.c_source_files.append(arena, .{ + .owner = undefined, + .src_path = "a.c", // dummy name + .ext = .c, + }); + } + }, } if (create_module.c_source_files.items.len == 0 and !anyObjectLinkInputs(create_module.cli_link_inputs.items) and diff --git a/tools/update_clang_options.zig b/tools/update_clang_options.zig index 882404d5d0a73238e090d6415a353e1f0b5d199e..b2661ac181f1a2f3405ffc19a8da1e48d811647b 100644 --- a/tools/update_clang_options.zig +++ b/tools/update_clang_options.zig @@ -590,6 +590,10 @@ const known_options = [_]KnownOpt{ .name = "dynamic", .ident = "dynamic", }, + .{ + .name = "version", + .ident = "version", + }, }; const blacklisted_options = [_][]const u8{}; -- 2.54.0