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