mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-01 15:38:35 +00:00
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
11ce062a91 | ||
![]() |
b21b9b2dcf |
@@ -4,7 +4,7 @@ const builtin = @import("builtin");
|
||||
const buildpkg = @import("src/build/main.zig");
|
||||
|
||||
comptime {
|
||||
buildpkg.requireZig("0.14.0");
|
||||
buildpkg.requireZig("0.15.1");
|
||||
}
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
@@ -249,8 +249,6 @@ pub fn build(b: *std.Build) !void {
|
||||
{
|
||||
const mod_vt_test = b.addTest(.{
|
||||
.root_module = mod.vt,
|
||||
.target = config.target,
|
||||
.optimize = config.optimize,
|
||||
.filters = test_filters,
|
||||
});
|
||||
const mod_vt_test_run = b.addRunArtifact(mod_vt_test);
|
||||
@@ -258,8 +256,6 @@ pub fn build(b: *std.Build) !void {
|
||||
|
||||
const mod_vt_c_test = b.addTest(.{
|
||||
.root_module = mod.vt_c,
|
||||
.target = config.target,
|
||||
.optimize = config.optimize,
|
||||
.filters = test_filters,
|
||||
});
|
||||
const mod_vt_c_test_run = b.addRunArtifact(mod_vt_c_test);
|
||||
|
@@ -9,48 +9,49 @@
|
||||
|
||||
.libxev = .{
|
||||
// mitchellh/libxev
|
||||
.url = "https://github.com/mitchellh/libxev/archive/7f803181b158a10fec8619f793e3b4df515566cb.tar.gz",
|
||||
.hash = "libxev-0.0.0-86vtc2UaEwDfiTKX3iBI-s_hdzfzWQUarT3MUrmUQl-Q",
|
||||
.url = "https://github.com/mitchellh/libxev/archive/34fa50878aec6e5fa8f532867001ab3c36fae23e.tar.gz",
|
||||
.hash = "libxev-0.0.0-86vtc4IcEwCqEYxEYoN_3KXmc6A9VLcm22aVImfvecYs",
|
||||
.lazy = true,
|
||||
},
|
||||
.vaxis = .{
|
||||
// rockorager/libvaxis
|
||||
.url = "git+https://github.com/rockorager/libvaxis#1f41c121e8fc153d9ce8c6eb64b2bbab68ad7d23",
|
||||
.hash = "vaxis-0.1.0-BWNV_FUICQAFZnTCL11TUvnUr1Y0_ZdqtXHhd51d76Rn",
|
||||
.url = "https://github.com/rockorager/libvaxis/archive/6eb16bb4190dc074dafaf4f0ce7dadd50e81192a.tar.gz",
|
||||
.hash = "vaxis-0.5.1-BWNV_BMgCQDXdZzABeY4F_xwgE7nHFtYEP07KgEwJWo8",
|
||||
.lazy = true,
|
||||
},
|
||||
.z2d = .{
|
||||
// vancluever/z2d
|
||||
.url = "https://github.com/vancluever/z2d/archive/refs/tags/v0.8.1.tar.gz",
|
||||
.hash = "z2d-0.8.1-j5P_Hq8vDwB8ZaDA54-SzESDLF2zznG_zvTHiQNJImZP",
|
||||
.url = "https://github.com/vancluever/z2d/archive/a1237f6881d99b75abd8a20a934e62e34b44a005.tar.gz",
|
||||
.hash = "z2d-0.8.2-pre-j5P_HlVRFgCsBTQ3EgUoKbYHx5JMnyH1mHsOSPiafnef",
|
||||
.lazy = true,
|
||||
},
|
||||
.zig_objc = .{
|
||||
// mitchellh/zig-objc
|
||||
.url = "https://github.com/mitchellh/zig-objc/archive/c9e917a4e15a983b672ca779c7985d738a2d517c.tar.gz",
|
||||
.hash = "zig_objc-0.0.0-Ir_SpwsPAQBJgi9YRm2ubJMfdoysSq5gKpsIj3izQ8Zk",
|
||||
.url = "https://github.com/mitchellh/zig-objc/archive/f356ed02833f0f1b8e84d50bed9e807bf7cdc0ae.tar.gz",
|
||||
.hash = "zig_objc-0.0.0-Ir_Sp5gTAQCvxxR7oVIrPXxXwsfKgVP7_wqoOQrZjFeK",
|
||||
.lazy = true,
|
||||
},
|
||||
.zig_js = .{
|
||||
// mitchellh/zig-js
|
||||
.url = "https://deps.files.ghostty.org/zig_js-12205a66d423259567764fa0fc60c82be35365c21aeb76c5a7dc99698401f4f6fefc.tar.gz",
|
||||
.hash = "N-V-__8AAB9YCQBaZtQjJZVndk-g_GDIK-NTZcIa63bFp9yZ",
|
||||
.url = "https://github.com/mitchellh/zig-js/archive/04db83c617da1956ac5adc1cb9ba1e434c1cb6fd.tar.gz",
|
||||
.hash = "zig_js-0.0.0-rjCAV-6GAADxFug7rDmPH-uM_XcnJ5NmuAMJCAscMjhi",
|
||||
.lazy = true,
|
||||
},
|
||||
.uucode = .{
|
||||
.url = "https://github.com/jacobsandlund/uucode/archive/190706c6b56f0842d29778007f74f7d3d1335fc5.tar.gz",
|
||||
.hash = "uucode-0.1.0-ZZjBPpAFQABNCvd9cVPBg4I7233Ays-NWfWphPNqGbyE",
|
||||
// TODO: currently the use-llvm branch because its broken on self-hosted
|
||||
.url = "https://github.com/jacobsandlund/uucode/archive/f81f8ef8518b8ec5a7fca30ec5fdbc76cc6197df.tar.gz",
|
||||
.hash = "uucode-0.1.0-ZZjBPjQHQADuCy1VMWftjrMl3iWqgMpUugWVQJG6_7xT",
|
||||
},
|
||||
.zig_wayland = .{
|
||||
// codeberg ifreund/zig-wayland
|
||||
.url = "https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz",
|
||||
.hash = "wayland-0.4.0-dev-lQa1kjfIAQCmhhQu3xF0KH-94-TzeMXOqfnP0-Dg6Wyy",
|
||||
.url = "https://codeberg.org/ifreund/zig-wayland/archive/1b5c038ec10da20ed3a15b0b2a6db1c21383e8ea.tar.gz",
|
||||
.hash = "wayland-0.5.0-dev-lQa1khrMAQDJDwYFKpdH3HizherB7sHo5dKMECfvxQHe",
|
||||
.lazy = true,
|
||||
},
|
||||
.zf = .{
|
||||
// natecraddock/zf
|
||||
.url = "https://github.com/natecraddock/zf/archive/7aacbe6d155d64d15937ca95ca6c014905eb531f.tar.gz",
|
||||
.hash = "zf-0.10.3-OIRy8aiIAACLrBllz0zjxaH0aOe5oNm3KtEMyCntST-9",
|
||||
.url = "https://github.com/jcollie/zf/archive/52ad2e5528ab754f77437edf08a07b5ec843661c.tar.gz",
|
||||
.hash = "zf-0.10.3-OIRy8QGJAACJcu3tCGtfbJnnd3Y4QL7OW_X8PJ8u_ASR",
|
||||
.lazy = true,
|
||||
},
|
||||
.gobject = .{
|
||||
|
6
flake.lock
generated
6
flake.lock
generated
@@ -97,11 +97,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1748261582,
|
||||
"narHash": "sha256-3i0IL3s18hdDlbsf0/E+5kyPRkZwGPbSFngq5eToiAA=",
|
||||
"lastModified": 1759192380,
|
||||
"narHash": "sha256-0BWJgt4OSzxCESij5oo8WLWrPZ+1qLp8KUQe32QeV4Q=",
|
||||
"owner": "mitchellh",
|
||||
"repo": "zig-overlay",
|
||||
"rev": "aafb1b093fb838f7a02613b719e85ec912914221",
|
||||
"rev": "0bcd1401ed43d10f10cbded49624206553e92f57",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@@ -47,7 +47,7 @@
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in {
|
||||
devShell.${system} = pkgs.callPackage ./nix/devShell.nix {
|
||||
zig = zig.packages.${system}."0.14.1";
|
||||
zig = zig.packages.${system}."0.15.1";
|
||||
wraptest = pkgs.callPackage ./nix/wraptest.nix {};
|
||||
zon2nix = zon2nix;
|
||||
};
|
||||
|
@@ -46,19 +46,19 @@ pub fn addPaths(
|
||||
// find the SDK path.
|
||||
const libc = try std.zig.LibCInstallation.findNative(.{
|
||||
.allocator = b.allocator,
|
||||
.target = step.rootModuleTarget(),
|
||||
.target = &step.rootModuleTarget(),
|
||||
.verbose = false,
|
||||
});
|
||||
|
||||
// Render the file compatible with the `--libc` Zig flag.
|
||||
var list: std.ArrayList(u8) = .init(b.allocator);
|
||||
defer list.deinit();
|
||||
try libc.render(list.writer());
|
||||
var stream: std.io.Writer.Allocating = .init(b.allocator);
|
||||
defer stream.deinit();
|
||||
try libc.render(&stream.writer);
|
||||
|
||||
// Create a temporary file to store the libc path because
|
||||
// `--libc` expects a file path.
|
||||
const wf = b.addWriteFiles();
|
||||
const path = wf.add("libc.txt", list.items);
|
||||
const path = wf.add("libc.txt", stream.written());
|
||||
|
||||
// Determine our framework path. Zig has a bug where it doesn't
|
||||
// parse this from the libc txt file for `-framework` flags:
|
||||
|
@@ -19,9 +19,8 @@ pub fn build(b: *std.Build) !void {
|
||||
try apple_sdk.addPaths(b, lib);
|
||||
}
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{});
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
|
||||
if (b.lazyDependency("breakpad", .{})) |upstream| {
|
||||
lib.addIncludePath(upstream.path("src"));
|
||||
|
@@ -55,19 +55,19 @@ pub fn build(b: *std.Build) !void {
|
||||
if (imgui_) |imgui| lib.addIncludePath(imgui.path(""));
|
||||
module.addIncludePath(b.path("vendor"));
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DCIMGUI_FREETYPE=1",
|
||||
"-DIMGUI_USE_WCHAR32=1",
|
||||
"-DIMGUI_DISABLE_OBSOLETE_FUNCTIONS=1",
|
||||
});
|
||||
if (target.result.os.tag == .windows) {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DIMGUI_IMPL_API=extern\t\"C\"\t__declspec(dllexport)",
|
||||
});
|
||||
} else {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DIMGUI_IMPL_API=extern\t\"C\"",
|
||||
});
|
||||
}
|
||||
|
@@ -82,9 +82,9 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
lib.addIncludePath(b.path("override/include"));
|
||||
module.addIncludePath(b.path("override/include"));
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DHAVE_DIRENT_H",
|
||||
"-DHAVE_FCNTL_H",
|
||||
"-DHAVE_STDLIB_H",
|
||||
@@ -129,12 +129,12 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
});
|
||||
|
||||
switch (target.result.ptrBitWidth()) {
|
||||
32 => try flags.appendSlice(&.{
|
||||
32 => try flags.appendSlice(b.allocator, &.{
|
||||
"-DSIZEOF_VOID_P=4",
|
||||
"-DALIGNOF_VOID_P=4",
|
||||
}),
|
||||
|
||||
64 => try flags.appendSlice(&.{
|
||||
64 => try flags.appendSlice(b.allocator, &.{
|
||||
"-DSIZEOF_VOID_P=8",
|
||||
"-DALIGNOF_VOID_P=8",
|
||||
}),
|
||||
@@ -142,14 +142,14 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
else => @panic("unsupported arch"),
|
||||
}
|
||||
if (target.result.os.tag == .windows) {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DFC_CACHEDIR=\"LOCAL_APPDATA_FONTCONFIG_CACHE\"",
|
||||
"-DFC_TEMPLATEDIR=\"c:/share/fontconfig/conf.avail\"",
|
||||
"-DCONFIGDIR=\"c:/etc/fonts/conf.d\"",
|
||||
"-DFC_DEFAULT_FONTS=\"\\t<dir>WINDOWSFONTDIR</dir>\\n\\t<dir>WINDOWSUSERFONTDIR</dir>\\n\"",
|
||||
});
|
||||
} else {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DHAVE_FSTATFS",
|
||||
"-DHAVE_FSTATVFS",
|
||||
"-DHAVE_GETOPT",
|
||||
@@ -173,13 +173,13 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
});
|
||||
|
||||
if (target.result.os.tag == .freebsd) {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DFC_TEMPLATEDIR=\"/usr/local/etc/fonts/conf.avail\"",
|
||||
"-DFONTCONFIG_PATH=\"/usr/local/etc/fonts\"",
|
||||
"-DCONFIGDIR=\"/usr/local/etc/fonts/conf.d\"",
|
||||
});
|
||||
} else {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DFC_TEMPLATEDIR=\"/usr/share/fontconfig/conf.avail\"",
|
||||
"-DFONTCONFIG_PATH=\"/etc/fonts\"",
|
||||
"-DCONFIGDIR=\"/usr/local/fontconfig/conf.d\"",
|
||||
@@ -187,7 +187,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
}
|
||||
|
||||
if (target.result.os.tag == .linux) {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DHAVE_SYS_STATFS_H",
|
||||
"-DHAVE_SYS_VFS_H",
|
||||
});
|
||||
@@ -214,14 +214,14 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
// Libxml2
|
||||
_ = b.systemIntegrationOption("libxml2", .{}); // So it shows up in help
|
||||
if (libxml2_enabled) {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DENABLE_LIBXML2",
|
||||
"-DLIBXML_STATIC",
|
||||
"-DLIBXML_PUSH_ENABLED",
|
||||
});
|
||||
if (target.result.os.tag == .windows) {
|
||||
// NOTE: this should be defined on all targets
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-Werror=implicit-function-declaration",
|
||||
});
|
||||
}
|
||||
|
@@ -77,9 +77,9 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
try apple_sdk.addPaths(b, lib);
|
||||
}
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DFT2_BUILD_LIBRARY",
|
||||
|
||||
"-DFT_CONFIG_OPTION_SYSTEM_ZLIB=1",
|
||||
@@ -103,7 +103,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
// Libpng
|
||||
_ = b.systemIntegrationOption("libpng", .{}); // So it shows up in help
|
||||
if (libpng_enabled) {
|
||||
try flags.append("-DFT_CONFIG_OPTION_USE_PNG=1");
|
||||
try flags.append(b.allocator, "-DFT_CONFIG_OPTION_USE_PNG=1");
|
||||
|
||||
if (b.systemIntegrationOption("libpng", .{})) {
|
||||
lib.linkSystemLibrary2("libpng", dynamic_link_opts);
|
||||
|
@@ -59,9 +59,9 @@ fn buildGlslang(
|
||||
try apple_sdk.addPaths(b, lib);
|
||||
}
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-fno-sanitize=undefined",
|
||||
"-fno-sanitize-trap=undefined",
|
||||
});
|
||||
|
@@ -36,10 +36,13 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
const optimize = options.optimize;
|
||||
|
||||
// Shared library
|
||||
const lib = b.addSharedLibrary(.{
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "gtk4-layer-shell",
|
||||
.linkage = .dynamic,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
b.installArtifact(lib);
|
||||
|
||||
|
@@ -111,13 +111,13 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
|
||||
const dynamic_link_opts = options.dynamic_link_opts;
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DHAVE_STDBOOL_H",
|
||||
});
|
||||
if (target.result.os.tag != .windows) {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DHAVE_UNISTD_H",
|
||||
"-DHAVE_SYS_MMAN_H",
|
||||
"-DHAVE_PTHREAD=1",
|
||||
@@ -127,7 +127,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
// Freetype
|
||||
_ = b.systemIntegrationOption("freetype", .{}); // So it shows up in help
|
||||
if (freetype_enabled) {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DHAVE_FREETYPE=1",
|
||||
|
||||
// Let's just assume a new freetype
|
||||
@@ -153,7 +153,7 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
}
|
||||
|
||||
if (coretext_enabled) {
|
||||
try flags.appendSlice(&.{"-DHAVE_CORETEXT=1"});
|
||||
try flags.appendSlice(b.allocator, &.{"-DHAVE_CORETEXT=1"});
|
||||
lib.linkFramework("CoreText");
|
||||
module.linkFramework("CoreText", .{});
|
||||
}
|
||||
|
@@ -31,9 +31,9 @@ pub fn build(b: *std.Build) !void {
|
||||
try apple_sdk.addPaths(b, lib);
|
||||
}
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
// Avoid changing binaries based on the current time and date.
|
||||
"-Wno-builtin-macro-redefined",
|
||||
"-D__DATE__=\"redacted\"",
|
||||
@@ -69,7 +69,7 @@ pub fn build(b: *std.Build) !void {
|
||||
"-fno-vectorize",
|
||||
});
|
||||
if (target.result.os.tag != .windows) {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-fmath-errno",
|
||||
"-fno-exceptions",
|
||||
});
|
||||
|
@@ -22,9 +22,9 @@ pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DHAVE_CONFIG_H",
|
||||
"-DLOCALEDIR=\"\"",
|
||||
});
|
||||
|
@@ -46,9 +46,9 @@ pub fn build(b: *std.Build) !void {
|
||||
}
|
||||
|
||||
if (b.lazyDependency("libpng", .{})) |upstream| {
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DPNG_ARM_NEON_OPT=0",
|
||||
"-DPNG_POWERPC_VSX_OPT=0",
|
||||
"-DPNG_INTEL_SSE_OPT=0",
|
||||
|
@@ -25,9 +25,9 @@ pub fn build(b: *std.Build) !void {
|
||||
lib.addIncludePath(b.path("override/config/posix"));
|
||||
}
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
// Version info, hardcoded
|
||||
comptime "-DLIBXML_VERSION=" ++ Version.number(),
|
||||
comptime "-DLIBXML_VERSION_STRING=" ++ Version.string(),
|
||||
@@ -46,7 +46,7 @@ pub fn build(b: *std.Build) !void {
|
||||
"-DWITHOUT_TRIO=1",
|
||||
});
|
||||
if (target.result.os.tag != .windows) {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DHAVE_ARPA_INET_H=1",
|
||||
"-DHAVE_ARPA_NAMESER_H=1",
|
||||
"-DHAVE_DL_H=1",
|
||||
@@ -74,25 +74,25 @@ pub fn build(b: *std.Build) !void {
|
||||
var nameBuf: [32]u8 = undefined;
|
||||
const name = std.ascii.upperString(&nameBuf, field.name);
|
||||
const define = try std.fmt.allocPrint(b.allocator, "-DLIBXML_{s}_ENABLED=1", .{name});
|
||||
try flags.append(define);
|
||||
try flags.append(b.allocator, define);
|
||||
|
||||
if (std.mem.eql(u8, field.name, "history")) {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DHAVE_LIBHISTORY=1",
|
||||
"-DHAVE_LIBREADLINE=1",
|
||||
});
|
||||
}
|
||||
if (std.mem.eql(u8, field.name, "mem_debug")) {
|
||||
try flags.append("-DDEBUG_MEMORY_LOCATION=1");
|
||||
try flags.append(b.allocator, "-DDEBUG_MEMORY_LOCATION=1");
|
||||
}
|
||||
if (std.mem.eql(u8, field.name, "regexp")) {
|
||||
try flags.append("-DLIBXML_UNICODE_ENABLED=1");
|
||||
try flags.append(b.allocator, "-DLIBXML_UNICODE_ENABLED=1");
|
||||
}
|
||||
if (std.mem.eql(u8, field.name, "run_debug")) {
|
||||
try flags.append("-DLIBXML_DEBUG_RUNTIME=1");
|
||||
try flags.append(b.allocator, "-DLIBXML_DEBUG_RUNTIME=1");
|
||||
}
|
||||
if (std.mem.eql(u8, field.name, "thread")) {
|
||||
try flags.append("-DHAVE_LIBPTHREAD=1");
|
||||
try flags.append(b.allocator, "-DHAVE_LIBPTHREAD=1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -100,9 +100,8 @@ fn buildLib(b: *std.Build, module: *std.Build.Module, options: anytype) !*std.Bu
|
||||
.SIZEOF_VOIDP = t.ptrBitWidth() / t.cTypeBitSize(.char),
|
||||
}));
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{});
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.flags = flags.items,
|
||||
|
@@ -26,22 +26,21 @@ pub fn build(b: *std.Build) !void {
|
||||
try apple_sdk.addPaths(b, lib);
|
||||
}
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{});
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
if (target.result.os.tag == .windows) {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DSENTRY_WITH_UNWINDER_DBGHELP",
|
||||
});
|
||||
} else {
|
||||
try flags.appendSlice(&.{
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DSENTRY_WITH_UNWINDER_LIBBACKTRACE",
|
||||
});
|
||||
}
|
||||
switch (backend) {
|
||||
.crashpad => try flags.append("-DSENTRY_BACKEND_CRASHPAD"),
|
||||
.breakpad => try flags.append("-DSENTRY_BACKEND_BREAKPAD"),
|
||||
.inproc => try flags.append("-DSENTRY_BACKEND_INPROC"),
|
||||
.crashpad => try flags.append(b.allocator, "-DSENTRY_BACKEND_CRASHPAD"),
|
||||
.breakpad => try flags.append(b.allocator, "-DSENTRY_BACKEND_BREAKPAD"),
|
||||
.inproc => try flags.append(b.allocator, "-DSENTRY_BACKEND_INPROC"),
|
||||
.none => {},
|
||||
}
|
||||
|
||||
|
@@ -20,11 +20,11 @@ pub fn build(b: *std.Build) !void {
|
||||
try apple_sdk.addPaths(b, lib);
|
||||
}
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
// Zig 0.13 bug: https://github.com/ziglang/zig/issues/20414
|
||||
// (See root Ghostty build.zig on why we do this)
|
||||
try flags.appendSlice(&.{"-DSIMDUTF_IMPLEMENTATION_ICELAKE=0"});
|
||||
try flags.appendSlice(b.allocator, &.{"-DSIMDUTF_IMPLEMENTATION_ICELAKE=0"});
|
||||
|
||||
lib.addCSourceFiles(.{
|
||||
.flags = flags.items,
|
||||
|
@@ -64,9 +64,9 @@ fn buildSpirvCross(
|
||||
try apple_sdk.addPaths(b, lib);
|
||||
}
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DSPIRV_CROSS_C_API_GLSL=1",
|
||||
"-DSPIRV_CROSS_C_API_MSL=1",
|
||||
|
||||
|
@@ -19,9 +19,8 @@ pub fn build(b: *std.Build) !void {
|
||||
try apple_sdk.addPaths(b, lib);
|
||||
}
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{});
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
|
||||
lib.addCSourceFiles(.{
|
||||
.flags = flags.items,
|
||||
|
@@ -17,11 +17,11 @@ pub fn build(b: *std.Build) !void {
|
||||
});
|
||||
unit_tests.linkLibC();
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.append("-DWUFFS_IMPLEMENTATION");
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.append(b.allocator, "-DWUFFS_IMPLEMENTATION");
|
||||
inline for (@import("src/c.zig").defines) |key| {
|
||||
try flags.append("-D" ++ key);
|
||||
try flags.append(b.allocator, "-D" ++ key);
|
||||
}
|
||||
|
||||
if (b.lazyDependency("wuffs", .{})) |wuffs_dep| {
|
||||
|
@@ -26,9 +26,9 @@ pub fn build(b: *std.Build) !void {
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
var flags: std.ArrayList([]const u8) = .empty;
|
||||
defer flags.deinit(b.allocator);
|
||||
try flags.appendSlice(b.allocator, &.{
|
||||
"-DHAVE_SYS_TYPES_H",
|
||||
"-DHAVE_STDINT_H",
|
||||
"-DHAVE_STDDEF_H",
|
||||
|
@@ -477,7 +477,7 @@ pub fn addOptions(self: *const Config, step: *std.Build.Step.Options) !void {
|
||||
step.addOption(std.SemanticVersion, "app_version", self.version);
|
||||
step.addOption([:0]const u8, "app_version_string", try std.fmt.bufPrintZ(
|
||||
&buf,
|
||||
"{}",
|
||||
"{f}",
|
||||
.{self.version},
|
||||
));
|
||||
step.addOption(
|
||||
|
@@ -11,8 +11,8 @@ pub fn init(
|
||||
b: *std.Build,
|
||||
deps: *const SharedDeps,
|
||||
) !GhosttyBench {
|
||||
var steps = std.ArrayList(*std.Build.Step.Compile).init(b.allocator);
|
||||
errdefer steps.deinit();
|
||||
var steps: std.ArrayList(*std.Build.Step.Compile) = .empty;
|
||||
errdefer steps.deinit(b.allocator);
|
||||
|
||||
// Our synthetic data generator
|
||||
{
|
||||
@@ -28,7 +28,7 @@ pub fn init(
|
||||
});
|
||||
exe.linkLibC();
|
||||
_ = try deps.add(exe);
|
||||
try steps.append(exe);
|
||||
try steps.append(b.allocator, exe);
|
||||
}
|
||||
|
||||
// Our benchmarking application.
|
||||
@@ -44,7 +44,7 @@ pub fn init(
|
||||
});
|
||||
exe.linkLibC();
|
||||
_ = try deps.add(exe);
|
||||
try steps.append(exe);
|
||||
try steps.append(b.allocator, exe);
|
||||
}
|
||||
|
||||
return .{ .steps = steps.items };
|
||||
|
@@ -38,10 +38,10 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
||||
|
||||
// embed the Ghostty version in the tarball
|
||||
{
|
||||
const version = b.addWriteFiles().add("VERSION", b.fmt("{}", .{cfg.version}));
|
||||
const version = b.addWriteFiles().add("VERSION", b.fmt("{f}", .{cfg.version}));
|
||||
// --add-file uses the most recent --prefix to determine the path
|
||||
// in the archive to copy the file (the directory only).
|
||||
git_archive.addArg(b.fmt("--prefix=ghostty-{}/", .{
|
||||
git_archive.addArg(b.fmt("--prefix=ghostty-{f}/", .{
|
||||
cfg.version,
|
||||
}));
|
||||
git_archive.addPrefixedFileArg("--add-file=", version);
|
||||
@@ -60,7 +60,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
||||
|
||||
// --add-file uses the most recent --prefix to determine the path
|
||||
// in the archive to copy the file (the directory only).
|
||||
git_archive.addArg(b.fmt("--prefix=ghostty-{}/{s}/", .{
|
||||
git_archive.addArg(b.fmt("--prefix=ghostty-{f}/{s}/", .{
|
||||
cfg.version,
|
||||
std.fs.path.dirname(resource.dist).?,
|
||||
}));
|
||||
@@ -72,11 +72,11 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
||||
// This is important. Standard source tarballs extract into
|
||||
// a directory named `project-version`. This is expected by
|
||||
// standard tooling such as debhelper and rpmbuild.
|
||||
b.fmt("--prefix=ghostty-{}/", .{cfg.version}),
|
||||
b.fmt("--prefix=ghostty-{f}/", .{cfg.version}),
|
||||
"-o",
|
||||
});
|
||||
const output = git_archive.addOutputFileArg(b.fmt(
|
||||
"ghostty-{}.tar.gz",
|
||||
"ghostty-{f}.tar.gz",
|
||||
.{cfg.version},
|
||||
));
|
||||
git_archive.addArg("HEAD");
|
||||
@@ -84,7 +84,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
||||
// The install step to put the dist into the build directory.
|
||||
const install = b.addInstallFile(
|
||||
output,
|
||||
b.fmt("dist/ghostty-{}.tar.gz", .{cfg.version}),
|
||||
b.fmt("dist/ghostty-{f}.tar.gz", .{cfg.version}),
|
||||
);
|
||||
|
||||
// The check step to ensure the archive works.
|
||||
@@ -96,7 +96,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyDist {
|
||||
// i.e. this is way `build.zig` is.
|
||||
const extract_dir = check
|
||||
.addOutputDirectoryArg("ghostty")
|
||||
.path(b, b.fmt("ghostty-{}", .{cfg.version}));
|
||||
.path(b, b.fmt("ghostty-{f}", .{cfg.version}));
|
||||
|
||||
// Check that tests pass within the extracted directory. This isn't
|
||||
// a fully hermetic test because we're sharing the Zig cache. In
|
||||
|
@@ -12,8 +12,8 @@ pub fn init(
|
||||
b: *std.Build,
|
||||
deps: *const SharedDeps,
|
||||
) !GhosttyDocs {
|
||||
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
||||
errdefer steps.deinit();
|
||||
var steps: std.ArrayList(*std.Build.Step) = .empty;
|
||||
errdefer steps.deinit(b.allocator);
|
||||
|
||||
const manpages = [_]struct {
|
||||
name: []const u8,
|
||||
@@ -52,7 +52,7 @@ pub fn init(
|
||||
const generate_markdown_step = b.addRunArtifact(generate_markdown);
|
||||
const markdown_output = generate_markdown_step.captureStdOut();
|
||||
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
markdown_output,
|
||||
"share/ghostty/doc/" ++ manpage.name ++ "." ++ manpage.section ++ ".md",
|
||||
).step);
|
||||
@@ -67,7 +67,7 @@ pub fn init(
|
||||
});
|
||||
generate_html.addFileArg(markdown_output);
|
||||
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
generate_html.captureStdOut(),
|
||||
"share/ghostty/doc/" ++ manpage.name ++ "." ++ manpage.section ++ ".html",
|
||||
).step);
|
||||
@@ -82,7 +82,7 @@ pub fn init(
|
||||
});
|
||||
generate_manpage.addFileArg(markdown_output);
|
||||
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
generate_manpage.captureStdOut(),
|
||||
"share/man/man" ++ manpage.section ++ "/" ++ manpage.name ++ "." ++ manpage.section,
|
||||
).step);
|
||||
|
@@ -18,8 +18,8 @@ update_step: *std.Build.Step,
|
||||
pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n {
|
||||
_ = cfg;
|
||||
|
||||
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
||||
defer steps.deinit();
|
||||
var steps: std.ArrayList(*std.Build.Step) = .empty;
|
||||
defer steps.deinit(b.allocator);
|
||||
|
||||
inline for (locales) |locale| {
|
||||
// There is no encoding suffix in the LC_MESSAGES path on FreeBSD,
|
||||
@@ -33,7 +33,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n {
|
||||
const msgfmt = b.addSystemCommand(&.{ "msgfmt", "-o", "-" });
|
||||
msgfmt.addFileArg(b.path("po/" ++ locale ++ ".po"));
|
||||
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
msgfmt.captureStdOut(),
|
||||
std.fmt.comptimePrint(
|
||||
"share/locale/{s}/LC_MESSAGES/{s}.mo",
|
||||
@@ -45,7 +45,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyI18n {
|
||||
return .{
|
||||
.owner = b,
|
||||
.update_step = try createUpdateStep(b),
|
||||
.steps = try steps.toOwnedSlice(),
|
||||
.steps = try steps.toOwnedSlice(b.allocator),
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -40,7 +40,7 @@ pub fn initStatic(
|
||||
// Add our dependencies. Get the list of all static deps so we can
|
||||
// build a combined archive if necessary.
|
||||
var lib_list = try deps.add(lib);
|
||||
try lib_list.append(lib.getEmittedBin());
|
||||
try lib_list.append(b.allocator, lib.getEmittedBin());
|
||||
|
||||
if (!deps.config.target.result.os.tag.isDarwin()) return .{
|
||||
.step = &lib.step,
|
||||
@@ -69,8 +69,9 @@ pub fn initShared(
|
||||
b: *std.Build,
|
||||
deps: *const SharedDeps,
|
||||
) !GhosttyLib {
|
||||
const lib = b.addSharedLibrary(.{
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "ghostty",
|
||||
.linkage = .dynamic,
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main_c.zig"),
|
||||
.target = deps.config.target,
|
||||
|
@@ -24,8 +24,9 @@ pub fn initShared(
|
||||
zig: *const GhosttyZig,
|
||||
) !GhosttyLibVt {
|
||||
const target = zig.vt.resolved_target.?;
|
||||
const lib = b.addSharedLibrary(.{
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "ghostty-vt",
|
||||
.linkage = .dynamic,
|
||||
.root_module = zig.vt_c,
|
||||
.version = std.SemanticVersion{ .major = 0, .minor = 1, .patch = 0 },
|
||||
});
|
||||
|
@@ -10,8 +10,8 @@ const RunStep = std.Build.Step.Run;
|
||||
steps: []*std.Build.Step,
|
||||
|
||||
pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
||||
errdefer steps.deinit();
|
||||
var steps: std.ArrayList(*std.Build.Step) = .empty;
|
||||
errdefer steps.deinit(b.allocator);
|
||||
|
||||
// This is the exe used to generate some build data.
|
||||
const build_data_exe = b.addExecutable(.{
|
||||
@@ -49,7 +49,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
"share/terminfo/ghostty.terminfo",
|
||||
);
|
||||
|
||||
try steps.append(&source_install.step);
|
||||
try steps.append(b.allocator, &source_install.step);
|
||||
}
|
||||
|
||||
// Windows doesn't have the binaries below.
|
||||
@@ -73,7 +73,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
"share/terminfo/ghostty.termcap",
|
||||
);
|
||||
|
||||
try steps.append(&cap_install.step);
|
||||
try steps.append(b.allocator, &cap_install.step);
|
||||
}
|
||||
|
||||
// Compile the terminfo source into a terminfo database
|
||||
@@ -99,7 +99,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
.{ b.install_path, terminfo_share_dir },
|
||||
));
|
||||
|
||||
try steps.append(&mkdir_step.step);
|
||||
try steps.append(b.allocator, &mkdir_step.step);
|
||||
|
||||
// Use cp -R instead of Step.InstallDir because we need to preserve
|
||||
// symlinks in the terminfo database. Zig's InstallDir step doesn't
|
||||
@@ -109,7 +109,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
copy_step.addFileArg(path);
|
||||
copy_step.addArg(b.fmt("{s}/share", .{b.install_path}));
|
||||
copy_step.step.dependOn(&mkdir_step.step);
|
||||
try steps.append(©_step.step);
|
||||
try steps.append(b.allocator, ©_step.step);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
.install_subdir = b.pathJoin(&.{ "ghostty", "shell-integration" }),
|
||||
.exclude_extensions = &.{".md"},
|
||||
});
|
||||
try steps.append(&install_step.step);
|
||||
try steps.append(b.allocator, &install_step.step);
|
||||
}
|
||||
|
||||
// Themes
|
||||
@@ -132,7 +132,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
.install_subdir = b.pathJoin(&.{ "ghostty", "themes" }),
|
||||
.exclude_extensions = &.{".md"},
|
||||
});
|
||||
try steps.append(&install_step.step);
|
||||
try steps.append(b.allocator, &install_step.step);
|
||||
}
|
||||
|
||||
// Fish shell completions
|
||||
@@ -147,7 +147,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
.install_dir = .prefix,
|
||||
.install_subdir = "share/fish/vendor_completions.d",
|
||||
});
|
||||
try steps.append(&install_step.step);
|
||||
try steps.append(b.allocator, &install_step.step);
|
||||
}
|
||||
|
||||
// zsh shell completions
|
||||
@@ -162,7 +162,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
.install_dir = .prefix,
|
||||
.install_subdir = "share/zsh/site-functions",
|
||||
});
|
||||
try steps.append(&install_step.step);
|
||||
try steps.append(b.allocator, &install_step.step);
|
||||
}
|
||||
|
||||
// bash shell completions
|
||||
@@ -177,7 +177,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
.install_dir = .prefix,
|
||||
.install_subdir = "share/bash-completion/completions",
|
||||
});
|
||||
try steps.append(&install_step.step);
|
||||
try steps.append(b.allocator, &install_step.step);
|
||||
}
|
||||
|
||||
// Vim and Neovim plugin
|
||||
@@ -210,14 +210,14 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
.install_dir = .prefix,
|
||||
.install_subdir = "share/vim/vimfiles",
|
||||
});
|
||||
try steps.append(&vim_step.step);
|
||||
try steps.append(b.allocator, &vim_step.step);
|
||||
|
||||
const neovim_step = b.addInstallDirectory(.{
|
||||
.source_dir = wf.getDirectory(),
|
||||
.install_dir = .prefix,
|
||||
.install_subdir = "share/nvim/site",
|
||||
});
|
||||
try steps.append(&neovim_step.step);
|
||||
try steps.append(b.allocator, &neovim_step.step);
|
||||
}
|
||||
|
||||
// Sublime syntax highlighting for bat cli tool
|
||||
@@ -237,7 +237,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
||||
.install_dir = .prefix,
|
||||
.install_subdir = "share/bat/syntaxes",
|
||||
});
|
||||
try steps.append(&install_step.step);
|
||||
try steps.append(b.allocator, &install_step.step);
|
||||
}
|
||||
|
||||
// App (Linux)
|
||||
@@ -286,16 +286,17 @@ fn addLinuxAppResources(
|
||||
// second element of the tuple.
|
||||
const Template = struct { std.Build.LazyPath, []const u8 };
|
||||
const templates: []const Template = templates: {
|
||||
var ts: std.ArrayList(Template) = .init(b.allocator);
|
||||
var ts: std.ArrayList(Template) = .empty;
|
||||
defer ts.deinit(b.allocator);
|
||||
|
||||
// Desktop file so that we have an icon and other metadata
|
||||
try ts.append(.{
|
||||
try ts.append(b.allocator, .{
|
||||
b.path("dist/linux/app.desktop.in"),
|
||||
b.fmt("share/applications/{s}.desktop", .{app_id}),
|
||||
});
|
||||
|
||||
// Service for DBus activation.
|
||||
try ts.append(.{
|
||||
try ts.append(b.allocator, .{
|
||||
if (cfg.flatpak)
|
||||
b.path("dist/linux/dbus.service.flatpak.in")
|
||||
else
|
||||
@@ -320,7 +321,7 @@ fn addLinuxAppResources(
|
||||
// See the following code:
|
||||
//
|
||||
// https://github.com/flatpak/xdg-desktop-portal/blob/7d4d48cf079147c8887da17ec6c3954acd5a285c/src/xdp-utils.c#L152-L220
|
||||
if (!cfg.flatpak) try ts.append(.{
|
||||
if (!cfg.flatpak) try ts.append(b.allocator, .{
|
||||
b.path("dist/linux/systemd.service.in"),
|
||||
b.fmt(
|
||||
"{s}/systemd/user/app-{s}.service",
|
||||
@@ -333,12 +334,12 @@ fn addLinuxAppResources(
|
||||
|
||||
// AppStream metainfo so that application has rich metadata
|
||||
// within app stores
|
||||
try ts.append(.{
|
||||
try ts.append(b.allocator, .{
|
||||
b.path("dist/linux/com.mitchellh.ghostty.metainfo.xml.in"),
|
||||
b.fmt("share/metainfo/{s}.metainfo.xml", .{app_id}),
|
||||
});
|
||||
|
||||
break :templates ts.items;
|
||||
break :templates try ts.toOwnedSlice(b.allocator);
|
||||
};
|
||||
|
||||
// Process all our templates
|
||||
@@ -361,65 +362,65 @@ fn addLinuxAppResources(
|
||||
template[1],
|
||||
);
|
||||
|
||||
try steps.append(©.step);
|
||||
try steps.append(b.allocator, ©.step);
|
||||
}
|
||||
|
||||
// Right click menu action for Plasma desktop
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("dist/linux/ghostty_dolphin.desktop"),
|
||||
"share/kio/servicemenus/com.mitchellh.ghostty.desktop",
|
||||
).step);
|
||||
|
||||
// Right click menu action for Nautilus. Note that this _must_ be named
|
||||
// `ghostty.py`. Using the full app id causes problems (see #5468).
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("dist/linux/ghostty_nautilus.py"),
|
||||
"share/nautilus-python/extensions/ghostty.py",
|
||||
).step);
|
||||
|
||||
// Various icons that our application can use, including the icon
|
||||
// that will be used for the desktop.
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("images/gnome/16.png"),
|
||||
"share/icons/hicolor/16x16/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("images/gnome/32.png"),
|
||||
"share/icons/hicolor/32x32/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("images/gnome/128.png"),
|
||||
"share/icons/hicolor/128x128/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("images/gnome/256.png"),
|
||||
"share/icons/hicolor/256x256/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("images/gnome/512.png"),
|
||||
"share/icons/hicolor/512x512/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
// Flatpaks only support icons up to 512x512.
|
||||
if (!cfg.flatpak) {
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("images/gnome/1024.png"),
|
||||
"share/icons/hicolor/1024x1024/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
}
|
||||
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("images/gnome/32.png"),
|
||||
"share/icons/hicolor/16x16@2/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("images/gnome/64.png"),
|
||||
"share/icons/hicolor/32x32@2/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("images/gnome/256.png"),
|
||||
"share/icons/hicolor/128x128@2/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
b.path("images/gnome/512.png"),
|
||||
"share/icons/hicolor/256x256@2/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
|
@@ -12,8 +12,8 @@ pub fn init(
|
||||
b: *std.Build,
|
||||
deps: *const SharedDeps,
|
||||
) !GhosttyWebdata {
|
||||
var steps = std.ArrayList(*std.Build.Step).init(b.allocator);
|
||||
errdefer steps.deinit();
|
||||
var steps: std.ArrayList(*std.Build.Step) = .empty;
|
||||
errdefer steps.deinit(b.allocator);
|
||||
|
||||
{
|
||||
const webgen_config = b.addExecutable(.{
|
||||
@@ -43,7 +43,7 @@ pub fn init(
|
||||
const webgen_config_step = b.addRunArtifact(webgen_config);
|
||||
const webgen_config_out = webgen_config_step.captureStdOut();
|
||||
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
webgen_config_out,
|
||||
"share/ghostty/webdata/config.mdx",
|
||||
).step);
|
||||
@@ -52,8 +52,10 @@ pub fn init(
|
||||
{
|
||||
const webgen_actions = b.addExecutable(.{
|
||||
.name = "webgen_actions",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = b.graph.host,
|
||||
}),
|
||||
});
|
||||
deps.help_strings.addImport(webgen_actions);
|
||||
|
||||
@@ -72,7 +74,7 @@ pub fn init(
|
||||
const webgen_actions_step = b.addRunArtifact(webgen_actions);
|
||||
const webgen_actions_out = webgen_actions_step.captureStdOut();
|
||||
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
webgen_actions_out,
|
||||
"share/ghostty/webdata/actions.mdx",
|
||||
).step);
|
||||
@@ -81,8 +83,10 @@ pub fn init(
|
||||
{
|
||||
const webgen_commands = b.addExecutable(.{
|
||||
.name = "webgen_commands",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = b.graph.host,
|
||||
}),
|
||||
});
|
||||
deps.help_strings.addImport(webgen_commands);
|
||||
|
||||
@@ -101,7 +105,7 @@ pub fn init(
|
||||
const webgen_commands_step = b.addRunArtifact(webgen_commands);
|
||||
const webgen_commands_out = webgen_commands_step.captureStdOut();
|
||||
|
||||
try steps.append(&b.addInstallFile(
|
||||
try steps.append(b.allocator, &b.addInstallFile(
|
||||
webgen_commands_out,
|
||||
"share/ghostty/webdata/commands.mdx",
|
||||
).step);
|
||||
|
@@ -44,7 +44,7 @@ pub fn create(b: *std.Build, opts: Options) ?*MetallibStep {
|
||||
const self = b.allocator.create(MetallibStep) catch @panic("OOM");
|
||||
|
||||
const min_version = if (opts.target.query.os_version_min) |v|
|
||||
b.fmt("{}", .{v.semver})
|
||||
b.fmt("{f}", .{v.semver})
|
||||
else switch (opts.target.result.os.tag) {
|
||||
.macos => "10.14",
|
||||
.ios => "11.0",
|
||||
|
@@ -113,8 +113,8 @@ pub fn add(
|
||||
|
||||
// We maintain a list of our static libraries and return it so that
|
||||
// we can build a single fat static library for the final app.
|
||||
var static_libs = LazyPathList.init(b.allocator);
|
||||
errdefer static_libs.deinit();
|
||||
var static_libs: LazyPathList = .empty;
|
||||
errdefer static_libs.deinit(b.allocator);
|
||||
|
||||
// WARNING: This is a hack!
|
||||
// If we're cross-compiling to Darwin then we don't add any deps.
|
||||
@@ -154,6 +154,7 @@ pub fn add(
|
||||
} else {
|
||||
step.linkLibrary(freetype_dep.artifact("freetype"));
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
freetype_dep.artifact("freetype").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -178,6 +179,7 @@ pub fn add(
|
||||
} else {
|
||||
step.linkLibrary(harfbuzz_dep.artifact("harfbuzz"));
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
harfbuzz_dep.artifact("harfbuzz").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -201,6 +203,7 @@ pub fn add(
|
||||
} else {
|
||||
step.linkLibrary(fontconfig_dep.artifact("fontconfig"));
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
fontconfig_dep.artifact("fontconfig").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -218,6 +221,7 @@ pub fn add(
|
||||
})) |libpng_dep| {
|
||||
step.linkLibrary(libpng_dep.artifact("png"));
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
libpng_dep.artifact("png").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -231,6 +235,7 @@ pub fn add(
|
||||
})) |zlib_dep| {
|
||||
step.linkLibrary(zlib_dep.artifact("z"));
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
zlib_dep.artifact("z").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -250,6 +255,7 @@ pub fn add(
|
||||
} else {
|
||||
step.linkLibrary(oniguruma_dep.artifact("oniguruma"));
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
oniguruma_dep.artifact("oniguruma").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -270,6 +276,7 @@ pub fn add(
|
||||
} else {
|
||||
step.linkLibrary(glslang_dep.artifact("glslang"));
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
glslang_dep.artifact("glslang").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -289,6 +296,7 @@ pub fn add(
|
||||
} else {
|
||||
step.linkLibrary(spirv_cross_dep.artifact("spirv_cross"));
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
spirv_cross_dep.artifact("spirv_cross").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -307,6 +315,7 @@ pub fn add(
|
||||
);
|
||||
step.linkLibrary(sentry_dep.artifact("sentry"));
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
sentry_dep.artifact("sentry").getEmittedBin(),
|
||||
);
|
||||
|
||||
@@ -316,6 +325,7 @@ pub fn add(
|
||||
.optimize = optimize,
|
||||
})) |breakpad_dep| {
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
breakpad_dep.artifact("breakpad").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -443,6 +453,7 @@ pub fn add(
|
||||
macos_dep.artifact("macos"),
|
||||
);
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
macos_dep.artifact("macos").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -461,6 +472,7 @@ pub fn add(
|
||||
})) |libintl_dep| {
|
||||
step.linkLibrary(libintl_dep.artifact("intl"));
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
libintl_dep.artifact("intl").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -473,7 +485,10 @@ pub fn add(
|
||||
})) |cimgui_dep| {
|
||||
step.root_module.addImport("cimgui", cimgui_dep.module("cimgui"));
|
||||
step.linkLibrary(cimgui_dep.artifact("cimgui"));
|
||||
try static_libs.append(cimgui_dep.artifact("cimgui").getEmittedBin());
|
||||
try static_libs.append(
|
||||
b.allocator,
|
||||
cimgui_dep.artifact("cimgui").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
|
||||
// Fonts
|
||||
@@ -697,6 +712,7 @@ pub fn addSimd(
|
||||
})) |simdutf_dep| {
|
||||
m.linkLibrary(simdutf_dep.artifact("simdutf"));
|
||||
if (static_libs) |v| try v.append(
|
||||
b.allocator,
|
||||
simdutf_dep.artifact("simdutf").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
@@ -708,7 +724,10 @@ pub fn addSimd(
|
||||
.optimize = optimize,
|
||||
})) |highway_dep| {
|
||||
m.linkLibrary(highway_dep.artifact("highway"));
|
||||
if (static_libs) |v| try v.append(highway_dep.artifact("highway").getEmittedBin());
|
||||
if (static_libs) |v| try v.append(
|
||||
b.allocator,
|
||||
highway_dep.artifact("highway").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
|
||||
// utfcpp - This is used as a dependency on our hand-written C++ code
|
||||
@@ -717,7 +736,10 @@ pub fn addSimd(
|
||||
.optimize = optimize,
|
||||
})) |utfcpp_dep| {
|
||||
m.linkLibrary(utfcpp_dep.artifact("utfcpp"));
|
||||
if (static_libs) |v| try v.append(utfcpp_dep.artifact("utfcpp").getEmittedBin());
|
||||
if (static_libs) |v| try v.append(
|
||||
b.allocator,
|
||||
utfcpp_dep.artifact("utfcpp").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
|
||||
// SIMD C++ files
|
||||
@@ -761,16 +783,20 @@ pub fn gtkNgDistResources(
|
||||
const gresource_xml = gresource_xml: {
|
||||
const xml_exe = b.addExecutable(.{
|
||||
.name = "generate_gresource_xml",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/apprt/gtk/build/gresource.zig"),
|
||||
.target = b.graph.host,
|
||||
}),
|
||||
});
|
||||
const xml_run = b.addRunArtifact(xml_exe);
|
||||
|
||||
// Run our blueprint compiler across all of our blueprint files.
|
||||
const blueprint_exe = b.addExecutable(.{
|
||||
.name = "gtk_blueprint_compiler",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/apprt/gtk/build/blueprint.zig"),
|
||||
.target = b.graph.host,
|
||||
}),
|
||||
});
|
||||
blueprint_exe.linkLibC();
|
||||
blueprint_exe.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
||||
|
@@ -21,6 +21,9 @@ pub fn init(b: *std.Build, uucode_tables: std.Build.LazyPath) !UnicodeTables {
|
||||
.omit_frame_pointer = false,
|
||||
.unwind_tables = .sync,
|
||||
}),
|
||||
|
||||
// TODO: x86_64 self-hosted crashes
|
||||
.use_llvm = true,
|
||||
});
|
||||
|
||||
const symbols_exe = b.addExecutable(.{
|
||||
@@ -32,6 +35,9 @@ pub fn init(b: *std.Build, uucode_tables: std.Build.LazyPath) !UnicodeTables {
|
||||
.omit_frame_pointer = false,
|
||||
.unwind_tables = .sync,
|
||||
}),
|
||||
|
||||
// TODO: x86_64 self-hosted crashes
|
||||
.use_llvm = true,
|
||||
});
|
||||
|
||||
if (b.lazyDependency("uucode", .{
|
||||
|
@@ -24,13 +24,9 @@ pub fn eql(a: Properties, b: Properties) bool {
|
||||
// Needed for lut.Generator
|
||||
pub fn format(
|
||||
self: Properties,
|
||||
comptime layout: []const u8,
|
||||
opts: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
writer: *std.Io.Writer,
|
||||
) !void {
|
||||
_ = layout;
|
||||
_ = opts;
|
||||
try std.fmt.format(writer,
|
||||
try writer.print(
|
||||
\\.{{
|
||||
\\ .width= {},
|
||||
\\ .grapheme_boundary_class= .{s},
|
||||
|
@@ -54,12 +54,14 @@ pub fn Generator(
|
||||
defer blocks_map.deinit();
|
||||
|
||||
// Our stages
|
||||
var stage1 = std.ArrayList(u16).init(alloc);
|
||||
defer stage1.deinit();
|
||||
var stage2 = std.ArrayList(u16).init(alloc);
|
||||
defer stage2.deinit();
|
||||
var stage3 = std.ArrayList(Elem).init(alloc);
|
||||
defer stage3.deinit();
|
||||
var stage1: std.ArrayList(u16) = .empty;
|
||||
var stage2: std.ArrayList(u16) = .empty;
|
||||
var stage3: std.ArrayList(Elem) = .empty;
|
||||
defer {
|
||||
stage1.deinit(alloc);
|
||||
stage2.deinit(alloc);
|
||||
stage3.deinit(alloc);
|
||||
}
|
||||
|
||||
var block: Block = undefined;
|
||||
var block_len: u16 = 0;
|
||||
@@ -74,7 +76,7 @@ pub fn Generator(
|
||||
}
|
||||
|
||||
const idx = stage3.items.len;
|
||||
try stage3.append(elem);
|
||||
try stage3.append(alloc, elem);
|
||||
break :block_idx idx;
|
||||
};
|
||||
|
||||
@@ -96,11 +98,11 @@ pub fn Generator(
|
||||
u16,
|
||||
stage2.items.len,
|
||||
) orelse return error.Stage2TooLarge;
|
||||
for (block[0..block_len]) |entry| try stage2.append(entry);
|
||||
for (block[0..block_len]) |entry| try stage2.append(alloc, entry);
|
||||
}
|
||||
|
||||
// Map stage1 => stage2 and reset our block
|
||||
try stage1.append(gop.value_ptr.*);
|
||||
try stage1.append(alloc, gop.value_ptr.*);
|
||||
block_len = 0;
|
||||
}
|
||||
|
||||
@@ -109,11 +111,11 @@ pub fn Generator(
|
||||
assert(stage2.items.len <= std.math.maxInt(u16));
|
||||
assert(stage3.items.len <= std.math.maxInt(u16));
|
||||
|
||||
const stage1_owned = try stage1.toOwnedSlice();
|
||||
const stage1_owned = try stage1.toOwnedSlice(alloc);
|
||||
errdefer alloc.free(stage1_owned);
|
||||
const stage2_owned = try stage2.toOwnedSlice();
|
||||
const stage2_owned = try stage2.toOwnedSlice(alloc);
|
||||
errdefer alloc.free(stage2_owned);
|
||||
const stage3_owned = try stage3.toOwnedSlice();
|
||||
const stage3_owned = try stage3.toOwnedSlice(alloc);
|
||||
errdefer alloc.free(stage3_owned);
|
||||
|
||||
return .{
|
||||
@@ -145,7 +147,7 @@ pub fn Tables(comptime Elem: type) type {
|
||||
/// Writes the lookup table as Zig to the given writer. The
|
||||
/// written file exports three constants: stage1, stage2, and
|
||||
/// stage3. These can be used to rebuild the lookup table in Zig.
|
||||
pub fn writeZig(self: *const Self, writer: anytype) !void {
|
||||
pub fn writeZig(self: *const Self, writer: *std.Io.Writer) !void {
|
||||
try writer.print(
|
||||
\\//! This file is auto-generated. Do not edit.
|
||||
\\
|
||||
@@ -168,7 +170,13 @@ pub fn Tables(comptime Elem: type) type {
|
||||
\\
|
||||
\\pub const stage3: [{}]Elem = .{{
|
||||
, .{self.stage3.len});
|
||||
for (self.stage3) |entry| try writer.print("{},", .{entry});
|
||||
for (self.stage3) |entry| {
|
||||
if (@typeInfo(@TypeOf(entry)) == .@"struct" and
|
||||
@hasDecl(@TypeOf(entry), "format"))
|
||||
try writer.print("{f},", .{entry})
|
||||
else
|
||||
try writer.print("{},", .{entry});
|
||||
}
|
||||
try writer.writeAll(
|
||||
\\};
|
||||
\\ };
|
||||
|
@@ -84,7 +84,11 @@ pub fn main() !void {
|
||||
defer alloc.free(t.stage1);
|
||||
defer alloc.free(t.stage2);
|
||||
defer alloc.free(t.stage3);
|
||||
try t.writeZig(std.io.getStdOut().writer());
|
||||
|
||||
var buf: [4096]u8 = undefined;
|
||||
var stdout = std.fs.File.stdout().writer(&buf);
|
||||
try t.writeZig(&stdout.interface);
|
||||
try stdout.end();
|
||||
|
||||
// Uncomment when manually debugging to see our table sizes.
|
||||
// std.log.warn("stage1={} stage2={} stage3={}", .{
|
||||
|
@@ -30,7 +30,11 @@ pub fn main() !void {
|
||||
defer alloc.free(t.stage1);
|
||||
defer alloc.free(t.stage2);
|
||||
defer alloc.free(t.stage3);
|
||||
try t.writeZig(std.io.getStdOut().writer());
|
||||
|
||||
var buf: [4096]u8 = undefined;
|
||||
var stdout = std.fs.File.stdout().writer(&buf);
|
||||
try t.writeZig(&stdout.interface);
|
||||
try stdout.end();
|
||||
|
||||
// Uncomment when manually debugging to see our table sizes.
|
||||
// std.log.warn("stage1={} stage2={} stage3={}", .{
|
||||
|
Reference in New Issue
Block a user