authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-13 18:09:32+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:39+01:00
log6cdcf61a5ce193104c3c0f14189014f65bcd104d
tree46ee9a48bf658d7506b32aaad1b244dc9419b3d8
parentaa50bca1516f6fc2c9d6c7ca66ef8585b4b5e197

test/link/macho: upgrade and migrate dead_strip test


4 files changed, 82 insertions(+), 76 deletions(-)

test/link.zig-4
......@@ -107,10 +107,6 @@ pub const cases = [_]Case{
107107 .build_root = "test/link/macho/bugs/16628",
108108 .import = @import("link/macho/bugs/16628/build.zig"),
109109 },
110 .{
111 .build_root = "test/link/macho/dead_strip",
112 .import = @import("link/macho/dead_strip/build.zig"),
113 },
114110 .{
115111 .build_root = "test/link/macho/dead_strip_dylibs",
116112 .import = @import("link/macho/dead_strip_dylibs/build.zig"),
test/link/macho.zig+82
......@@ -8,12 +8,94 @@ pub fn testAll(b: *std.Build) *Step {
88 .os_tag = .macos,
99 });
1010
11 macho_step.dependOn(testDeadStrip(b, .{ .target = default_target }));
1112 macho_step.dependOn(testEntryPointDylib(b, .{ .target = default_target }));
1213 macho_step.dependOn(testSectionBoundarySymbols(b, .{ .target = default_target }));
1314
1415 return macho_step;
1516}
1617
18fn testDeadStrip(b: *std.Build, opts: Options) *Step {
19 const test_step = addTestStep(b, "macho-dead-strip", opts);
20
21 const obj = addObject(b, opts, .{ .name = "a", .cpp_source_bytes =
22 \\#include <stdio.h>
23 \\int two() { return 2; }
24 \\int live_var1 = 1;
25 \\int live_var2 = two();
26 \\int dead_var1 = 3;
27 \\int dead_var2 = 4;
28 \\void live_fn1() {}
29 \\void live_fn2() { live_fn1(); }
30 \\void dead_fn1() {}
31 \\void dead_fn2() { dead_fn1(); }
32 \\int main() {
33 \\ printf("%d %d\n", live_var1, live_var2);
34 \\ live_fn2();
35 \\}
36 });
37
38 {
39 const exe = addExecutable(b, opts, .{ .name = "no_dead_strip" });
40 exe.addObject(obj);
41 exe.link_gc_sections = false;
42
43 const check = exe.checkObject();
44 check.checkInSymtab();
45 check.checkContains("live_var1");
46 check.checkInSymtab();
47 check.checkContains("live_var2");
48 check.checkInSymtab();
49 check.checkContains("dead_var1");
50 check.checkInSymtab();
51 check.checkContains("dead_var2");
52 check.checkInSymtab();
53 check.checkContains("live_fn1");
54 check.checkInSymtab();
55 check.checkContains("live_fn2");
56 check.checkInSymtab();
57 check.checkContains("dead_fn1");
58 check.checkInSymtab();
59 check.checkContains("dead_fn2");
60 test_step.dependOn(&check.step);
61
62 const run = addRunArtifact(exe);
63 run.expectStdOutEqual("1 2\n");
64 test_step.dependOn(&run.step);
65 }
66
67 {
68 const exe = addExecutable(b, opts, .{ .name = "yes_dead_strip" });
69 exe.addObject(obj);
70 exe.link_gc_sections = true;
71
72 const check = exe.checkObject();
73 check.checkInSymtab();
74 check.checkContains("live_var1");
75 check.checkInSymtab();
76 check.checkContains("live_var2");
77 check.checkInSymtab();
78 check.checkNotPresent("dead_var1");
79 check.checkInSymtab();
80 check.checkNotPresent("dead_var2");
81 check.checkInSymtab();
82 check.checkContains("live_fn1");
83 check.checkInSymtab();
84 check.checkContains("live_fn2");
85 check.checkInSymtab();
86 check.checkNotPresent("dead_fn1");
87 check.checkInSymtab();
88 check.checkNotPresent("dead_fn2");
89 test_step.dependOn(&check.step);
90
91 const run = addRunArtifact(exe);
92 run.expectStdOutEqual("1 2\n");
93 test_step.dependOn(&run.step);
94 }
95
96 return test_step;
97}
98
1799fn testEntryPointDylib(b: *std.Build, opts: Options) *Step {
18100 const test_step = addTestStep(b, "macho-entry-point-dylib", opts);
19101
test/link/macho/dead_strip/build.zig deleted-58
......@@ -1,58 +0,0 @@
1const std = @import("std");
2
3pub const requires_symlinks = true;
4
5pub fn build(b: *std.Build) void {
6 const optimize: std.builtin.OptimizeMode = .Debug;
7 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
8
9 const test_step = b.step("test", "Test the program");
10 b.default_step = test_step;
11
12 {
13 // Without -dead_strip, we expect `iAmUnused` symbol present
14 const exe = createScenario(b, optimize, target, "no-gc");
15
16 const check = exe.checkObject();
17 check.checkInSymtab();
18 check.checkContains("(__TEXT,__text) external _iAmUnused");
19 test_step.dependOn(&check.step);
20
21 const run = b.addRunArtifact(exe);
22 run.skip_foreign_checks = true;
23 run.expectStdOutEqual("Hello!\n");
24 test_step.dependOn(&run.step);
25 }
26
27 {
28 // With -dead_strip, no `iAmUnused` symbol should be present
29 const exe = createScenario(b, optimize, target, "yes-gc");
30 exe.link_gc_sections = true;
31
32 const check = exe.checkObject();
33 check.checkInSymtab();
34 check.checkNotPresent("(__TEXT,__text) external _iAmUnused");
35 test_step.dependOn(&check.step);
36
37 const run = b.addRunArtifact(exe);
38 run.skip_foreign_checks = true;
39 run.expectStdOutEqual("Hello!\n");
40 test_step.dependOn(&run.step);
41 }
42}
43
44fn createScenario(
45 b: *std.Build,
46 optimize: std.builtin.OptimizeMode,
47 target: std.Build.ResolvedTarget,
48 name: []const u8,
49) *std.Build.Step.Compile {
50 const exe = b.addExecutable(.{
51 .name = name,
52 .optimize = optimize,
53 .target = target,
54 });
55 exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
56 exe.linkLibC();
57 return exe;
58}
test/link/macho/dead_strip/main.c deleted-14
......@@ -1,14 +0,0 @@
1#include <stdio.h>
2
3void printMe() {
4 printf("Hello!\n");
5}
6
7int main(int argc, char* argv[]) {
8 printMe();
9 return 0;
10}
11
12void iAmUnused() {
13 printf("YOU SHALL NOT PASS!\n");
14}