build: use VERSION file if present, expose via libghostty (#11932)
If a `VERSION` file is present from our build root, prefer that as our version source of truth over `build.zig.zon`. This file is automatically created in source tarballs and will allow us to cut pre-release tarballs of libghostty in particular (but affects all) that has a more specific version than what can be in build.zig.zon. This also adds the APIs necessary to extract this via the C API. I started prepping for a separate libghostty version but not sure if I'll wire that up in this PR yet or not...pull/11950/head
commit
0f6e733f8c
30
build.zig
30
build.zig
|
|
@ -3,11 +3,17 @@ const assert = std.debug.assert;
|
|||
const builtin = @import("builtin");
|
||||
const buildpkg = @import("src/build/main.zig");
|
||||
|
||||
const appVersion = @import("build.zig.zon").version;
|
||||
const minimumZigVersion = @import("build.zig.zon").minimum_zig_version;
|
||||
/// App version from build.zig.zon.
|
||||
const app_zon_version = @import("build.zig.zon").version;
|
||||
|
||||
/// Libghostty version. We use a separate version from the app.
|
||||
const lib_version = "0.1.0";
|
||||
|
||||
/// Minimum required zig version.
|
||||
const minimum_zig_version = @import("build.zig.zon").minimum_zig_version;
|
||||
|
||||
comptime {
|
||||
buildpkg.requireZig(minimumZigVersion);
|
||||
buildpkg.requireZig(minimum_zig_version);
|
||||
}
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
|
|
@ -15,7 +21,23 @@ pub fn build(b: *std.Build) !void {
|
|||
// want to know what options are available, you can run `--help` or
|
||||
// you can read `src/build/Config.zig`.
|
||||
|
||||
const config = try buildpkg.Config.init(b, appVersion);
|
||||
// If we have a VERSION file (present in source tarballs) then we
|
||||
// use that as the version source of truth. Otherwise we fall back
|
||||
// to what is in the build.zig.zon.
|
||||
const file_version: ?[]const u8 = if (b.build_root.handle.readFileAlloc(
|
||||
b.allocator,
|
||||
"VERSION",
|
||||
128,
|
||||
)) |content| std.mem.trim(
|
||||
u8,
|
||||
content,
|
||||
&std.ascii.whitespace,
|
||||
) else |_| null;
|
||||
|
||||
const config = try buildpkg.Config.init(
|
||||
b,
|
||||
file_version orelse app_zon_version,
|
||||
);
|
||||
const test_filters = b.option(
|
||||
[][]const u8,
|
||||
"test-filter",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,28 @@ void query_build_info() {
|
|||
printf("SIMD: %s\n", simd ? "enabled" : "disabled");
|
||||
printf("Kitty graphics: %s\n", kitty_graphics ? "enabled" : "disabled");
|
||||
printf("Tmux control mode: %s\n", tmux_control_mode ? "enabled" : "disabled");
|
||||
|
||||
GhosttyString version_string = {0};
|
||||
size_t version_major = 0;
|
||||
size_t version_minor = 0;
|
||||
size_t version_patch = 0;
|
||||
GhosttyString version_build = {0};
|
||||
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_VERSION_STRING, &version_string);
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_VERSION_MAJOR, &version_major);
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_VERSION_MINOR, &version_minor);
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_VERSION_PATCH, &version_patch);
|
||||
ghostty_build_info(GHOSTTY_BUILD_INFO_VERSION_BUILD, &version_build);
|
||||
|
||||
printf("Version: %.*s\n", (int)version_string.len, version_string.ptr);
|
||||
printf("Version major: %zu\n", version_major);
|
||||
printf("Version minor: %zu\n", version_minor);
|
||||
printf("Version patch: %zu\n", version_patch);
|
||||
if (version_build.len > 0) {
|
||||
printf("Version build: %.*s\n", (int)version_build.len, version_build.ptr);
|
||||
} else {
|
||||
printf("Version build: (none)\n");
|
||||
}
|
||||
}
|
||||
//! [build-info-query]
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <ghostty/vt/types.h>
|
||||
|
|
@ -77,6 +78,42 @@ typedef enum {
|
|||
* Output type: GhosttyOptimizeMode *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_OPTIMIZE = 4,
|
||||
|
||||
/**
|
||||
* The full version string (e.g. "1.2.3" or "1.2.3-dev+abcdef").
|
||||
*
|
||||
* Output type: GhosttyString *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_VERSION_STRING = 5,
|
||||
|
||||
/**
|
||||
* The major version number.
|
||||
*
|
||||
* Output type: size_t *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_VERSION_MAJOR = 6,
|
||||
|
||||
/**
|
||||
* The minor version number.
|
||||
*
|
||||
* Output type: size_t *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_VERSION_MINOR = 7,
|
||||
|
||||
/**
|
||||
* The patch version number.
|
||||
*
|
||||
* Output type: size_t *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_VERSION_PATCH = 8,
|
||||
|
||||
/**
|
||||
* The build metadata string (e.g. commit hash). Has zero length if
|
||||
* no build metadata is present.
|
||||
*
|
||||
* Output type: GhosttyString *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_VERSION_BUILD = 9,
|
||||
} GhosttyBuildInfo;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -545,6 +545,7 @@ pub fn terminalOptions(self: *const Config) TerminalBuildOptions {
|
|||
.simd = self.simd,
|
||||
.oniguruma = true,
|
||||
.c_abi = false,
|
||||
.version = self.version,
|
||||
.slow_runtime_safety = switch (self.optimize) {
|
||||
.Debug => true,
|
||||
.ReleaseSafe,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,13 @@ pub const Options = struct {
|
|||
/// Options.
|
||||
c_abi: bool,
|
||||
|
||||
/// The version of the application.
|
||||
version: std.SemanticVersion,
|
||||
|
||||
/// Add the required build options for the terminal module.
|
||||
///
|
||||
/// The memory referenced by self is expected to stick around (it isn't
|
||||
/// copied), since we expect we're in a build environment.
|
||||
pub fn add(
|
||||
self: Options,
|
||||
b: *std.Build,
|
||||
|
|
@ -45,6 +51,22 @@ pub const Options = struct {
|
|||
opts.addOption(bool, "kitty_graphics", self.oniguruma);
|
||||
opts.addOption(bool, "tmux_control_mode", self.oniguruma);
|
||||
|
||||
// Version information.
|
||||
var buf: [1024]u8 = undefined;
|
||||
opts.addOption(
|
||||
[]const u8,
|
||||
"version_string",
|
||||
std.fmt.bufPrint(
|
||||
&buf,
|
||||
"{f}",
|
||||
.{self.version},
|
||||
) catch @panic("version string too long"),
|
||||
);
|
||||
opts.addOption(usize, "version_major", self.version.major);
|
||||
opts.addOption(usize, "version_minor", self.version.minor);
|
||||
opts.addOption(usize, "version_patch", self.version.patch);
|
||||
opts.addOption(?[]const u8, "version_build", self.version.build);
|
||||
|
||||
m.addOptions("terminal_options", opts);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@ pub const BuildInfo = enum(c_int) {
|
|||
kitty_graphics = 2,
|
||||
tmux_control_mode = 3,
|
||||
optimize = 4,
|
||||
version_string = 5,
|
||||
version_major = 6,
|
||||
version_minor = 7,
|
||||
version_patch = 8,
|
||||
version_build = 9,
|
||||
|
||||
/// Output type expected for querying the data of the given kind.
|
||||
pub fn OutType(comptime self: BuildInfo) type {
|
||||
|
|
@ -28,6 +33,8 @@ pub const BuildInfo = enum(c_int) {
|
|||
.invalid => void,
|
||||
.simd, .kitty_graphics, .tmux_control_mode => bool,
|
||||
.optimize => OptimizeMode,
|
||||
.version_string, .version_build => lib.String,
|
||||
.version_major, .version_minor, .version_patch => usize,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
@ -67,6 +74,17 @@ fn getTyped(
|
|||
.ReleaseSmall => .release_small,
|
||||
.ReleaseFast => .release_fast,
|
||||
},
|
||||
.version_string => out.* = .{ .ptr = build_options.version_string.ptr, .len = build_options.version_string.len },
|
||||
.version_major => out.* = build_options.version_major,
|
||||
.version_minor => out.* = build_options.version_minor,
|
||||
.version_patch => out.* = build_options.version_patch,
|
||||
.version_build => {
|
||||
if (build_options.version_build) |b| {
|
||||
out.* = .{ .ptr = b.ptr, .len = b.len };
|
||||
} else {
|
||||
out.* = .{ .ptr = "", .len = 0 };
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
return .success;
|
||||
|
|
@ -105,6 +123,40 @@ test "get optimize" {
|
|||
}, value);
|
||||
}
|
||||
|
||||
test "get version_string" {
|
||||
const testing = std.testing;
|
||||
var value: lib.String = undefined;
|
||||
try testing.expectEqual(Result.success, get(.version_string, @ptrCast(&value)));
|
||||
try testing.expect(value.len > 0);
|
||||
}
|
||||
|
||||
test "get version_major" {
|
||||
const testing = std.testing;
|
||||
var value: usize = undefined;
|
||||
try testing.expectEqual(Result.success, get(.version_major, @ptrCast(&value)));
|
||||
try testing.expectEqual(build_options.version_major, value);
|
||||
}
|
||||
|
||||
test "get version_minor" {
|
||||
const testing = std.testing;
|
||||
var value: usize = undefined;
|
||||
try testing.expectEqual(Result.success, get(.version_minor, @ptrCast(&value)));
|
||||
try testing.expectEqual(build_options.version_minor, value);
|
||||
}
|
||||
|
||||
test "get version_patch" {
|
||||
const testing = std.testing;
|
||||
var value: usize = undefined;
|
||||
try testing.expectEqual(Result.success, get(.version_patch, @ptrCast(&value)));
|
||||
try testing.expectEqual(build_options.version_patch, value);
|
||||
}
|
||||
|
||||
test "get version_build" {
|
||||
const testing = std.testing;
|
||||
var value: lib.String = undefined;
|
||||
try testing.expectEqual(Result.success, get(.version_build, @ptrCast(&value)));
|
||||
}
|
||||
|
||||
test "get invalid" {
|
||||
try std.testing.expectEqual(Result.invalid_value, get(.invalid, null));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue