Skip to content

Commit 0a76a9b

Browse files
committed
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.
1 parent 800c5de commit 0a76a9b

File tree

8 files changed

+92
-45
lines changed

8 files changed

+92
-45
lines changed

lib/std/build.zig

Lines changed: 64 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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

@@ -1166,7 +1173,7 @@ pub const LibExeObjStep = struct {
11661173
version_script: ?[]const u8 = null,
11671174
out_filename: []const u8,
11681175
is_dynamic: bool,
1169-
version: Version,
1176+
version: ?Version,
11701177
build_mode: builtin.Mode,
11711178
kind: Kind,
11721179
major_only_filename: []const u8,
@@ -1268,33 +1275,41 @@ pub const LibExeObjStep = struct {
12681275
Test,
12691276
};
12701277

1271-
pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource, ver: Version) *LibExeObjStep {
1278+
const SharedLibKind = union(enum) {
1279+
versioned: Version,
1280+
unversioned: void,
1281+
};
1282+
1283+
pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource, kind: SharedLibKind) *LibExeObjStep {
12721284
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
1273-
self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, ver);
1285+
self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, switch (kind) {
1286+
.versioned => |ver| ver,
1287+
.unversioned => null,
1288+
});
12741289
return self;
12751290
}
12761291

12771292
pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep {
12781293
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
1279-
self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, builder.version(0, 0, 0));
1294+
self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, null);
12801295
return self;
12811296
}
12821297

12831298
pub fn createObject(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep {
12841299
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
1285-
self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
1300+
self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, null);
12861301
return self;
12871302
}
12881303

12891304
pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?FileSource, is_dynamic: bool) *LibExeObjStep {
12901305
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
1291-
self.* = initExtraArgs(builder, name, root_src, Kind.Exe, is_dynamic, builder.version(0, 0, 0));
1306+
self.* = initExtraArgs(builder, name, root_src, Kind.Exe, is_dynamic, null);
12921307
return self;
12931308
}
12941309

