From 2f20ee373bbb2527272ed04af46ba68963f8b7ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sun, 7 Dec 2025 09:11:01 +0100 Subject: [PATCH] libc: deal with freebsd 15 changes (new libsys, libutil sover) --- src/libs/freebsd.zig | 41 ++++++++++++++++++++++++++++++++--------- src/link/Lld.zig | 6 +++++- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/libs/freebsd.zig b/src/libs/freebsd.zig index ff32b4649a..439ee903a5 100644 --- a/src/libs/freebsd.zig +++ b/src/libs/freebsd.zig @@ -257,6 +257,12 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre pub const Lib = struct { name: []const u8, sover: u8, + added_in: ?Version = null, + + pub fn getSoVersion(lib: Lib, os: *const std.Target.Os) u8 { + if (std.mem.eql(u8, lib.name, "util") and os.version_range.semver.min.major >= 15) return 10; + return lib.sover; + } }; pub const libs = [_]Lib{ @@ -269,6 +275,7 @@ pub const libs = [_]Lib{ .{ .name = "ld", .sover = 1 }, .{ .name = "util", .sover = 9 }, .{ .name = "execinfo", .sover = 1 }, + .{ .name = "sys", .sover = 7, .added_in = .{ .major = 15, .minor = 0, .patch = 0 } }, }; pub const ABI = struct { @@ -434,7 +441,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye const target = comp.getTarget(); // FreeBSD 7 == FBSD_1.0, ..., FreeBSD 14 == FBSD_1.7 - const target_version: Version = .{ .major = 1, .minor = target.os.version_range.semver.min.major - 7, .patch = 0 }; + const target_os_version: Version = target.os.version_range.semver.min; + const target_libc_version: Version = .{ .major = 1, .minor = target_os_version.major - 7, .patch = 0 }; // Use the global cache directory. var cache: Cache = .{ @@ -452,7 +460,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye man.hash.addBytes(build_options.version); man.hash.add(target.cpu.arch); man.hash.add(target.abi); - man.hash.add(target_version); + man.hash.add(target_os_version); const full_abilists_path = try comp.dirs.zig_lib.join(arena, &.{abilists_path}); const abilists_index = try man.addFile(full_abilists_path, abilists_max_size); @@ -494,19 +502,19 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye }; const target_ver_index = for (metadata.all_versions, 0..) |ver, i| { - switch (ver.order(target_version)) { + switch (ver.order(target_libc_version)) { .eq => break i, .lt => continue, .gt => { // TODO Expose via compile error mechanism instead of log. - log.warn("invalid target FreeBSD libc version: {f}", .{target_version}); + log.warn("invalid target FreeBSD libc version: {f}", .{target_libc_version}); return error.InvalidTargetLibCVersion; }, } } else blk: { const latest_index = metadata.all_versions.len - 1; log.warn("zig cannot build new FreeBSD libc version {f}; providing instead {f}", .{ - target_version, metadata.all_versions[latest_index], + target_libc_version, metadata.all_versions[latest_index], }); break :blk latest_index; }; @@ -524,6 +532,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye defer stubs_asm.deinit(); for (libs, 0..) |lib, lib_i| { + if (lib.added_in) |add_in| { + // Note: Compare OS version, not libc version. + if (target.os.version_range.semver.min.order(add_in) == .lt) continue; + } + stubs_asm.shrinkRetainingCapacity(0); try stubs_asm.appendSlice(".text\n"); @@ -983,6 +996,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye } fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { + const target = comp.getTarget(); + const target_os_version = target.os.version_range.semver.min; + assert(comp.freebsd_so_files == null); comp.freebsd_so_files = so_files; @@ -994,10 +1010,14 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { defer comp.mutex.unlock(); for (libs) |lib| { + if (lib.added_in) |add_in| { + if (target_os_version.order(add_in) == .lt) continue; + } + const so_path: Path = .{ .root_dir = so_files.dir_path.root_dir, .sub_path = std.fmt.allocPrint(comp.arena, "{s}{c}lib{s}.so.{d}", .{ - so_files.dir_path.sub_path, fs.path.sep, lib.name, lib.sover, + so_files.dir_path.sub_path, fs.path.sep, lib.name, lib.getSoVersion(&target.os), }) catch return comp.setAllocFailure(), }; task_buffer[task_buffer_i] = .{ .load_dso = so_path }; @@ -1019,10 +1039,13 @@ fn buildSharedLib( const tracy = trace(@src()); defer tracy.end(); + const target = comp.getTarget(); + const io = comp.io; - const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover }); - const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 }; - const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?); + const sover = lib.getSoVersion(&target.os); + const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, sover }); + const version: Version = .{ .major = sover, .minor = 0, .patch = 0 }; + const ld_basename = path.basename(target.standardDynamicLinkerPath().get().?); const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename; const map_file_path = try path.join(arena, &.{ bin_directory.path.?, all_map_basename }); diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 7b1e34df78..2345090482 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -1190,8 +1190,12 @@ fn elfLink(lld: *Lld, arena: Allocator) !void { })); } else if (target.isFreeBSDLibC()) { for (freebsd.libs) |lib| { + if (lib.added_in) |add_in| { + if (target.os.version_range.semver.min.order(add_in) == .lt) continue; + } + const lib_path = try std.fmt.allocPrint(arena, "{f}{c}lib{s}.so.{d}", .{ - comp.freebsd_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover, + comp.freebsd_so_files.?.dir_path, fs.path.sep, lib.name, lib.getSoVersion(&target.os), }); try argv.append(lib_path); }