mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 00:35:10 +00:00
Merge pull request #6315 from ifreund/optional-shlib-version
std, stage1: make shared library versioning optional
This commit is contained in:
commit
42c32dbc7b
@ -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,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -1167,7 +1174,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,
|
||||
@ -1271,33 +1278,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;
|
||||
}
|
||||
|
||||
@ -1307,7 +1322,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});
|
||||
@ -1379,17 +1394,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;
|
||||
@ -1399,14 +1414,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;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -2041,14 +2067,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");
|
||||
@ -2289,7 +2317,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);
|
||||
}
|
||||
}
|
||||
@ -2333,8 +2361,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);
|
||||
}
|
||||
@ -2354,7 +2384,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| {
|
||||
|
||||
@ -2265,6 +2265,7 @@ struct CodeGen {
|
||||
|
||||
Stage2LibCInstallation *libc;
|
||||
|
||||
bool is_versioned;
|
||||
size_t version_major;
|
||||
size_t version_minor;
|
||||
size_t version_patch;
|
||||
|
||||
@ -90,7 +90,8 @@ void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix) {
|
||||
g->test_name_prefix = prefix;
|
||||
}
|
||||
|
||||
void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch) {
|
||||
void codegen_set_lib_version(CodeGen *g, bool is_versioned, size_t major, size_t minor, size_t patch) {
|
||||
g->is_versioned = is_versioned;
|
||||
g->version_major = major;
|
||||
g->version_minor = minor;
|
||||
g->version_patch = patch;
|
||||
@ -10823,6 +10824,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
|
||||
cache_bool(ch, g->emit_bin);
|
||||
cache_bool(ch, g->emit_llvm_ir);
|
||||
cache_bool(ch, g->emit_asm);
|
||||
cache_bool(ch, g->is_versioned);
|
||||
cache_usize(ch, g->version_major);
|
||||
cache_usize(ch, g->version_minor);
|
||||
cache_usize(ch, g->version_patch);
|
||||
@ -10893,7 +10895,7 @@ static void resolve_out_paths(CodeGen *g) {
|
||||
buf_resize(out_basename, 0);
|
||||
buf_append_str(out_basename, target_lib_file_prefix(g->zig_target));
|
||||
buf_append_buf(out_basename, g->root_out_name);
|
||||
buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic,
|
||||
buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic, g->is_versioned,
|
||||
g->version_major, g->version_minor, g->version_patch));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic);
|
||||
void codegen_set_linker_script(CodeGen *g, const char *linker_script);
|
||||
void codegen_set_test_filter(CodeGen *g, Buf *filter);
|
||||
void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix);
|
||||
void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch);
|
||||
void codegen_set_lib_version(CodeGen *g, bool is_versioned, size_t major, size_t minor, size_t patch);
|
||||
void codegen_add_time_event(CodeGen *g, const char *name);
|
||||
void codegen_print_timing_report(CodeGen *g, FILE *f);
|
||||
void codegen_link(CodeGen *g);
|
||||
|
||||
@ -335,7 +335,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con
|
||||
bool is_ld = (strcmp(lib->name, "ld") == 0);
|
||||
|
||||
CodeGen *child_gen = create_child_codegen(g, zig_file_path, OutTypeLib, nullptr, lib->name, progress_node);
|
||||
codegen_set_lib_version(child_gen, lib->sover, 0, 0);
|
||||
codegen_set_lib_version(child_gen, true, lib->sover, 0, 0);
|
||||
child_gen->is_dynamic = true;
|
||||
child_gen->is_dummy_so = true;
|
||||
child_gen->version_script_path = map_file_path;
|
||||
|
||||
@ -416,6 +416,7 @@ static int main0(int argc, char **argv) {
|
||||
const char *test_filter = nullptr;
|
||||
const char *test_name_prefix = nullptr;
|
||||
bool test_evented_io = false;
|
||||
bool is_versioned = false;
|
||||
size_t ver_major = 0;
|
||||
size_t ver_minor = 0;
|
||||
size_t ver_patch = 0;
|
||||
@ -870,6 +871,7 @@ static int main0(int argc, char **argv) {
|
||||
fprintf(stderr, "expected linker arg after '%s'\n", buf_ptr(arg));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
is_versioned = true;
|
||||
ver_major = atoi(buf_ptr(linker_args.at(i)));
|
||||
} else if (buf_eql_str(arg, "--minor-image-version")) {
|
||||
i += 1;
|
||||
@ -877,6 +879,7 @@ static int main0(int argc, char **argv) {
|
||||
fprintf(stderr, "expected linker arg after '%s'\n", buf_ptr(arg));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
is_versioned = true;
|
||||
ver_minor = atoi(buf_ptr(linker_args.at(i)));
|
||||
} else if (buf_eql_str(arg, "--stack")) {
|
||||
i += 1;
|
||||
@ -1228,10 +1231,13 @@ static int main0(int argc, char **argv) {
|
||||
} else if (strcmp(arg, "--test-name-prefix") == 0) {
|
||||
test_name_prefix = argv[i];
|
||||
} else if (strcmp(arg, "--ver-major") == 0) {
|
||||
is_versioned = true;
|
||||
ver_major = atoi(argv[i]);
|
||||
} else if (strcmp(arg, "--ver-minor") == 0) {
|
||||
is_versioned = true;
|
||||
ver_minor = atoi(argv[i]);
|
||||
} else if (strcmp(arg, "--ver-patch") == 0) {
|
||||
is_versioned = true;
|
||||
ver_patch = atoi(argv[i]);
|
||||
} else if (strcmp(arg, "--test-cmd") == 0) {
|
||||
test_exec_args.append(argv[i]);
|
||||
@ -1590,7 +1596,7 @@ static int main0(int argc, char **argv) {
|
||||
g->emit_llvm_ir = emit_llvm_ir;
|
||||
|
||||
codegen_set_out_name(g, buf_out_name);
|
||||
codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
|
||||
codegen_set_lib_version(g, is_versioned, ver_major, ver_minor, ver_patch);
|
||||
g->want_single_threaded = want_single_threaded;
|
||||
codegen_set_linker_script(g, linker_script);
|
||||
g->version_script_path = version_script;
|
||||
|
||||
@ -779,7 +779,7 @@ const char *target_lib_file_prefix(const ZigTarget *target) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
|
||||
const char *target_lib_file_ext(const ZigTarget *target, bool is_static, bool is_versioned,
|
||||
size_t version_major, size_t version_minor, size_t version_patch)
|
||||
{
|
||||
if (target_is_wasm(target)) {
|
||||
@ -799,11 +799,19 @@ const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
|
||||
if (is_static) {
|
||||
return ".a";
|
||||
} else if (target_os_is_darwin(target->os)) {
|
||||
return buf_ptr(buf_sprintf(".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib",
|
||||
version_major, version_minor, version_patch));
|
||||
if (is_versioned) {
|
||||
return buf_ptr(buf_sprintf(".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib",
|
||||
version_major, version_minor, version_patch));
|
||||
} else {
|
||||
return ".dylib";
|
||||
}
|
||||
} else {
|
||||
return buf_ptr(buf_sprintf(".so.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize,
|
||||
version_major, version_minor, version_patch));
|
||||
if (is_versioned) {
|
||||
return buf_ptr(buf_sprintf(".so.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize,
|
||||
version_major, version_minor, version_patch));
|
||||
} else {
|
||||
return ".so";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ const char *target_asm_file_ext(const ZigTarget *target);
|
||||
const char *target_llvm_ir_file_ext(const ZigTarget *target);
|
||||
const char *target_exe_file_ext(const ZigTarget *target);
|
||||
const char *target_lib_file_prefix(const ZigTarget *target);
|
||||
const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
|
||||
const char *target_lib_file_ext(const ZigTarget *target, bool is_static, bool is_versioned,
|
||||
size_t version_major, size_t version_minor, size_t version_patch);
|
||||
|
||||
bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user