diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig index 3af7d51fbaf82a22a41355c252d6bbbf921e7f97..fe44e3a307ccaa56671b2dbfe50b25afc4f4f935 100644 --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -22,7 +22,7 @@ sys_include_dir: ?[]const u8 = null, crt_dir: ?[]const u8 = null, msvc_lib_dir: ?[]const u8 = null, kernel32_lib_dir: ?[]const u8 = null, -gcc_dir: ?[]const u8 = null, +cc_dir: ?[]const u8 = null, pub const FindError = error{ OutOfMemory, @@ -67,7 +67,10 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const const name = line_it.first(); const value = line_it.rest(); inline for (field_names, 0..) |field_name, i| { - if (std.mem.eql(u8, name, field_name)) { + // Allow `gcc_dir` as an alias for `cc_dir` for compatibility with older files. + if (std.mem.eql(u8, name, field_name) or + (std.mem.eql(u8, name, "gcc_dir") and std.mem.eql(u8, field_name, "cc_dir"))) + { found_keys[i].found = true; if (value.len == 0) { @field(self, field_name) = null; @@ -95,6 +98,12 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const } const os_tag = target.os.tag; + + if (self.cc_dir == null and (os_tag == .haiku or os_tag == .serenity or os_tag == .linux)) { + log.err("cc_dir may not be empty for {s}", .{@tagName(os_tag)}); + return error.ParseError; + } + if (self.crt_dir == null and !target.os.tag.isDarwin()) { log.err("crt_dir may not be empty for {s}", .{@tagName(os_tag)}); return error.ParseError; @@ -115,11 +124,6 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const return error.ParseError; } - if (self.gcc_dir == null and (os_tag == .haiku or os_tag == .serenity)) { - log.err("gcc_dir may not be empty for {s}", .{@tagName(os_tag)}); - return error.ParseError; - } - return self; } @@ -130,21 +134,26 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void { const crt_dir = self.crt_dir orelse ""; const msvc_lib_dir = self.msvc_lib_dir orelse ""; const kernel32_lib_dir = self.kernel32_lib_dir orelse ""; - const gcc_dir = self.gcc_dir orelse ""; + const cc_dir = self.cc_dir orelse ""; try out.print( \\# The directory that contains `stdlib.h`. - \\# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null` + \\# On POSIX, can be found with: `cc -E -Wp,-v -xc /dev/null` \\include_dir={s} \\ \\# The system-specific include directory. May be the same as `include_dir`. - \\# On Windows it's the directory that includes `vcruntime.h`. - \\# On POSIX it's the directory that includes `sys/errno.h`. + \\# On Windows, it's the directory that includes `vcruntime.h`. + \\# On POSIX, it's the directory that includes `sys/errno.h`. \\sys_include_dir={s} \\ + \\# The directory that contains `crtbegin.o` and `crtend.o`. May be the same as `crt_dir`. + \\# On POSIX, can be found with `cc -print-file-name=crtbegin.o`. + \\# Only needed when targeting Haiku, Linux, or SerenityOS. + \\cc_dir={s} + \\ \\# The directory that contains `crt1.o` or `crt2.o`. \\# On POSIX, can be found with `cc -print-file-name=crt1.o`. - \\# Not needed when targeting MacOS. + \\# Not needed when targeting macOS. \\crt_dir={s} \\ \\# The directory that contains `vcruntime.lib`. @@ -155,17 +164,13 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void { \\# Only needed when targeting MSVC on Windows. \\kernel32_lib_dir={s} \\ - \\# The directory that contains `crtbeginS.o` and `crtendS.o` - \\# Only needed when targeting Haiku. - \\gcc_dir={s} - \\ , .{ include_dir, sys_include_dir, crt_dir, msvc_lib_dir, kernel32_lib_dir, - gcc_dir, + cc_dir, }); } @@ -467,7 +472,7 @@ fn findNativeCrtDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: } fn findNativeGccDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void { - self.gcc_dir = try ccPrintFileName(gpa, io, .{ + self.cc_dir = try ccPrintFileName(gpa, io, .{ .environ_map = args.environ_map, .search_basename = "crtbeginS.o", .want_dirname = .only_dir, @@ -1002,7 +1007,7 @@ pub fn resolveCrtPaths( arena: Allocator, crt_basenames: CrtBasenames, target: *const std.Target, -) error{ OutOfMemory, LibCInstallationMissingCrtDir }!CrtPaths { +) error{ OutOfMemory, LibCInstallationMissingCcDir, LibCInstallationMissingCrtDir }!CrtPaths { const crt_dir_path: Path = .{ .root_dir = Cache.Directory.cwd(), .sub_path = lci.crt_dir orelse return error.LibCInstallationMissingCrtDir, @@ -1030,15 +1035,15 @@ pub fn resolveCrtPaths( }; }, .haiku, .serenity, .linux => { - const gcc_dir_path: Path = .{ + const cc_dir_path: Path = .{ .root_dir = Cache.Directory.cwd(), - .sub_path = lci.gcc_dir orelse return error.LibCInstallationMissingCrtDir, + .sub_path = lci.cc_dir orelse return error.LibCInstallationMissingCcDir, }; return .{ .crt0 = if (crt_basenames.crt0) |basename| try crt_dir_path.join(arena, basename) else null, .crti = if (crt_basenames.crti) |basename| try crt_dir_path.join(arena, basename) else null, - .crtbegin = if (crt_basenames.crtbegin) |basename| try gcc_dir_path.join(arena, basename) else null, - .crtend = if (crt_basenames.crtend) |basename| try gcc_dir_path.join(arena, basename) else null, + .crtbegin = if (crt_basenames.crtbegin) |basename| try cc_dir_path.join(arena, basename) else null, + .crtend = if (crt_basenames.crtend) |basename| try cc_dir_path.join(arena, basename) else null, .crtn = if (crt_basenames.crtn) |basename| try crt_dir_path.join(arena, basename) else null, }; }, diff --git a/src/Compilation.zig b/src/Compilation.zig index b07db94185836ffcffb95cbf7a3286c947439820..1b5ba7c652f9c940c8e947241536cbd110d1692b 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1679,6 +1679,7 @@ pub const CreateDiagnostic = union(enum) { illegal_zig_import, cross_libc_unavailable, find_native_libc: std.zig.LibCInstallation.FindError, + libc_installation_missing_cc_dir, libc_installation_missing_crt_dir, create_cache_path: CreateCachePath, open_output_bin: link.File.OpenError, @@ -1694,6 +1695,7 @@ pub const CreateDiagnostic = union(enum) { .illegal_zig_import => try w.writeAll("this compiler implementation does not support importing the root source file of a provided module"), .cross_libc_unavailable => try w.writeAll("unable to provide libc for this target"), .find_native_libc => |err| try w.print("failed to find libc installation: {t}", .{err}), + .libc_installation_missing_cc_dir => try w.writeAll("libc installation is missing cc directory"), .libc_installation_missing_crt_dir => try w.writeAll("libc installation is missing crt directory"), .create_cache_path => |cache| try w.print("failed to create path '{s}' in {t} cache directory: {t}", .{ cache.sub, @@ -2441,6 +2443,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, }); const paths = lci.resolveCrtPaths(arena, basenames, target) catch |err| switch (err) { error.OutOfMemory => |e| return e, + error.LibCInstallationMissingCcDir => return diag.fail(.libc_installation_missing_cc_dir), error.LibCInstallationMissingCrtDir => return diag.fail(.libc_installation_missing_crt_dir), }; @@ -7657,7 +7660,7 @@ pub fn toCrtFile(comp: *Compilation) Allocator.Error!CrtFile { pub fn getCrtPaths( comp: *Compilation, arena: Allocator, -) error{ OutOfMemory, LibCInstallationMissingCrtDir }!LibCInstallation.CrtPaths { +) error{ OutOfMemory, LibCInstallationMissingCcDir, LibCInstallationMissingCrtDir }!LibCInstallation.CrtPaths { const target = &comp.root_mod.resolved_target.result; return getCrtPathsInner(arena, target, comp.config, comp.libc_installation, &comp.crt_files); } @@ -7668,7 +7671,7 @@ fn getCrtPathsInner( config: Config, libc_installation: ?*const LibCInstallation, crt_files: *std.StringHashMapUnmanaged(CrtFile), -) error{ OutOfMemory, LibCInstallationMissingCrtDir }!LibCInstallation.CrtPaths { +) error{ OutOfMemory, LibCInstallationMissingCcDir, LibCInstallationMissingCrtDir }!LibCInstallation.CrtPaths { const basenames = LibCInstallation.CrtBasenames.get(.{ .target = target, .link_libc = config.link_libc,