From 0a76a9bd738471e2edddf71a822ff76c47bfd094 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Fri, 11 Sep 2020 01:22:18 +0200 Subject: std, stage1: make shared library versioning optional This commit changes the behavior of stage1 to emit libfoo.so instead of libfoo.so.0.0.0 when none of the --ver-major, --ver-minor, or --ver-patch flags are set. It also makes it possible to create unversioned shared libraries using the zig build system, changing the version parameter of addSharedLibrary() to a tagged union. --- lib/std/build.zig | 98 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 34 deletions(-) (limited to 'lib/std') diff --git a/lib/std/build.zig b/lib/std/build.zig index 1673737bef..8aa473f8bc 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -258,9 +258,14 @@ pub const Builder = struct { })); } - pub fn addSharedLibrary(self: *Builder, name: []const u8, root_src: ?[]const u8, ver: Version) *LibExeObjStep { + pub fn addSharedLibrary( + self: *Builder, + name: []const u8, + root_src: ?[]const u8, + kind: LibExeObjStep.SharedLibKind, + ) *LibExeObjStep { const root_src_param = if (root_src) |p| @as(FileSource, .{ .path = p }) else null; - return LibExeObjStep.createSharedLibrary(self, name, root_src_param, ver); + return LibExeObjStep.createSharedLibrary(self, name, root_src_param, kind); } pub fn addStaticLibrary(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { @@ -338,11 +343,13 @@ pub const Builder = struct { return TranslateCStep.create(self, source); } - pub fn version(self: *const Builder, major: u32, minor: u32, patch: u32) Version { - return Version{ - .major = major, - .minor = minor, - .patch = patch, + pub fn version(self: *const Builder, major: u32, minor: u32, patch: u32) LibExeObjStep.SharedLibKind { + return .{ + .versioned = .{ + .major = major, + .minor = minor, + .patch = patch, + }, }; } @@ -1166,7 +1173,7 @@ pub const LibExeObjStep = struct { version_script: ?[]const u8 = null, out_filename: []const u8, is_dynamic: bool, - version: Version, + version: ?Version, build_mode: builtin.Mode, kind: Kind, major_only_filename: []const u8, @@ -1268,33 +1275,41 @@ pub const LibExeObjStep = struct { Test, }; - pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource, ver: Version) *LibExeObjStep { + const SharedLibKind = union(enum) { + versioned: Version, + unversioned: void, + }; + + pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource, kind: SharedLibKind) *LibExeObjStep { const self = builder.allocator.create(LibExeObjStep) catch unreachable; - self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, ver); + self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, switch (kind) { + .versioned => |ver| ver, + .unversioned => null, + }); return self; } pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { const self = builder.allocator.create(LibExeObjStep) catch unreachable; - self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, builder.version(0, 0, 0)); + self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, null); return self; } pub fn createObject(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { const self = builder.allocator.create(LibExeObjStep) catch unreachable; - self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0)); + self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, null); return self; } pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?FileSource, is_dynamic: bool) *LibExeObjStep { const self = builder.allocator.create(LibExeObjStep) catch unreachable; - self.* = initExtraArgs(builder, name, root_src, Kind.Exe, is_dynamic, builder.version(0, 0, 0)); + self.* = initExtraArgs(builder, name, root_src, Kind.Exe, is_dynamic, null); return self; } pub fn createTest(builder: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep { const self = builder.allocator.create(LibExeObjStep) catch unreachable; - self.* = initExtraArgs(builder, name, root_src, Kind.Test, false, builder.version(0, 0, 0)); + self.* = initExtraArgs(builder, name, root_src, Kind.Test, false, null); return self; } @@ -1304,7 +1319,7 @@ pub const LibExeObjStep = struct { root_src: ?FileSource, kind: Kind, is_dynamic: bool, - ver: Version, + ver: ?Version, ) LibExeObjStep { if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) { panic("invalid name: '{}'. It looks like a file path, but it is supposed to be the library or application name.", .{name}); @@ -1375,17 +1390,17 @@ pub const LibExeObjStep = struct { self.target.staticLibSuffix(), }); self.out_lib_filename = self.out_filename; - } else { + } else if (self.version) |version| { if (self.target.isDarwin()) { self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", .{ self.name, - self.version.major, - self.version.minor, - self.version.patch, + version.major, + version.minor, + version.patch, }); self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", .{ self.name, - self.version.major, + version.major, }); self.name_only_filename = self.builder.fmt("lib{}.dylib", .{self.name}); self.out_lib_filename = self.out_filename; @@ -1395,14 +1410,25 @@ pub const LibExeObjStep = struct { } else { self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", .{ self.name, - self.version.major, - self.version.minor, - self.version.patch, + version.major, + version.minor, + version.patch, }); - self.major_only_filename = self.builder.fmt("lib{}.so.{d}", .{ self.name, self.version.major }); + self.major_only_filename = self.builder.fmt("lib{}.so.{d}", .{ self.name, version.major }); self.name_only_filename = self.builder.fmt("lib{}.so", .{self.name}); self.out_lib_filename = self.out_filename; } + } else { + if (self.target.isDarwin()) { + self.out_filename = self.builder.fmt("lib{}.dylib", .{self.name}); + self.out_lib_filename = self.out_filename; + } else if (self.target.isWindows()) { + self.out_filename = self.builder.fmt("{}.dll", .{self.name}); + self.out_lib_filename = self.builder.fmt("{}.lib", .{self.name}); + } else { + self.out_filename = self.builder.fmt("lib{}.so", .{self.name}); + self.out_lib_filename = self.out_filename; + } } }, } @@ -2037,14 +2063,16 @@ pub const LibExeObjStep = struct { zig_args.append(self.name) catch unreachable; if (self.kind == Kind.Lib and self.is_dynamic) { - zig_args.append("--ver-major") catch unreachable; - zig_args.append(builder.fmt("{}", .{self.version.major})) catch unreachable; + if (self.version) |version| { + zig_args.append("--ver-major") catch unreachable; + zig_args.append(builder.fmt("{}", .{version.major})) catch unreachable; - zig_args.append("--ver-minor") catch unreachable; - zig_args.append(builder.fmt("{}", .{self.version.minor})) catch unreachable; + zig_args.append("--ver-minor") catch unreachable; + zig_args.append(builder.fmt("{}", .{version.minor})) catch unreachable; - zig_args.append("--ver-patch") catch unreachable; - zig_args.append(builder.fmt("{}", .{self.version.patch})) catch unreachable; + zig_args.append("--ver-patch") catch unreachable; + zig_args.append(builder.fmt("{}", .{version.patch})) catch unreachable; + } } if (self.is_dynamic) { try zig_args.append("-dynamic"); @@ -2285,7 +2313,7 @@ pub const LibExeObjStep = struct { } } - if (self.kind == Kind.Lib and self.is_dynamic and self.target.wantSharedLibSymLinks()) { + if (self.kind == Kind.Lib and self.is_dynamic and self.version != null and self.target.wantSharedLibSymLinks()) { try doAtomicSymLinks(builder.allocator, self.getOutputPath(), self.major_only_filename, self.name_only_filename); } } @@ -2329,8 +2357,10 @@ pub const InstallArtifactStep = struct { builder.pushInstalledFile(self.dest_dir, artifact.out_filename); if (self.artifact.isDynamicLibrary()) { - builder.pushInstalledFile(.Lib, artifact.major_only_filename); - builder.pushInstalledFile(.Lib, artifact.name_only_filename); + if (self.artifact.version != null) { + builder.pushInstalledFile(.Lib, artifact.major_only_filename); + builder.pushInstalledFile(.Lib, artifact.name_only_filename); + } if (self.artifact.target.isWindows()) { builder.pushInstalledFile(.Lib, artifact.out_lib_filename); } @@ -2350,7 +2380,7 @@ pub const InstallArtifactStep = struct { const full_dest_path = builder.getInstallPath(self.dest_dir, self.artifact.out_filename); try builder.updateFile(self.artifact.getOutputPath(), full_dest_path); - if (self.artifact.isDynamicLibrary() and self.artifact.target.wantSharedLibSymLinks()) { + if (self.artifact.isDynamicLibrary() and self.artifact.version != null and self.artifact.target.wantSharedLibSymLinks()) { try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename, self.artifact.name_only_filename); } if (self.pdb_dir) |pdb_dir| { -- cgit v1.2.3