1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
// Build recipe
// SPDX-FileCopyrightText: 2025 Nguyễn Gia Phong
// SPDX-License-Identifier: GPL-3.0-or-later
const Build = std.Build;
const Module = Build.Module;
const NativePaths = std.zig.system.NativePaths;
const getStdOut = std.io.getStdOut;
const openDirAbsolute = std.fs.openDirAbsolute;
const std = @import("std");
const tokenize = std.mem.tokenizeScalar;
const supported_languages = @embedFile("src/supported-languages");
/// Generates the "language" module.
pub fn main() !void {
const stdout = getStdOut().writer();
try stdout.writeAll(
\\const Language = @import("tree-sitter").Language;
\\pub const Create = *const fn () callconv(.c) *const Language;
);
var language_names = tokenize(u8, supported_languages, '\n');
while (language_names.next()) |name|
try stdout.print(
\\pub const {s} = @extern(Create, .{{ .name = "tree_sitter_{s}" }});
, .{ name, name });
}
fn linkTreeSitterGrammars(b: *Build, module: *Module) !void {
const target = module.resolved_target.?;
const native_paths = try NativePaths.detect(b.allocator, target.result);
for (native_paths.lib_dirs.items) |lib_dir| {
// Guix somehow puts the shared objects in $output/lib/tree-sitter/.
const tree_sitter_dir = b.pathJoin(&.{ lib_dir, "tree-sitter" });
var dir = openDirAbsolute(tree_sitter_dir, .{}) catch continue;
dir.close();
module.addLibraryPath(.{ .cwd_relative = tree_sitter_dir });
}
var language_names = tokenize(u8, supported_languages, '\n');
while (language_names.next()) |name|
module.linkSystemLibrary(b.fmt("tree-sitter-{s}", .{ name }), .{});
const languages = b.createModule(.{
.root_source_file = b.addRunArtifact(b.addExecutable(.{
.name = "extern-tree-sitter-grammars",
.root_source_file = b.path(@src().file), // main function above
.target = b.graph.host,
})).captureStdOut(),
.target = target,
.optimize = module.optimize.?,
});
const lib = "tree-sitter";
languages.addImport(lib, b.dependency(lib, .{}).module(lib));
module.addImport("languages", languages);
}
pub fn build(b: *Build) !void {
const mod = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = b.standardTargetOptions(.{}),
.optimize = b.standardOptimizeOption(.{}),
});
inline for (.{ "known-folders", "tree-sitter", "vaxis", "zsanett" }) |lib|
mod.addImport(lib, b.dependency(lib, .{}).module(lib));
try linkTreeSitterGrammars(b, mod);
const unit_tests = b.addTest(.{ .root_module = mod });
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&b.addRunArtifact(unit_tests).step);
const exe = b.addExecutable(.{ .name = "kay", .root_module = mod });
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args|
run_cmd.addArgs(args);
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}
|