From 0c1d610015e04c96508750e95b2f88408ded8843 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Tue, 23 Nov 2021 15:59:49 +0100 Subject: [PATCH] zld: handle -current_version and -compatibility_version and transfer them correctly to the generated dylib as part of the dylib id load command. --- src/Compilation.zig | 2 ++ src/link.zig | 1 + src/link/MachO.zig | 8 ++++++-- src/main.zig | 20 +++++++++++++++++++- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index e23b6a12e495fd5e9f459ffa702085228c2b103e..48899f6f6e9c6696e24c956f6478f628dec0cdff 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -758,6 +758,7 @@ pub const InitOptions = struct { image_base_override: ?u64 = null, self_exe_path: ?[]const u8 = null, version: ?std.builtin.Version = null, + compatibility_version: ?std.builtin.Version = null, libc_installation: ?*const LibCInstallation = null, machine_code_model: std.builtin.CodeModel = .default, clang_preprocessor_mode: ClangPreprocessorMode = .no, @@ -1439,6 +1440,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .extra_lld_args = options.lld_argv, .soname = options.soname, .version = options.version, + .compatibility_version = options.compatibility_version, .libc_installation = libc_dirs.libc_installation, .pic = pic, .pie = pie, diff --git a/src/link.zig b/src/link.zig index 932c582367b6d1eb5a3e739a3ad882e119c0f2c2..4ad5952767e4310f9bf131f67edd7b87292ff64a 100644 --- a/src/link.zig +++ b/src/link.zig @@ -143,6 +143,7 @@ pub const Options = struct { rpath_list: []const []const u8, version: ?std.builtin.Version, + compatibility_version: ?std.builtin.Version, libc_installation: ?*const LibCInstallation, /// WASI-only. Type of WASI execution model ("command" or "reactor"). diff --git a/src/link/MachO.zig b/src/link/MachO.zig index d1971baa05fb3182dad7a39e877ef6732ac72dc3..483c5c837170773dd9b001d303ef185e31a8ba45 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -4038,12 +4038,16 @@ pub fn populateMissingMetadata(self: *MachO) !void { self.base.options.emit.?.sub_path, }); defer self.base.allocator.free(install_name); + const current_version = self.base.options.version orelse + std.builtin.Version{ .major = 1, .minor = 0, .patch = 0 }; + const compat_version = self.base.options.compatibility_version orelse + std.builtin.Version{ .major = 1, .minor = 0, .patch = 0 }; var dylib_cmd = try commands.createLoadDylibCommand( self.base.allocator, install_name, 2, - 0x10000, // TODO forward user-provided versions - 0x10000, + current_version.major << 16 | current_version.minor << 8 | current_version.patch, + compat_version.major << 16 | compat_version.minor << 8 | compat_version.patch, ); errdefer dylib_cmd.deinit(self.base.allocator); dylib_cmd.inner.cmd = macho.LC_ID_DYLIB; diff --git a/src/main.zig b/src/main.zig index 824cc6384684a87bbbadcdf4346e59515eab029e..0b274b3aee1403964e6db7c49c60fcce1e766da7 100644 --- a/src/main.zig +++ b/src/main.zig @@ -564,6 +564,7 @@ fn buildOutputType( var root_src_file: ?[]const u8 = null; var version: std.builtin.Version = .{ .major = 0, .minor = 0, .patch = 0 }; var have_version = false; + var compatibility_version: ?std.builtin.Version = null; var strip = false; var single_threaded = false; var function_sections = false; @@ -1613,12 +1614,29 @@ fn buildOutputType( ) catch |err| { fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); }; - } else if (mem.eql(u8, arg, "-weak_framework")) { + } else if (mem.eql(u8, arg, "-framework") or mem.eql(u8, arg, "-weak_framework")) { i += 1; if (i >= linker_args.items.len) { fatal("expected linker arg after '{s}'", .{arg}); } try frameworks.append(linker_args.items[i]); + } else if (mem.eql(u8, arg, "-compatibility_version")) { + i += 1; + if (i >= linker_args.items.len) { + fatal("expected linker arg after '{s}'", .{arg}); + } + compatibility_version = std.builtin.Version.parse(linker_args.items[i]) catch |err| { + fatal("unable to parse -compatibility_version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); + }; + } else if (mem.eql(u8, arg, "-current_version")) { + i += 1; + if (i >= linker_args.items.len) { + fatal("expected linker arg after '{s}'", .{arg}); + } + version = std.builtin.Version.parse(linker_args.items[i]) catch |err| { + fatal("unable to parse -current_version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); + }; + have_version = true; } else { warn("unsupported linker arg: {s}", .{arg}); } -- 2.54.0