diff --git a/src/build/Config.zig b/src/build/Config.zig index b65a8d5665..c6f0e6d093 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 cae907ec2d..a7ff40cbdc 100644 --- a/src/build/GhosttyResources.zig +++ b/src/build/GhosttyResources.zig @@ -23,9 +23,12 @@ 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"); + try steps.append(&source_install.step); + } // Windows doesn't have the binaries below. if (cfg.target.result.os.tag == .windows) break :terminfo; @@ -33,10 +36,10 @@ 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(src_source); + run_step.addFileArg(source); const out_source = run_step.captureStdOut(); _ = run_step.captureStdErr(); // so we don't see stderr @@ -49,23 +52,29 @@ 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); + // 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. + 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 c0f82dec5d..4ef256c1ac 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;