-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbuild.zig
More file actions
136 lines (120 loc) · 5.19 KB
/
build.zig
File metadata and controls
136 lines (120 loc) · 5.19 KB
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// --- Build options ---
const profile_opcodes = b.option(bool, "profile-opcodes", "Enable opcode frequency profiling") orelse false;
const profile_alloc = b.option(bool, "profile-alloc", "Enable allocation size profiling") orelse false;
const enable_wasm = b.option(bool, "wasm", "Enable Wasm FFI support (default: true)") orelse true;
const build_zon = @import("build.zig.zon");
const options = b.addOptions();
options.addOption(bool, "profile_opcodes", profile_opcodes);
options.addOption(bool, "profile_alloc", profile_alloc);
options.addOption(bool, "enable_wasm", enable_wasm);
options.addOption([]const u8, "version", build_zon.version);
const options_module = options.createModule();
// zwasm dependency (Wasm runtime library) — only when wasm enabled
const zwasm_mod = if (enable_wasm) blk: {
const zwasm_dep = b.dependency("zwasm", .{
.target = target,
.optimize = optimize,
});
break :blk zwasm_dep.module("zwasm");
} else null;
const zwasm_native_mod = if (enable_wasm) blk: {
const zwasm_native_dep = b.dependency("zwasm", .{
.target = b.graph.host,
.optimize = .ReleaseSafe,
});
break :blk zwasm_native_dep.module("zwasm");
} else null;
// Library module (test root)
const mod = b.addModule("ClojureWasm", .{
.root_source_file = b.path("src/root.zig"),
.target = target,
});
mod.addImport("build_options", options_module);
if (zwasm_mod) |m| mod.addImport("zwasm", m);
// --- Bootstrap cache generation (D81) ---
// Build-time tool that bootstraps from .clj sources, serializes the env
// snapshot, and writes it to a file. The main binary embeds this cache
// for instant startup (restoreFromBootstrapCache instead of loadBootstrapAll).
const cache_gen = b.addExecutable(.{
.name = "cache_gen",
.root_module = b.createModule(.{
.root_source_file = b.path("src/cache_gen.zig"),
.target = b.resolveTargetQuery(.{}),
.optimize = .ReleaseSafe,
}),
});
cache_gen.root_module.addImport("build_options", options_module);
if (zwasm_native_mod) |m| cache_gen.root_module.addImport("zwasm", m);
cache_gen.stack_size = 512 * 1024 * 1024;
const run_cache_gen = b.addRunArtifact(cache_gen);
const cache_bin = run_cache_gen.addOutputFileArg("bootstrap.cache");
// Create a wrapper .zig file that @embedFile's the generated cache.
// Both files live in the same WriteFile directory so the relative path works.
const embed_files = b.addWriteFiles();
_ = embed_files.addCopyFile(cache_bin, "bootstrap.cache");
const wrapper = embed_files.add("bootstrap_cache.zig",
\\pub const data: []const u8 = @embedFile("bootstrap.cache");
\\
);
// Executable (same source tree, no module boundary — avoids self-referential type loop)
const exe = b.addExecutable(.{
.name = "cljw",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
}),
});
exe.root_module.addImport("build_options", options_module);
if (zwasm_mod) |m| exe.root_module.addImport("zwasm", m);
exe.root_module.addAnonymousImport("bootstrap_cache", .{
.root_source_file = wrapper,
});
// 512MB stack for Debug builds — deeply nested lazy-seq realization
// (e.g. sieve of Eratosthenes with 168 nested filters) creates ~381KB
// frames per recursion level in Debug mode. ReleaseSafe needs ~64MB.
exe.stack_size = 512 * 1024 * 1024;
b.installArtifact(exe);
// Run step
const run_step = b.step("run", "Run the interpreter");
const run_cmd = b.addRunArtifact(exe);
run_step.dependOn(&run_cmd.step);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
// Wasm build step (wasm32-wasi)
const wasm_exe = b.addExecutable(.{
.name = "cljw",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = b.resolveTargetQuery(.{
.cpu_arch = .wasm32,
.os_tag = .wasi,
}),
.optimize = optimize,
}),
});
wasm_exe.root_module.addImport("build_options", options_module);
const wasm_step = b.step("wasm", "Build for wasm32-wasi");
const wasm_install = b.addInstallArtifact(wasm_exe, .{});
wasm_step.dependOn(&wasm_install.step);
// Test step
const test_step = b.step("test", "Run all tests");
const mod_tests = b.addTest(.{
.root_module = mod,
});
mod_tests.stack_size = 512 * 1024 * 1024;
const run_mod_tests = b.addRunArtifact(mod_tests);
test_step.dependOn(&run_mod_tests.step);
const exe_tests = b.addTest(.{
.root_module = exe.root_module,
});
exe_tests.stack_size = 512 * 1024 * 1024;
const run_exe_tests = b.addRunArtifact(exe_tests);
test_step.dependOn(&run_exe_tests.step);
}