Commit 2c0c86944e

Jakub Konka <kubkon@jakubkonka.com>
2024-01-14 00:17:23
test/link/macho: upgrade and migrate headerpad test
1 parent 9533628
Changed files (4)
test
test/link/macho/headerpad/build.zig
@@ -1,137 +0,0 @@
-const std = @import("std");
-const builtin = @import("builtin");
-
-pub const requires_symlinks = true;
-pub const requires_macos_sdk = true;
-
-pub fn build(b: *std.Build) void {
-    const test_step = b.step("test", "Test it");
-    b.default_step = test_step;
-
-    add(b, test_step, .Debug);
-    add(b, test_step, .ReleaseFast);
-    add(b, test_step, .ReleaseSmall);
-    add(b, test_step, .ReleaseSafe);
-}
-
-fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
-    {
-        // Test -headerpad_max_install_names
-        const exe = simpleExe(b, optimize, "headerpad_max_install_names");
-        exe.headerpad_max_install_names = true;
-
-        const check = exe.checkObject();
-        check.checkInHeaders();
-        check.checkExact("sectname __text");
-        check.checkExtract("offset {offset}");
-
-        switch (builtin.cpu.arch) {
-            .aarch64 => {
-                check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x4000 } });
-            },
-            .x86_64 => {
-                check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x1000 } });
-            },
-            else => unreachable,
-        }
-
-        test_step.dependOn(&check.step);
-
-        const run = b.addRunArtifact(exe);
-        test_step.dependOn(&run.step);
-    }
-
-    {
-        // Test -headerpad
-        const exe = simpleExe(b, optimize, "headerpad");
-        exe.headerpad_size = 0x10000;
-
-        const check = exe.checkObject();
-        check.checkInHeaders();
-        check.checkExact("sectname __text");
-        check.checkExtract("offset {offset}");
-        check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });
-
-        test_step.dependOn(&check.step);
-
-        const run = b.addRunArtifact(exe);
-        test_step.dependOn(&run.step);
-    }
-
-    {
-        // Test both flags with -headerpad overriding -headerpad_max_install_names
-        const exe = simpleExe(b, optimize, "headerpad_overriding");
-        exe.headerpad_max_install_names = true;
-        exe.headerpad_size = 0x10000;
-
-        const check = exe.checkObject();
-        check.checkInHeaders();
-        check.checkExact("sectname __text");
-        check.checkExtract("offset {offset}");
-        check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });
-
-        test_step.dependOn(&check.step);
-
-        const run = b.addRunArtifact(exe);
-        test_step.dependOn(&run.step);
-    }
-
-    {
-        // Test both flags with -headerpad_max_install_names overriding -headerpad
-        const exe = simpleExe(b, optimize, "headerpad_max_install_names_overriding");
-        exe.headerpad_size = 0x1000;
-        exe.headerpad_max_install_names = true;
-
-        const check = exe.checkObject();
-        check.checkInHeaders();
-        check.checkExact("sectname __text");
-        check.checkExtract("offset {offset}");
-
-        switch (builtin.cpu.arch) {
-            .aarch64 => {
-                check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x4000 } });
-            },
-            .x86_64 => {
-                check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x1000 } });
-            },
-            else => unreachable,
-        }
-
-        test_step.dependOn(&check.step);
-
-        const run = b.addRunArtifact(exe);
-        test_step.dependOn(&run.step);
-    }
-}
-
-fn simpleExe(
-    b: *std.Build,
-    optimize: std.builtin.OptimizeMode,
-    name: []const u8,
-) *std.Build.Step.Compile {
-    const exe = b.addExecutable(.{
-        .name = name,
-        .optimize = optimize,
-        .target = b.host,
-    });
-    exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
-    exe.linkLibC();
-    exe.linkFramework("CoreFoundation");
-    exe.linkFramework("Foundation");
-    exe.linkFramework("Cocoa");
-    exe.linkFramework("CoreGraphics");
-    exe.linkFramework("CoreHaptics");
-    exe.linkFramework("CoreAudio");
-    exe.linkFramework("AVFoundation");
-    exe.linkFramework("CoreImage");
-    exe.linkFramework("CoreLocation");
-    exe.linkFramework("CoreML");
-    exe.linkFramework("CoreVideo");
-    exe.linkFramework("CoreText");
-    exe.linkFramework("CryptoKit");
-    exe.linkFramework("GameKit");
-    exe.linkFramework("SwiftUI");
-    exe.linkFramework("StoreKit");
-    exe.linkFramework("SpriteKit");
-    return exe;
-}
test/link/macho/headerpad/main.c
@@ -1,3 +0,0 @@
-int main(int argc, char* argv[]) {
-  return 0;
-}
test/link/macho.zig
@@ -24,6 +24,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
 
         // Tests requiring presence of macOS SDK in system path
         if (build_opts.has_macos_sdk) {
+            macho_step.dependOn(testHeaderpad(b, .{ .target = b.host }));
             macho_step.dependOn(testNeededFramework(b, .{ .target = b.host }));
         }
     }
