authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-04-30 09:57:20+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-05-28 08:54:23+01:00
log2b8a05b8d9125b7465f0d3bd44e90d82a06dd5fa
treea5efb21a2146e3b393ea6cce940d31db9b2ec08d
parent89f86e46d278a35a613bbc662cdd3f65ffc76ed7
signaturelock-open Commit is signed but in an unrecognized format.

tests: restore standalone/ios, add Zig code to it

This was deleted in beef9fdf42726d8cfe3017ff3017767fb615ef08 because it was setting `b.sysroot`. However, I frankly have no idea why it was doing that---the test works just fine without touching `b.sysroot`! Even before it was removed, this test was never actually running, because the executable was not added as a dependency of `test_step`. I made it run, and updated it to work (it was previously failing due to a missing framework path). I also added some Zig source code, the goal being to test that the panic handler compiles okay on iOS. I confirmed that the updated test passes as-is, but fails if the fix in the previous commit is reverted. Because this test requires the iOS SDK to be installed, it is only run if `-Denable-ios-sdk` is passed to `zig build`, which is currently not the case in CI. For now, I am not changing this, because the aarch64-macos CI runner currently does not have the iOS SDK installed. It would be good to enable this coverage on CI at some point, though.

4 files changed, 86 insertions(+), 0 deletions(-)

test/standalone/build.zig.zon+3
......@@ -153,6 +153,9 @@
153153 .compiler_rt_panic = .{
154154 .path = "compiler_rt_panic",
155155 },
156 .ios = .{
157 .path = "ios",
158 },
156159 .depend_on_main_mod = .{
157160 .path = "depend_on_main_mod",
158161 },
test/standalone/ios/build.zig created+41
......@@ -0,0 +1,41 @@
1const std = @import("std");
2
3pub const requires_symlinks = true;
4pub const requires_ios_sdk = true;
5
6pub fn build(b: *std.Build) void {
7 const test_step = b.step("test", "Test it");
8 b.default_step = test_step;
9
10 const target = b.resolveTargetQuery(.{
11 .cpu_arch = .aarch64,
12 .os_tag = .ios,
13 });
14
15 const exe = b.addExecutable(.{
16 .name = "main",
17 .root_module = b.createModule(.{
18 .root_source_file = b.path("panic.zig"),
19 .optimize = .Debug,
20 .target = target,
21 .link_libc = true,
22 }),
23 });
24
25 const io = b.graph.io;
26
27 if (std.zig.system.darwin.getSdk(b.allocator, io, &target.result)) |sdk| {
28 exe.root_module.addSystemIncludePath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/usr/include" }) });
29 exe.root_module.addSystemFrameworkPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/System/Library/Frameworks" }) });
30 exe.root_module.addSystemFrameworkPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/System/Library/SubFrameworks" }) });
31 exe.root_module.addLibraryPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/usr/lib" }) });
32 } else {
33 exe.step.dependOn(&b.addFail("no iOS SDK found").step);
34 }
35
36 exe.root_module.addCSourceFile(.{ .file = b.path("main.m"), .flags = &.{} });
37 exe.root_module.linkFramework("Foundation", .{});
38 exe.root_module.linkFramework("UIKit", .{});
39
40 test_step.dependOn(&b.addInstallArtifact(exe, .{}).step);
41}
test/standalone/ios/main.m created+38
......@@ -0,0 +1,38 @@
1#import <UIKit/UIKit.h>
2
3@interface AppDelegate : UIResponder <UIApplicationDelegate>
4@property (strong, nonatomic) UIWindow *window;
5@end
6
7extern void zig_panic();
8
9int main() {
10 @autoreleasepool {
11 return UIApplicationMain(0, nil, nil, NSStringFromClass([AppDelegate class]));
12 }
13}
14
15@implementation AppDelegate
16
17- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(id)options {
18 CGRect mainScreenBounds = [[UIScreen mainScreen] bounds];
19 self.window = [[UIWindow alloc] initWithFrame:mainScreenBounds];
20 UIViewController *viewController = [[UIViewController alloc] init];
21 viewController.view.frame = mainScreenBounds;
22
23 NSString* msg = @"Hello world";
24
25 UILabel *label = [[UILabel alloc] initWithFrame:mainScreenBounds];
26 [label setText:msg];
27 [viewController.view addSubview: label];
28
29 self.window.rootViewController = viewController;
30
31 [self.window makeKeyAndVisible];
32
33 zig_panic();
34
35 return YES;
36}
37
38@end
test/standalone/ios/panic.zig created+4
......@@ -0,0 +1,4 @@
1export fn zig_panic() void {
2 @panic("called zig_panic");
3}
4pub const _start = {}; // entry point is in main.m