diff --git a/build.zig b/build.zig index 03c9e23..a55bd38 100644 --- a/build.zig +++ b/build.zig @@ -20,9 +20,11 @@ pub fn build(b: *std.Build) !void { const tests = b.addTest(.{ .name = "objc-test", - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }), }); tests.linkSystemLibrary("objc"); tests.linkFramework("Foundation"); @@ -66,7 +68,7 @@ pub fn addAppleSDK(b: *std.Build, m: *std.Build.Module) !void { if (!gop.found_existing) { gop.value_ptr.* = std.zig.system.darwin.getSdk( b.allocator, - m.resolved_target.?.result, + &m.resolved_target.?.result, ); } diff --git a/flake.lock b/flake.lock index 6616332..4fc4052 100644 --- a/flake.lock +++ b/flake.lock @@ -67,16 +67,16 @@ }, "nixpkgs": { "locked": { - "lastModified": 1717895720, - "narHash": "sha256-Dl6JKx1rIDEuv4q9rtlt9QwyerSQbrk1bUtNHzx9bIY=", + "lastModified": 1759233736, + "narHash": "sha256-xv9wRPGkBfaMil8j2N7Q9LTn9rTiIX3egAGVWnx6Di4=", "owner": "nixos", "repo": "nixpkgs", - "rev": "0e0826ec06d2b3db8e28e280d68179f022b1d160", + "rev": "6a976061fb5305de938de2571af78755a7ec09ee", "type": "github" }, "original": { "owner": "nixos", - "ref": "release-24.05", + "ref": "release-25.05", "repo": "nixpkgs", "type": "github" } @@ -127,11 +127,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1741702955, - "narHash": "sha256-Emk3VnNByigCBlBN34IH2cMrsUqIhdex02uw9TSDsN0=", + "lastModified": 1759192380, + "narHash": "sha256-0BWJgt4OSzxCESij5oo8WLWrPZ+1qLp8KUQe32QeV4Q=", "owner": "mitchellh", "repo": "zig-overlay", - "rev": "1152ce759114a94134081270affd970ae1b957ed", + "rev": "0bcd1401ed43d10f10cbded49624206553e92f57", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 6717cab..bb3a348 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,7 @@ description = "Objective-C runtime bindings for Zig"; inputs = { - nixpkgs.url = "github:nixos/nixpkgs/release-24.05"; + nixpkgs.url = "github:nixos/nixpkgs/release-25.05"; flake-utils.url = "github:numtide/flake-utils"; zig.url = "github:mitchellh/zig-overlay"; @@ -35,7 +35,7 @@ in rec { devShells.default = pkgs.mkShell { nativeBuildInputs = with pkgs; [ - zigpkgs."0.14.0" + zigpkgs."0.15.1" ]; }; diff --git a/src/block.zig b/src/block.zig index 550f8e4..4df6dca 100644 --- a/src/block.zig +++ b/src/block.zig @@ -120,7 +120,7 @@ pub fn Block( _Block_release(@ptrCast(@alignCast(ctx))); } - fn descCopyHelper(src: *anyopaque, dst: *anyopaque) callconv(.C) void { + fn descCopyHelper(src: *anyopaque, dst: *anyopaque) callconv(.c) void { const real_src: *Context = @ptrCast(@alignCast(src)); const real_dst: *Context = @ptrCast(@alignCast(dst)); inline for (captures_info.fields) |field| { @@ -134,7 +134,7 @@ pub fn Block( } } - fn descDisposeHelper(src: *anyopaque) callconv(.C) void { + fn descDisposeHelper(src: *anyopaque) callconv(.c) void { const real_src: *Context = @ptrCast(@alignCast(src)); inline for (captures_info.fields) |field| { if (field.type == objc.c.id) { @@ -158,7 +158,7 @@ pub fn Block( return @Type(.{ .@"fn" = .{ - .calling_convention = .C, + .calling_convention = .c, .is_generic = false, .is_var_args = false, .return_type = Return, @@ -249,16 +249,16 @@ const BlockFieldFlags = enum(c_int) { byref_caller = 128, // BLOCK_BYREF_CALLER }; -extern "C" fn _Block_copy(src: *const anyopaque) callconv(.c) ?*anyopaque; -extern "C" fn _Block_release(src: *const anyopaque) callconv(.c) void; -extern "C" fn _Block_object_assign(dst: *anyopaque, src: *const anyopaque, flag: BlockFieldFlags) void; -extern "C" fn _Block_object_dispose(src: *const anyopaque, flag: BlockFieldFlags) void; +extern "c" fn _Block_copy(src: *const anyopaque) callconv(.c) ?*anyopaque; +extern "c" fn _Block_release(src: *const anyopaque) callconv(.c) void; +extern "c" fn _Block_object_assign(dst: *anyopaque, src: *const anyopaque, flag: BlockFieldFlags) void; +extern "c" fn _Block_object_dispose(src: *const anyopaque, flag: BlockFieldFlags) void; const Descriptor = extern struct { reserved: c_ulong = 0, size: c_ulong, - copy_helper: *const fn (dst: *anyopaque, src: *anyopaque) callconv(.C) void, - dispose_helper: *const fn (src: *anyopaque) callconv(.C) void, + copy_helper: *const fn (dst: *anyopaque, src: *anyopaque) callconv(.c) void, + dispose_helper: *const fn (src: *anyopaque) callconv(.c) void, signature: ?[*:0]const u8, }; @@ -287,7 +287,7 @@ test "Block" { }; var block: AddBlock.Context = AddBlock.init(captures, (struct { - fn addFn(block: *const AddBlock.Context) callconv(.C) i32 { + fn addFn(block: *const AddBlock.Context) callconv(.c) i32 { return block.x + block.y; } }).addFn); @@ -317,7 +317,7 @@ test "Block copy objc id" { var block = TestBlock.init(.{ .id = obj.value, }, (struct { - fn addFn(block: *const TestBlock.Context) callconv(.C) i32 { + fn addFn(block: *const TestBlock.Context) callconv(.c) i32 { _ = block; return 0; } diff --git a/src/class.zig b/src/class.zig index bf92b7c..34feea1 100644 --- a/src/class.zig +++ b/src/class.zig @@ -167,7 +167,7 @@ test "allocatecClassPair and replaceMethod" { const NSObject = getClass("NSObject").?; var my_object = allocateClassPair(NSObject, "my_object").?; my_object.replaceMethod("hash", struct { - fn inner(target: c.id, sel: c.SEL) callconv(.C) u64 { + fn inner(target: c.id, sel: c.SEL) callconv(.c) u64 { _ = sel; _ = target; return 69; @@ -208,7 +208,7 @@ test "addMethod" { const My_Class = allocateClassPair(objc.getClass("NSObject").?, "my_class").?; defer registerClassPair(My_Class); std.debug.assert(My_Class.addMethod("my_addition", struct { - fn imp(target: objc.c.id, sel: objc.c.SEL, a: i32, b: i32) callconv(.C) i32 { + fn imp(target: objc.c.id, sel: objc.c.SEL, a: i32, b: i32) callconv(.c) i32 { _ = sel; _ = target; return a + b; diff --git a/src/encoding.zig b/src/encoding.zig index 7fdafac..7cfdf1b 100644 --- a/src/encoding.zig +++ b/src/encoding.zig @@ -10,9 +10,9 @@ fn comptimeN(comptime T: type) usize { const encoding = objc.Encoding.init(T); // Figure out how much space we need - var counting = std.io.countingWriter(std.io.null_writer); - try std.fmt.format(counting.writer(), "{}", .{encoding}); - return counting.bytes_written; + var stream: std.io.Writer.Discarding = .init(&.{}); + stream.writer.print("{f}", .{encoding}) catch unreachable; + return stream.count; } } @@ -23,8 +23,8 @@ pub fn comptimeEncode(comptime T: type) [comptimeN(T):0]u8 { // Build our final signature var buf: [comptimeN(T) + 1]u8 = undefined; - var fbs = std.io.fixedBufferStream(buf[0 .. buf.len - 1]); - try std.fmt.format(fbs.writer(), "{}", .{encoding}); + var fbs: std.io.Writer = .fixed(buf[0 .. buf.len - 1]); + fbs.print("{f}", .{encoding}) catch unreachable; buf[buf.len - 1] = 0; return buf[0 .. buf.len - 1 :0].*; @@ -107,9 +107,7 @@ pub const Encoding = union(enum) { pub fn format( comptime self: Encoding, - comptime fmt: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, + writer: *std.io.Writer, ) !void { switch (self) { .char => try writer.writeAll("c"), @@ -133,7 +131,7 @@ pub const Encoding = union(enum) { .array => |a| { try writer.print("[{}", .{a.len}); const encode_type = init(a.arr_type); - try encode_type.format(fmt, options, writer); + try encode_type.format(writer); try writer.writeAll("]"); }, .structure => |s| { @@ -152,7 +150,7 @@ pub const Encoding = union(enum) { try writer.writeAll("="); inline for (struct_info.@"struct".fields) |field| { const field_encode = init(field.type); - try field_encode.format(fmt, options, writer); + try field_encode.format(writer); } } @@ -174,7 +172,7 @@ pub const Encoding = union(enum) { try writer.writeAll("="); inline for (union_info.@"union".fields) |field| { const field_encode = init(field.type); - try field_encode.format(fmt, options, writer); + try field_encode.format(writer); } } @@ -209,7 +207,7 @@ pub const Encoding = union(enum) { } // call this format function again, this time with the child type encoding - try encoding.format(fmt, options, writer); + try encoding.format(writer); }, else => @compileError("Pointer size not supported for encoding"), } @@ -219,10 +217,10 @@ pub const Encoding = union(enum) { // Return type is first in a method encoding const ret_type_enc = init(fn_info.return_type.?); - try ret_type_enc.format(fmt, options, writer); + try ret_type_enc.format(writer); inline for (fn_info.params) |param| { const param_enc = init(param.type.?); - try param_enc.format(fmt, options, writer); + try param_enc.format(writer); } }, .unknown => {}, @@ -249,7 +247,7 @@ fn indirectionCountAndType(comptime T: type) struct { fn encodingMatchesType(comptime T: type, expected_encoding: []const u8) !void { var buf: [200]u8 = undefined; const enc = Encoding.init(T); - const enc_string = try std.fmt.bufPrint(&buf, "{s}", .{enc}); + const enc_string = try std.fmt.bufPrint(&buf, "{f}", .{enc}); try testing.expectEqualStrings(expected_encoding, enc_string); } @@ -400,7 +398,7 @@ test "**Union to Encoding.union encoding" { test "Fn to Encoding.function encoding" { const test_fn = struct { - fn add(_: c.id, _: c.SEL, _: i8) callconv(.C) void {} + fn add(_: c.id, _: c.SEL, _: i8) callconv(.c) void {} }; try encodingMatchesType(@TypeOf(test_fn.add), "v@:c"); diff --git a/src/msg_send.zig b/src/msg_send.zig index 39fb5a9..7b5dcb2 100644 --- a/src/msg_send.zig +++ b/src/msg_send.zig @@ -65,7 +65,7 @@ pub fn MsgSend(comptime T: type) type { const msg_send_ptr: *const Fn = @ptrCast(msg_send_fn); var super: c.objc_super = .{ .receiver = target.value, - .super_class = superclass.value, + .class = superclass.value, }; const result = @call(.auto, msg_send_ptr, .{ &super, sel.value } ++ args); @@ -78,7 +78,7 @@ pub fn MsgSend(comptime T: type) type { fn msgSendPtr( comptime Return: type, comptime super: bool, - ) *const fn () callconv(.C) void { + ) *const fn () callconv(.c) void { // See objc/message.h. The high-level is that depending on the // target architecture and return type, we must use a different // objc_msgSend function. @@ -204,7 +204,7 @@ fn MsgSendFn( return @Type(.{ .@"fn" = .{ - .calling_convention = .C, + .calling_convention = .c, .is_generic = false, .is_var_args = false, .return_type = Return, @@ -218,8 +218,8 @@ test { try testing.expectEqual(fn ( c.id, c.SEL, - ) callconv(.C) u64, MsgSendFn(u64, c.id, @TypeOf(.{}))); - try testing.expectEqual(fn (c.id, c.SEL, u16, u32) callconv(.C) u64, MsgSendFn(u64, c.id, @TypeOf(.{ + ) callconv(.c) u64, MsgSendFn(u64, c.id, @TypeOf(.{}))); + try testing.expectEqual(fn (c.id, c.SEL, u16, u32) callconv(.c) u64, MsgSendFn(u64, c.id, @TypeOf(.{ @as(u16, 0), @as(u32, 0), }))); @@ -229,7 +229,7 @@ test "subClass" { const Subclass = objc.allocateClassPair(objc.getClass("NSObject").?, "subclass").?; defer objc.disposeClassPair(Subclass); const str = struct { - fn inner(target: objc.c.id, sel: objc.c.SEL) callconv(.C) objc.c.id { + fn inner(target: objc.c.id, sel: objc.c.SEL) callconv(.c) objc.c.id { _ = sel; const self = objc.Object.fromId(target); self.msgSendSuper(objc.getClass("NSObject").?, void, "init", .{});