Skip to content

Commit 0c1d610

Browse files
committed
zld: handle -current_version and -compatibility_version
and transfer them correctly to the generated dylib as part of the dylib id load command.
1 parent de8e612 commit 0c1d610

File tree

4 files changed

+28
-3
lines changed

4 files changed

+28
-3
lines changed

src/Compilation.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ pub const InitOptions = struct {
758758
image_base_override: ?u64 = null,
759759
self_exe_path: ?[]const u8 = null,
760760
version: ?std.builtin.Version = null,
761+
compatibility_version: ?std.builtin.Version = null,
761762
libc_installation: ?*const LibCInstallation = null,
762763
machine_code_model: std.builtin.CodeModel = .default,
763764
clang_preprocessor_mode: ClangPreprocessorMode = .no,
@@ -1439,6 +1440,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
14391440
.extra_lld_args = options.lld_argv,
14401441
.soname = options.soname,
14411442
.version = options.version,
1443+
.compatibility_version = options.compatibility_version,
14421444
.libc_installation = libc_dirs.libc_installation,
14431445
.pic = pic,
14441446
.pie = pie,

src/link.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ pub const Options = struct {
143143
rpath_list: []const []const u8,
144144

145145
version: ?std.builtin.Version,
146+
compatibility_version: ?std.builtin.Version,
146147
libc_installation: ?*const LibCInstallation,
147148

148149
/// WASI-only. Type of WASI execution model ("command" or "reactor").

src/link/MachO.zig

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4038,12 +4038,16 @@ pub fn populateMissingMetadata(self: *MachO) !void {
40384038
self.base.options.emit.?.sub_path,
40394039
});
40404040
defer self.base.allocator.free(install_name);
4041+
const current_version = self.base.options.version orelse
4042+
std.builtin.Version{ .major = 1, .minor = 0, .patch = 0 };
4043+
const compat_version = self.base.options.compatibility_version orelse
4044+
std.builtin.Version{ .major = 1, .minor = 0, .patch = 0 };
40414045
var dylib_cmd = try commands.createLoadDylibCommand(
40424046
self.base.allocator,
40434047
install_name,
40444048
2,
4045-
0x10000, // TODO forward user-provided versions
4046-
0x10000,
4049+
current_version.major << 16 | current_version.minor << 8 | current_version.patch,
4050+
compat_version.major << 16 | compat_version.minor << 8 | compat_version.patch,
40474051
);
40484052
errdefer dylib_cmd.deinit(self.base.allocator);
40494053
dylib_cmd.inner.cmd = macho.LC_ID_DYLIB;

src/main.zig

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ fn buildOutputType(
564564
var root_src_file: ?[]const u8 = null;
565565
var version: std.builtin.Version = .{ .major = 0, .minor = 0, .patch = 0 };
566566
var have_version = false;
567+
var compatibility_version: ?std.builtin.Version = null;
567568
var strip = false;
568569
var single_threaded = false;
569570
var function_sections = false;
@@ -1613,12 +1614,29 @@ fn buildOutputType(
16131614
) catch |err| {
16141615
fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
16151616
};
1616-
} else if (mem.eql(u8, arg, "-weak_framework")) {
1617+
} else if (mem.eql(u8, arg, "-framework") or mem.eql(u8, arg, "-weak_framework")) {
16171618
i += 1;
16181619
if (i >= linker_args.items.len) {
16191620
fatal("expected linker arg after '{s}'", .{arg});
16201621
}
16211622
try frameworks.append(linker_args.items[i]);
1623+
} else if (mem.eql(u8, arg, "-compatibility_version")) {
1624+
i += 1;
1625+
if (i >= linker_args.items.len) {
1626+
fatal("expected linker arg after '{s}'", .{arg});
1627+
}
1628+
compatibility_version = std.builtin.Version.parse(linker_args.items[i]) catch |err| {
1629+
fatal("unable to parse -compatibility_version '{s}': {s}", .{ linker_args.items[i], @errorName(err) });
1630+
};
1631+
} else if (mem.eql(u8, arg, "-current_version")) {
1632+
i += 1;
1633+
if (i >= linker_args.items.len) {
1634+
fatal("expected linker arg after '{s}'", .{arg});
1635+
}
1636+
version = std.builtin.Version.parse(linker_args.items[i]) catch |err| {
1637+
fatal("unable to parse -current_version '{s}': {s}", .{ linker_args.items[i], @errorName(err) });
1638+
};
1639+
have_version = true;
16221640
} else {
16231641
warn("unsupported linker arg: {s}", .{arg});
16241642
}

0 commit comments

Comments
 (0)