diff options
Diffstat (limited to 'build.zig')
| -rw-r--r-- | build.zig | 54 |
1 files changed, 51 insertions, 3 deletions
@@ -2,6 +2,12 @@ const std = @import("std"); const snap_build = @import("build/snap.zig"); pub const Platform = enum { tty, gui, web }; + +/// The ZLS the language backend links, spelled once. It names the commit +/// build.zig.zon pins (0.16.x branch) and is passed BOTH to ZLS's own +/// `-Dversion-string` (its build.zig otherwise shells out to `git describe`, +/// which fails on a fetched package that has no .git) and to `SPC l i`. +const zls_version = "0.16.1-dev+3e0d0820"; pub const TreeSitterGrammars = enum { disabled, zig, minimal, full }; const GhosttyArtifact = enum { ghostty, lib }; @@ -131,14 +137,19 @@ pub fn build(b: *std.Build) void { opts.addOption(bool, "syntax_full_grammars", tree_sitter_grammars == .full); opts.addOption(bool, "enable_tracy", tracy != null); opts.addOption(bool, "zls_backend", zls_backend); + // Which ZLS is compiled in, for `SPC l i`. Kept next to the dependency it + // names: the .zon pins a commit, and a status screen that cannot say WHICH + // analyser answered is not worth opening. + opts.addOption([]const u8, "zls_version", if (zls_backend) zls_version else "none"); // The stdlib this binary was compiled against, so `gd` on `std.mem.count` // can open the same mem.zig the compiler used. ZLS resolves `@import("std")` // through `zig_lib_dir` and nothing else; without it every std symbol is a // silent miss, and asking the `zig` binary for it is the subprocess this // whole backend exists to avoid. ZIG_LIB_DIR overrides it at runtime. opts.addOption([]const u8, "zig_lib_dir", b.graph.zig_lib_directory.path orelse ""); - root_mod.addOptions("pardes_config", opts); - hx_core_mod.addOptions("pardes_config", opts); + // NOTE: `opts` is attached to the modules at the BOTTOM of this function, + // after every addImport — the module-import table below is folded out of + // root_mod.import_table and would be empty if we attached it here. if (zls_backend) { // .target/.optimize are mandatory: createZLSModule bakes them into the @@ -154,7 +165,7 @@ pub fn build(b: *std.Build) void { const zls_dep = b.dependency("zls", .{ .target = target, .optimize = optimize, - .@"version-string" = @as([]const u8, "0.16.1-dev"), + .@"version-string" = @as([]const u8, zls_version), }); root_mod.addImport("zls", zls_dep.module("zls")); hx_core_mod.addImport("zls", zls_dep.module("zls")); @@ -376,6 +387,43 @@ pub fn build(b: *std.Build) void { root_mod.addImport("uucode", uucode_mod); hx_core_mod.addImport("uucode", uucode_mod); + // --- the dependency module map, for `gd` on `@import("vaxis")` --- + // + // ZLS resolves an import string three ways: a relative `.zig` path, `std` + // (via zig_lib_dir), and everything else — which it can only answer by + // running `zig build --build-runner` to learn the module graph. This + // backend sets `zig_exe_path = null` on purpose, so that last branch + // returns nothing and every `@import("<dependency>")` is a silent miss + // while `std` works perfectly. That asymmetry is the whole bug report. + // + // We do not need the compiler to answer it: THIS FILE *is* the module + // graph. Fold the imports we just wired into a name->root-source table and + // hand it to the backend, which consults it exactly where ZLS gave up. + // Costs one build option and stays correct by construction — a dependency + // that is added or renamed above cannot forget to update it. + var mod_names: std.ArrayList([]const u8) = .empty; + var mod_roots: std.ArrayList([]const u8) = .empty; + { + var it = root_mod.import_table.iterator(); + while (it.next()) |e| { + const lp = e.value_ptr.*.root_source_file orelse continue; + // `generated` is a build artifact (the options modules): it has no + // path until make() runs, and pointing an editor at one is useless + const abs = switch (lp) { + .src_path => |sp| sp.owner.pathFromRoot(sp.sub_path), + .cwd_relative => |cr| cr, + else => continue, + }; + mod_names.append(b.allocator, e.key_ptr.*) catch @panic("OOM"); + mod_roots.append(b.allocator, abs) catch @panic("OOM"); + } + } + opts.addOption([]const []const u8, "module_names", mod_names.items); + opts.addOption([]const []const u8, "module_roots", mod_roots.items); + + root_mod.addOptions("pardes_config", opts); + hx_core_mod.addOptions("pardes_config", opts); + // SDL3 shell wiring (-Dplatform=gui and web). The sdl package builds SDL3 // from source as a static lib + emits the SDL3/ headers; gui.zig @cImports // those, plus a small stb_truetype C shim for the glyph atlas, and embeds |
