@pkmn/engine 0.1.0-dev.6ebbd3bc → 0.1.0-dev.724afcb1

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