Upstream-Bug: https://codeberg.org/ziglang/zig/issues/36919 Patch-Author: https://codeberg.org/mganguin --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -24,6 +24,8 @@ msvc_lib_dir: ?[]const u8 = null, kernel32_lib_dir: ?[]const u8 = null, cc_dir: ?[]const u8 = null, darwin_sdk_dir: ?[]const u8 = null, +crtbegin_obj: ?[]const u8 = null, +crtend_obj: ?[]const u8 = null, pub const FindError = error{ OutOfMemory, @@ -147,6 +149,11 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void { \\# Only needed when targeting Haiku, Linux, or SerenityOS. \\cc_dir={s} \\ + \\# Define these if the crtbegin/end files are not named `crtbegin.o` and `crtend.o` + \\# Only needed when using LLVM compiler-rt versions `clang_rt.crtbegin-x86_64.o` + \\crtbegin_obj={s} + \\crtend_obj={s} + \\ \\# The directory that contains `crt1.o` or `crt2.o`. \\# On POSIX, can be found with `cc -print-file-name=crt1.o`. \\crt_dir={s} @@ -167,6 +174,8 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void { self.include_dir orelse "", self.sys_include_dir orelse "", self.cc_dir orelse "", + self.crtbegin_obj orelse "", + self.crtend_obj orelse "", self.crt_dir orelse "", self.msvc_lib_dir orelse "", self.kernel32_lib_dir orelse "", @@ -469,12 +478,25 @@ fn findNativeCrtDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: } fn findNativeGccDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void { - self.cc_dir = try ccPrintFileName(gpa, io, .{ + self.cc_dir = ccPrintFileName(gpa, io, .{ .environ_map = args.environ_map, .search_basename = "crtbeginS.o", .want_dirname = .only_dir, .verbose = args.verbose, - }); + }) catch |err| switch (err) { + error.LibCRuntimeNotFound => blk: { + // crtbeginS.o not found, try again with LLVM compiler-rt crtbegin + self.crtbegin_obj = try gpa.print("clang_rt.crtbegin-{s}.o", .{@tagName(args.target.cpu.arch)}); + self.crtend_obj = try gpa.print("clang_rt.crtend-{s}.o", .{@tagName(args.target.cpu.arch)}); + break :blk try ccPrintFileName(gpa, io, .{ + .environ_map = args.environ_map, + .search_basename = self.crtbegin_obj.?, + .want_dirname = .only_dir, + .verbose = args.verbose, + }); + }, + else => return err, + }; } fn findNativeKernel32LibDir( @@ -1036,11 +1058,16 @@ pub fn resolveCrtPaths( .root_dir = Cache.Directory.cwd(), .sub_path = lci.cc_dir orelse return error.LibCInstallationMissingCcDir, }; + + // LLVM compiler-rt has only one version of crtbegin, regardless of link_mode + const crtbegin = lci.crtbegin_obj orelse crt_basenames.crtbegin; + const crtend = lci.crtend_obj orelse crt_basenames.crtend; + 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 cc_dir_path.join(arena, basename) else null, - .crtend = if (crt_basenames.crtend) |basename| try cc_dir_path.join(arena, basename) else null, + .crtbegin = if (crtbegin) |basename| try cc_dir_path.join(arena, basename) else null, + .crtend = if (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, }; },