@@ -166,6 +167,113 @@ fn testEntryPointDylib(b: *Build, opts: Options) *Step {
     return test_step;
 }
 
+fn testHeaderpad(b: *Build, opts: Options) *Step {
+    const test_step = addTestStep(b, "macho-headerpad", opts);
+
+    const addExe = struct {
+        fn addExe(bb: *Build, o: Options, name: []const u8) *Compile {
+            const exe = addExecutable(bb, o, .{
+                .name = name,
+                .c_source_bytes = "int main() { return 0; }",
+            });
+            exe.linkFramework("CoreFoundation");
+            exe.linkFramework("Foundation");
+            exe.linkFramework("Cocoa");
+            exe.linkFramework("CoreGraphics");
+            exe.linkFramework("CoreHaptics");
+            exe.linkFramework("CoreAudio");
+            exe.linkFramework("AVFoundation");
+            exe.linkFramework("CoreImage");
+            exe.linkFramework("CoreLocation");
+            exe.linkFramework("CoreML");
+            exe.linkFramework("CoreVideo");
+            exe.linkFramework("CoreText");
+            exe.linkFramework("CryptoKit");
+            exe.linkFramework("GameKit");
+            exe.linkFramework("SwiftUI");
+            exe.linkFramework("StoreKit");
+            exe.linkFramework("SpriteKit");
+            return exe;
+        }
+    }.addExe;
+
+    {
+        const exe = addExe(b, opts, "main1");
+        exe.headerpad_max_install_names = true;
+
+        const check = exe.checkObject();
+        check.checkInHeaders();
+        check.checkExact("sectname __text");
+        check.checkExtract("offset {offset}");
+        switch (opts.target.result.cpu.arch) {
+            .aarch64 => check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x4000 } }),
+            .x86_64 => check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x1000 } }),
+            else => unreachable,
+        }
+        test_step.dependOn(&check.step);
+
+        const run = addRunArtifact(exe);
+        run.expectExitCode(0);
+        test_step.dependOn(&run.step);
+    }
+
+    {
+        const exe = addExe(b, opts, "main2");
+        exe.headerpad_size = 0x10000;
+
+        const check = exe.checkObject();
+        check.checkInHeaders();
+        check.checkExact("sectname __text");
+        check.checkExtract("offset {offset}");
+        check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });
+        test_step.dependOn(&check.step);
+
+        const run = addRunArtifact(exe);
+        run.expectExitCode(0);
+        test_step.dependOn(&run.step);
+    }
+
+    {
+        const exe = addExe(b, opts, "main3");
+        exe.headerpad_max_install_names = true;
+        exe.headerpad_size = 0x10000;
+
+        const check = exe.checkObject();
+        check.checkInHeaders();
+        check.checkExact("sectname __text");
+        check.checkExtract("offset {offset}");
+        check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });
+        test_step.dependOn(&check.step);
+
+        const run = addRunArtifact(exe);
+        run.expectExitCode(0);
+        test_step.dependOn(&run.step);
+    }
+
+    {
+        const exe = addExe(b, opts, "main4");
+        exe.headerpad_max_install_names = true;
+        exe.headerpad_size = 0x1000;
+
+        const check = exe.checkObject();
+        check.checkInHeaders();
+        check.checkExact("sectname __text");
+        check.checkExtract("offset {offset}");
+        switch (opts.target.result.cpu.arch) {
+            .aarch64 => check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x4000 } }),
+            .x86_64 => check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x1000 } }),
+            else => unreachable,
+        }
+        test_step.dependOn(&check.step);
+
+        const run = addRunArtifact(exe);
+        run.expectExitCode(0);
+        test_step.dependOn(&run.step);
+    }
+
+    return test_step;
+}
+
 // Adapted from https://github.com/llvm/llvm-project/blob/main/lld/test/MachO/weak-header-flags.s
 fn testHeaderWeakFlags(b: *Build, opts: Options) *Step {
     const test_step = addTestStep(b, "macho-header-weak-flags", opts);
@@ -537,5 +645,6 @@ const std = @import("std");
 
 const Build = std.Build;
 const BuildOptions = link.BuildOptions;
+const Compile = Step.Compile;
 const Options = link.Options;
 const Step = Build.Step;
test/link.zig
@@ -127,10 +127,6 @@ pub const cases = [_]Case{
         .build_root = "test/link/macho/entry_in_archive",
         .import = @import("link/macho/entry_in_archive/build.zig"),
     },
-    .{
-        .build_root = "test/link/macho/headerpad",
-        .import = @import("link/macho/headerpad/build.zig"),
-    },
     .{
         .build_root = "test/link/macho/linksection",
         .import = @import("link/macho/linksection/build.zig"),