master
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test");
5 b.default_step = test_step;
6
7 add(b, test_step, .Debug);
8 add(b, test_step, .ReleaseFast);
9}
10
11fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.OptimizeMode) void {
12 const exe = b.addExecutable(.{
13 .name = "lib",
14 .root_module = b.createModule(.{
15 .root_source_file = b.path("lib.zig"),
16 .target = b.resolveTargetQuery(.{
17 .cpu_arch = .wasm32,
18 .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp },
19 .cpu_features_add = std.Target.wasm.featureSet(&.{ .atomics, .bulk_memory }),
20 .os_tag = .freestanding,
21 }),
22 .optimize = optimize_mode,
23 .strip = false,
24 .single_threaded = false,
25 }),
26 });
27 exe.entry = .disabled;
28 exe.use_lld = false;
29 exe.import_memory = true;
30 exe.export_memory = true;
31 exe.shared_memory = true;
32 exe.max_memory = 67108864;
33 exe.root_module.export_symbol_names = &.{"foo"};
34 // Don't pull in ubsan, since we're just expecting a very minimal executable.
35 exe.bundle_ubsan_rt = false;
36
37 const check_exe = exe.checkObject();
38
39 check_exe.checkInHeaders();
40 check_exe.checkExact("Section import");
41 check_exe.checkExact("entries 1");
42 check_exe.checkExact("module env");
43 check_exe.checkExact("name memory"); // ensure we are importing memory
44
45 check_exe.checkInHeaders();
46 check_exe.checkExact("Section export");
47 check_exe.checkExact("entries 2");
48 check_exe.checkExact("name foo");
49 check_exe.checkExact("name memory"); // ensure we also export memory again
50
51 // This section *must* be emit as the start function is set to the index
52 // of __wasm_init_memory
53 // release modes will have the TLS segment optimized out in our test-case.
54 // This means we won't have __wasm_init_memory in such case, and therefore
55 // should also not have a section "start"
56 if (optimize_mode == .Debug) {
57 check_exe.checkInHeaders();
58 check_exe.checkExact("Section start");
59 }
60
61 // This section is only and *must* be emit when shared-memory is enabled
62 // release modes will have the TLS segment optimized out in our test-case.
63 if (optimize_mode == .Debug) {
64 check_exe.checkInHeaders();
65 check_exe.checkExact("Section data_count");
66 check_exe.checkExact("count 1");
67 }
68
69 check_exe.checkInHeaders();
70 check_exe.checkExact("Section custom");
71 check_exe.checkExact("name name");
72 check_exe.checkExact("type function");
73 if (optimize_mode == .Debug) {
74 check_exe.checkExact("name __wasm_init_memory");
75 check_exe.checkExact("name __wasm_init_tls");
76 }
77 check_exe.checkExact("type global");
78
79 // In debug mode the symbol __tls_base is resolved to an undefined symbol
80 // from the object file, hence its placement differs than in release modes
81 // where the entire tls segment is optimized away, and tls_base will have
82 // its original position.
83 if (optimize_mode == .Debug) {
84 check_exe.checkExact("name __tls_base");
85 check_exe.checkExact("name __tls_size");
86 check_exe.checkExact("name __tls_align");
87
88 check_exe.checkExact("type data_segment");
89 check_exe.checkExact("names 1");
90 check_exe.checkExact("index 0");
91 check_exe.checkExact("name .tdata");
92 } else {
93 check_exe.checkNotPresent("name __tls_base");
94 check_exe.checkNotPresent("name __tls_size");
95 check_exe.checkNotPresent("name __tls_align");
96 }
97
98 test_step.dependOn(&check_exe.step);
99}