mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
test/link/macho: migrate all tests to the new test matrix
This commit is contained in:
parent
2b3ac3e82f
commit
03b33b0f01
@ -89,30 +89,4 @@ pub const cases = [_]Case{
|
||||
.build_root = "test/link/wasm/type",
|
||||
.import = @import("link/wasm/type/build.zig"),
|
||||
},
|
||||
|
||||
// Mach-O Cases
|
||||
.{
|
||||
.build_root = "test/link/macho/bugs/13056",
|
||||
.import = @import("link/macho/bugs/13056/build.zig"),
|
||||
},
|
||||
.{
|
||||
.build_root = "test/link/macho/bugs/13457",
|
||||
.import = @import("link/macho/bugs/13457/build.zig"),
|
||||
},
|
||||
.{
|
||||
.build_root = "test/link/macho/bugs/16308",
|
||||
.import = @import("link/macho/bugs/16308/build.zig"),
|
||||
},
|
||||
.{
|
||||
.build_root = "test/link/macho/bugs/16628",
|
||||
.import = @import("link/macho/bugs/16628/build.zig"),
|
||||
},
|
||||
.{
|
||||
.build_root = "test/link/macho/linksection",
|
||||
.import = @import("link/macho/linksection/build.zig"),
|
||||
},
|
||||
.{
|
||||
.build_root = "test/link/macho/objcpp",
|
||||
.import = @import("link/macho/objcpp/build.zig"),
|
||||
},
|
||||
};
|
||||
|
||||
@ -48,6 +48,8 @@ const OverlayOptions = struct {
|
||||
cpp_source_flags: []const []const u8 = &.{},
|
||||
objc_source_bytes: ?[]const u8 = null,
|
||||
objc_source_flags: []const []const u8 = &.{},
|
||||
objcpp_source_bytes: ?[]const u8 = null,
|
||||
objcpp_source_flags: []const []const u8 = &.{},
|
||||
zig_source_bytes: ?[]const u8 = null,
|
||||
pic: ?bool = null,
|
||||
strip: ?bool = null,
|
||||
@ -100,6 +102,12 @@ fn addCompileStep(
|
||||
.static_lib => .static,
|
||||
},
|
||||
});
|
||||
if (overlay.objcpp_source_bytes) |bytes| {
|
||||
compile_step.addCSourceFile(.{
|
||||
.file = b.addWriteFiles().add("a.mm", bytes),
|
||||
.flags = overlay.objcpp_source_flags,
|
||||
});
|
||||
}
|
||||
if (overlay.objc_source_bytes) |bytes| {
|
||||
compile_step.addCSourceFile(.{
|
||||
.file = b.addWriteFiles().add("a.m", bytes),
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
//! Here we test our MachO linker for correctness and functionality.
|
||||
//! TODO migrate standalone tests from test/link/macho/* to here.
|
||||
|
||||
pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
|
||||
const macho_step = b.step("test-macho", "Run MachO tests");
|
||||
@ -18,12 +17,14 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
|
||||
|
||||
macho_step.dependOn(testDeadStrip(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testEmptyObject(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testEmptyZig(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testEntryPoint(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testHeaderWeakFlags(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testHelloC(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testHelloZig(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testLargeBss(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testLayout(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testLinksection(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testMhExecuteHeader(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testNoDeadStrip(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testNoExportsDylib(b, .{ .target = default_target }));
|
||||
@ -59,8 +60,10 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
|
||||
if (build_opts.has_macos_sdk) {
|
||||
macho_step.dependOn(testDeadStripDylibs(b, .{ .target = b.host }));
|
||||
macho_step.dependOn(testHeaderpad(b, .{ .target = b.host }));
|
||||
macho_step.dependOn(testLinkDirectlyCppTbd(b, .{ .target = b.host }));
|
||||
macho_step.dependOn(testNeededFramework(b, .{ .target = b.host }));
|
||||
macho_step.dependOn(testObjc(b, .{ .target = b.host }));
|
||||
macho_step.dependOn(testObjcpp(b, .{ .target = b.host }));
|
||||
macho_step.dependOn(testWeakFramework(b, .{ .target = b.host }));
|
||||
}
|
||||
}
|
||||
@ -255,6 +258,18 @@ fn testEmptyObject(b: *Build, opts: Options) *Step {
|
||||
return test_step;
|
||||
}
|
||||
|
||||
fn testEmptyZig(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "macho-empty-zig", opts);
|
||||
|
||||
const exe = addExecutable(b, opts, .{ .name = "empty", .zig_source_bytes = "pub fn main() void {}" });
|
||||
|
||||
const run = addRunArtifact(exe);
|
||||
run.expectExitCode(0);
|
||||
test_step.dependOn(&run.step);
|
||||
|
||||
return test_step;
|
||||
}
|
||||
|
||||
fn testEntryPoint(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "macho-entry-point", opts);
|
||||
|
||||
@ -745,6 +760,65 @@ fn testLayout(b: *Build, opts: Options) *Step {
|
||||
return test_step;
|
||||
}
|
||||
|
||||
fn testLinkDirectlyCppTbd(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "macho-link-directly-cpp-tbd", opts);
|
||||
|
||||
const sdk = std.zig.system.darwin.getSdk(b.allocator, opts.target.result) orelse
|
||||
@panic("macOS SDK is required to run the test");
|
||||
|
||||
const exe = addExecutable(b, opts, .{
|
||||
.name = "main",
|
||||
.cpp_source_bytes =
|
||||
\\#include <new>
|
||||
\\#include <cstdio>
|
||||
\\int main() {
|
||||
\\ int *x = new int;
|
||||
\\ *x = 5;
|
||||
\\ fprintf(stderr, "x: %d\n", *x);
|
||||
\\ delete x;
|
||||
\\}
|
||||
,
|
||||
.cpp_source_flags = &.{ "-nostdlib++", "-nostdinc++" },
|
||||
});
|
||||
exe.root_module.addSystemIncludePath(.{ .path = b.pathJoin(&.{ sdk, "/usr/include" }) });
|
||||
exe.root_module.addIncludePath(.{ .path = b.pathJoin(&.{ sdk, "/usr/include/c++/v1" }) });
|
||||
exe.root_module.addObjectFile(.{ .path = b.pathJoin(&.{ sdk, "/usr/lib/libc++.tbd" }) });
|
||||
|
||||
const check = exe.checkObject();
|
||||
check.checkInSymtab();
|
||||
check.checkContains("[referenced dynamically] external __mh_execute_header");
|
||||
test_step.dependOn(&check.step);
|
||||
|
||||
return test_step;
|
||||
}
|
||||
|
||||
fn testLinksection(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "macho-linksection", opts);
|
||||
|
||||
const obj = addObject(b, opts, .{ .name = "main", .zig_source_bytes =
|
||||
\\export var test_global: u32 linksection("__DATA,__TestGlobal") = undefined;
|
||||
\\export fn testFn() linksection("__TEXT,__TestFn") callconv(.C) void {
|
||||
\\ testGenericFn("A");
|
||||
\\}
|
||||
\\fn testGenericFn(comptime suffix: []const u8) linksection("__TEXT,__TestGenFn" ++ suffix) void {}
|
||||
});
|
||||
|
||||
const check = obj.checkObject();
|
||||
check.checkInSymtab();
|
||||
check.checkContains("(__DATA,__TestGlobal) external _test_global");
|
||||
check.checkInSymtab();
|
||||
check.checkContains("(__TEXT,__TestFn) external _testFn");
|
||||
|
||||
if (opts.optimize == .Debug) {
|
||||
check.checkInSymtab();
|
||||
check.checkContains("(__TEXT,__TestGenFnA) _a.testGenericFn__anon_");
|
||||
}
|
||||
|
||||
test_step.dependOn(&check.step);
|
||||
|
||||
return test_step;
|
||||
}
|
||||
|
||||
fn testMhExecuteHeader(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "macho-mh-execute-header", opts);
|
||||
|
||||
@ -870,6 +944,59 @@ fn testObjc(b: *Build, opts: Options) *Step {
|
||||
return test_step;
|
||||
}
|
||||
|
||||
fn testObjcpp(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "macho-objcpp", opts);
|
||||
|
||||
const foo_h = foo_h: {
|
||||
const wf = WriteFile.create(b);
|
||||
break :foo_h wf.add("Foo.h",
|
||||
\\#import <Foundation/Foundation.h>
|
||||
\\@interface Foo : NSObject
|
||||
\\- (NSString *)name;
|
||||
\\@end
|
||||
);
|
||||
};
|
||||
|
||||
const foo_o = addObject(b, opts, .{ .name = "foo", .objcpp_source_bytes =
|
||||
\\#import "Foo.h"
|
||||
\\@implementation Foo
|
||||
\\- (NSString *)name
|
||||
\\{
|
||||
\\ NSString *str = [[NSString alloc] initWithFormat:@"Zig"];
|
||||
\\ return str;
|
||||
\\}
|
||||
\\@end
|
||||
});
|
||||
foo_o.root_module.addIncludePath(foo_h.dirname());
|
||||
foo_o.linkLibCpp();
|
||||
|
||||
const exe = addExecutable(b, opts, .{ .name = "main", .objcpp_source_bytes =
|
||||
\\#import "Foo.h"
|
||||
\\#import <assert.h>
|
||||
\\#include <iostream>
|
||||
\\int main(int argc, char *argv[])
|
||||
\\{
|
||||
\\ @autoreleasepool {
|
||||
\\ Foo *foo = [[Foo alloc] init];
|
||||
\\ NSString *result = [foo name];
|
||||
\\ std::cout << "Hello from C++ and " << [result UTF8String];
|
||||
\\ assert([result isEqualToString:@"Zig"]);
|
||||
\\ return 0;
|
||||
\\ }
|
||||
\\}
|
||||
});
|
||||
exe.root_module.addIncludePath(foo_h.dirname());
|
||||
exe.addObject(foo_o);
|
||||
exe.linkLibCpp();
|
||||
exe.root_module.linkFramework("Foundation", .{});
|
||||
|
||||
const run = addRunArtifact(exe);
|
||||
run.expectStdOutEqual("Hello from C++ and Zig");
|
||||
test_step.dependOn(&run.step);
|
||||
|
||||
return test_step;
|
||||
}
|
||||
|
||||
fn testPagezeroSize(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "macho-pagezero-size", opts);
|
||||
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const requires_macos_sdk = true;
|
||||
pub const requires_symlinks = true;
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const test_step = b.step("test", "Test it");
|
||||
b.default_step = test_step;
|
||||
|
||||
add(b, test_step, .Debug);
|
||||
add(b, test_step, .ReleaseFast);
|
||||
add(b, test_step, .ReleaseSmall);
|
||||
add(b, test_step, .ReleaseSafe);
|
||||
}
|
||||
|
||||
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
|
||||
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
|
||||
const sdk = std.zig.system.darwin.getSdk(b.allocator, target.result) orelse
|
||||
@panic("macOS SDK is required to run the test");
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "test",
|
||||
.optimize = optimize,
|
||||
.target = b.host,
|
||||
});
|
||||
exe.addSystemIncludePath(.{ .path = b.pathJoin(&.{ sdk, "/usr/include" }) });
|
||||
exe.addIncludePath(.{ .path = b.pathJoin(&.{ sdk, "/usr/include/c++/v1" }) });
|
||||
exe.addCSourceFile(.{ .file = .{ .path = "test.cpp" }, .flags = &.{
|
||||
"-nostdlib++",
|
||||
"-nostdinc++",
|
||||
} });
|
||||
exe.addObjectFile(.{ .path = b.pathJoin(&.{ sdk, "/usr/lib/libc++.tbd" }) });
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.expectStdErrEqual("x: 5\n");
|
||||
|
||||
test_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
// test.cpp
|
||||
#include <new>
|
||||
#include <cstdio>
|
||||
|
||||
int main() {
|
||||
int *x = new int;
|
||||
*x = 5;
|
||||
fprintf(stderr, "x: %d\n", *x);
|
||||
delete x;
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const requires_symlinks = true;
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const test_step = b.step("test", "Test it");
|
||||
b.default_step = test_step;
|
||||
|
||||
add(b, test_step, .Debug);
|
||||
add(b, test_step, .ReleaseFast);
|
||||
add(b, test_step, .ReleaseSmall);
|
||||
add(b, test_step, .ReleaseSafe);
|
||||
}
|
||||
|
||||
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
|
||||
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "test",
|
||||
.root_source_file = .{ .path = "main.zig" },
|
||||
.optimize = optimize,
|
||||
.target = target,
|
||||
});
|
||||
|
||||
const run = b.addRunArtifact(exe);
|
||||
run.skip_foreign_checks = true;
|
||||
run.expectStdOutEqual("");
|
||||
|
||||
test_step.dependOn(&run.step);
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
pub fn main() void {}
|
||||
@ -1,23 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const requires_symlinks = true;
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const test_step = b.step("test", "Test it");
|
||||
b.default_step = test_step;
|
||||
|
||||
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
|
||||
|
||||
const lib = b.addSharedLibrary(.{
|
||||
.name = "a",
|
||||
.root_source_file = .{ .path = "main.zig" },
|
||||
.optimize = .Debug,
|
||||
.target = target,
|
||||
});
|
||||
|
||||
const check = lib.checkObject();
|
||||
check.checkInSymtab();
|
||||
check.checkNotPresent("external _abc");
|
||||
|
||||
test_step.dependOn(&check.step);
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
fn abc() void {}
|
||||
@ -1,37 +0,0 @@
|
||||
.globl _foo
|
||||
.align 4
|
||||
_foo:
|
||||
.cfi_startproc
|
||||
stp x29, x30, [sp, #-32]!
|
||||
.cfi_def_cfa_offset 32
|
||||
.cfi_offset w30, -24
|
||||
.cfi_offset w29, -32
|
||||
mov x29, sp
|
||||
.cfi_def_cfa w29, 32
|
||||
bl _bar
|
||||
ldp x29, x30, [sp], #32
|
||||
.cfi_restore w29
|
||||
.cfi_restore w30
|
||||
.cfi_def_cfa_offset 0
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
||||
.globl _bar
|
||||
.align 4
|
||||
_bar:
|
||||
.cfi_startproc
|
||||
sub sp, sp, #32
|
||||
.cfi_def_cfa_offset -32
|
||||
stp x29, x30, [sp, #16]
|
||||
.cfi_offset w30, -24
|
||||
.cfi_offset w29, -32
|
||||
mov x29, sp
|
||||
.cfi_def_cfa w29, 32
|
||||
mov w0, #4
|
||||
ldp x29, x30, [sp, #16]
|
||||
.cfi_restore w29
|
||||
.cfi_restore w30
|
||||
add sp, sp, #32
|
||||
.cfi_def_cfa_offset 0
|
||||
ret
|
||||
.cfi_endproc
|
||||
@ -1,29 +0,0 @@
|
||||
.globl _foo
|
||||
_foo:
|
||||
.cfi_startproc
|
||||
push %rbp
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_offset %rbp, -8
|
||||
mov %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
call _bar
|
||||
pop %rbp
|
||||
.cfi_restore %rbp
|
||||
.cfi_def_cfa_offset 0
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
||||
.globl _bar
|
||||
_bar:
|
||||
.cfi_startproc
|
||||
push %rbp
|
||||
.cfi_def_cfa_offset 8
|
||||
.cfi_offset %rbp, -8
|
||||
mov %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
mov $4, %rax
|
||||
pop %rbp
|
||||
.cfi_restore %rbp
|
||||
.cfi_def_cfa_offset 0
|
||||
ret
|
||||
.cfi_endproc
|
||||
@ -1,42 +0,0 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
pub const requires_symlinks = true;
|
||||
pub const requires_macos_sdk = false;
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const test_step = b.step("test", "Test it");
|
||||
b.default_step = test_step;
|
||||
|
||||
add(b, test_step, .Debug);
|
||||
add(b, test_step, .ReleaseFast);
|
||||
add(b, test_step, .ReleaseSmall);
|
||||
add(b, test_step, .ReleaseSafe);
|
||||
}
|
||||
|
||||
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
|
||||
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "test",
|
||||
.optimize = optimize,
|
||||
.target = target,
|
||||
});
|
||||
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
|
||||
switch (builtin.cpu.arch) {
|
||||
.aarch64 => {
|
||||
exe.addCSourceFile(.{ .file = .{ .path = "a_arm64.s" }, .flags = &[0][]const u8{} });
|
||||
},
|
||||
.x86_64 => {
|
||||
exe.addCSourceFile(.{ .file = .{ .path = "a_x64.s" }, .flags = &[0][]const u8{} });
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
exe.linkLibC();
|
||||
|
||||
const run = b.addRunArtifact(exe);
|
||||
run.skip_foreign_checks = true;
|
||||
run.expectStdOutEqual("4\n");
|
||||
|
||||
test_step.dependOn(&run.step);
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int foo();
|
||||
|
||||
int main() {
|
||||
printf("%d\n", foo());
|
||||
return 0;
|
||||
}
|
||||
@ -1,61 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const requires_macos_sdk = true;
|
||||
pub const requires_symlinks = true;
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const test_step = b.step("test", "Test it");
|
||||
b.default_step = test_step;
|
||||
|
||||
add(b, test_step, .Debug);
|
||||
add(b, test_step, .ReleaseFast);
|
||||
add(b, test_step, .ReleaseSmall);
|
||||
add(b, test_step, .ReleaseSafe);
|
||||
}
|
||||
|
||||
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
|
||||
{
|
||||
// Without -dead_strip_dylibs we expect `-la` to include liba.dylib in the final executable
|
||||
const exe = createScenario(b, optimize, "no-dead-strip");
|
||||
|
||||
const check = exe.checkObject();
|
||||
check.checkInHeaders();
|
||||
check.checkExact("cmd LOAD_DYLIB");
|
||||
check.checkContains("Cocoa");
|
||||
|
||||
check.checkInHeaders();
|
||||
check.checkExact("cmd LOAD_DYLIB");
|
||||
check.checkContains("libobjc");
|
||||
|
||||
test_step.dependOn(&check.step);
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
test_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
|
||||
{
|
||||
// With -dead_strip_dylibs, we should include liba.dylib as it's unreachable
|
||||
const exe = createScenario(b, optimize, "yes-dead-strip");
|
||||
exe.dead_strip_dylibs = true;
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.expectExitCode(@as(u8, @bitCast(@as(i8, -2)))); // should fail
|
||||
test_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
}
|
||||
|
||||
fn createScenario(
|
||||
b: *std.Build,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
name: []const u8,
|
||||
) *std.Build.Step.Compile {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = name,
|
||||
.optimize = optimize,
|
||||
.target = b.host,
|
||||
});
|
||||
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
|
||||
exe.linkLibC();
|
||||
exe.linkFramework("Cocoa");
|
||||
return exe;
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
#include <objc/runtime.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (objc_getClass("NSObject") == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (objc_getClass("NSApplication") == 0) {
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const requires_symlinks = true;
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const test_step = b.step("test", "Test it");
|
||||
b.default_step = test_step;
|
||||
|
||||
add(b, test_step, .Debug);
|
||||
add(b, test_step, .ReleaseFast);
|
||||
add(b, test_step, .ReleaseSmall);
|
||||
add(b, test_step, .ReleaseSafe);
|
||||
}
|
||||
|
||||
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
|
||||
const target = b.resolveTargetQuery(.{ .os_tag = .macos });
|
||||
|
||||
const obj = b.addObject(.{
|
||||
.name = "test",
|
||||
.root_source_file = .{ .path = "main.zig" },
|
||||
.optimize = optimize,
|
||||
.target = target,
|
||||
});
|
||||
|
||||
const check = obj.checkObject();
|
||||
|
||||
check.checkInSymtab();
|
||||
check.checkContains("(__DATA,__TestGlobal) external _test_global");
|
||||
|
||||
check.checkInSymtab();
|
||||
check.checkContains("(__TEXT,__TestFn) external _testFn");
|
||||
|
||||
if (optimize == .Debug) {
|
||||
check.checkInSymtab();
|
||||
check.checkContains("(__TEXT,__TestGenFnA) _main.testGenericFn__anon_");
|
||||
}
|
||||
|
||||
test_step.dependOn(&check.step);
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
export var test_global: u32 linksection("__DATA,__TestGlobal") = undefined;
|
||||
export fn testFn() linksection("__TEXT,__TestFn") callconv(.C) void {
|
||||
testGenericFn("A");
|
||||
}
|
||||
fn testGenericFn(comptime suffix: []const u8) linksection("__TEXT,__TestGenFn" ++ suffix) void {}
|
||||
@ -1,7 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Foo : NSObject
|
||||
|
||||
- (NSString *)name;
|
||||
|
||||
@end
|
||||
@ -1,11 +0,0 @@
|
||||
#import "Foo.h"
|
||||
|
||||
@implementation Foo
|
||||
|
||||
- (NSString *)name
|
||||
{
|
||||
NSString *str = [[NSString alloc] initWithFormat:@"Zig"];
|
||||
return str;
|
||||
}
|
||||
|
||||
@end
|
||||
@ -1,35 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const requires_symlinks = true;
|
||||
pub const requires_macos_sdk = true;
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const test_step = b.step("test", "Test it");
|
||||
b.default_step = test_step;
|
||||
|
||||
add(b, test_step, .Debug);
|
||||
add(b, test_step, .ReleaseFast);
|
||||
add(b, test_step, .ReleaseSmall);
|
||||
add(b, test_step, .ReleaseSafe);
|
||||
}
|
||||
|
||||
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "test",
|
||||
.optimize = optimize,
|
||||
.target = b.host,
|
||||
});
|
||||
b.default_step.dependOn(&exe.step);
|
||||
exe.addIncludePath(.{ .path = "." });
|
||||
exe.addCSourceFile(.{ .file = .{ .path = "Foo.mm" }, .flags = &[0][]const u8{} });
|
||||
exe.addCSourceFile(.{ .file = .{ .path = "test.mm" }, .flags = &[0][]const u8{} });
|
||||
exe.linkLibCpp();
|
||||
// TODO when we figure out how to ship framework stubs for cross-compilation,
|
||||
// populate paths to the sysroot here.
|
||||
exe.linkFramework("Foundation");
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.expectStdOutEqual("Hello from C++ and Zig");
|
||||
|
||||
test_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
#import "Foo.h"
|
||||
#import <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
Foo *foo = [[Foo alloc] init];
|
||||
NSString *result = [foo name];
|
||||
std::cout << "Hello from C++ and " << [result UTF8String];
|
||||
assert([result isEqualToString:@"Zig"]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user