12951310
pub fn createTest(builder: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep {
12961311
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
1297-
self.* = initExtraArgs(builder, name, root_src, Kind.Test, false, builder.version(0, 0, 0));
1312+
self.* = initExtraArgs(builder, name, root_src, Kind.Test, false, null);
12981313
return self;
12991314
}
13001315

@@ -1304,7 +1319,7 @@ pub const LibExeObjStep = struct {
13041319
root_src: ?FileSource,
13051320
kind: Kind,
13061321
is_dynamic: bool,
1307-
ver: Version,
1322+
ver: ?Version,
13081323
) LibExeObjStep {
13091324
if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) {
13101325
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 {
13751390
self.target.staticLibSuffix(),
13761391
});
13771392
self.out_lib_filename = self.out_filename;
1378-
} else {
1393+
} else if (self.version) |version| {
13791394
if (self.target.isDarwin()) {
13801395
self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", .{
13811396
self.name,
1382-
self.version.major,
1383-
self.version.minor,
1384-
self.version.patch,
1397+
version.major,
1398+
version.minor,
1399+
version.patch,
13851400
});
13861401
self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", .{
13871402
self.name,
1388-
self.version.major,
1403+
version.major,
13891404
});
13901405
self.name_only_filename = self.builder.fmt("lib{}.dylib", .{self.name});
13911406
self.out_lib_filename = self.out_filename;
@@ -1395,14 +1410,25 @@ pub const LibExeObjStep = struct {
13951410
} else {
13961411
self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", .{
13971412
self.name,
1398-
self.version.major,
1399-
self.version.minor,
1400-
self.version.patch,
1413+
version.major,
1414+
version.minor,
1415+
version.patch,
14011416
});
1402-
self.major_only_filename = self.builder.fmt("lib{}.so.{d}", .{ self.name, self.version.major });
1417+
self.major_only_filename = self.builder.fmt("lib{}.so.{d}", .{ self.name, version.major });
14031418
self.name_only_filename = self.builder.fmt("lib{}.so", .{self.name});
14041419
self.out_lib_filename = self.out_filename;
14051420
}
1421+
} else {
1422+
if (self.target.isDarwin()) {
1423+
self.out_filename = self.builder.fmt("lib{}.dylib", .{self.name});
1424+
self.out_lib_filename = self.out_filename;
1425+
} else if (self.target.isWindows()) {
1426+
self.out_filename = self.builder.fmt("{}.dll", .{self.name});
1427+
self.out_lib_filename = self.builder.fmt("{}.lib", .{self.name});
1428+
} else {
1429+
self.out_filename = self.builder.fmt("lib{}.so", .{self.name});
1430+
self.out_lib_filename = self.out_filename;
1431+
}
14061432
}
14071433
},
14081434
}
@@ -2037,14 +2063,16 @@ pub const LibExeObjStep = struct {
20372063
zig_args.append(self.name) catch unreachable;
20382064

20392065
if (self.kind == Kind.Lib and self.is_dynamic) {
2040-
zig_args.append("--ver-major") catch unreachable;
2041-
zig_args.append(builder.fmt("{}", .{self.version.major})) catch unreachable;
2066+
if (self.version) |version| {
2067+
zig_args.append("--ver-major") catch unreachable;
2068+
zig_args.append(builder.fmt("{}", .{version.major})) catch unreachable;
20422069

2043-
zig_args.append("--ver-minor") catch unreachable;
2044-
zig_args.append(builder.fmt("{}", .{self.version.minor})) catch unreachable;
2070+
zig_args.append("--ver-minor") catch unreachable;
2071+
zig_args.append(builder.fmt("{}", .{version.minor})) catch unreachable;
20452072

2046-
zig_args.append("--ver-patch") catch unreachable;
2047-
zig_args.append(builder.fmt("{}", .{self.version.patch})) catch unreachable;
2073+
zig_args.append("--ver-patch") catch unreachable;
2074+
zig_args.append(builder.fmt("{}", .{version.patch})) catch unreachable;
2075+
}
20482076
}
20492077
if (self.is_dynamic) {
20502078
try zig_args.append("-dynamic");
@@ -2285,7 +2313,7 @@ pub const LibExeObjStep = struct {
22852313
}
22862314
}
22872315

2288-
if (self.kind == Kind.Lib and self.is_dynamic and self.target.wantSharedLibSymLinks()) {
2316+
if (self.kind == Kind.Lib and self.is_dynamic and self.version != null and self.target.wantSharedLibSymLinks()) {
22892317
try doAtomicSymLinks(builder.allocator, self.getOutputPath(), self.major_only_filename, self.name_only_filename);
22902318
}
22912319
}
@@ -2329,8 +2357,10 @@ pub const InstallArtifactStep = struct {
23292357

23302358
builder.pushInstalledFile(self.dest_dir, artifact.out_filename);
23312359
if (self.artifact.isDynamicLibrary()) {
2332-
builder.pushInstalledFile(.Lib, artifact.major_only_filename);
2333-
builder.pushInstalledFile(.Lib, artifact.name_only_filename);
2360+
if (self.artifact.version != null) {
2361+
builder.pushInstalledFile(.Lib, artifact.major_only_filename);
2362+
builder.pushInstalledFile(.Lib, artifact.name_only_filename);
2363+
}
23342364
if (self.artifact.target.isWindows()) {
23352365
builder.pushInstalledFile(.Lib, artifact.out_lib_filename);
23362366
}
@@ -2350,7 +2380,7 @@ pub const InstallArtifactStep = struct {
23502380

23512381
const full_dest_path = builder.getInstallPath(self.dest_dir, self.artifact.out_filename);
23522382
try builder.updateFile(self.artifact.getOutputPath(), full_dest_path);
2353-
if (self.artifact.isDynamicLibrary() and self.artifact.target.wantSharedLibSymLinks()) {
2383+
if (self.artifact.isDynamicLibrary() and self.artifact.version != null and self.artifact.target.wantSharedLibSymLinks()) {
23542384
try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename, self.artifact.name_only_filename);
23552385
}
23562386
if (self.pdb_dir) |pdb_dir| {

src/all_types.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix) {
9090
g->test_name_prefix = prefix;
9191
}
9292

93-
void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch) {
93+
void 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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic);
3838
void codegen_set_linker_script(CodeGen *g, const char *linker_script);
3939
void codegen_set_test_filter(CodeGen *g, Buf *filter);
4040
void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix);
41-
void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch);
41+
void codegen_set_lib_version(CodeGen *g, bool is_versioned, size_t major, size_t minor, size_t patch);
4242
void codegen_add_time_event(CodeGen *g, const char *name);
4343
void codegen_print_timing_report(CodeGen *g, FILE *f);
4444
void codegen_link(CodeGen *g);

src/glibc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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,13 +871,15 @@ 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;
876878
if (i >= linker_args.length) {
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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ const char *target_lib_file_prefix(const ZigTarget *target) {
779779
}
780780
}
781781

782-
const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
782+
const 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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ const char *target_asm_file_ext(const ZigTarget *target);
8787
const char *target_llvm_ir_file_ext(const ZigTarget *target);
8888
const char *target_exe_file_ext(const ZigTarget *target);
8989
const char *target_lib_file_prefix(const ZigTarget *target);
90-
const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
90+
const 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

9393
bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);

0 commit comments

Comments
 (0)