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