Commit 3bb4d65b2f
Changed files (22)
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(
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;
test/link/dylib/a.c → test/link/macho/dylib/a.c
File renamed without changes
test/link/dylib/build.zig → test/link/macho/dylib/build.zig
File renamed without changes
test/link/dylib/main.c → test/link/macho/dylib/main.c
File renamed without changes
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);
+}
test/link/macho/entry/main.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int non_main() {
+ printf("%d", 42);
+ return 0;
+}
test/link/frameworks/build.zig → test/link/macho/frameworks/build.zig
File renamed without changes
test/link/frameworks/main.c → test/link/macho/frameworks/main.c
File renamed without changes
test/link/objc/build.zig → test/link/macho/objc/build.zig
File renamed without changes
test/link/objc/Foo.h → test/link/macho/objc/Foo.h
File renamed without changes
test/link/objc/Foo.m → test/link/macho/objc/Foo.m
File renamed without changes
test/link/objc/test.m → test/link/macho/objc/test.m
File renamed without changes
test/link/objcpp/build.zig → test/link/macho/objcpp/build.zig
File renamed without changes
test/link/objcpp/Foo.h → test/link/macho/objcpp/Foo.h
File renamed without changes
test/link/objcpp/Foo.mm → test/link/macho/objcpp/Foo.mm
File renamed without changes
test/link/objcpp/test.mm → test/link/macho/objcpp/test.mm
File renamed without changes
test/link/pagezero/build.zig → test/link/macho/pagezero/build.zig
File renamed without changes
test/link/pagezero/main.c → test/link/macho/pagezero/main.c
File renamed without changes
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);
+}
test/link/macho/stack_size/main.c
@@ -0,0 +1,3 @@
+int main(int argc, char* argv[]) {
+ return 0;
+}
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", .{
+ cases.addBuildFile("test/link/entry/build.zig", .{
+ .build_modes = true,
+ });
+
+ cases.addBuildFile("test/link/macho/pagezero/build.zig", .{
.build_modes = false,
});
- cases.addBuildFile("test/link/dylib/build.zig", .{
+ cases.addBuildFile("test/link/macho/dylib/build.zig", .{
.build_modes = true,
});
- cases.addBuildFile("test/link/frameworks/build.zig", .{
+ 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,
+ });
}
}