authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-02-08 11:13:36+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-02-08 17:26:25+01:00
log2d017f379f6dfa5e35944044eaf34347371b8d33
treec4a7201efbea61c24e178acec58c6099b02b82b0
parent94c68c1f9ed74cd5e2b4ab4329166ba5e5d7abc3

link-tests: do not hardcode UUID when testing the build with/out DI


1 files changed, 132 insertions(+), 15 deletions(-)

test/link/macho/uuid/build.zig+132-15
...@@ -1,4 +1,8 @@...@@ -1,4 +1,8 @@
1const std = @import("std");1const std = @import("std");
2const Builder = std.Build.Builder;
3const CompileStep = std.Build.CompileStep;
4const FileSource = std.Build.FileSource;
5const Step = std.Build.Step;
26
3pub fn build(b: *std.Build) void {7pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test");8 const test_step = b.step("test", "Test");
...@@ -10,18 +14,18 @@ pub fn build(b: *std.Build) void {...@@ -10,18 +14,18 @@ pub fn build(b: *std.Build) void {
10 .os_tag = .macos,14 .os_tag = .macos,
11 };15 };
1216
13 testUuid(b, test_step, .ReleaseSafe, aarch64_macos, "675bb6ba8e5d3d3191f7936d7168f0e9");17 testUuid(b, test_step, .ReleaseSafe, aarch64_macos);
14 testUuid(b, test_step, .ReleaseFast, aarch64_macos, "675bb6ba8e5d3d3191f7936d7168f0e9");18 testUuid(b, test_step, .ReleaseFast, aarch64_macos);
15 testUuid(b, test_step, .ReleaseSmall, aarch64_macos, "675bb6ba8e5d3d3191f7936d7168f0e9");19 testUuid(b, test_step, .ReleaseSmall, aarch64_macos);
1620
17 const x86_64_macos = std.zig.CrossTarget{21 const x86_64_macos = std.zig.CrossTarget{
18 .cpu_arch = .x86_64,22 .cpu_arch = .x86_64,
19 .os_tag = .macos,23 .os_tag = .macos,
20 };24 };
2125
22 testUuid(b, test_step, .ReleaseSafe, x86_64_macos, "5b7071b4587c3071b0d2352fadce0e48");26 testUuid(b, test_step, .ReleaseSafe, x86_64_macos);
23 testUuid(b, test_step, .ReleaseFast, x86_64_macos, "5b7071b4587c3071b0d2352fadce0e48");27 testUuid(b, test_step, .ReleaseFast, x86_64_macos);
24 testUuid(b, test_step, .ReleaseSmall, x86_64_macos, "4b58f2583c383169bbe3a716bd240048");28 testUuid(b, test_step, .ReleaseSmall, x86_64_macos);
25}29}
2630
27fn testUuid(31fn testUuid(
...@@ -29,25 +33,23 @@ fn testUuid(...@@ -29,25 +33,23 @@ fn testUuid(
29 test_step: *std.Build.Step,33 test_step: *std.Build.Step,
30 optimize: std.builtin.OptimizeMode,34 optimize: std.builtin.OptimizeMode,
31 target: std.zig.CrossTarget,35 target: std.zig.CrossTarget,
32 comptime exp: []const u8,
33) void {36) void {
34 // The calculated UUID value is independent of debug info and so it should37 // The calculated UUID value is independent of debug info and so it should
35 // stay the same across builds.38 // stay the same across builds.
36 {39 {
37 const dylib = simpleDylib(b, optimize, target);40 const dylib = simpleDylib(b, optimize, target);
38 const check_dylib = dylib.checkObject(.macho);41 const install_step = installWithRename(dylib, "test1.dylib");
39 check_dylib.checkStart("cmd UUID");42 install_step.step.dependOn(&dylib.step);
40 check_dylib.checkNext("uuid " ++ exp);
41 test_step.dependOn(&check_dylib.step);
42 }43 }
43 {44 {
44 const dylib = simpleDylib(b, optimize, target);45 const dylib = simpleDylib(b, optimize, target);
45 dylib.strip = true;46 dylib.strip = true;
46 const check_dylib = dylib.checkObject(.macho);47 const install_step = installWithRename(dylib, "test2.dylib");
47 check_dylib.checkStart("cmd UUID");48 install_step.step.dependOn(&dylib.step);
48 check_dylib.checkNext("uuid " ++ exp);
49 test_step.dependOn(&check_dylib.step);
50 }49 }
50
51 const cmp_step = CompareUuid.create(b, "test1.dylib", "test2.dylib");
52 test_step.dependOn(&cmp_step.step);
51}53}
5254
53fn simpleDylib(55fn simpleDylib(
...@@ -65,3 +67,118 @@ fn simpleDylib(...@@ -65,3 +67,118 @@ fn simpleDylib(
65 dylib.linkLibC();67 dylib.linkLibC();
66 return dylib;68 return dylib;
67}69}
70
71fn installWithRename(cs: *CompileStep, name: []const u8) *InstallWithRename {
72 const step = InstallWithRename.create(cs.builder, cs.getOutputSource(), name);
73 cs.builder.getInstallStep().dependOn(&step.step);
74 return step;
75}
76
77const InstallWithRename = struct {
78 pub const base_id = .custom;
79
80 step: Step,
81 builder: *Builder,
82 source: FileSource,
83 name: []const u8,
84
85 pub fn create(
86 builder: *Builder,
87 source: FileSource,
88 name: []const u8,
89 ) *InstallWithRename {
90 const self = builder.allocator.create(InstallWithRename) catch @panic("OOM");
91 self.* = InstallWithRename{
92 .builder = builder,
93 .step = Step.init(.custom, builder.fmt("install and rename: {s} -> {s}", .{
94 source.getDisplayName(),
95 name,
96 }), builder.allocator, make),
97 .source = source,
98 .name = builder.dupe(name),
99 };
100 return self;
101 }
102
103 fn make(step: *Step) anyerror!void {
104 const self = @fieldParentPtr(InstallWithRename, "step", step);
105 const source_path = self.source.getPath(self.builder);
106 const target_path = self.builder.getInstallPath(.lib, self.name);
107 self.builder.updateFile(source_path, target_path) catch |err| {
108 std.log.err("Unable to rename: {s} -> {s}", .{ source_path, target_path });
109 return err;
110 };
111 }
112};
113
114const CompareUuid = struct {
115 pub const base_id = .custom;
116
117 step: Step,
118 builder: *Builder,
119 lhs: []const u8,
120 rhs: []const u8,
121
122 pub fn create(builder: *Builder, lhs: []const u8, rhs: []const u8) *CompareUuid {
123 const self = builder.allocator.create(CompareUuid) catch @panic("OOM");
124 self.* = CompareUuid{
125 .builder = builder,
126 .step = Step.init(
127 .custom,
128 builder.fmt("compare uuid: {s} and {s}", .{
129 lhs,
130 rhs,
131 }),
132 builder.allocator,
133 make,
134 ),
135 .lhs = lhs,
136 .rhs = rhs,
137 };
138 return self;
139 }
140
141 fn make(step: *Step) anyerror!void {
142 const self = @fieldParentPtr(CompareUuid, "step", step);
143 const gpa = self.builder.allocator;
144
145 var lhs_uuid: [16]u8 = undefined;
146 const lhs_path = self.builder.getInstallPath(.lib, self.lhs);
147 try parseUuid(gpa, lhs_path, &lhs_uuid);
148
149 var rhs_uuid: [16]u8 = undefined;
150 const rhs_path = self.builder.getInstallPath(.lib, self.rhs);
151 try parseUuid(gpa, rhs_path, &rhs_uuid);
152
153 try std.testing.expectEqualStrings(&lhs_uuid, &rhs_uuid);
154 }
155
156 fn parseUuid(gpa: std.mem.Allocator, path: []const u8, uuid: *[16]u8) anyerror!void {
157 const max_bytes: usize = 20 * 1024 * 1024;
158 const data = try std.fs.cwd().readFileAllocOptions(
159 gpa,
160 path,
161 max_bytes,
162 null,
163 @alignOf(u64),
164 null,
165 );
166 var stream = std.io.fixedBufferStream(data);
167 const reader = stream.reader();
168
169 const hdr = try reader.readStruct(std.macho.mach_header_64);
170 if (hdr.magic != std.macho.MH_MAGIC_64) {
171 return error.InvalidMagicNumber;
172 }
173
174 var it = std.macho.LoadCommandIterator{
175 .ncmds = hdr.ncmds,
176 .buffer = data[@sizeOf(std.macho.mach_header_64)..][0..hdr.sizeofcmds],
177 };
178 const cmd = while (it.next()) |cmd| switch (cmd.cmd()) {
179 .UUID => break cmd.cast(std.macho.uuid_command).?,
180 else => {},
181 } else return error.UuidLoadCommandNotFound;
182 std.mem.copy(u8, uuid, &cmd.uuid);
183 }
184};