| author | |
| committer | |
| log | 3bb4d65b2f8d7cbaf1586b85909c7e45f6b5eec2 |
| tree | 14f69c2cfe1b591b97070252a4805b57cb544a3c |
| parent | 937464f398241358c7d3e534b179dfbdfdf2ffd9 |
Handle `-e` option in MachO linker allowing the user to set a custom
entrypoint address.37 files changed, 333 insertions(+), 255 deletions(-)
lib/std/build/CheckMachOStep.zig+8| ... | @@ -156,6 +156,14 @@ fn dumpLoadCommand(lc: macho.LoadCommand, index: u16, writer: anytype) !void { | ... | @@ -156,6 +156,14 @@ fn dumpLoadCommand(lc: macho.LoadCommand, index: u16, writer: anytype) !void { |
| 156 | }); | 156 | }); |
| 157 | }, | 157 | }, |
| 158 | 158 | ||
| 159 | .MAIN => { | ||
| 160 | try writer.writeByte('\n'); | ||
| 161 | try writer.print( | ||
| 162 | \\entryoff {x} | ||
| 163 | \\stacksize {x} | ||
| 164 | , .{ lc.main.entryoff, lc.main.stacksize }); | ||
| 165 | }, | ||
| 166 | |||
| 159 | .RPATH => { | 167 | .RPATH => { |
| 160 | try writer.writeByte('\n'); | 168 | try writer.writeByte('\n'); |
| 161 | try writer.print( | 169 | try writer.print( |
src/link/MachO.zig+8-4| ... | @@ -934,6 +934,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -934,6 +934,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 934 | try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{pagezero_size})); | 934 | try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{pagezero_size})); |
| 935 | } | 935 | } |
| 936 | 936 | ||
| 937 | if (self.base.options.entry) |entry| { | ||
| 938 | try argv.append("-e"); | ||
| 939 | try argv.append(entry); | ||
| 940 | } | ||
| 941 | |||
| 937 | try argv.appendSlice(positionals.items); | 942 | try argv.appendSlice(positionals.items); |
| 938 | 943 | ||
| 939 | try argv.append("-o"); | 944 | try argv.append("-o"); |
| ... | @@ -3371,13 +3376,12 @@ fn addCodeSignatureLC(self: *MachO) !void { | ... | @@ -3371,13 +3376,12 @@ fn addCodeSignatureLC(self: *MachO) !void { |
| 3371 | fn setEntryPoint(self: *MachO) !void { | 3376 | fn setEntryPoint(self: *MachO) !void { |
| 3372 | if (self.base.options.output_mode != .Exe) return; | 3377 | if (self.base.options.output_mode != .Exe) return; |
| 3373 | 3378 | ||
| 3374 | // TODO we should respect the -entry flag passed in by the user to set a custom | ||
| 3375 | // entrypoint. For now, assume default of `_main`. | ||
| 3376 | const seg = self.load_commands.items[self.text_segment_cmd_index.?].segment; | 3379 | const seg = self.load_commands.items[self.text_segment_cmd_index.?].segment; |
| 3377 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringIndexAdapter{ | 3380 | const entry_name = self.base.options.entry orelse "_main"; |
| 3381 | const n_strx = self.strtab_dir.getKeyAdapted(entry_name, StringIndexAdapter{ | ||
| 3378 | .bytes = &self.strtab, | 3382 | .bytes = &self.strtab, |
| 3379 | }) orelse { | 3383 | }) orelse { |
| 3380 | log.err("'_main' export not found", .{}); | 3384 | log.err("entrypoint '{s}' not found", .{entry_name}); |
| 3381 | return error.MissingMainEntrypoint; | 3385 | return error.MissingMainEntrypoint; |
| 3382 | }; | 3386 | }; |
| 3383 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; | 3387 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
test/link.zig+13-5| ... | @@ -28,29 +28,37 @@ pub fn addCases(cases: *tests.StandaloneContext) void { | ... | @@ -28,29 +28,37 @@ pub fn addCases(cases: *tests.StandaloneContext) void { |
| 28 | }); | 28 | }); |
| 29 | 29 | ||
| 30 | if (builtin.os.tag == .macos) { | 30 | if (builtin.os.tag == .macos) { |
| 31 | cases.addBuildFile("test/link/pagezero/build.zig", .{ | 31 | cases.addBuildFile("test/link/entry/build.zig", .{ |
| 32 | .build_modes = true, | ||
| 33 | }); | ||
| 34 | |||
| 35 | cases.addBuildFile("test/link/macho/pagezero/build.zig", .{ | ||
| 32 | .build_modes = false, | 36 | .build_modes = false, |
| 33 | }); | 37 | }); |
| 34 | 38 | ||
| 35 | cases.addBuildFile("test/link/dylib/build.zig", .{ | 39 | cases.addBuildFile("test/link/macho/dylib/build.zig", .{ |
| 36 | .build_modes = true, | 40 | .build_modes = true, |
| 37 | }); | 41 | }); |
| 38 | 42 | ||
| 39 | cases.addBuildFile("test/link/frameworks/build.zig", .{ | 43 | cases.addBuildFile("test/link/macho/frameworks/build.zig", .{ |
| 40 | .build_modes = true, | 44 | .build_modes = true, |
| 41 | .requires_macos_sdk = true, | 45 | .requires_macos_sdk = true, |
| 42 | }); | 46 | }); |
| 43 | 47 | ||
| 44 | // Try to build and run an Objective-C executable. | 48 | // Try to build and run an Objective-C executable. |
| 45 | cases.addBuildFile("test/link/objc/build.zig", .{ | 49 | cases.addBuildFile("test/link/macho/objc/build.zig", .{ |
| 46 | .build_modes = true, | 50 | .build_modes = true, |
| 47 | .requires_macos_sdk = true, | 51 | .requires_macos_sdk = true, |
| 48 | }); | 52 | }); |
| 49 | 53 | ||
| 50 | // Try to build and run an Objective-C++ executable. | 54 | // Try to build and run an Objective-C++ executable. |
| 51 | cases.addBuildFile("test/link/objcpp/build.zig", .{ | 55 | cases.addBuildFile("test/link/macho/objcpp/build.zig", .{ |
| 52 | .build_modes = true, | 56 | .build_modes = true, |
| 53 | .requires_macos_sdk = true, | 57 | .requires_macos_sdk = true, |
| 54 | }); | 58 | }); |
| 59 | |||
| 60 | cases.addBuildFile("test/link/macho/stack_size/build.zig", .{ | ||
| 61 | .build_modes = true, | ||
| 62 | }); | ||
| 55 | } | 63 | } |
| 56 | } | 64 | } |
test/link/dylib/a.c deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | #include <stdio.h> | ||
| 2 | |||
| 3 | char world[] = "world"; | ||
| 4 | |||
| 5 | char* hello() { | ||
| 6 | return "Hello"; | ||
| 7 | } | ||
test/link/dylib/build.zig deleted-49| ... | @@ -1,49 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test"); | ||
| 8 | test_step.dependOn(b.getInstallStep()); | ||
| 9 | |||
| 10 | const dylib = b.addSharedLibrary("a", null, b.version(1, 0, 0)); | ||
| 11 | dylib.setBuildMode(mode); | ||
| 12 | dylib.addCSourceFile("a.c", &.{}); | ||
| 13 | dylib.linkLibC(); | ||
| 14 | dylib.install(); | ||
| 15 | |||
| 16 | const check_dylib = dylib.checkMachO(); | ||
| 17 | check_dylib.check("cmd ID_DYLIB"); | ||
| 18 | check_dylib.checkNext("path @rpath/liba.dylib"); | ||
| 19 | check_dylib.checkNext("timestamp 2"); | ||
| 20 | check_dylib.checkNext("current version 10000"); | ||
| 21 | check_dylib.checkNext("compatibility version 10000"); | ||
| 22 | |||
| 23 | test_step.dependOn(&check_dylib.step); | ||
| 24 | |||
| 25 | const exe = b.addExecutable("main", null); | ||
| 26 | exe.setBuildMode(mode); | ||
| 27 | exe.addCSourceFile("main.c", &.{}); | ||
| 28 | exe.linkSystemLibrary("a"); | ||
| 29 | exe.linkLibC(); | ||
| 30 | exe.addLibraryPath(b.pathFromRoot("zig-out/lib/")); | ||
| 31 | exe.addRPath(b.pathFromRoot("zig-out/lib")); | ||
| 32 | |||
| 33 | const check_exe = exe.checkMachO(); | ||
| 34 | check_exe.check("cmd LOAD_DYLIB"); | ||
| 35 | check_exe.checkNext("path @rpath/liba.dylib"); | ||
| 36 | check_exe.checkNext("timestamp 2"); | ||
| 37 | check_exe.checkNext("current version 10000"); | ||
| 38 | check_exe.checkNext("compatibility version 10000"); | ||
| 39 | |||
| 40 | check_exe.check("cmd RPATH"); | ||
| 41 | check_exe.checkNext(std.fmt.allocPrint(b.allocator, "path {s}", .{b.pathFromRoot("zig-out/lib")}) catch unreachable); | ||
| 42 | |||
| 43 | test_step.dependOn(&check_exe.step); | ||
| 44 | |||
| 45 | const run = exe.run(); | ||
| 46 | run.cwd = b.pathFromRoot("."); | ||
| 47 | run.expectStdOutEqual("Hello world"); | ||
| 48 | test_step.dependOn(&run.step); | ||
| 49 | } | ||
test/link/dylib/main.c deleted-9| ... | @@ -1,9 +0,0 @@ | ||
| 1 | #include <stdio.h> | ||
| 2 | |||
| 3 | char* hello(); | ||
| 4 | extern char world[]; | ||
| 5 | |||
| 6 | int main() { | ||
| 7 | printf("%s %s", hello(), world); | ||
| 8 | return 0; | ||
| 9 | } | ||
test/link/frameworks/build.zig deleted-20| ... | @@ -1,20 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test the program"); | ||
| 8 | |||
| 9 | const exe = b.addExecutable("test", null); | ||
| 10 | b.default_step.dependOn(&exe.step); | ||
| 11 | exe.addCSourceFile("main.c", &[0][]const u8{}); | ||
| 12 | exe.setBuildMode(mode); | ||
| 13 | exe.linkLibC(); | ||
| 14 | // TODO when we figure out how to ship framework stubs for cross-compilation, | ||
| 15 | // populate paths to the sysroot here. | ||
| 16 | exe.linkFramework("Cocoa"); | ||
| 17 | |||
| 18 | const run_cmd = exe.run(); | ||
| 19 | test_step.dependOn(&run_cmd.step); | ||
| 20 | } | ||
test/link/frameworks/main.c deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | #include <assert.h> | ||
| 2 | #include <objc/runtime.h> | ||
| 3 | |||
| 4 | int main() { | ||
| 5 | assert(objc_getClass("NSObject") > 0); | ||
| 6 | assert(objc_getClass("NSApplication") > 0); | ||
| 7 | } | ||
test/link/macho/dylib/a.c created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | #include <stdio.h> | ||
| 2 | |||
| 3 | char world[] = "world"; | ||
| 4 | |||
| 5 | char* hello() { | ||
| 6 | return "Hello"; | ||
| 7 | } | ||
test/link/macho/dylib/build.zig created+49| ... | @@ -0,0 +1,49 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test"); | ||
| 8 | test_step.dependOn(b.getInstallStep()); | ||
| 9 | |||
| 10 | const dylib = b.addSharedLibrary("a", null, b.version(1, 0, 0)); | ||
| 11 | dylib.setBuildMode(mode); | ||
| 12 | dylib.addCSourceFile("a.c", &.{}); | ||
| 13 | dylib.linkLibC(); | ||
| 14 | dylib.install(); | ||
| 15 | |||
| 16 | const check_dylib = dylib.checkMachO(); | ||
| 17 | check_dylib.check("cmd ID_DYLIB"); | ||
| 18 | check_dylib.checkNext("path @rpath/liba.dylib"); | ||
| 19 | check_dylib.checkNext("timestamp 2"); | ||
| 20 | check_dylib.checkNext("current version 10000"); | ||
| 21 | check_dylib.checkNext("compatibility version 10000"); | ||
| 22 | |||
| 23 | test_step.dependOn(&check_dylib.step); | ||
| 24 | |||
| 25 | const exe = b.addExecutable("main", null); | ||
| 26 | exe.setBuildMode(mode); | ||
| 27 | exe.addCSourceFile("main.c", &.{}); | ||
| 28 | exe.linkSystemLibrary("a"); | ||
| 29 | exe.linkLibC(); | ||
| 30 | exe.addLibraryPath(b.pathFromRoot("zig-out/lib/")); | ||
| 31 | exe.addRPath(b.pathFromRoot("zig-out/lib")); | ||
| 32 | |||
| 33 | const check_exe = exe.checkMachO(); | ||
| 34 | check_exe.check("cmd LOAD_DYLIB"); | ||
| 35 | check_exe.checkNext("path @rpath/liba.dylib"); | ||
| 36 | check_exe.checkNext("timestamp 2"); | ||
| 37 | check_exe.checkNext("current version 10000"); | ||
| 38 | check_exe.checkNext("compatibility version 10000"); | ||
| 39 | |||
| 40 | check_exe.check("cmd RPATH"); | ||
| 41 | check_exe.checkNext(std.fmt.allocPrint(b.allocator, "path {s}", .{b.pathFromRoot("zig-out/lib")}) catch unreachable); | ||
| 42 | |||
| 43 | test_step.dependOn(&check_exe.step); | ||
| 44 | |||
| 45 | const run = exe.run(); | ||
| 46 | run.cwd = b.pathFromRoot("."); | ||
| 47 | run.expectStdOutEqual("Hello world"); | ||
| 48 | test_step.dependOn(&run.step); | ||
| 49 | } | ||
test/link/macho/dylib/main.c created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | #include <stdio.h> | ||
| 2 | |||
| 3 | char* hello(); | ||
| 4 | extern char world[]; | ||
| 5 | |||
| 6 | int main() { | ||
| 7 | printf("%s %s", hello(), world); | ||
| 8 | return 0; | ||
| 9 | } | ||
test/link/macho/entry/build.zig created+25| ... | @@ -0,0 +1,25 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test"); | ||
| 8 | test_step.dependOn(b.getInstallStep()); | ||
| 9 | |||
| 10 | const exe = b.addExecutable("main", null); | ||
| 11 | exe.setBuildMode(mode); | ||
| 12 | exe.addCSourceFile("main.c", &.{}); | ||
| 13 | exe.linkLibC(); | ||
| 14 | exe.entry_symbol_name = "_non_main"; | ||
| 15 | |||
| 16 | const check_exe = exe.checkMachO(); | ||
| 17 | check_exe.check("cmd MAIN"); | ||
| 18 | check_exe.checkNext("entryoff {x}"); | ||
| 19 | |||
| 20 | test_step.dependOn(&check_exe.step); | ||
| 21 | |||
| 22 | const run = exe.run(); | ||
| 23 | run.expectStdOutEqual("42"); | ||
| 24 | test_step.dependOn(&run.step); | ||
| 25 | } | ||
test/link/macho/entry/main.c created+6| ... | @@ -0,0 +1,6 @@ | ||
| 1 | #include <stdio.h> | ||
| 2 | |||
| 3 | int non_main() { | ||
| 4 | printf("%d", 42); | ||
| 5 | return 0; | ||
| 6 | } | ||
test/link/macho/frameworks/build.zig created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test the program"); | ||
| 8 | |||
| 9 | const exe = b.addExecutable("test", null); | ||
| 10 | b.default_step.dependOn(&exe.step); | ||
| 11 | exe.addCSourceFile("main.c", &[0][]const u8{}); | ||
| 12 | exe.setBuildMode(mode); | ||
| 13 | exe.linkLibC(); | ||
| 14 | // TODO when we figure out how to ship framework stubs for cross-compilation, | ||
| 15 | // populate paths to the sysroot here. | ||
| 16 | exe.linkFramework("Cocoa"); | ||
| 17 | |||
| 18 | const run_cmd = exe.run(); | ||
| 19 | test_step.dependOn(&run_cmd.step); | ||
| 20 | } | ||
test/link/macho/frameworks/main.c created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | #include <assert.h> | ||
| 2 | #include <objc/runtime.h> | ||
| 3 | |||
| 4 | int main() { | ||
| 5 | assert(objc_getClass("NSObject") > 0); | ||
| 6 | assert(objc_getClass("NSApplication") > 0); | ||
| 7 | } | ||
test/link/macho/objc/Foo.h created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | #import <Foundation/Foundation.h> | ||
| 2 | |||
| 3 | @interface Foo : NSObject | ||
| 4 | |||
| 5 | - (NSString *)name; | ||
| 6 | |||
| 7 | @end | ||
test/link/macho/objc/Foo.m created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | #import "Foo.h" | ||
| 2 | |||
| 3 | @implementation Foo | ||
| 4 | |||
| 5 | - (NSString *)name | ||
| 6 | { | ||
| 7 | NSString *str = [[NSString alloc] initWithFormat:@"Zig"]; | ||
| 8 | return str; | ||
| 9 | } | ||
| 10 | |||
| 11 | @end | ||
test/link/macho/objc/build.zig created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test the program"); | ||
| 8 | |||
| 9 | const exe = b.addExecutable("test", null); | ||
| 10 | b.default_step.dependOn(&exe.step); | ||
| 11 | exe.addIncludePath("."); | ||
| 12 | exe.addCSourceFile("Foo.m", &[0][]const u8{}); | ||
| 13 | exe.addCSourceFile("test.m", &[0][]const u8{}); | ||
| 14 | exe.setBuildMode(mode); | ||
| 15 | exe.linkLibC(); | ||
| 16 | // TODO when we figure out how to ship framework stubs for cross-compilation, | ||
| 17 | // populate paths to the sysroot here. | ||
| 18 | exe.linkFramework("Foundation"); | ||
| 19 | |||
| 20 | const run_cmd = exe.run(); | ||
| 21 | test_step.dependOn(&run_cmd.step); | ||
| 22 | } | ||
test/link/macho/objc/test.m created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | #import "Foo.h" | ||
| 2 | #import <assert.h> | ||
| 3 | |||
| 4 | int main(int argc, char *argv[]) | ||
| 5 | { | ||
| 6 | @autoreleasepool { | ||
| 7 | Foo *foo = [[Foo alloc] init]; | ||
| 8 | NSString *result = [foo name]; | ||
| 9 | assert([result isEqualToString:@"Zig"]); | ||
| 10 | return 0; | ||
| 11 | } | ||
| 12 | } | ||
test/link/macho/objcpp/Foo.h created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | #import <Foundation/Foundation.h> | ||
| 2 | |||
| 3 | @interface Foo : NSObject | ||
| 4 | |||
| 5 | - (NSString *)name; | ||
| 6 | |||
| 7 | @end | ||
test/link/macho/objcpp/Foo.mm created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | #import "Foo.h" | ||
| 2 | |||
| 3 | @implementation Foo | ||
| 4 | |||
| 5 | - (NSString *)name | ||
| 6 | { | ||
| 7 | NSString *str = [[NSString alloc] initWithFormat:@"Zig"]; | ||
| 8 | return str; | ||
| 9 | } | ||
| 10 | |||
| 11 | @end | ||
test/link/macho/objcpp/build.zig created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test the program"); | ||
| 8 | |||
| 9 | const exe = b.addExecutable("test", null); | ||
| 10 | b.default_step.dependOn(&exe.step); | ||
| 11 | exe.addIncludePath("."); | ||
| 12 | exe.addCSourceFile("Foo.mm", &[0][]const u8{}); | ||
| 13 | exe.addCSourceFile("test.mm", &[0][]const u8{}); | ||
| 14 | exe.setBuildMode(mode); | ||
| 15 | exe.linkLibCpp(); | ||
| 16 | // TODO when we figure out how to ship framework stubs for cross-compilation, | ||
| 17 | // populate paths to the sysroot here. | ||
| 18 | exe.linkFramework("Foundation"); | ||
| 19 | |||
| 20 | const run_cmd = exe.run(); | ||
| 21 | run_cmd.expectStdOutEqual("Hello from C++ and Zig"); | ||
| 22 | |||
| 23 | test_step.dependOn(&run_cmd.step); | ||
| 24 | } | ||
test/link/macho/objcpp/test.mm created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | #import "Foo.h" | ||
| 2 | #import <assert.h> | ||
| 3 | #include <iostream> | ||
| 4 | |||
| 5 | int main(int argc, char *argv[]) | ||
| 6 | { | ||
| 7 | @autoreleasepool { | ||
| 8 | Foo *foo = [[Foo alloc] init]; | ||
| 9 | NSString *result = [foo name]; | ||
| 10 | std::cout << "Hello from C++ and " << [result UTF8String]; | ||
| 11 | assert([result isEqualToString:@"Zig"]); | ||
| 12 | return 0; | ||
| 13 | } | ||
| 14 | } | ||
test/link/macho/pagezero/build.zig created+43| ... | @@ -0,0 +1,43 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test"); | ||
| 8 | test_step.dependOn(b.getInstallStep()); | ||
| 9 | |||
| 10 | { | ||
| 11 | const exe = b.addExecutable("pagezero", null); | ||
| 12 | exe.setBuildMode(mode); | ||
| 13 | exe.addCSourceFile("main.c", &.{}); | ||
| 14 | exe.linkLibC(); | ||
| 15 | exe.pagezero_size = 0x4000; | ||
| 16 | |||
| 17 | const check = exe.checkMachO(); | ||
| 18 | check.check("LC 0"); | ||
| 19 | check.checkNext("segname __PAGEZERO"); | ||
| 20 | check.checkNext("vmaddr 0"); | ||
| 21 | check.checkNext("vmsize 4000"); | ||
| 22 | |||
| 23 | check.check("segname __TEXT"); | ||
| 24 | check.checkNext("vmaddr 4000"); | ||
| 25 | |||
| 26 | test_step.dependOn(&check.step); | ||
| 27 | } | ||
| 28 | |||
| 29 | { | ||
| 30 | const exe = b.addExecutable("no_pagezero", null); | ||
| 31 | exe.setBuildMode(mode); | ||
| 32 | exe.addCSourceFile("main.c", &.{}); | ||
| 33 | exe.linkLibC(); | ||
| 34 | exe.pagezero_size = 0; | ||
| 35 | |||
| 36 | const check = exe.checkMachO(); | ||
| 37 | check.check("LC 0"); | ||
| 38 | check.checkNext("segname __TEXT"); | ||
| 39 | check.checkNext("vmaddr 0"); | ||
| 40 | |||
| 41 | test_step.dependOn(&check.step); | ||
| 42 | } | ||
| 43 | } | ||
test/link/macho/pagezero/main.c created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | int main(int argc, char* argv[]) { | ||
| 2 | return 0; | ||
| 3 | } | ||
test/link/macho/stack_size/build.zig created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test"); | ||
| 8 | test_step.dependOn(b.getInstallStep()); | ||
| 9 | |||
| 10 | const exe = b.addExecutable("main", null); | ||
| 11 | exe.setBuildMode(mode); | ||
| 12 | exe.addCSourceFile("main.c", &.{}); | ||
| 13 | exe.linkLibC(); | ||
| 14 | exe.stack_size = 0x100000000; | ||
| 15 | |||
| 16 | const check_exe = exe.checkMachO(); | ||
| 17 | check_exe.check("cmd MAIN"); | ||
| 18 | check_exe.checkNext("stacksize 100000000"); | ||
| 19 | |||
| 20 | test_step.dependOn(&check_exe.step); | ||
| 21 | |||
| 22 | const run = exe.run(); | ||
| 23 | test_step.dependOn(&run.step); | ||
| 24 | } | ||
test/link/macho/stack_size/main.c created+3| ... | @@ -0,0 +1,3 @@ | ||
| 1 | int main(int argc, char* argv[]) { | ||
| 2 | return 0; | ||
| 3 | } | ||
test/link/objc/Foo.h deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | #import <Foundation/Foundation.h> | ||
| 2 | |||
| 3 | @interface Foo : NSObject | ||
| 4 | |||
| 5 | - (NSString *)name; | ||
| 6 | |||
| 7 | @end | ||
test/link/objc/Foo.m deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | #import "Foo.h" | ||
| 2 | |||
| 3 | @implementation Foo | ||
| 4 | |||
| 5 | - (NSString *)name | ||
| 6 | { | ||
| 7 | NSString *str = [[NSString alloc] initWithFormat:@"Zig"]; | ||
| 8 | return str; | ||
| 9 | } | ||
| 10 | |||
| 11 | @end | ||
test/link/objc/build.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test the program"); | ||
| 8 | |||
| 9 | const exe = b.addExecutable("test", null); | ||
| 10 | b.default_step.dependOn(&exe.step); | ||
| 11 | exe.addIncludePath("."); | ||
| 12 | exe.addCSourceFile("Foo.m", &[0][]const u8{}); | ||
| 13 | exe.addCSourceFile("test.m", &[0][]const u8{}); | ||
| 14 | exe.setBuildMode(mode); | ||
| 15 | exe.linkLibC(); | ||
| 16 | // TODO when we figure out how to ship framework stubs for cross-compilation, | ||
| 17 | // populate paths to the sysroot here. | ||
| 18 | exe.linkFramework("Foundation"); | ||
| 19 | |||
| 20 | const run_cmd = exe.run(); | ||
| 21 | test_step.dependOn(&run_cmd.step); | ||
| 22 | } | ||
test/link/objc/test.m deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | #import "Foo.h" | ||
| 2 | #import <assert.h> | ||
| 3 | |||
| 4 | int main(int argc, char *argv[]) | ||
| 5 | { | ||
| 6 | @autoreleasepool { | ||
| 7 | Foo *foo = [[Foo alloc] init]; | ||
| 8 | NSString *result = [foo name]; | ||
| 9 | assert([result isEqualToString:@"Zig"]); | ||
| 10 | return 0; | ||
| 11 | } | ||
| 12 | } | ||
test/link/objcpp/Foo.h deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | #import <Foundation/Foundation.h> | ||
| 2 | |||
| 3 | @interface Foo : NSObject | ||
| 4 | |||
| 5 | - (NSString *)name; | ||
| 6 | |||
| 7 | @end | ||
test/link/objcpp/Foo.mm deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | #import "Foo.h" | ||
| 2 | |||
| 3 | @implementation Foo | ||
| 4 | |||
| 5 | - (NSString *)name | ||
| 6 | { | ||
| 7 | NSString *str = [[NSString alloc] initWithFormat:@"Zig"]; | ||
| 8 | return str; | ||
| 9 | } | ||
| 10 | |||
| 11 | @end | ||
test/link/objcpp/build.zig deleted-24| ... | @@ -1,24 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test the program"); | ||
| 8 | |||
| 9 | const exe = b.addExecutable("test", null); | ||
| 10 | b.default_step.dependOn(&exe.step); | ||
| 11 | exe.addIncludePath("."); | ||
| 12 | exe.addCSourceFile("Foo.mm", &[0][]const u8{}); | ||
| 13 | exe.addCSourceFile("test.mm", &[0][]const u8{}); | ||
| 14 | exe.setBuildMode(mode); | ||
| 15 | exe.linkLibCpp(); | ||
| 16 | // TODO when we figure out how to ship framework stubs for cross-compilation, | ||
| 17 | // populate paths to the sysroot here. | ||
| 18 | exe.linkFramework("Foundation"); | ||
| 19 | |||
| 20 | const run_cmd = exe.run(); | ||
| 21 | run_cmd.expectStdOutEqual("Hello from C++ and Zig"); | ||
| 22 | |||
| 23 | test_step.dependOn(&run_cmd.step); | ||
| 24 | } | ||
test/link/objcpp/test.mm deleted-14| ... | @@ -1,14 +0,0 @@ | ||
| 1 | #import "Foo.h" | ||
| 2 | #import <assert.h> | ||
| 3 | #include <iostream> | ||
| 4 | |||
| 5 | int main(int argc, char *argv[]) | ||
| 6 | { | ||
| 7 | @autoreleasepool { | ||
| 8 | Foo *foo = [[Foo alloc] init]; | ||
| 9 | NSString *result = [foo name]; | ||
| 10 | std::cout << "Hello from C++ and " << [result UTF8String]; | ||
| 11 | assert([result isEqualToString:@"Zig"]); | ||
| 12 | return 0; | ||
| 13 | } | ||
| 14 | } | ||
test/link/pagezero/build.zig deleted-43| ... | @@ -1,43 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const Builder = std.build.Builder; | ||
| 3 | |||
| 4 | pub fn build(b: *Builder) void { | ||
| 5 | const mode = b.standardReleaseOptions(); | ||
| 6 | |||
| 7 | const test_step = b.step("test", "Test"); | ||
| 8 | test_step.dependOn(b.getInstallStep()); | ||
| 9 | |||
| 10 | { | ||
| 11 | const exe = b.addExecutable("pagezero", null); | ||
| 12 | exe.setBuildMode(mode); | ||
| 13 | exe.addCSourceFile("main.c", &.{}); | ||
| 14 | exe.linkLibC(); | ||
| 15 | exe.pagezero_size = 0x4000; | ||
| 16 | |||
| 17 | const check = exe.checkMachO(); | ||
| 18 | check.check("LC 0"); | ||
| 19 | check.checkNext("segname __PAGEZERO"); | ||
| 20 | check.checkNext("vmaddr 0"); | ||
| 21 | check.checkNext("vmsize 4000"); | ||
| 22 | |||
| 23 | check.check("segname __TEXT"); | ||
| 24 | check.checkNext("vmaddr 4000"); | ||
| 25 | |||
| 26 | test_step.dependOn(&check.step); | ||
| 27 | } | ||
| 28 | |||
| 29 | { | ||
| 30 | const exe = b.addExecutable("no_pagezero", null); | ||
| 31 | exe.setBuildMode(mode); | ||
| 32 | exe.addCSourceFile("main.c", &.{}); | ||
| 33 | exe.linkLibC(); | ||
| 34 | exe.pagezero_size = 0; | ||
| 35 | |||
| 36 | const check = exe.checkMachO(); | ||
| 37 | check.check("LC 0"); | ||
| 38 | check.checkNext("segname __TEXT"); | ||
| 39 | check.checkNext("vmaddr 0"); | ||
| 40 | |||
| 41 | test_step.dependOn(&check.step); | ||
| 42 | } | ||
| 43 | } | ||
test/link/pagezero/main.c deleted-3| ... | @@ -1,3 +0,0 @@ | ||
| 1 | int main(int argc, char* argv[]) { | ||
| 2 | return 0; | ||
| 3 | } | ||