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