authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-11 16:07:13-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-09-11 16:07:13-04:00
log42c32dbc7b6cb474a1aa6dc524acb7451efeb15e
tree0056010cd160f780338fe584712744276fd9736c
parentbee34f5d036a74e520f5174fcaa132e6fb4114c6
parent0a76a9bd738471e2edddf71a822ff76c47bfd094
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #6315 from ifreund/optional-shlib-version

std, stage1: make shared library versioning optional

8 files changed, 92 insertions(+), 45 deletions(-)

lib/std/build.zig+64-34
......@@ -258,9 +258,14 @@ pub const Builder = struct {
258258 }));
259259 }
260260
261 pub fn addSharedLibrary(self: *Builder, name: []const u8, root_src: ?[]const u8, ver: Version) *LibExeObjStep {
261 pub fn addSharedLibrary(
262 self: *Builder,
263 name: []const u8,
264 root_src: ?[]const u8,
265 kind: LibExeObjStep.SharedLibKind,
266 ) *LibExeObjStep {
262267 const root_src_param = if (root_src) |p| @as(FileSource, .{ .path = p }) else null;
263 return LibExeObjStep.createSharedLibrary(self, name, root_src_param, ver);
268 return LibExeObjStep.createSharedLibrary(self, name, root_src_param, kind);
264269 }
265270
266271 pub fn addStaticLibrary(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
......@@ -338,11 +343,13 @@ pub const Builder = struct {
338343 return TranslateCStep.create(self, source);
339344 }
340345
341 pub fn version(self: *const Builder, major: u32, minor: u32, patch: u32) Version {
342 return Version{
343 .major = major,
344 .minor = minor,
345 .patch = patch,
346 pub fn version(self: *const Builder, major: u32, minor: u32, patch: u32) LibExeObjStep.SharedLibKind {
347 return .{
348 .versioned = .{
349 .major = major,
350 .minor = minor,
351 .patch = patch,
352 },
346353 };
347354 }
348355
......@@ -1167,7 +1174,7 @@ pub const LibExeObjStep = struct {
11671174 version_script: ?[]const u8 = null,
11681175 out_filename: []const u8,
11691176 is_dynamic: bool,
1170 version: Version,
1177 version: ?Version,
11711178 build_mode: builtin.Mode,
11721179 kind: Kind,
11731180 major_only_filename: []const u8,
......@@ -1271,33 +1278,41 @@ pub const LibExeObjStep = struct {
12711278 Test,
12721279 };
12731280
1274 pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource, ver: Version) *LibExeObjStep {
1281 const SharedLibKind = union(enum) {
1282 versioned: Version,
1283 unversioned: void,
1284 };
1285
1286 pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource, kind: SharedLibKind) *LibExeObjStep {
12751287 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
1276 self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, ver);
1288 self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, switch (kind) {
1289 .versioned => |ver| ver,
1290 .unversioned => null,
1291 });
12771292 return self;
12781293 }
12791294
12801295 pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep {
12811296 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
1282 self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, builder.version(0, 0, 0));
1297 self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, null);
12831298 return self;
12841299 }
12851300
12861301 pub fn createObject(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep {
12871302 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
1288 self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
1303 self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, null);
12891304 return self;
12901305 }
12911306
12921307 pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?FileSource, is_dynamic: bool) *LibExeObjStep {
12931308 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
1294 self.* = initExtraArgs(builder, name, root_src, Kind.Exe, is_dynamic, builder.version(0, 0, 0));
1309 self.* = initExtraArgs(builder, name, root_src, Kind.Exe, is_dynamic, null);
12951310 return self;
12961311 }
12971312
12981313 pub fn createTest(builder: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep {
12991314 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
1300 self.* = initExtraArgs(builder, name, root_src, Kind.Test, false, builder.version(0, 0, 0));
1315 self.* = initExtraArgs(builder, name, root_src, Kind.Test, false, null);
13011316 return self;
13021317 }
13031318
......@@ -1307,7 +1322,7 @@ pub const LibExeObjStep = struct {
13071322 root_src: ?FileSource,
13081323 kind: Kind,
13091324 is_dynamic: bool,
1310 ver: Version,
1325 ver: ?Version,
13111326 ) LibExeObjStep {
13121327 if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) {
13131328 panic("invalid name: '{}'. It looks like a file path, but it is supposed to be the library or application name.", .{name});
......@@ -1379,17 +1394,17 @@ pub const LibExeObjStep = struct {
13791394 self.target.staticLibSuffix(),
13801395 });
13811396 self.out_lib_filename = self.out_filename;
1382 } else {
1397 } else if (self.version) |version| {
13831398 if (self.target.isDarwin()) {
13841399 self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", .{
13851400 self.name,
1386 self.version.major,
1387 self.version.minor,
1388 self.version.patch,
1401 version.major,
1402 version.minor,
1403 version.patch,
13891404 });
13901405 self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", .{
13911406 self.name,
1392 self.version.major,
1407 version.major,
13931408 });
13941409 self.name_only_filename = self.builder.fmt("lib{}.dylib", .{self.name});
13951410 self.out_lib_filename = self.out_filename;
......@@ -1399,14 +1414,25 @@ pub const LibExeObjStep = struct {
13991414 } else {
14001415 self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", .{
14011416 self.name,
1402 self.version.major,
1403 self.version.minor,
1404 self.version.patch,
1417 version.major,
1418 version.minor,
1419 version.patch,
14051420 });
1406 self.major_only_filename = self.builder.fmt("lib{}.so.{d}", .{ self.name, self.version.major });
1421 self.major_only_filename = self.builder.fmt("lib{}.so.{d}", .{ self.name, version.major });
14071422 self.name_only_filename = self.builder.fmt("lib{}.so", .{self.name});
14081423 self.out_lib_filename = self.out_filename;
14091424 }
1425 } else {
1426 if (self.target.isDarwin()) {
1427 self.out_filename = self.builder.fmt("lib{}.dylib", .{self.name});
1428 self.out_lib_filename = self.out_filename;
1429 } else if (self.target.isWindows()) {
1430 self.out_filename = self.builder.fmt("{}.dll", .{self.name});
1431 self.out_lib_filename = self.builder.fmt("{}.lib", .{self.name});
1432 } else {
1433 self.out_filename = self.builder.fmt("lib{}.so", .{self.name});
1434 self.out_lib_filename = self.out_filename;
1435 }
14101436 }
14111437 },
14121438 }
......@@ -2041,14 +2067,16 @@ pub const LibExeObjStep = struct {
20412067 zig_args.append(self.name) catch unreachable;
20422068
20432069 if (self.kind == Kind.Lib and self.is_dynamic) {
2044 zig_args.append("--ver-major") catch unreachable;
2045 zig_args.append(builder.fmt("{}", .{self.version.major})) catch unreachable;
2070 if (self.version) |version| {
2071 zig_args.append("--ver-major") catch unreachable;
2072 zig_args.append(builder.fmt("{}", .{version.major})) catch unreachable;
20462073
2047 zig_args.append("--ver-minor") catch unreachable;
2048 zig_args.append(builder.fmt("{}", .{self.version.minor})) catch unreachable;
2074 zig_args.append("--ver-minor") catch unreachable;
2075 zig_args.append(builder.fmt("{}", .{version.minor})) catch unreachable;
20492076
2050 zig_args.append("--ver-patch") catch unreachable;
2051 zig_args.append(builder.fmt("{}", .{self.version.patch})) catch unreachable;
2077 zig_args.append("--ver-patch") catch unreachable;
2078 zig_args.append(builder.fmt("{}", .{version.patch})) catch unreachable;
2079 }
20522080 }
20532081 if (self.is_dynamic) {
20542082 try zig_args.append("-dynamic");
......@@ -2289,7 +2317,7 @@ pub const LibExeObjStep = struct {
22892317 }
22902318 }
22912319
2292 if (self.kind == Kind.Lib and self.is_dynamic and self.target.wantSharedLibSymLinks()) {
2320 if (self.kind == Kind.Lib and self.is_dynamic and self.version != null and self.target.wantSharedLibSymLinks()) {
22932321 try doAtomicSymLinks(builder.allocator, self.getOutputPath(), self.major_only_filename, self.name_only_filename);
22942322 }
22952323 }
......@@ -2333,8 +2361,10 @@ pub const InstallArtifactStep = struct {
23332361
23342362 builder.pushInstalledFile(self.dest_dir, artifact.out_filename);
23352363 if (self.artifact.isDynamicLibrary()) {
2336 builder.pushInstalledFile(.Lib, artifact.major_only_filename);
2337 builder.pushInstalledFile(.Lib, artifact.name_only_filename);
2364 if (self.artifact.version != null) {
2365 builder.pushInstalledFile(.Lib, artifact.major_only_filename);
2366 builder.pushInstalledFile(.Lib, artifact.name_only_filename);
2367 }
23382368 if (self.artifact.target.isWindows()) {
23392369 builder.pushInstalledFile(.Lib, artifact.out_lib_filename);
23402370 }
......@@ -2354,7 +2384,7 @@ pub const InstallArtifactStep = struct {
23542384
23552385 const full_dest_path = builder.getInstallPath(self.dest_dir, self.artifact.out_filename);
23562386 try builder.updateFile(self.artifact.getOutputPath(), full_dest_path);
2357 if (self.artifact.isDynamicLibrary() and self.artifact.target.wantSharedLibSymLinks()) {
2387 if (self.artifact.isDynamicLibrary() and self.artifact.version != null and self.artifact.target.wantSharedLibSymLinks()) {
23582388 try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename, self.artifact.name_only_filename);
23592389 }
23602390 if (self.pdb_dir) |pdb_dir| {
src/all_types.hpp+1
......@@ -2265,6 +2265,7 @@ struct CodeGen {
22652265
22662266 Stage2LibCInstallation *libc;
22672267
2268 bool is_versioned;
22682269 size_t version_major;
22692270 size_t version_minor;
22702271 size_t version_patch;
src/codegen.cpp+4-2
......@@ -90,7 +90,8 @@ void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix) {
9090 g->test_name_prefix = prefix;
9191}
9292
93void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch) {
93void codegen_set_lib_version(CodeGen *g, bool is_versioned, size_t major, size_t minor, size_t patch) {
94 g->is_versioned = is_versioned;
9495 g->version_major = major;
9596 g->version_minor = minor;
9697 g->version_patch = patch;
......@@ -10823,6 +10824,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
1082310824 cache_bool(ch, g->emit_bin);
1082410825 cache_bool(ch, g->emit_llvm_ir);
1082510826 cache_bool(ch, g->emit_asm);
10827 cache_bool(ch, g->is_versioned);
1082610828 cache_usize(ch, g->version_major);
1082710829 cache_usize(ch, g->version_minor);
1082810830 cache_usize(ch, g->version_patch);
......@@ -10893,7 +10895,7 @@ static void resolve_out_paths(CodeGen *g) {
1089310895 buf_resize(out_basename, 0);
1089410896 buf_append_str(out_basename, target_lib_file_prefix(g->zig_target));
1089510897 buf_append_buf(out_basename, g->root_out_name);
10896 buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic,
10898 buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic, g->is_versioned,
1089710899 g->version_major, g->version_minor, g->version_patch));
1089810900 break;
1089910901 }
src/codegen.hpp+1-1
......@@ -38,7 +38,7 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic);
3838void codegen_set_linker_script(CodeGen *g, const char *linker_script);
3939void codegen_set_test_filter(CodeGen *g, Buf *filter);
4040void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix);
41void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch);
41void codegen_set_lib_version(CodeGen *g, bool is_versioned, size_t major, size_t minor, size_t patch);
4242void codegen_add_time_event(CodeGen *g, const char *name);
4343void codegen_print_timing_report(CodeGen *g, FILE *f);
4444void codegen_link(CodeGen *g);
src/glibc.cpp+1-1
......@@ -335,7 +335,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con
335335 bool is_ld = (strcmp(lib->name, "ld") == 0);
336336
337337 CodeGen *child_gen = create_child_codegen(g, zig_file_path, OutTypeLib, nullptr, lib->name, progress_node);
338 codegen_set_lib_version(child_gen, lib->sover, 0, 0);
338 codegen_set_lib_version(child_gen, true, lib->sover, 0, 0);
339339 child_gen->is_dynamic = true;
340340 child_gen->is_dummy_so = true;
341341 child_gen->version_script_path = map_file_path;
src/main.cpp+7-1
......@@ -416,6 +416,7 @@ static int main0(int argc, char **argv) {
416416 const char *test_filter = nullptr;
417417 const char *test_name_prefix = nullptr;
418418 bool test_evented_io = false;
419 bool is_versioned = false;
419420 size_t ver_major = 0;
420421 size_t ver_minor = 0;
421422 size_t ver_patch = 0;
......@@ -870,6 +871,7 @@ static int main0(int argc, char **argv) {
870871 fprintf(stderr, "expected linker arg after '%s'\n", buf_ptr(arg));
871872 return EXIT_FAILURE;
872873 }
874 is_versioned = true;
873875 ver_major = atoi(buf_ptr(linker_args.at(i)));
874876 } else if (buf_eql_str(arg, "--minor-image-version")) {
875877 i += 1;
......@@ -877,6 +879,7 @@ static int main0(int argc, char **argv) {
877879 fprintf(stderr, "expected linker arg after '%s'\n", buf_ptr(arg));
878880 return EXIT_FAILURE;
879881 }
882 is_versioned = true;
880883 ver_minor = atoi(buf_ptr(linker_args.at(i)));
881884 } else if (buf_eql_str(arg, "--stack")) {
882885 i += 1;
......@@ -1228,10 +1231,13 @@ static int main0(int argc, char **argv) {
12281231 } else if (strcmp(arg, "--test-name-prefix") == 0) {
12291232 test_name_prefix = argv[i];
12301233 } else if (strcmp(arg, "--ver-major") == 0) {
1234 is_versioned = true;
12311235 ver_major = atoi(argv[i]);
12321236 } else if (strcmp(arg, "--ver-minor") == 0) {
1237 is_versioned = true;
12331238 ver_minor = atoi(argv[i]);
12341239 } else if (strcmp(arg, "--ver-patch") == 0) {
1240 is_versioned = true;
12351241 ver_patch = atoi(argv[i]);
12361242 } else if (strcmp(arg, "--test-cmd") == 0) {
12371243 test_exec_args.append(argv[i]);
......@@ -1590,7 +1596,7 @@ static int main0(int argc, char **argv) {
15901596 g->emit_llvm_ir = emit_llvm_ir;
15911597
15921598 codegen_set_out_name(g, buf_out_name);
1593 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
1599 codegen_set_lib_version(g, is_versioned, ver_major, ver_minor, ver_patch);
15941600 g->want_single_threaded = want_single_threaded;
15951601 codegen_set_linker_script(g, linker_script);
15961602 g->version_script_path = version_script;
src/target.cpp+13-5
......@@ -779,7 +779,7 @@ const char *target_lib_file_prefix(const ZigTarget *target) {
779779 }
780780}
781781
782const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
782const char *target_lib_file_ext(const ZigTarget *target, bool is_static, bool is_versioned,
783783 size_t version_major, size_t version_minor, size_t version_patch)
784784{
785785 if (target_is_wasm(target)) {
......@@ -799,11 +799,19 @@ const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
799799 if (is_static) {
800800 return ".a";
801801 } else if (target_os_is_darwin(target->os)) {
802 return buf_ptr(buf_sprintf(".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib",
803 version_major, version_minor, version_patch));
802 if (is_versioned) {
803 return buf_ptr(buf_sprintf(".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib",
804 version_major, version_minor, version_patch));
805 } else {
806 return ".dylib";
807 }
804808 } else {
805 return buf_ptr(buf_sprintf(".so.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize,
806 version_major, version_minor, version_patch));
809 if (is_versioned) {
810 return buf_ptr(buf_sprintf(".so.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize,
811 version_major, version_minor, version_patch));
812 } else {
813 return ".so";
814 }
807815 }
808816 }
809817}
src/target.hpp+1-1
......@@ -87,7 +87,7 @@ const char *target_asm_file_ext(const ZigTarget *target);
8787const char *target_llvm_ir_file_ext(const ZigTarget *target);
8888const char *target_exe_file_ext(const ZigTarget *target);
8989const char *target_lib_file_prefix(const ZigTarget *target);
90const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
90const char *target_lib_file_ext(const ZigTarget *target, bool is_static, bool is_versioned,
9191 size_t version_major, size_t version_minor, size_t version_patch);
9292
9393bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);