diff --git a/lib/std/build/CheckMachOStep.zig b/lib/std/build/CheckMachOStep.zig index b58cfa6e46..06e79081f5 100644 --- a/lib/std/build/CheckMachOStep.zig +++ b/lib/std/build/CheckMachOStep.zig @@ -156,6 +156,14 @@ fn dumpLoadCommand(lc: macho.LoadCommand, index: u16, writer: anytype) !void { }); }, + .MAIN => { + try writer.writeByte('\n'); + try writer.print( + \\entryoff {x} + \\stacksize {x} + , .{ lc.main.entryoff, lc.main.stacksize }); + }, + .RPATH => { try writer.writeByte('\n'); try writer.print( diff --git a/src/link/MachO.zig b/src/link/MachO.zig index aea44d9357..af84ce8846 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -934,6 +934,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{pagezero_size})); } + if (self.base.options.entry) |entry| { + try argv.append("-e"); + try argv.append(entry); + } + try argv.appendSlice(positionals.items); try argv.append("-o"); @@ -3371,13 +3376,12 @@ fn addCodeSignatureLC(self: *MachO) !void { fn setEntryPoint(self: *MachO) !void { if (self.base.options.output_mode != .Exe) return; - // TODO we should respect the -entry flag passed in by the user to set a custom - // entrypoint. For now, assume default of `_main`. const seg = self.load_commands.items[self.text_segment_cmd_index.?].segment; - const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringIndexAdapter{ + const entry_name = self.base.options.entry orelse "_main"; + const n_strx = self.strtab_dir.getKeyAdapted(entry_name, StringIndexAdapter{ .bytes = &self.strtab, }) orelse { - log.err("'_main' export not found", .{}); + log.err("entrypoint '{s}' not found", .{entry_name}); return error.MissingMainEntrypoint; }; const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; diff --git a/test/link.zig b/test/link.zig index bc69003e68..e3dcfa1ec6 100644 --- a/test/link.zig +++ b/test/link.zig @@ -28,29 +28,37 @@ pub fn addCases(cases: *tests.StandaloneContext) void { }); if (builtin.os.tag == .macos) { - cases.addBuildFile("test/link/pagezero/build.zig", .{ - .build_modes = false, - }); - - cases.addBuildFile("test/link/dylib/build.zig", .{ + cases.addBuildFile("test/link/entry/build.zig", .{ .build_modes = true, }); - cases.addBuildFile("test/link/frameworks/build.zig", .{ + cases.addBuildFile("test/link/macho/pagezero/build.zig", .{ + .build_modes = false, + }); + + cases.addBuildFile("test/link/macho/dylib/build.zig", .{ + .build_modes = true, + }); + + cases.addBuildFile("test/link/macho/frameworks/build.zig", .{ .build_modes = true, .requires_macos_sdk = true, }); // Try to build and run an Objective-C executable. - cases.addBuildFile("test/link/objc/build.zig", .{ + cases.addBuildFile("test/link/macho/objc/build.zig", .{ .build_modes = true, .requires_macos_sdk = true, }); // Try to build and run an Objective-C++ executable. - cases.addBuildFile("test/link/objcpp/build.zig", .{ + cases.addBuildFile("test/link/macho/objcpp/build.zig", .{ .build_modes = true, .requires_macos_sdk = true, }); + + cases.addBuildFile("test/link/macho/stack_size/build.zig", .{ + .build_modes = true, + }); } } diff --git a/test/link/dylib/a.c b/test/link/macho/dylib/a.c similarity index 100% rename from test/link/dylib/a.c rename to test/link/macho/dylib/a.c diff --git a/test/link/dylib/build.zig b/test/link/macho/dylib/build.zig similarity index 100% rename from test/link/dylib/build.zig rename to test/link/macho/dylib/build.zig diff --git a/test/link/dylib/main.c b/test/link/macho/dylib/main.c similarity index 100% rename from test/link/dylib/main.c rename to test/link/macho/dylib/main.c diff --git a/test/link/macho/entry/build.zig b/test/link/macho/entry/build.zig new file mode 100644 index 0000000000..24037ba8eb --- /dev/null +++ b/test/link/macho/entry/build.zig @@ -0,0 +1,25 @@ +const std = @import("std"); +const Builder = std.build.Builder; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + + const test_step = b.step("test", "Test"); + test_step.dependOn(b.getInstallStep()); + + const exe = b.addExecutable("main", null); + exe.setBuildMode(mode); + exe.addCSourceFile("main.c", &.{}); + exe.linkLibC(); + exe.entry_symbol_name = "_non_main"; + + const check_exe = exe.checkMachO(); + check_exe.check("cmd MAIN"); + check_exe.checkNext("entryoff {x}"); + + test_step.dependOn(&check_exe.step); + + const run = exe.run(); + run.expectStdOutEqual("42"); + test_step.dependOn(&run.step); +} diff --git a/test/link/macho/entry/main.c b/test/link/macho/entry/main.c new file mode 100644 index 0000000000..5fc58fc465 --- /dev/null +++ b/test/link/macho/entry/main.c @@ -0,0 +1,6 @@ +#include + +int non_main() { + printf("%d", 42); + return 0; +} diff --git a/test/link/frameworks/build.zig b/test/link/macho/frameworks/build.zig similarity index 100% rename from test/link/frameworks/build.zig rename to test/link/macho/frameworks/build.zig diff --git a/test/link/frameworks/main.c b/test/link/macho/frameworks/main.c similarity index 100% rename from test/link/frameworks/main.c rename to test/link/macho/frameworks/main.c diff --git a/test/link/objc/Foo.h b/test/link/macho/objc/Foo.h similarity index 100% rename from test/link/objc/Foo.h rename to test/link/macho/objc/Foo.h diff --git a/test/link/objc/Foo.m b/test/link/macho/objc/Foo.m similarity index 100% rename from test/link/objc/Foo.m rename to test/link/macho/objc/Foo.m diff --git a/test/link/objc/build.zig b/test/link/macho/objc/build.zig similarity index 100% rename from test/link/objc/build.zig rename to test/link/macho/objc/build.zig diff --git a/test/link/objc/test.m b/test/link/macho/objc/test.m similarity index 100% rename from test/link/objc/test.m rename to test/link/macho/objc/test.m diff --git a/test/link/objcpp/Foo.h b/test/link/macho/objcpp/Foo.h similarity index 100% rename from test/link/objcpp/Foo.h rename to test/link/macho/objcpp/Foo.h diff --git a/test/link/objcpp/Foo.mm b/test/link/macho/objcpp/Foo.mm similarity index 100% rename from test/link/objcpp/Foo.mm rename to test/link/macho/objcpp/Foo.mm diff --git a/test/link/objcpp/build.zig b/test/link/macho/objcpp/build.zig similarity index 100% rename from test/link/objcpp/build.zig rename to test/link/macho/objcpp/build.zig diff --git a/test/link/objcpp/test.mm b/test/link/macho/objcpp/test.mm similarity index 100% rename from test/link/objcpp/test.mm rename to test/link/macho/objcpp/test.mm diff --git a/test/link/pagezero/build.zig b/test/link/macho/pagezero/build.zig similarity index 100% rename from test/link/pagezero/build.zig rename to test/link/macho/pagezero/build.zig diff --git a/test/link/pagezero/main.c b/test/link/macho/pagezero/main.c similarity index 100% rename from test/link/pagezero/main.c rename to test/link/macho/pagezero/main.c diff --git a/test/link/macho/stack_size/build.zig b/test/link/macho/stack_size/build.zig new file mode 100644 index 0000000000..10b5a3f83d --- /dev/null +++ b/test/link/macho/stack_size/build.zig @@ -0,0 +1,24 @@ +const std = @import("std"); +const Builder = std.build.Builder; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + + const test_step = b.step("test", "Test"); + test_step.dependOn(b.getInstallStep()); + + const exe = b.addExecutable("main", null); + exe.setBuildMode(mode); + exe.addCSourceFile("main.c", &.{}); + exe.linkLibC(); + exe.stack_size = 0x100000000; + + const check_exe = exe.checkMachO(); + check_exe.check("cmd MAIN"); + check_exe.checkNext("stacksize 100000000"); + + test_step.dependOn(&check_exe.step); + + const run = exe.run(); + test_step.dependOn(&run.step); +} diff --git a/test/link/macho/stack_size/main.c b/test/link/macho/stack_size/main.c new file mode 100644 index 0000000000..ca68d24cc7 --- /dev/null +++ b/test/link/macho/stack_size/main.c @@ -0,0 +1,3 @@ +int main(int argc, char* argv[]) { + return 0; +}