From 2f8b0dc899dd197f1e018ccedcfadbe6d82994ad Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Thu, 23 Jan 2025 22:29:47 -0600 Subject: [PATCH 1/3] build: options to enable/disable terminfo & termcap install (take 2) Fixes #5253 Add -Demit-terminfo and -Demit-termcap build options to enable/disable installation of source terminfo and termcap files. --- src/build/Config.zig | 23 +++++++++++++++++ src/build/GhosttyResources.zig | 47 ++++++++++++++++++++-------------- src/os/resourcesdir.zig | 6 ++++- 3 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/build/Config.zig b/src/build/Config.zig index b65a8d566..c6f0e6d09 100644 --- a/src/build/Config.zig +++ b/src/build/Config.zig @@ -55,6 +55,8 @@ emit_helpgen: bool = false, emit_docs: bool = false, emit_webdata: bool = false, emit_xcframework: bool = false, +emit_terminfo: bool = false, +emit_termcap: bool = false, /// Environmental properties env: std.process.EnvMap, @@ -306,6 +308,27 @@ pub fn init(b: *std.Build) !Config { break :emit_docs path != null; }; + config.emit_terminfo = b.option( + bool, + "emit-terminfo", + "Install Ghostty terminfo source file", + ) orelse switch (target.result.os.tag) { + .windows => true, + else => switch (optimize) { + .Debug => true, + .ReleaseSafe, .ReleaseFast, .ReleaseSmall => false, + }, + }; + + config.emit_termcap = b.option( + bool, + "emit-termcap", + "Install Ghostty termcap file", + ) orelse switch (optimize) { + .Debug => true, + .ReleaseSafe, .ReleaseFast, .ReleaseSmall => false, + }; + config.emit_webdata = b.option( bool, "emit-webdata", diff --git a/src/build/GhosttyResources.zig b/src/build/GhosttyResources.zig index cae907ec2..2fdfbe81d 100644 --- a/src/build/GhosttyResources.zig +++ b/src/build/GhosttyResources.zig @@ -16,6 +16,15 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources { // Terminfo terminfo: { + const mkdir_step = RunStep.create(b, "make share/terminfo directory"); + switch (cfg.target.result.os.tag) { + // windows mkdir shouldn't need "-p" + .windows => mkdir_step.addArgs(&.{"mkdir"}), + else => mkdir_step.addArgs(&.{ "mkdir", "-p" }), + } + mkdir_step.addArg(b.fmt("{s}/share/terminfo", .{b.install_path})); + try steps.append(&mkdir_step.step); + // Encode our terminfo var str = std.ArrayList(u8).init(b.allocator); defer str.deinit(); @@ -23,9 +32,13 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources { // Write it var wf = b.addWriteFiles(); - const src_source = wf.add("share/terminfo/ghostty.terminfo", str.items); - const src_install = b.addInstallFile(src_source, "share/terminfo/ghostty.terminfo"); - try steps.append(&src_install.step); + const source = wf.add("ghostty.terminfo", str.items); + + if (cfg.emit_terminfo) { + const source_install = b.addInstallFile(source, "share/terminfo/ghostty.terminfo"); + source_install.step.dependOn(&mkdir_step.step); + try steps.append(&source_install.step); + } // Windows doesn't have the binaries below. if (cfg.target.result.os.tag == .windows) break :terminfo; @@ -36,11 +49,12 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources { { const run_step = RunStep.create(b, "infotocap"); run_step.addArg("infotocap"); - run_step.addFileArg(src_source); + run_step.addFileArg(source); const out_source = run_step.captureStdOut(); _ = run_step.captureStdErr(); // so we don't see stderr const cap_install = b.addInstallFile(out_source, "share/terminfo/ghostty.termcap"); + cap_install.step.dependOn(&mkdir_step.step); try steps.append(&cap_install.step); } @@ -49,23 +63,18 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources { const run_step = RunStep.create(b, "tic"); run_step.addArgs(&.{ "tic", "-x", "-o" }); const path = run_step.addOutputFileArg("terminfo"); - run_step.addFileArg(src_source); + run_step.addFileArg(source); _ = run_step.captureStdErr(); // so we don't see stderr - // Depend on the terminfo source install step so that Zig build - // creates the "share" directory for us. - run_step.step.dependOn(&src_install.step); - - { - // Use cp -R instead of Step.InstallDir because we need to preserve - // symlinks in the terminfo database. Zig's InstallDir step doesn't - // handle symlinks correctly yet. - const copy_step = RunStep.create(b, "copy terminfo db"); - copy_step.addArgs(&.{ "cp", "-R" }); - copy_step.addFileArg(path); - copy_step.addArg(b.fmt("{s}/share", .{b.install_path})); - try steps.append(©_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 + // handle symlinks correctly yet. + const copy_step = RunStep.create(b, "copy terminfo db"); + copy_step.addArgs(&.{ "cp", "-R" }); + 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); } } diff --git a/src/os/resourcesdir.zig b/src/os/resourcesdir.zig index c0f82dec5..4ef256c1a 100644 --- a/src/os/resourcesdir.zig +++ b/src/os/resourcesdir.zig @@ -21,7 +21,11 @@ pub fn resourcesDir(alloc: std.mem.Allocator) !?[]const u8 { // This is the sentinel value we look for in the path to know // we've found the resources directory. - const sentinel = "terminfo/ghostty.termcap"; + const sentinel = switch (comptime builtin.target.os.tag) { + .windows => "terminfo/ghostty.terminfo", + .macos => "terminfo/78/xterm-ghostty", + else => "terminfo/x/xterm-ghostty", + }; // Get the path to our running binary var exe_buf: [std.fs.max_path_bytes]u8 = undefined; From d1969f74acee0b8d34ebc0b4fba4de7dd4494618 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Fri, 24 Jan 2025 10:05:56 -0600 Subject: [PATCH 2/3] only the cp step needs to depend on the mkdir step --- src/build/GhosttyResources.zig | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/build/GhosttyResources.zig b/src/build/GhosttyResources.zig index 2fdfbe81d..1ce3fd66c 100644 --- a/src/build/GhosttyResources.zig +++ b/src/build/GhosttyResources.zig @@ -16,15 +16,6 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources { // Terminfo terminfo: { - const mkdir_step = RunStep.create(b, "make share/terminfo directory"); - switch (cfg.target.result.os.tag) { - // windows mkdir shouldn't need "-p" - .windows => mkdir_step.addArgs(&.{"mkdir"}), - else => mkdir_step.addArgs(&.{ "mkdir", "-p" }), - } - mkdir_step.addArg(b.fmt("{s}/share/terminfo", .{b.install_path})); - try steps.append(&mkdir_step.step); - // Encode our terminfo var str = std.ArrayList(u8).init(b.allocator); defer str.deinit(); @@ -36,7 +27,6 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources { if (cfg.emit_terminfo) { const source_install = b.addInstallFile(source, "share/terminfo/ghostty.terminfo"); - source_install.step.dependOn(&mkdir_step.step); try steps.append(&source_install.step); } @@ -54,7 +44,6 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources { _ = run_step.captureStdErr(); // so we don't see stderr const cap_install = b.addInstallFile(out_source, "share/terminfo/ghostty.termcap"); - cap_install.step.dependOn(&mkdir_step.step); try steps.append(&cap_install.step); } @@ -66,6 +55,17 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources { run_step.addFileArg(source); _ = run_step.captureStdErr(); // so we don't see stderr + // Ensure that `share/terminfo` is a directory, otherwise the `cp + // -R` will create a file named `share/terminfo` + const mkdir_step = RunStep.create(b, "make share/terminfo directory"); + switch (cfg.target.result.os.tag) { + // windows mkdir shouldn't need "-p" + .windows => mkdir_step.addArgs(&.{"mkdir"}), + else => mkdir_step.addArgs(&.{ "mkdir", "-p" }), + } + mkdir_step.addArg(b.fmt("{s}/share/terminfo", .{b.install_path})); + try steps.append(&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 // handle symlinks correctly yet. From 593d70a42f8a7d0c87136a7f222eb45ef2821c37 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Fri, 24 Jan 2025 10:06:32 -0600 Subject: [PATCH 3/3] fix missing check of emit_termcap build option --- src/build/GhosttyResources.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build/GhosttyResources.zig b/src/build/GhosttyResources.zig index 1ce3fd66c..a7ff40cbd 100644 --- a/src/build/GhosttyResources.zig +++ b/src/build/GhosttyResources.zig @@ -36,7 +36,7 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources { // Convert to termcap source format if thats helpful to people and // install it. The resulting value here is the termcap source in case // that is used for other commands. - { + if (cfg.emit_termcap) { const run_step = RunStep.create(b, "infotocap"); run_step.addArg("infotocap"); run_step.addFileArg(source);