authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-09-25 11:32:46+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-09-25 23:41:20+02:00
log1e770dbef6f5f34ccb1e61db7edcfb1e705fe1ee
tree8166c4f521cd9e2c0c1d815cd127a84426face96
parent7cef4755c33ca77137fb7e4d83146e27b5703685

std.zig.LibCInstallation: rename gcc_dir to cc_dir, clarify doc comments and errors

closes https://codeberg.org/ziglang/zig/issues/36948

2 files changed, 33 insertions(+), 25 deletions(-)

lib/std/zig/LibCInstallation.zig+28-23
...@@ -22,7 +22,7 @@ sys_include_dir: ?[]const u8 = null,...@@ -22,7 +22,7 @@ sys_include_dir: ?[]const u8 = null,
22crt_dir: ?[]const u8 = null,22crt_dir: ?[]const u8 = null,
23msvc_lib_dir: ?[]const u8 = null,23msvc_lib_dir: ?[]const u8 = null,
24kernel32_lib_dir: ?[]const u8 = null,24kernel32_lib_dir: ?[]const u8 = null,
25gcc_dir: ?[]const u8 = null,25cc_dir: ?[]const u8 = null,
2626
27pub const FindError = error{27pub const FindError = error{
28 OutOfMemory,28 OutOfMemory,
...@@ -67,7 +67,10 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const...@@ -67,7 +67,10 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const
67 const name = line_it.first();67 const name = line_it.first();
68 const value = line_it.rest();68 const value = line_it.rest();
69 inline for (field_names, 0..) |field_name, i| {69 inline for (field_names, 0..) |field_name, i| {
70 if (std.mem.eql(u8, name, field_name)) {70 // Allow `gcc_dir` as an alias for `cc_dir` for compatibility with older files.
71 if (std.mem.eql(u8, name, field_name) or
72 (std.mem.eql(u8, name, "gcc_dir") and std.mem.eql(u8, field_name, "cc_dir")))
73 {
71 found_keys[i].found = true;74 found_keys[i].found = true;
72 if (value.len == 0) {75 if (value.len == 0) {
73 @field(self, field_name) = null;76 @field(self, field_name) = null;
...@@ -95,6 +98,12 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const...@@ -95,6 +98,12 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const
95 }98 }
9699
97 const os_tag = target.os.tag;100 const os_tag = target.os.tag;
101
102 if (self.cc_dir == null and (os_tag == .haiku or os_tag == .serenity or os_tag == .linux)) {
103 log.err("cc_dir may not be empty for {s}", .{@tagName(os_tag)});
104 return error.ParseError;
105 }
106
98 if (self.crt_dir == null and !target.os.tag.isDarwin()) {107 if (self.crt_dir == null and !target.os.tag.isDarwin()) {
99 log.err("crt_dir may not be empty for {s}", .{@tagName(os_tag)});108 log.err("crt_dir may not be empty for {s}", .{@tagName(os_tag)});
100 return error.ParseError;109 return error.ParseError;
...@@ -115,11 +124,6 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const...@@ -115,11 +124,6 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const
115 return error.ParseError;124 return error.ParseError;
116 }125 }
117126
118 if (self.gcc_dir == null and (os_tag == .haiku or os_tag == .serenity)) {
119 log.err("gcc_dir may not be empty for {s}", .{@tagName(os_tag)});
120 return error.ParseError;
121 }
122
123 return self;127 return self;
124}128}
125129
...@@ -130,21 +134,26 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void {...@@ -130,21 +134,26 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void {
130 const crt_dir = self.crt_dir orelse "";134 const crt_dir = self.crt_dir orelse "";
131 const msvc_lib_dir = self.msvc_lib_dir orelse "";135 const msvc_lib_dir = self.msvc_lib_dir orelse "";
132 const kernel32_lib_dir = self.kernel32_lib_dir orelse "";136 const kernel32_lib_dir = self.kernel32_lib_dir orelse "";
133 const gcc_dir = self.gcc_dir orelse "";137 const cc_dir = self.cc_dir orelse "";
134138
135 try out.print(139 try out.print(
136 \\# The directory that contains `stdlib.h`.140 \\# The directory that contains `stdlib.h`.
137 \\# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`141 \\# On POSIX, can be found with: `cc -E -Wp,-v -xc /dev/null`
138 \\include_dir={s}142 \\include_dir={s}
139 \\143 \\
140 \\# The system-specific include directory. May be the same as `include_dir`.144 \\# The system-specific include directory. May be the same as `include_dir`.
141 \\# On Windows it's the directory that includes `vcruntime.h`.145 \\# On Windows, it's the directory that includes `vcruntime.h`.
142 \\# On POSIX it's the directory that includes `sys/errno.h`.146 \\# On POSIX, it's the directory that includes `sys/errno.h`.
143 \\sys_include_dir={s}147 \\sys_include_dir={s}
144 \\148 \\
149 \\# The directory that contains `crtbegin.o` and `crtend.o`. May be the same as `crt_dir`.
150 \\# On POSIX, can be found with `cc -print-file-name=crtbegin.o`.
151 \\# Only needed when targeting Haiku, Linux, or SerenityOS.
152 \\cc_dir={s}
153 \\
145 \\# The directory that contains `crt1.o` or `crt2.o`.154 \\# The directory that contains `crt1.o` or `crt2.o`.
146 \\# On POSIX, can be found with `cc -print-file-name=crt1.o`.155 \\# On POSIX, can be found with `cc -print-file-name=crt1.o`.
147 \\# Not needed when targeting MacOS.156 \\# Not needed when targeting macOS.
148 \\crt_dir={s}157 \\crt_dir={s}
149 \\158 \\
150 \\# The directory that contains `vcruntime.lib`.159 \\# The directory that contains `vcruntime.lib`.
...@@ -155,17 +164,13 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void {...@@ -155,17 +164,13 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void {
155 \\# Only needed when targeting MSVC on Windows.164 \\# Only needed when targeting MSVC on Windows.
156 \\kernel32_lib_dir={s}165 \\kernel32_lib_dir={s}
157 \\166 \\
158 \\# The directory that contains `crtbeginS.o` and `crtendS.o`
159 \\# Only needed when targeting Haiku.
160 \\gcc_dir={s}
161 \\
162 , .{167 , .{
163 include_dir,168 include_dir,
164 sys_include_dir,169 sys_include_dir,
165 crt_dir,170 crt_dir,
166 msvc_lib_dir,171 msvc_lib_dir,
167 kernel32_lib_dir,172 kernel32_lib_dir,
168 gcc_dir,173 cc_dir,
169 });174 });
170}175}
171176
...@@ -467,7 +472,7 @@ fn findNativeCrtDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args:...@@ -467,7 +472,7 @@ fn findNativeCrtDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args:
467}472}
468473
469fn findNativeGccDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {474fn findNativeGccDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
470 self.gcc_dir = try ccPrintFileName(gpa, io, .{475 self.cc_dir = try ccPrintFileName(gpa, io, .{
471 .environ_map = args.environ_map,476 .environ_map = args.environ_map,
472 .search_basename = "crtbeginS.o",477 .search_basename = "crtbeginS.o",
473 .want_dirname = .only_dir,478 .want_dirname = .only_dir,
...@@ -1002,7 +1007,7 @@ pub fn resolveCrtPaths(...@@ -1002,7 +1007,7 @@ pub fn resolveCrtPaths(
1002 arena: Allocator,1007 arena: Allocator,
1003 crt_basenames: CrtBasenames,1008 crt_basenames: CrtBasenames,
1004 target: *const std.Target,1009 target: *const std.Target,
1005) error{ OutOfMemory, LibCInstallationMissingCrtDir }!CrtPaths {1010) error{ OutOfMemory, LibCInstallationMissingCcDir, LibCInstallationMissingCrtDir }!CrtPaths {
1006 const crt_dir_path: Path = .{1011 const crt_dir_path: Path = .{
1007 .root_dir = Cache.Directory.cwd(),1012 .root_dir = Cache.Directory.cwd(),
1008 .sub_path = lci.crt_dir orelse return error.LibCInstallationMissingCrtDir,1013 .sub_path = lci.crt_dir orelse return error.LibCInstallationMissingCrtDir,
...@@ -1030,15 +1035,15 @@ pub fn resolveCrtPaths(...@@ -1030,15 +1035,15 @@ pub fn resolveCrtPaths(
1030 };1035 };
1031 },1036 },
1032 .haiku, .serenity, .linux => {1037 .haiku, .serenity, .linux => {
1033 const gcc_dir_path: Path = .{1038 const cc_dir_path: Path = .{
1034 .root_dir = Cache.Directory.cwd(),1039 .root_dir = Cache.Directory.cwd(),
1035 .sub_path = lci.gcc_dir orelse return error.LibCInstallationMissingCrtDir,1040 .sub_path = lci.cc_dir orelse return error.LibCInstallationMissingCcDir,
1036 };1041 };
1037 return .{1042 return .{
1038 .crt0 = if (crt_basenames.crt0) |basename| try crt_dir_path.join(arena, basename) else null,1043 .crt0 = if (crt_basenames.crt0) |basename| try crt_dir_path.join(arena, basename) else null,
1039 .crti = if (crt_basenames.crti) |basename| try crt_dir_path.join(arena, basename) else null,1044 .crti = if (crt_basenames.crti) |basename| try crt_dir_path.join(arena, basename) else null,
1040 .crtbegin = if (crt_basenames.crtbegin) |basename| try gcc_dir_path.join(arena, basename) else null,1045 .crtbegin = if (crt_basenames.crtbegin) |basename| try cc_dir_path.join(arena, basename) else null,
1041 .crtend = if (crt_basenames.crtend) |basename| try gcc_dir_path.join(arena, basename) else null,1046 .crtend = if (crt_basenames.crtend) |basename| try cc_dir_path.join(arena, basename) else null,
1042 .crtn = if (crt_basenames.crtn) |basename| try crt_dir_path.join(arena, basename) else null,1047 .crtn = if (crt_basenames.crtn) |basename| try crt_dir_path.join(arena, basename) else null,
1043 };1048 };
1044 },1049 },
src/Compilation.zig+5-2
...@@ -1679,6 +1679,7 @@ pub const CreateDiagnostic = union(enum) {...@@ -1679,6 +1679,7 @@ pub const CreateDiagnostic = union(enum) {
1679 illegal_zig_import,1679 illegal_zig_import,
1680 cross_libc_unavailable,1680 cross_libc_unavailable,
1681 find_native_libc: std.zig.LibCInstallation.FindError,1681 find_native_libc: std.zig.LibCInstallation.FindError,
1682 libc_installation_missing_cc_dir,
1682 libc_installation_missing_crt_dir,1683 libc_installation_missing_crt_dir,
1683 create_cache_path: CreateCachePath,1684 create_cache_path: CreateCachePath,
1684 open_output_bin: link.File.OpenError,1685 open_output_bin: link.File.OpenError,
...@@ -1694,6 +1695,7 @@ pub const CreateDiagnostic = union(enum) {...@@ -1694,6 +1695,7 @@ pub const CreateDiagnostic = union(enum) {
1694 .illegal_zig_import => try w.writeAll("this compiler implementation does not support importing the root source file of a provided module"),1695 .illegal_zig_import => try w.writeAll("this compiler implementation does not support importing the root source file of a provided module"),
1695 .cross_libc_unavailable => try w.writeAll("unable to provide libc for this target"),1696 .cross_libc_unavailable => try w.writeAll("unable to provide libc for this target"),
1696 .find_native_libc => |err| try w.print("failed to find libc installation: {t}", .{err}),1697 .find_native_libc => |err| try w.print("failed to find libc installation: {t}", .{err}),
1698 .libc_installation_missing_cc_dir => try w.writeAll("libc installation is missing cc directory"),
1697 .libc_installation_missing_crt_dir => try w.writeAll("libc installation is missing crt directory"),1699 .libc_installation_missing_crt_dir => try w.writeAll("libc installation is missing crt directory"),
1698 .create_cache_path => |cache| try w.print("failed to create path '{s}' in {t} cache directory: {t}", .{1700 .create_cache_path => |cache| try w.print("failed to create path '{s}' in {t} cache directory: {t}", .{
1699 cache.sub,1701 cache.sub,
...@@ -2441,6 +2443,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2441,6 +2443,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
2441 });2443 });
2442 const paths = lci.resolveCrtPaths(arena, basenames, target) catch |err| switch (err) {2444 const paths = lci.resolveCrtPaths(arena, basenames, target) catch |err| switch (err) {
2443 error.OutOfMemory => |e| return e,2445 error.OutOfMemory => |e| return e,
2446 error.LibCInstallationMissingCcDir => return diag.fail(.libc_installation_missing_cc_dir),
2444 error.LibCInstallationMissingCrtDir => return diag.fail(.libc_installation_missing_crt_dir),2447 error.LibCInstallationMissingCrtDir => return diag.fail(.libc_installation_missing_crt_dir),
2445 };2448 };
24462449
...@@ -7657,7 +7660,7 @@ pub fn toCrtFile(comp: *Compilation) Allocator.Error!CrtFile {...@@ -7657,7 +7660,7 @@ pub fn toCrtFile(comp: *Compilation) Allocator.Error!CrtFile {
7657pub fn getCrtPaths(7660pub fn getCrtPaths(
7658 comp: *Compilation,7661 comp: *Compilation,
7659 arena: Allocator,7662 arena: Allocator,
7660) error{ OutOfMemory, LibCInstallationMissingCrtDir }!LibCInstallation.CrtPaths {7663) error{ OutOfMemory, LibCInstallationMissingCcDir, LibCInstallationMissingCrtDir }!LibCInstallation.CrtPaths {
7661 const target = &comp.root_mod.resolved_target.result;7664 const target = &comp.root_mod.resolved_target.result;
7662 return getCrtPathsInner(arena, target, comp.config, comp.libc_installation, &comp.crt_files);7665 return getCrtPathsInner(arena, target, comp.config, comp.libc_installation, &comp.crt_files);
7663}7666}
...@@ -7668,7 +7671,7 @@ fn getCrtPathsInner(...@@ -7668,7 +7671,7 @@ fn getCrtPathsInner(
7668 config: Config,7671 config: Config,
7669 libc_installation: ?*const LibCInstallation,7672 libc_installation: ?*const LibCInstallation,
7670 crt_files: *std.StringHashMapUnmanaged(CrtFile),7673 crt_files: *std.StringHashMapUnmanaged(CrtFile),
7671) error{ OutOfMemory, LibCInstallationMissingCrtDir }!LibCInstallation.CrtPaths {7674) error{ OutOfMemory, LibCInstallationMissingCcDir, LibCInstallationMissingCrtDir }!LibCInstallation.CrtPaths {
7672 const basenames = LibCInstallation.CrtBasenames.get(.{7675 const basenames = LibCInstallation.CrtBasenames.get(.{
7673 .target = target,7676 .target = target,
7674 .link_libc = config.link_libc,7677 .link_libc = config.link_libc,