@pkmn/engine 0.1.0-dev.683fba11 → 0.1.0-dev.6b383c80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +22 -16
- package/build/pkg/addon/browser.js +6 -3
- package/build/pkg/addon/browser.js.map +1 -1
- package/build/pkg/addon/node.js +23 -10
- package/build/pkg/addon/node.js.map +1 -1
- package/build/pkg/addon/wasm.js +23 -14
- package/build/pkg/addon/wasm.js.map +1 -1
- package/build/pkg/addon.d.ts +5 -5
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.d.ts +2 -1
- package/build/pkg/gen1.js +22 -9
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +2 -0
- package/build/pkg/index.js +17 -7
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +11 -2
- package/build/pkg/protocol.js.map +1 -1
- package/build/tools/debug.js +54 -11
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +19 -94
- package/build/tools/display/debug.jsx.map +1 -1
- package/build/tools/display/index.js +18 -7
- package/build/tools/display/index.js.map +1 -1
- package/build/tools/display/ui.jsx +20 -9
- package/build/tools/display/ui.jsx.map +1 -1
- package/build/tools/display/util.js +140 -1
- package/build/tools/display/util.js.map +1 -1
- package/build.zig +255 -313
- package/package.json +29 -131
- package/src/bin/install-pkmn-engine +24 -22
- package/src/lib/bindings/c.zig +201 -0
- package/src/lib/bindings/node.zig +117 -0
- package/src/lib/bindings/wasm.zig +51 -0
- package/src/lib/common/array.zig +9 -16
- package/src/lib/common/data.zig +8 -8
- package/src/lib/common/debug.zig +46 -61
- package/src/lib/common/js.zig +3 -9
- package/src/lib/common/optional.zig +20 -25
- package/src/lib/common/protocol.zig +224 -189
- package/src/lib/common/rational.zig +275 -284
- package/src/lib/common/rng.zig +4 -4
- package/src/lib/common/util.zig +34 -31
- package/src/lib/gen1/calc.zig +141 -119
- package/src/lib/gen1/chance.zig +162 -101
- package/src/lib/gen1/data/types.zig +2 -2
- package/src/lib/gen1/data.zig +27 -24
- package/src/lib/gen1/helpers.zig +36 -26
- package/src/lib/gen1/mechanics.zig +45 -49
- package/src/lib/gen2/calc.zig +3 -6
- package/src/lib/gen2/chance.zig +55 -43
- package/src/lib/gen2/data/types.zig +6 -3
- package/src/lib/gen2/data.zig +20 -16
- package/src/lib/gen2/helpers.zig +27 -19
- package/src/lib/gen2/mechanics.zig +17 -17
- package/src/lib/napi.h +2 -0
- package/src/lib/node.zig +3 -118
- package/src/lib/pkmn.zig +94 -19
- package/src/lib/wasm.zig +9 -44
- package/src/tools/display/dom.ts +43 -31
package/build.zig
CHANGED
|
@@ -1,73 +1,44 @@
|
|
|
1
|
-
const builtin = @import("builtin");
|
|
2
1
|
const std = @import("std");
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
.Compile = std.Build.CompileStep,
|
|
13
|
-
.Options = std.Build.OptionsStep,
|
|
14
|
-
.Run = std.Build.RunStep,
|
|
15
|
-
};
|
|
16
|
-
const has_path = @hasField(std.Build.LazyPath, "path");
|
|
17
|
-
const root_module = @hasField(Step.Compile, "root_module");
|
|
18
|
-
const force_pic = !@hasField(std.Build.SharedLibraryOptions, "pic");
|
|
19
|
-
const ResolvedTarget =
|
|
20
|
-
if (@hasDecl(std.Build, "ResolvedTarget")) std.Build.ResolvedTarget else std.zig.CrossTarget;
|
|
21
|
-
|
|
22
|
-
pub fn module(b: *std.Build, options: Options) *std.Build.Module {
|
|
23
|
-
const dirname = comptime std.fs.path.dirname(@src().file) orelse ".";
|
|
24
|
-
const build_options = b.addOptions();
|
|
25
|
-
build_options.addOption(?bool, "showdown", options.showdown);
|
|
26
|
-
build_options.addOption(?bool, "log", options.log);
|
|
27
|
-
build_options.addOption(?bool, "chance", options.chance);
|
|
28
|
-
build_options.addOption(?bool, "calc", options.calc);
|
|
29
|
-
|
|
30
|
-
const root_source_file = .{ .cwd_relative = dirname ++ "/src/lib/pkmn.zig" };
|
|
31
|
-
const imports = &.{.{ .name = "build_options", .module = build_options.createModule() }};
|
|
32
|
-
return b.createModule(if (@hasDecl(std.Build, "CreateModuleOptions"))
|
|
33
|
-
.{ .source_file = root_source_file, .dependencies = imports }
|
|
34
|
-
else
|
|
35
|
-
.{ .root_source_file = root_source_file, .imports = imports });
|
|
36
|
-
}
|
|
3
|
+
const Debug: std.builtin.OptimizeMode =
|
|
4
|
+
if (@hasDecl(std.builtin.OptimizeMode, "Debug")) .debug else .Debug;
|
|
5
|
+
const ReleaseSafe: std.builtin.OptimizeMode =
|
|
6
|
+
if (@hasDecl(std.builtin.OptimizeMode, "ReleaseSafe")) .safe else .ReleaseSafe;
|
|
7
|
+
const ReleaseFast: std.builtin.OptimizeMode =
|
|
8
|
+
if (@hasDecl(std.builtin.OptimizeMode, "ReleaseFast")) .fast else .ReleaseFast;
|
|
9
|
+
const ReleaseSmall: std.builtin.OptimizeMode =
|
|
10
|
+
if (@hasDecl(std.builtin.OptimizeMode, "ReleaseSmall")) .small else .ReleaseSmall;
|
|
37
11
|
|
|
38
12
|
pub fn build(b: *std.Build) !void {
|
|
39
13
|
const target = b.standardTargetOptions(.{});
|
|
40
14
|
const optimize = b.standardOptimizeOption(.{});
|
|
41
15
|
|
|
42
|
-
const default: ?bool = if (force_pic) false else null;
|
|
43
16
|
const node_headers = b.option([]const u8, "node-headers", "Path to node-headers");
|
|
44
17
|
const node_import_lib =
|
|
45
18
|
b.option([]const u8, "node-import-library", "Path to node import library (Windows)");
|
|
19
|
+
const demo = if (try exists(b, "src/tools/demo.zig"))
|
|
20
|
+
b.option(bool, "demo", "Build the demo library") orelse false
|
|
21
|
+
else
|
|
22
|
+
false;
|
|
46
23
|
const wasm = b.option(bool, "wasm", "Build a WASM library") orelse false;
|
|
47
24
|
const wasm_stack_size =
|
|
48
25
|
b.option(u64, "wasm-stack-size", "The size of WASM stack") orelse std.wasm.page_size;
|
|
49
26
|
const dynamic = b.option(bool, "dynamic", "Build a dynamic library") orelse false;
|
|
50
|
-
const strip = b.option(bool, "strip", "Strip debugging symbols from binary")
|
|
51
|
-
const
|
|
27
|
+
const strip = b.option(bool, "strip", "Strip debugging symbols from binary");
|
|
28
|
+
const unwind_tables: ?std.builtin.UnwindTables =
|
|
29
|
+
if ((strip orelse false) and target.result.os.tag != .windows) .none else null;
|
|
30
|
+
const pic = b.option(bool, "pic", "Force position independent code");
|
|
52
31
|
const emit_asm = b.option(bool, "emit-asm", "Output .s (assembly code)") orelse false;
|
|
53
32
|
const emit_ll = b.option(bool, "emit-ll", "Output .ll (LLVM IR)") orelse false;
|
|
54
33
|
|
|
55
|
-
const cmd = b.findProgram(&.{"strip"}, &.{}) catch null;
|
|
56
|
-
|
|
57
34
|
const json = @embedFile("package.json");
|
|
58
35
|
var parsed = try std.json.parseFromSlice(std.json.Value, b.allocator, json, .{});
|
|
59
36
|
defer parsed.deinit();
|
|
60
37
|
const version = parsed.value.object.get("version").?.string;
|
|
61
38
|
const description = parsed.value.object.get("description").?.string;
|
|
62
|
-
var repository = std.mem.
|
|
39
|
+
var repository = std.mem.splitScalar(u8, parsed.value.object.get("repository").?.string, ':');
|
|
63
40
|
std.debug.assert(std.mem.eql(u8, repository.first(), "github"));
|
|
64
41
|
|
|
65
|
-
const fast = try std.SemanticVersion.parse("0.12.0-dev.866+3a47bc715");
|
|
66
|
-
if (optimize != .Debug and fast.order(builtin.zig_version) == .lt) {
|
|
67
|
-
std.log.warn("Release builds are ~10-20% slower than before Zig " ++
|
|
68
|
-
"v0.12.0-dev.866+3a47bc715 due to ziglang/zig#17768", .{});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
42
|
const showdown =
|
|
72
43
|
b.option(bool, "showdown", "Enable Pokémon Showdown compatibility mode") orelse false;
|
|
73
44
|
const log = b.option(bool, "log", "Enable protocol message logging") orelse false;
|
|
@@ -100,99 +71,98 @@ pub fn build(b: *std.Build) !void {
|
|
|
100
71
|
|
|
101
72
|
const name = if (showdown) "pkmn-showdown" else "pkmn";
|
|
102
73
|
|
|
103
|
-
const pkmn =
|
|
104
|
-
.root_source_file =
|
|
105
|
-
.{ .path = "src/lib/pkmn.zig" }
|
|
106
|
-
else
|
|
107
|
-
b.path("src/lib/pkmn.zig"),
|
|
108
|
-
.optimize = optimize,
|
|
109
|
-
.target = target,
|
|
74
|
+
const pkmn = b.addModule("pkmn", .{
|
|
75
|
+
.root_source_file = b.path("src/lib/pkmn.zig"),
|
|
110
76
|
.imports = &.{.{ .name = "build_options", .module = options.createModule() }},
|
|
111
77
|
});
|
|
112
78
|
|
|
113
79
|
var c = false;
|
|
114
80
|
if (node_headers) |headers| {
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
const lib = b.addSharedLibrary(if (force_pic) .{
|
|
118
|
-
.name = addon,
|
|
119
|
-
.root_source_file = path,
|
|
120
|
-
.optimize = optimize,
|
|
81
|
+
const translate_c = b.addTranslateC(.{
|
|
82
|
+
.root_source_file = b.path("src/lib/napi.h"),
|
|
121
83
|
.target = target,
|
|
122
|
-
|
|
84
|
+
// TODO: workaround for ziglang/zig#35515
|
|
85
|
+
.optimize = Debug,
|
|
86
|
+
});
|
|
87
|
+
translate_c.addSystemIncludePath(b.path(headers));
|
|
88
|
+
const addon = b.fmt("{s}.node", .{name});
|
|
89
|
+
const path = b.path("src/lib/node.zig");
|
|
90
|
+
const lib = b.addLibrary(.{
|
|
91
|
+
.linkage = .dynamic,
|
|
123
92
|
.name = addon,
|
|
124
|
-
.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
93
|
+
.root_module = b.createModule(.{
|
|
94
|
+
.root_source_file = path,
|
|
95
|
+
.optimize = optimize,
|
|
96
|
+
.target = target,
|
|
97
|
+
.strip = strip,
|
|
98
|
+
.unwind_tables = unwind_tables,
|
|
99
|
+
.pic = pic,
|
|
100
|
+
}),
|
|
129
101
|
});
|
|
130
|
-
|
|
131
|
-
lib.
|
|
132
|
-
lib.
|
|
102
|
+
lib.discard_local_symbols = strip orelse false;
|
|
103
|
+
lib.root_module.addOptions("build_options", options);
|
|
104
|
+
lib.root_module.addImport("napi", translate_c.createModule());
|
|
105
|
+
lib.root_module.link_libc = true;
|
|
133
106
|
if (node_import_lib) |il| {
|
|
134
|
-
lib.addObjectFile(
|
|
135
|
-
} else if (
|
|
136
|
-
|
|
107
|
+
lib.root_module.addObjectFile(b.path(il));
|
|
108
|
+
} else if (target.result.os.tag == .windows) {
|
|
109
|
+
var err = std.Io.File.stderr().writer(b.graph.io, &.{});
|
|
110
|
+
try err.interface.writeAll("Must provide --node-import-library path on Windows\n");
|
|
137
111
|
std.process.exit(1);
|
|
138
112
|
}
|
|
139
113
|
lib.linker_allow_shlib_undefined = true;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
// b.getInstallStep().dependOn(&lib.step);
|
|
147
|
-
//
|
|
148
|
-
// But ziglang/zig#14647 broke this so we now need to do an install() and then manually
|
|
149
|
-
// rename the file ourself in install-pkmn-engine
|
|
150
|
-
b.installArtifact(lib);
|
|
114
|
+
b.getInstallStep().dependOn(&b.addInstallArtifact(lib, .{
|
|
115
|
+
.dest_dir = .{ .override = .lib },
|
|
116
|
+
.dest_sub_path = addon,
|
|
117
|
+
.implib_dir = .disabled,
|
|
118
|
+
.pdb_dir = .disabled,
|
|
119
|
+
}).step);
|
|
151
120
|
} else if (wasm) {
|
|
152
|
-
|
|
121
|
+
const path = "src/lib/wasm.zig";
|
|
122
|
+
try buildWasm(b, name, path, optimize, strip, pic, wasm_stack_size, null, options);
|
|
123
|
+
} else if (demo) {
|
|
124
|
+
const path = "src/tools/demo.zig";
|
|
125
|
+
const n = if (showdown) "demo-showdown" else "demo";
|
|
126
|
+
try buildWasm(b, n, path, optimize, strip, pic, wasm_stack_size, pkmn, options);
|
|
153
127
|
} else if (dynamic) {
|
|
154
|
-
const path =
|
|
155
|
-
const lib = b.
|
|
128
|
+
const path = b.path("src/lib/c.zig");
|
|
129
|
+
const lib = b.addLibrary(.{
|
|
130
|
+
.linkage = .dynamic,
|
|
156
131
|
.name = name,
|
|
157
|
-
.
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
.optimize = optimize,
|
|
166
|
-
.target = target,
|
|
167
|
-
.strip = strip,
|
|
168
|
-
.pic = pic,
|
|
132
|
+
.root_module = b.createModule(.{
|
|
133
|
+
.root_source_file = path,
|
|
134
|
+
.optimize = optimize,
|
|
135
|
+
.target = target,
|
|
136
|
+
.strip = strip,
|
|
137
|
+
.unwind_tables = unwind_tables,
|
|
138
|
+
.pic = pic,
|
|
139
|
+
}),
|
|
169
140
|
});
|
|
170
|
-
|
|
171
|
-
lib.
|
|
172
|
-
|
|
173
|
-
if (force_pic and pic orelse false) lib.force_pic = pic;
|
|
141
|
+
lib.discard_local_symbols = strip orelse false;
|
|
142
|
+
lib.root_module.addOptions("build_options", options);
|
|
143
|
+
lib.root_module.addIncludePath(b.path("src/include"));
|
|
174
144
|
b.installArtifact(lib);
|
|
175
145
|
c = true;
|
|
176
146
|
} else {
|
|
177
|
-
const path =
|
|
178
|
-
const lib = b.
|
|
179
|
-
.
|
|
180
|
-
.root_source_file = path,
|
|
181
|
-
.optimize = optimize,
|
|
182
|
-
.target = target,
|
|
183
|
-
} else .{
|
|
147
|
+
const path = b.path("src/lib/c.zig");
|
|
148
|
+
const lib = b.addLibrary(.{
|
|
149
|
+
.linkage = .static,
|
|
184
150
|
.name = name,
|
|
185
|
-
.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
151
|
+
.root_module = b.createModule(.{
|
|
152
|
+
.root_source_file = path,
|
|
153
|
+
.optimize = optimize,
|
|
154
|
+
.target = target,
|
|
155
|
+
.strip = strip,
|
|
156
|
+
.unwind_tables = unwind_tables,
|
|
157
|
+
.pic = pic,
|
|
158
|
+
}),
|
|
190
159
|
});
|
|
191
|
-
|
|
192
|
-
lib.
|
|
193
|
-
lib.
|
|
194
|
-
|
|
195
|
-
|
|
160
|
+
lib.discard_local_symbols = strip orelse false;
|
|
161
|
+
lib.root_module.addOptions("build_options", options);
|
|
162
|
+
lib.root_module.addIncludePath(b.path("src/include"));
|
|
163
|
+
if (target.result.os.tag != .macos) {
|
|
164
|
+
lib.bundle_compiler_rt = true;
|
|
165
|
+
}
|
|
196
166
|
if (emit_asm) {
|
|
197
167
|
b.getInstallStep().dependOn(&b.addInstallFileWithDir(
|
|
198
168
|
lib.getEmittedAsm(),
|
|
@@ -212,72 +182,64 @@ pub fn build(b: *std.Build) !void {
|
|
|
212
182
|
}
|
|
213
183
|
|
|
214
184
|
if (c) {
|
|
215
|
-
const path =
|
|
216
|
-
if (has_path) .{ .path = "src/include/pkmn.h" } else b.path("src/include/pkmn.h");
|
|
185
|
+
const path = b.path("src/include/pkmn.h");
|
|
217
186
|
const header = b.addInstallFileWithDir(path, .header, "pkmn.h");
|
|
218
187
|
b.getInstallStep().dependOn(&header.step);
|
|
219
188
|
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
b.allocator,
|
|
223
|
-
try std.process.getCwdAlloc(b.allocator),
|
|
224
|
-
try b.cache_root.join(b.allocator, &.{pc}),
|
|
225
|
-
);
|
|
226
|
-
const pkgconfig_file = try std.fs.cwd().createFile(file, .{});
|
|
227
|
-
|
|
228
|
-
const dirname = comptime std.fs.path.dirname(@src().file) orelse ".";
|
|
229
|
-
const writer = pkgconfig_file.writer();
|
|
230
|
-
try writer.print(
|
|
231
|
-
\\prefix={0s}/{1s}
|
|
189
|
+
const content = try std.fmt.allocPrint(b.allocator,
|
|
190
|
+
\\prefix=${{pcfiledir}}/../..
|
|
232
191
|
\\includedir=${{prefix}}/include
|
|
233
192
|
\\libdir=${{prefix}}/lib
|
|
234
193
|
\\
|
|
235
|
-
\\Name: lib{
|
|
236
|
-
\\URL: https://github.com/{
|
|
237
|
-
\\Description: {
|
|
238
|
-
\\Version: {
|
|
194
|
+
\\Name: lib{0s}
|
|
195
|
+
\\URL: https://github.com/{1s}
|
|
196
|
+
\\Description: {2s}
|
|
197
|
+
\\Version: {3s}
|
|
239
198
|
\\Cflags: -I${{includedir}}
|
|
240
|
-
\\Libs: -L${{libdir}} -l{
|
|
241
|
-
, .{
|
|
242
|
-
defer pkgconfig_file.close();
|
|
199
|
+
\\Libs: -L${{libdir}} -l{0s}
|
|
200
|
+
, .{ name, repository.next().?, description, version });
|
|
243
201
|
|
|
244
|
-
|
|
202
|
+
const pc = b.fmt("lib{s}.pc", .{name});
|
|
203
|
+
const write_file = b.addWriteFiles();
|
|
204
|
+
const pkgconfig = write_file.add(pc, content);
|
|
205
|
+
b.getInstallStep().dependOn(&b.addInstallFileWithDir(
|
|
206
|
+
pkgconfig,
|
|
207
|
+
.prefix,
|
|
208
|
+
b.fmt("share/pkgconfig/{s}", .{pc}),
|
|
209
|
+
).step);
|
|
245
210
|
}
|
|
246
211
|
|
|
247
|
-
const config = .{
|
|
212
|
+
const config: Config = .{
|
|
248
213
|
.target = target,
|
|
249
214
|
.optimize = optimize,
|
|
250
215
|
.pic = pic,
|
|
251
216
|
.strip = strip,
|
|
252
|
-
.
|
|
217
|
+
.unwind_tables = unwind_tables,
|
|
253
218
|
};
|
|
254
219
|
|
|
255
220
|
// TODO: tests can be run multiple times due to @imports
|
|
256
221
|
const tests = TestStep.create(b, options, config);
|
|
257
222
|
|
|
258
|
-
var exes
|
|
223
|
+
var exes: std.ArrayList(*std.Build.Step.Compile) = .empty;
|
|
259
224
|
const tools: ToolConfig = .{
|
|
260
|
-
.
|
|
261
|
-
.showdown = showdown,
|
|
262
|
-
.log = log,
|
|
263
|
-
.chance = chance,
|
|
264
|
-
.calc = calc,
|
|
265
|
-
},
|
|
225
|
+
.showdown = showdown,
|
|
266
226
|
.module = pkmn,
|
|
267
227
|
.general = config,
|
|
268
228
|
.tool = .{
|
|
269
|
-
.tests = if (tests.build) tests else null,
|
|
229
|
+
.tests = if (tests.build) tests.step else null,
|
|
270
230
|
.exes = &exes,
|
|
271
231
|
},
|
|
272
232
|
};
|
|
273
233
|
|
|
274
234
|
var benchmark_config = tools;
|
|
275
|
-
benchmark_config.general.optimize =
|
|
235
|
+
benchmark_config.general.optimize = ReleaseFast;
|
|
276
236
|
benchmark_config.general.strip = true;
|
|
237
|
+
benchmark_config.general.unwind_tables = if (target.result.os.tag != .windows) .none else null;
|
|
277
238
|
const benchmark = try tool(b, "src/test/benchmark.zig", benchmark_config);
|
|
278
239
|
|
|
279
240
|
var fuzz_config = tools;
|
|
280
241
|
fuzz_config.general.strip = false;
|
|
242
|
+
fuzz_config.general.unwind_tables = null;
|
|
281
243
|
fuzz_config.tool.name = "fuzz";
|
|
282
244
|
const fuzz = try tool(b, "src/test/fuzz.zig", fuzz_config);
|
|
283
245
|
|
|
@@ -287,7 +249,7 @@ pub fn build(b: *std.Build) !void {
|
|
|
287
249
|
|
|
288
250
|
// FIXME: serde randomly fails to build in some release configurations
|
|
289
251
|
var hack = tools;
|
|
290
|
-
if (optimize !=
|
|
252
|
+
if (optimize != Debug) hack.tool.tests = null;
|
|
291
253
|
const serde = try tool(b, "src/tools/serde.zig", hack);
|
|
292
254
|
|
|
293
255
|
if (analyze) |t| b.step("analyze", "Run LLVM analysis tool").dependOn(&t.step);
|
|
@@ -295,8 +257,9 @@ pub fn build(b: *std.Build) !void {
|
|
|
295
257
|
if (dump) |t| b.step("dump", "Run protocol dump tool").dependOn(&t.step);
|
|
296
258
|
if (fuzz) |t| b.step("fuzz", "Run fuzz tester").dependOn(&t.step);
|
|
297
259
|
if (serde) |t| b.step("serde", "Run serialization/deserialization tool").dependOn(&t.step);
|
|
298
|
-
b.step("test", "Run all tests").dependOn(
|
|
299
|
-
b.step("tools", "Install tools")
|
|
260
|
+
b.step("test", "Run all tests").dependOn(tests.step);
|
|
261
|
+
const install_tools = b.step("tools", "Install tools");
|
|
262
|
+
for (exes.items) |t| install_tools.dependOn(&b.addInstallArtifact(t, .{}).step);
|
|
300
263
|
if (transitions) |t| {
|
|
301
264
|
b.step("transitions", "Visualize transitions algorithm search").dependOn(&t.step);
|
|
302
265
|
}
|
|
@@ -310,229 +273,208 @@ fn buildWasm(
|
|
|
310
273
|
strip: ?bool,
|
|
311
274
|
pic: ?bool,
|
|
312
275
|
wasm_stack_size: u64,
|
|
313
|
-
|
|
276
|
+
import: ?*std.Build.Module,
|
|
277
|
+
options: *std.Build.Step.Options,
|
|
314
278
|
) !void {
|
|
315
|
-
const entry = @hasDecl(Step.Compile, "Entry");
|
|
316
279
|
const mode = switch (optimize) {
|
|
317
|
-
|
|
280
|
+
ReleaseFast, ReleaseSafe => ReleaseSmall,
|
|
318
281
|
else => optimize,
|
|
319
282
|
};
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
283
|
+
// https://webassembly.org/features/
|
|
284
|
+
const features = std.Target.wasm.featureSet(&.{
|
|
285
|
+
.atomics,
|
|
286
|
+
.bulk_memory,
|
|
287
|
+
// .exception_handling,
|
|
288
|
+
.extended_const,
|
|
289
|
+
// .half_precision,
|
|
290
|
+
// .multimemory,
|
|
291
|
+
.multivalue,
|
|
292
|
+
.mutable_globals,
|
|
293
|
+
.nontrapping_fptoint,
|
|
294
|
+
.reference_types,
|
|
295
|
+
// .relaxed_simd,
|
|
296
|
+
.sign_ext,
|
|
297
|
+
.simd128,
|
|
298
|
+
// .tail_call,
|
|
299
|
+
});
|
|
300
|
+
const freestanding = b.resolveTargetQuery(.{
|
|
301
|
+
.cpu_arch = .wasm32,
|
|
302
|
+
.os_tag = .freestanding,
|
|
303
|
+
.cpu_features_add = features,
|
|
304
|
+
});
|
|
305
|
+
const path = b.path(root_src_file);
|
|
306
|
+
const exe = b.addExecutable(.{
|
|
307
|
+
.name = name,
|
|
308
|
+
.root_module = b.createModule(.{
|
|
333
309
|
.root_source_file = path,
|
|
334
310
|
.optimize = mode,
|
|
335
311
|
.target = freestanding,
|
|
336
312
|
.strip = strip,
|
|
313
|
+
.unwind_tables = if (strip orelse false) .none else null,
|
|
337
314
|
.pic = pic,
|
|
315
|
+
}),
|
|
316
|
+
});
|
|
317
|
+
exe.discard_local_symbols = strip orelse false;
|
|
318
|
+
|
|
319
|
+
if (@hasDecl(std.Build, "FindProgramOptions")) b.dependOnFileContents(path);
|
|
320
|
+
const root = if (@hasField(std.Build, "root")) b.root.root_dir.handle else b.build_root.handle;
|
|
321
|
+
var file = try root.openFile(b.graph.io, root_src_file, .{});
|
|
322
|
+
defer file.close(b.graph.io);
|
|
323
|
+
var reader = file.reader(b.graph.io, &.{});
|
|
324
|
+
const bytes = try reader.interface.allocRemaining(b.allocator, .unlimited);
|
|
325
|
+
exe.root_module.export_symbol_names = try exports(b, bytes);
|
|
326
|
+
exe.entry = .disabled;
|
|
327
|
+
|
|
328
|
+
if (import) |i| {
|
|
329
|
+
exe.root_module.addImport("pkmn", i);
|
|
330
|
+
} else {
|
|
331
|
+
exe.root_module.addOptions("build_options", options);
|
|
332
|
+
}
|
|
333
|
+
exe.stack_size = wasm_stack_size;
|
|
334
|
+
|
|
335
|
+
const opt = if (optimize == Debug)
|
|
336
|
+
null
|
|
337
|
+
else if (@hasDecl(std.Build, "FindProgramOptions")) blk: {
|
|
338
|
+
if (exists(b, "./node_modules/.bin/wasm-opt") catch false) {
|
|
339
|
+
break :blk "./node_modules/.bin/wasm-opt";
|
|
340
|
+
}
|
|
341
|
+
break :blk b.findProgram(.{ .names = &.{"wasm-opt"} });
|
|
342
|
+
} else b.findProgram(&.{"wasm-opt"}, &.{"./node_modules/.bin"}) catch null;
|
|
343
|
+
if (opt) |wasm_opt| {
|
|
344
|
+
const out = b.fmt("{s}.wasm", .{name});
|
|
345
|
+
const sh = b.addSystemCommand(&.{
|
|
346
|
+
wasm_opt,
|
|
347
|
+
"--enable-bulk-memory",
|
|
348
|
+
"--enable-simd",
|
|
349
|
+
"-O4",
|
|
338
350
|
});
|
|
339
|
-
(
|
|
340
|
-
exe.entry = .disabled;
|
|
341
|
-
break :bin exe;
|
|
342
|
-
} else bin: {
|
|
343
|
-
const lib = b.addSharedLibrary(.{
|
|
344
|
-
.name = name,
|
|
345
|
-
.root_source_file = path,
|
|
346
|
-
.optimize = mode,
|
|
347
|
-
.target = freestanding,
|
|
348
|
-
});
|
|
349
|
-
lib.rdynamic = true;
|
|
350
|
-
break :bin lib;
|
|
351
|
-
};
|
|
352
|
-
bin.stack_size = wasm_stack_size;
|
|
353
|
-
if (@hasDecl(@TypeOf(bin.*), "strip")) bin.strip = strip orelse false;
|
|
354
|
-
if (force_pic and pic orelse false) bin.force_pic = pic;
|
|
355
|
-
(if (root_module) bin.root_module else bin).addOptions("build_options", options);
|
|
356
|
-
|
|
357
|
-
const opt = b.findProgram(&.{"wasm-opt"}, &.{"./node_modules/.bin"}) catch null;
|
|
358
|
-
if (optimize != .Debug and opt != null) {
|
|
359
|
-
const out = b.fmt("build/lib/{s}.wasm", .{name});
|
|
360
|
-
const sh = b.addSystemCommand(&.{ opt.?, "-O4" });
|
|
361
|
-
sh.addArtifactArg(bin);
|
|
351
|
+
sh.addArtifactArg(exe);
|
|
362
352
|
sh.addArg("-o");
|
|
363
|
-
|
|
364
|
-
sh.
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
b.getInstallStep().dependOn(&b.addInstallArtifact(bin, .{
|
|
372
|
-
.dest_dir = .{ .override = std.Build.InstallDir{ .lib = {} } },
|
|
353
|
+
b.getInstallStep().dependOn(&b.addInstallFileWithDir(
|
|
354
|
+
sh.addOutputFileArg(out),
|
|
355
|
+
.lib,
|
|
356
|
+
out,
|
|
357
|
+
).step);
|
|
358
|
+
} else {
|
|
359
|
+
b.getInstallStep().dependOn(&b.addInstallArtifact(exe, .{
|
|
360
|
+
.dest_dir = .{ .override = .lib },
|
|
373
361
|
}).step);
|
|
374
362
|
}
|
|
375
363
|
}
|
|
376
364
|
|
|
377
|
-
fn maybeStrip(
|
|
378
|
-
b: *std.Build,
|
|
379
|
-
artifact: *Step.Compile,
|
|
380
|
-
step: *std.Build.Step,
|
|
381
|
-
strip: ?bool,
|
|
382
|
-
cmd: ?[]const u8,
|
|
383
|
-
) void {
|
|
384
|
-
if (@hasDecl(@TypeOf(artifact.*), "strip")) artifact.strip = strip orelse false;
|
|
385
|
-
if (!(strip orelse false) or cmd == null) return;
|
|
386
|
-
// Using `strip -r -u` for dynamic libraries is supposed to work on macOS but doesn't...
|
|
387
|
-
const mac = builtin.os.tag == .macos;
|
|
388
|
-
if (mac and artifact.isDynamicLibrary()) return;
|
|
389
|
-
// Assuming GNU strip, which complains "illegal pathname found in archive member"...
|
|
390
|
-
if (!mac and artifact.isStaticLibrary()) return;
|
|
391
|
-
const sh = b.addSystemCommand(&.{ cmd.?, if (mac) "-x" else "-s" });
|
|
392
|
-
sh.addArtifactArg(artifact);
|
|
393
|
-
step.dependOn(&sh.step);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
365
|
const Config = struct {
|
|
397
|
-
target: ResolvedTarget,
|
|
366
|
+
target: std.Build.ResolvedTarget,
|
|
398
367
|
optimize: std.builtin.OptimizeMode,
|
|
399
368
|
pic: ?bool,
|
|
400
369
|
strip: ?bool,
|
|
401
|
-
|
|
370
|
+
unwind_tables: ?std.builtin.UnwindTables,
|
|
402
371
|
};
|
|
403
372
|
|
|
404
373
|
const TestStep = struct {
|
|
405
|
-
step: std.Build.Step,
|
|
374
|
+
step: *std.Build.Step,
|
|
406
375
|
build: bool,
|
|
407
376
|
|
|
408
|
-
pub fn create(b: *std.Build, options: *Step.Options, config: Config)
|
|
377
|
+
pub fn create(b: *std.Build, options: *std.Build.Step.Options, config: Config) TestStep {
|
|
409
378
|
const coverage = b.option([]const u8, "test-coverage", "Generate test coverage");
|
|
410
379
|
const test_filter =
|
|
411
380
|
b.option([]const u8, "test-filter", "Skip tests that do not match filter");
|
|
412
381
|
|
|
413
|
-
const
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
.
|
|
425
|
-
.optimize = config.optimize,
|
|
426
|
-
.target = config.target,
|
|
427
|
-
.filter = test_filter,
|
|
428
|
-
.single_threaded = true,
|
|
429
|
-
.strip = config.strip,
|
|
430
|
-
.pic = config.pic,
|
|
382
|
+
const path = b.path("src/lib/test.zig");
|
|
383
|
+
const tests = b.addTest(.{
|
|
384
|
+
.root_module = b.createModule(.{
|
|
385
|
+
.root_source_file = path,
|
|
386
|
+
.optimize = config.optimize,
|
|
387
|
+
.target = config.target,
|
|
388
|
+
.single_threaded = true,
|
|
389
|
+
.strip = config.strip,
|
|
390
|
+
.unwind_tables = config.unwind_tables,
|
|
391
|
+
.pic = config.pic,
|
|
392
|
+
}),
|
|
393
|
+
.filters = if (test_filter) |filter| &.{filter} else &.{},
|
|
431
394
|
});
|
|
432
|
-
|
|
395
|
+
tests.discard_local_symbols = config.strip orelse false;
|
|
396
|
+
tests.root_module.addOptions("build_options", options);
|
|
433
397
|
|
|
434
|
-
maybeStrip(b, tests, &tests.step, config.strip, config.cmd);
|
|
435
|
-
if (force_pic) {
|
|
436
|
-
tests.single_threaded = true;
|
|
437
|
-
if (config.pic orelse false) tests.force_pic = config.pic;
|
|
438
|
-
}
|
|
439
398
|
if (coverage) |c| {
|
|
440
|
-
|
|
399
|
+
const kcov_run = b.addSystemCommand(&.{ "kcov", "--include-pattern=src/lib", c });
|
|
400
|
+
kcov_run.addArtifactArg(tests);
|
|
401
|
+
kcov_run.enableTestRunnerMode();
|
|
402
|
+
return .{ .step = &kcov_run.step, .build = test_filter == null };
|
|
403
|
+
} else {
|
|
404
|
+
const run_step = b.addRunArtifact(tests);
|
|
405
|
+
return .{ .step = &run_step.step, .build = test_filter == null };
|
|
441
406
|
}
|
|
442
|
-
self.step.dependOn(&b.addRunArtifact(tests).step);
|
|
443
|
-
|
|
444
|
-
return self;
|
|
445
407
|
}
|
|
446
408
|
};
|
|
447
409
|
|
|
448
410
|
const ToolConfig = struct {
|
|
449
|
-
|
|
450
|
-
module:
|
|
411
|
+
showdown: ?bool,
|
|
412
|
+
module: *std.Build.Module,
|
|
451
413
|
general: Config,
|
|
452
414
|
tool: struct {
|
|
453
|
-
tests: ?*
|
|
415
|
+
tests: ?*std.Build.Step,
|
|
454
416
|
name: ?[]const u8 = null,
|
|
455
|
-
exes: *std.ArrayList(*Step.Compile),
|
|
417
|
+
exes: *std.ArrayList(*std.Build.Step.Compile),
|
|
456
418
|
},
|
|
457
419
|
};
|
|
458
420
|
|
|
459
|
-
fn tool(b: *std.Build, path: []const u8, config: ToolConfig) !?*Step.Run {
|
|
460
|
-
|
|
461
|
-
error.FileNotFound => return null,
|
|
462
|
-
else => |e| return e,
|
|
463
|
-
};
|
|
421
|
+
fn tool(b: *std.Build, path: []const u8, config: ToolConfig) !?*std.Build.Step.Run {
|
|
422
|
+
if (!try exists(b, path)) return null;
|
|
464
423
|
var name = config.tool.name orelse std.fs.path.basename(path);
|
|
465
424
|
const index = std.mem.lastIndexOfScalar(u8, name, '.');
|
|
466
425
|
if (index) |i| name = name[0..i];
|
|
467
|
-
if (config.
|
|
426
|
+
if (config.showdown orelse false) name = b.fmt("{s}-showdown", .{name});
|
|
468
427
|
|
|
469
|
-
const exe = b.addExecutable(
|
|
470
|
-
.name = name,
|
|
471
|
-
.root_source_file = if (has_path) .{ .path = path } else b.path(path),
|
|
472
|
-
.target = config.general.target,
|
|
473
|
-
.optimize = config.general.optimize,
|
|
474
|
-
} else .{
|
|
428
|
+
const exe = b.addExecutable(.{
|
|
475
429
|
.name = name,
|
|
476
|
-
.
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
430
|
+
.root_module = b.createModule(.{
|
|
431
|
+
.root_source_file = b.path(path),
|
|
432
|
+
.target = config.general.target,
|
|
433
|
+
.optimize = config.general.optimize,
|
|
434
|
+
.single_threaded = true,
|
|
435
|
+
.strip = config.general.strip,
|
|
436
|
+
.unwind_tables = config.general.unwind_tables,
|
|
437
|
+
.pic = config.general.pic,
|
|
438
|
+
}),
|
|
482
439
|
});
|
|
440
|
+
exe.discard_local_symbols = config.general.strip orelse false;
|
|
441
|
+
exe.root_module.addImport("pkmn", config.module);
|
|
483
442
|
|
|
484
|
-
if (
|
|
485
|
-
|
|
486
|
-
exe.root_module.addImport("pkmn", import);
|
|
487
|
-
} else {
|
|
488
|
-
exe.addModule("pkmn", module(b, config.options));
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
if (force_pic) {
|
|
492
|
-
exe.single_threaded = true;
|
|
493
|
-
if (config.general.pic orelse false) exe.force_pic = config.general.pic;
|
|
494
|
-
}
|
|
495
|
-
if (config.tool.tests) |ts| ts.step.dependOn(&exe.step);
|
|
496
|
-
config.tool.exes.append(exe) catch @panic("OOM");
|
|
443
|
+
if (config.tool.tests) |ts| ts.dependOn(&exe.step);
|
|
444
|
+
config.tool.exes.append(b.allocator, exe) catch @panic("OOM");
|
|
497
445
|
|
|
498
446
|
const run = b.addRunArtifact(exe);
|
|
499
|
-
|
|
500
|
-
|
|
447
|
+
if (@hasDecl(std.Build, "FindProgramOptions")) {
|
|
448
|
+
run.addPassthruArgs();
|
|
449
|
+
} else {
|
|
450
|
+
if (b.args) |args| run.addArgs(args);
|
|
451
|
+
}
|
|
501
452
|
|
|
502
453
|
return run;
|
|
503
454
|
}
|
|
504
455
|
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
return self;
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
|
|
517
|
-
fn detect(target: anytype) std.Target {
|
|
518
|
-
if (@hasField(@TypeOf(target), "result")) return target.result;
|
|
519
|
-
return (std.zig.system.NativeTargetInfo.detect(target) catch unreachable).target;
|
|
456
|
+
fn exists(b: *std.Build, path: []const u8) !bool {
|
|
457
|
+
const root = if (@hasField(std.Build, "root")) b.root.root_dir.handle else b.build_root.handle;
|
|
458
|
+
root.access(b.graph.io, path, .{}) catch |err| switch (err) {
|
|
459
|
+
error.FileNotFound => return false,
|
|
460
|
+
else => |e| return e,
|
|
461
|
+
};
|
|
462
|
+
if (@hasDecl(std.Build, "FindProgramOptions")) b.dependOnFileMetadata(b.path(path));
|
|
463
|
+
return true;
|
|
520
464
|
}
|
|
521
465
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
fn exports(b: *std.Build) ![][]const u8 {
|
|
525
|
-
var symbols = std.ArrayList([]const u8).init(b.allocator);
|
|
466
|
+
pub fn exports(b: *std.Build, bytes: []const u8) ![][]const u8 {
|
|
467
|
+
var symbols: std.ArrayList([]const u8) = .empty;
|
|
526
468
|
|
|
527
|
-
var it = std.mem.splitSequence(u8,
|
|
469
|
+
var it = std.mem.splitSequence(u8, bytes, "export ");
|
|
528
470
|
_ = it.next();
|
|
529
471
|
while (it.next()) |s| {
|
|
530
472
|
if (std.mem.startsWith(u8, s, "const ")) {
|
|
531
473
|
const i = std.mem.indexOf(u8, s[6..], " ").?;
|
|
532
|
-
try symbols.append(s[6 .. 6 + i]);
|
|
474
|
+
try symbols.append(b.allocator, s[6 .. 6 + i]);
|
|
533
475
|
} else { // "fn "
|
|
534
476
|
const i = std.mem.indexOf(u8, s[3..], "(").?;
|
|
535
|
-
try symbols.append(s[3 .. 3 + i]);
|
|
477
|
+
try symbols.append(b.allocator, s[3 .. 3 + i]);
|
|
536
478
|
}
|
|
537
479
|
}
|
|
538
480
|
|