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