diff --git a/build.zig b/build.zig index eb3a7bc50..78a871efb 100644 --- a/build.zig +++ b/build.zig @@ -9,7 +9,8 @@ const font = @import("src/font/main.zig"); const renderer = @import("src/renderer.zig"); const terminfo = @import("src/terminfo/main.zig"); const config_vim = @import("src/config/vim.zig"); -const BuildConfig = @import("src/build_config.zig").BuildConfig; +const build_config = @import("src/build_config.zig"); +const BuildConfig = build_config.BuildConfig; const WasmTarget = @import("src/os/wasm/target.zig").Target; const LibtoolStep = @import("src/build/LibtoolStep.zig"); const LipoStep = @import("src/build/LipoStep.zig"); @@ -417,7 +418,7 @@ pub fn build(b: *std.Build) !void { } // Documenation - if (emit_docs) buildDocumentation(b, config.version); + if (emit_docs) try buildDocumentation(b, config); // App (Linux) if (target.result.os.tag == .linux and config.app_runtime != .none) { @@ -1146,8 +1147,8 @@ fn addHelp( /// Generate documentation (manpages, etc.) from help strings fn buildDocumentation( b: *std.Build, - version: std.SemanticVersion, -) void { + config: BuildConfig, +) !void { const manpages = [_]struct { name: []const u8, section: []const u8, @@ -1159,15 +1160,22 @@ fn buildDocumentation( inline for (manpages) |manpage| { const generate_markdown = b.addExecutable(.{ .name = "mdgen_" ++ manpage.name ++ "_" ++ manpage.section, - .root_source_file = .{ - .path = "src/mdgen_" ++ manpage.name ++ "_" ++ manpage.section ++ ".zig", - }, + .root_source_file = .{ .path = "src/main.zig" }, .target = b.host, }); addHelp(b, generate_markdown); + const gen_config = config: { + var copy = config; + copy.exe_entrypoint = @field( + build_config.ExeEntrypoint, + "mdgen_" ++ manpage.name ++ "_" ++ manpage.section, + ); + break :config copy; + }; + const generate_markdown_options = b.addOptions(); - generate_markdown_options.addOption(std.SemanticVersion, "version", version); + try gen_config.addOptions(generate_markdown_options); generate_markdown.root_module.addOptions("build_options", generate_markdown_options); const generate_markdown_step = b.addRunArtifact(generate_markdown); diff --git a/src/mdgen_ghostty_1.zig b/src/build/mdgen/main_ghostty_1.zig similarity index 54% rename from src/mdgen_ghostty_1.zig rename to src/build/mdgen/main_ghostty_1.zig index eeb85c900..b3663de8d 100644 --- a/src/mdgen_ghostty_1.zig +++ b/src/build/mdgen/main_ghostty_1.zig @@ -1,13 +1,13 @@ const std = @import("std"); -const gen = @import("build/mdgen/mdgen.zig"); +const gen = @import("mdgen.zig"); pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const alloc = gpa.allocator(); const writer = std.io.getStdOut().writer(); - try gen.substitute(alloc, @embedFile("build/mdgen/ghostty_1_header.md"), writer); + try gen.substitute(alloc, @embedFile("ghostty_1_header.md"), writer); try gen.genActions(writer); try gen.genConfig(writer, true); - try gen.substitute(alloc, @embedFile("build/mdgen/ghostty_1_footer.md"), writer); + try gen.substitute(alloc, @embedFile("ghostty_1_footer.md"), writer); } diff --git a/src/mdgen_ghostty_5.zig b/src/build/mdgen/main_ghostty_5.zig similarity index 55% rename from src/mdgen_ghostty_5.zig rename to src/build/mdgen/main_ghostty_5.zig index 8773b433a..77c72b946 100644 --- a/src/mdgen_ghostty_5.zig +++ b/src/build/mdgen/main_ghostty_5.zig @@ -1,13 +1,13 @@ const std = @import("std"); -const gen = @import("build/mdgen/mdgen.zig"); +const gen = @import("mdgen.zig"); pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const alloc = gpa.allocator(); const output = std.io.getStdOut().writer(); - try gen.substitute(alloc, @embedFile("build/mdgen/ghostty_5_header.md"), output); + try gen.substitute(alloc, @embedFile("ghostty_5_header.md"), output); try gen.genConfig(output, false); try gen.genKeybindActions(output); - try gen.substitute(alloc, @embedFile("build/mdgen/ghostty_5_footer.md"), output); + try gen.substitute(alloc, @embedFile("ghostty_5_footer.md"), output); } diff --git a/src/build_config.zig b/src/build_config.zig index ee776fa8c..789155fee 100644 --- a/src/build_config.zig +++ b/src/build_config.zig @@ -27,6 +27,9 @@ pub const BuildConfig = struct { renderer: rendererpkg.Impl = .opengl, font_backend: font.Backend = .freetype, + /// The entrypoint for exe targets. + exe_entrypoint: ExeEntrypoint = .ghostty, + /// The target runtime for the wasm build and whether to use wasm shared /// memory or not. These are both legacy wasm-specific options that we /// will probably have to revisit when we get back to work on wasm. @@ -42,6 +45,7 @@ pub const BuildConfig = struct { step.addOption(apprt.Runtime, "app_runtime", self.app_runtime); step.addOption(font.Backend, "font_backend", self.font_backend); step.addOption(rendererpkg.Impl, "renderer", self.renderer); + step.addOption(ExeEntrypoint, "exe_entrypoint", self.exe_entrypoint); step.addOption(WasmTarget, "wasm_target", self.wasm_target); step.addOption(bool, "wasm_shared", self.wasm_shared); @@ -67,6 +71,7 @@ pub const BuildConfig = struct { .app_runtime = std.meta.stringToEnum(apprt.Runtime, @tagName(options.app_runtime)).?, .font_backend = std.meta.stringToEnum(font.Backend, @tagName(options.font_backend)).?, .renderer = std.meta.stringToEnum(rendererpkg.Impl, @tagName(options.renderer)).?, + .exe_entrypoint = std.meta.stringToEnum(ExeEntrypoint, @tagName(options.exe_entrypoint)).?, .wasm_target = std.meta.stringToEnum(WasmTarget, @tagName(options.wasm_target)).?, .wasm_shared = options.wasm_shared, }; @@ -85,6 +90,7 @@ pub const artifact = Artifact.detect(); /// top-level so its a bit cleaner to use throughout the code. See the doc /// comments in BuildConfig for details on each. pub 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; @@ -117,3 +123,18 @@ pub const Artifact = enum { }; } }; + +/// The possible entrypoints for the exe artifact. This has no effect on +/// other artifact types (i.e. lib, wasm_module). +/// +/// The whole existence of this enum is to workaround the fact that Zig +/// doesn't allow the main function to be in a file in a subdirctory +/// from the "root" of the module, and I don't want to pollute our root +/// directory with a bunch of individual zig files for each entrypoint. +/// +/// Therefore, main.zig uses this to switch between the different entrypoints. +pub const ExeEntrypoint = enum { + ghostty, + mdgen_ghostty_1, + mdgen_ghostty_5, +}; diff --git a/src/main.zig b/src/main.zig index fe3c24925..9038fc351 100644 --- a/src/main.zig +++ b/src/main.zig @@ -24,13 +24,26 @@ const Ghostty = @import("main_c.zig").Ghostty; /// rely on allocators being passed in as parameters. pub var state: GlobalState = undefined; -/// The return type for main() depends on the build artifact. +/// The return type for main() depends on the build artifact. The lib build +/// also calls "main" in order to run the CLI actions, but it calls it as +/// an API and not an entrypoint. const MainReturn = switch (build_config.artifact) { .lib => noreturn, else => void, }; pub fn main() !MainReturn { + // Load the proper main() function based on build config. + if (comptime build_config.artifact == .exe) entrypoint: { + switch (comptime build_config.exe_entrypoint) { + .ghostty => break :entrypoint, // This function + .mdgen_ghostty_1 => try @import("build/mdgen/main_ghostty_1.zig").main(), + .mdgen_ghostty_5 => try @import("build/mdgen/main_ghostty_5.zig").main(), + } + + return; + } + // We first start by initializing our global state. This will setup // process-level state we need to run the terminal. The reason we use // a global is because the C API needs to be able to access this state; @@ -284,6 +297,7 @@ pub const GlobalState = struct { } } }; + test { _ = @import("circ_buf.zig"); _ = @import("pty.zig");