build: generate a version number, show in log on startup

This commit is contained in:
Mitchell Hashimoto
2023-03-04 20:34:15 -08:00
parent 5906d87642
commit 0907da4eba
4 changed files with 87 additions and 1 deletions

View File

@ -26,6 +26,7 @@ const WasmTarget = @import("src/os/wasm/target.zig").Target;
const LibtoolStep = @import("src/build/LibtoolStep.zig");
const LipoStep = @import("src/build/LipoStep.zig");
const XCFrameworkStep = @import("src/build/XCFrameworkStep.zig");
const Version = @import("src/build/Version.zig");
// Do a comptime Zig version requirement. The required Zig version is
// somewhat arbitrary: it is meant to be a version that we feel works well,
@ -43,7 +44,10 @@ comptime {
}
}
// Build options, see the build options help for more info.
/// The version of the next release.
const app_version = std.builtin.Version{ .major = 0, .minor = 1, .patch = 0 };
/// Build options, see the build options help for more info.
var tracy: bool = false;
var flatpak: bool = false;
var app_runtime: apprt.Runtime = .none;
@ -112,6 +116,28 @@ pub fn build(b: *std.build.Builder) !void {
"Build and install the benchmark executables.",
) orelse false;
var version_string = b.option(
[]const u8,
"version-string",
"A specific version string to use for the build. " ++
"If not specified, git will be used. This must be a semantic version.",
);
var version: std.SemanticVersion = if (version_string) |v|
try std.SemanticVersion.parse(v)
else version: {
const vsn = try Version.detect(b);
if (vsn.tag != null) @panic("tagged releases are not yet supported");
break :version .{
.major = app_version.major,
.minor = app_version.minor,
.patch = app_version.patch,
.pre = vsn.branch,
.build = vsn.short_hash,
};
};
// We can use wasmtime to test wasm
b.enable_wasmtime = true;
@ -125,6 +151,8 @@ pub fn build(b: *std.build.Builder) !void {
.optimize = optimize,
});
const exe_options = b.addOptions();
exe_options.addOption(std.SemanticVersion, "app_version", version);
exe_options.addOption([]const u8, "app_version_string", b.fmt("{}", .{version}));
exe_options.addOption(bool, "tracy_enabled", tracy);
exe_options.addOption(bool, "flatpak", flatpak);
exe_options.addOption(apprt.Runtime, "app_runtime", app_runtime);

53
src/build/Version.zig Normal file
View File

@ -0,0 +1,53 @@
const Version = @This();
const std = @import("std");
/// The short hash (7 characters) of the latest commit.
short_hash: []const u8,
/// True if there was a diff at build time.
changes: bool,
/// The tag -- if any -- that this commit is a part of.
tag: ?[]const u8,
/// The branch that was checked out at the time of the build.
branch: []const u8,
/// Initialize the version and detect it from the Git environment. This
/// allocates using the build allocator and doesn't free.
pub fn detect(b: *std.Build) !Version {
// Execute a bunch of git commands to determine the automatic version.
var code: u8 = 0;
const branch = try b.execAllowFail(&[_][]const u8{ "git", "-C", b.build_root.path orelse ".", "rev-parse", "--abbrev-ref", "HEAD" }, &code, .Ignore);
const short_hash = short_hash: {
const output = try b.execAllowFail(&[_][]const u8{ "git", "-C", b.build_root.path orelse ".", "log", "--pretty=format:%h", "-n", "1" }, &code, .Ignore);
break :short_hash std.mem.trimRight(u8, output, "\r\n ");
};
const tag = b.execAllowFail(&[_][]const u8{ "git", "-C", b.build_root.path orelse ".", "describe", "--exact-match", "--tags" }, &code, .Ignore) catch |err| switch (err) {
error.ExitCodeFailure => "", // expected
else => return err,
};
_ = b.execAllowFail(&[_][]const u8{
"git",
"-C",
b.build_root.path orelse ".",
"diff",
"--quiet",
"--exit-code",
}, &code, .Ignore) catch |err| switch (err) {
error.ExitCodeFailure => {}, // expected
else => return err,
};
const changes = code != 0;
return .{
.short_hash = short_hash,
.changes = changes,
.tag = if (tag.len > 0) std.mem.trimRight(u8, tag, "\r\n ") else null,
.branch = std.mem.trimRight(u8, branch, "\r\n "),
};
}

View File

@ -9,6 +9,10 @@ const assert = std.debug.assert;
const apprt = @import("apprt.zig");
const font = @import("font/main.zig");
/// The semantic version of this build.
pub const version = options.app_version;
pub const version_string = options.app_version_string;
/// The artifact we're producing. This can be used to determine if we're
/// building a standalone exe, an embedded lib, etc.
pub const artifact = Artifact.detect();

View File

@ -128,6 +128,7 @@ pub const GlobalState = struct {
pub fn init(self: *GlobalState) void {
// Output some debug information right away
std.log.info("ghostty version={s}", .{build_config.version_string});
std.log.info("runtime={}", .{build_config.app_runtime});
std.log.info("font_backend={}", .{build_config.font_backend});
std.log.info("dependency harfbuzz={s}", .{harfbuzz.versionString()});