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