mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00

The major idea behind the refactor is to split the `build.zig` file up into distinct `src/build/*.zig` files. By doing so, we can improve readability of the primary `build.zig` while also enabling better reuse of steps. Our `build.zig` is now less than 150 lines of code (of course, it calls into a lot more lines but they're neatly organized now). Improvements: * `build.zig` is less than 150 lines of readable code. * Help strings and unicode table generators are only run once when multiple artifacts are built since the results are the same regardless of target. * Metal lib is only built once per architecture (rather than once per artifact) * Resources (shell integration, terminfo, etc.) and docs are only built/installed for artifacts that need them Breaking changes: * Removed broken wasm build (@gabydd will re-add) * Removed conformance files, shell scripts are better and we don't run these anymore * Removed macOS app bundle creation, we don't use this anymore since we use Xcode ## Some History Our `build.zig` hasn't been significantly refactored since the project started, when Zig was _version 0.10_. Since then, the build system has changed significantly. We've only ever duct taped the `build.zig` as we needed to support new Zig versions, new features, etc. It was a mess. The major improvement is adapting the entire Ghostty `build.zig` to the Step and LazyPath changes introduced way back in Zig 0.12. This lets us better take advantage of parallelism and the dependency graph so that steps are only executed as they're needed. As such, you can see in the build.zig that we initialize a lot of things, but unless a final target (i.e. install, run) references those steps, _they'll never be executed_. This lets us clean up a lot.
99 lines
3.6 KiB
Zig
99 lines
3.6 KiB
Zig
//! Build options, available at comptime. Used to configure features. This
|
|
//! will reproduce some of the fields from builtin and build_options just
|
|
//! so we can limit the amount of imports we need AND give us the ability
|
|
//! to shim logic and values into them later.
|
|
const std = @import("std");
|
|
const builtin = @import("builtin");
|
|
const options = @import("build_options");
|
|
const assert = std.debug.assert;
|
|
const apprt = @import("apprt.zig");
|
|
const font = @import("font/main.zig");
|
|
const rendererpkg = @import("renderer.zig");
|
|
const WasmTarget = @import("os/wasm/target.zig").Target;
|
|
const BuildConfig = @import("build/Config.zig");
|
|
|
|
pub const ReleaseChannel = BuildConfig.ReleaseChannel;
|
|
|
|
/// The semantic version of this build.
|
|
pub const version = options.app_version;
|
|
pub const version_string = options.app_version_string;
|
|
|
|
/// The release channel for this build.
|
|
pub const release_channel = std.meta.stringToEnum(ReleaseChannel, @tagName(options.release_channel)).?;
|
|
|
|
/// The optimization mode as a string.
|
|
pub const mode_string = mode: {
|
|
const m = @tagName(builtin.mode);
|
|
if (std.mem.lastIndexOfScalar(u8, m, '.')) |i| break :mode m[i..];
|
|
break :mode m;
|
|
};
|
|
|
|
/// 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();
|
|
|
|
/// Our build configuration. We re-export a lot of these back at the
|
|
/// top-level so its a bit cleaner to use throughout the code. See the doc
|
|
/// comments in BuildConfig for details on each.
|
|
const config = BuildConfig.fromOptions();
|
|
pub const exe_entrypoint = config.exe_entrypoint;
|
|
pub const flatpak = options.flatpak;
|
|
pub const app_runtime: apprt.Runtime = config.app_runtime;
|
|
pub const font_backend: font.Backend = config.font_backend;
|
|
pub const renderer: rendererpkg.Impl = config.renderer;
|
|
|
|
/// The bundle ID for the app. This is used in many places and is currently
|
|
/// hardcoded here. We could make this configurable in the future if there
|
|
/// is a reason to do so.
|
|
///
|
|
/// On macOS, this must match the App bundle ID. We can get that dynamically
|
|
/// via an API but I don't want to pay the cost of that at runtime.
|
|
///
|
|
/// On GTK, this should match the various folders with resources.
|
|
///
|
|
/// There are many places that don't use this variable so simply swapping
|
|
/// this variable is NOT ENOUGH to change the bundle ID. I just wanted to
|
|
/// avoid it in Zig coe as much as possible.
|
|
pub const bundle_id = "com.mitchellh.ghostty";
|
|
|
|
/// True if we should have "slow" runtime safety checks. The initial motivation
|
|
/// for this was terminal page/pagelist integrity checks. These were VERY
|
|
/// slow but very thorough. But they made it so slow that the terminal couldn't
|
|
/// be used for real work. We'd love to have an option to run a build with
|
|
/// safety checks that could be used for real work. This lets us do that.
|
|
pub const slow_runtime_safety = std.debug.runtime_safety and switch (builtin.mode) {
|
|
.Debug => true,
|
|
.ReleaseSafe,
|
|
.ReleaseSmall,
|
|
.ReleaseFast,
|
|
=> false,
|
|
};
|
|
|
|
pub const Artifact = enum {
|
|
/// Standalone executable
|
|
exe,
|
|
|
|
/// Embeddable library
|
|
lib,
|
|
|
|
/// The WASM-targeted module.
|
|
wasm_module,
|
|
|
|
pub fn detect() Artifact {
|
|
if (builtin.target.isWasm()) {
|
|
assert(builtin.output_mode == .Obj);
|
|
assert(builtin.link_mode == .Static);
|
|
return .wasm_module;
|
|
}
|
|
|
|
return switch (builtin.output_mode) {
|
|
.Exe => .exe,
|
|
.Lib => .lib,
|
|
else => {
|
|
@compileLog(builtin.output_mode);
|
|
@compileError("unsupported artifact output mode");
|
|
},
|
|
};
|
|
}
|
|
};
|