diff --git a/build.zig b/build.zig index fc97fc91bd79b2686a1d3569546dfa2de7e6f24a..0ca2e0d7d7814807f85796e39daabadcdffa5e69 100644 --- a/build.zig +++ b/build.zig @@ -489,6 +489,7 @@ pub fn build(b: *Builder) !void { toolchain_step.dependOn(tests.addCompareOutputTests(b, test_filter, modes)); toolchain_step.dependOn(tests.addStandaloneTests(b, test_filter, modes, skip_non_native, enable_macos_sdk, target)); + toolchain_step.dependOn(tests.addLinkTests(b, test_filter, modes, enable_macos_sdk)); toolchain_step.dependOn(tests.addStackTraceTests(b, test_filter, modes)); toolchain_step.dependOn(tests.addCliTests(b, test_filter, modes)); toolchain_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, modes)); diff --git a/lib/std/build/RunStep.zig b/lib/std/build/RunStep.zig index e8cf87a441ad2c12b1a443573cb666b7941e4b2e..0b8c233bfa713e0d23f22dc16d5b22a1360cb46f 100644 --- a/lib/std/build/RunStep.zig +++ b/lib/std/build/RunStep.zig @@ -149,6 +149,7 @@ fn make(step: *Step) !void { const cwd = if (self.cwd) |cwd| self.builder.pathFromRoot(cwd) else self.builder.build_root; var argv_list = ArrayList([]const u8).init(self.builder.allocator); + for (self.argv.items) |arg| { switch (arg) { .bytes => |bytes| try argv_list.append(bytes), diff --git a/test/link.zig b/test/link.zig new file mode 100644 index 0000000000000000000000000000000000000000..3c1b268d8636def57c4a4d66df622a2d3752a74f --- /dev/null +++ b/test/link.zig @@ -0,0 +1,52 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const tests = @import("tests.zig"); + +pub fn addCases(cases: *tests.StandaloneContext) void { + cases.addBuildFile("test/link/bss/build.zig", .{ + .build_modes = false, // we only guarantee zerofill for undefined in Debug + }); + + cases.addBuildFile("test/link/dylib/build.zig", .{ + .build_modes = true, + }); + + cases.addBuildFile("test/link/common_symbols/build.zig", .{ + .build_modes = true, + }); + + cases.addBuildFile("test/link/common_symbols_alignment/build.zig", .{ + .build_modes = true, + }); + + cases.addBuildFile("test/link/interdependent_static_c_libs/build.zig", .{ + .build_modes = true, + }); + + cases.addBuildFile("test/link/static_lib_as_system_lib/build.zig", .{ + .build_modes = true, + }); + + cases.addBuildFile("test/link/tls/build.zig", .{ + .build_modes = true, + }); + + if (builtin.os.tag == .macos) { + cases.addBuildFile("test/link/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", .{ + .build_modes = true, + .requires_macos_sdk = true, + }); + + // Try to build and run an Objective-C++ executable. + cases.addBuildFile("test/link/objcpp/build.zig", .{ + .build_modes = true, + .requires_macos_sdk = true, + }); + } +} diff --git a/test/link/bss/build.zig b/test/link/bss/build.zig new file mode 100644 index 0000000000000000000000000000000000000000..76e9bdb305f50e5e875a63dca3fc310e206a4dd4 --- /dev/null +++ b/test/link/bss/build.zig @@ -0,0 +1,14 @@ +const Builder = @import("std").build.Builder; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + const test_step = b.step("test", "Test"); + + const exe = b.addExecutable("bss", "main.zig"); + b.default_step.dependOn(&exe.step); + exe.setBuildMode(mode); + + const run = exe.run(); + run.expectStdOutEqual("0, 1, 0\n"); + test_step.dependOn(&run.step); +} diff --git a/test/link/bss/main.zig b/test/link/bss/main.zig new file mode 100644 index 0000000000000000000000000000000000000000..c901f0bb27363ef9e6ade0684b6cf5350662947c --- /dev/null +++ b/test/link/bss/main.zig @@ -0,0 +1,13 @@ +const std = @import("std"); + +// Stress test zerofill layout +var buffer: [0x1000000]u64 = undefined; + +pub fn main() anyerror!void { + buffer[0x10] = 1; + try std.io.getStdOut().writer().print("{d}, {d}, {d}\n", .{ + buffer[0], + buffer[0x10], + buffer[0x1000000 - 1], + }); +} diff --git a/test/link/common_symbols/a.c b/test/link/common_symbols/a.c new file mode 100644 index 0000000000000000000000000000000000000000..829a96e50725062964e97574c713a1cf783eca84 --- /dev/null +++ b/test/link/common_symbols/a.c @@ -0,0 +1,6 @@ +int i; +int j; + +int add_to_i_and_j(int x) { + return x + i + j; +} diff --git a/test/link/common_symbols/b.c b/test/link/common_symbols/b.c new file mode 100644 index 0000000000000000000000000000000000000000..18e8a8c23babf363a3da7c405cba5b6f4b8ea370 --- /dev/null +++ b/test/link/common_symbols/b.c @@ -0,0 +1,7 @@ +long i; +int j = 2; +int k; + +void incr_i() { + i++; +} diff --git a/test/link/common_symbols/build.zig b/test/link/common_symbols/build.zig new file mode 100644 index 0000000000000000000000000000000000000000..2f9f892e86c9f69bbd12df6712194bacd724ec50 --- /dev/null +++ b/test/link/common_symbols/build.zig @@ -0,0 +1,16 @@ +const Builder = @import("std").build.Builder; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + + const lib_a = b.addStaticLibrary("a", null); + lib_a.addCSourceFiles(&.{ "c.c", "a.c", "b.c" }, &.{"-fcommon"}); + lib_a.setBuildMode(mode); + + const test_exe = b.addTest("main.zig"); + test_exe.setBuildMode(mode); + test_exe.linkLibrary(lib_a); + + const test_step = b.step("test", "Test it"); + test_step.dependOn(&test_exe.step); +} diff --git a/test/link/common_symbols/c.c b/test/link/common_symbols/c.c new file mode 100644 index 0000000000000000000000000000000000000000..fdf60b9ca84495d78d27e642eba94e64a3f64a54 --- /dev/null +++ b/test/link/common_symbols/c.c @@ -0,0 +1,5 @@ +extern int k; + +int common_defined_externally() { + return k; +} diff --git a/test/link/common_symbols/main.zig b/test/link/common_symbols/main.zig new file mode 100644 index 0000000000000000000000000000000000000000..255b5aa6215612f1a169c3169f9064d0e3fe3516 --- /dev/null +++ b/test/link/common_symbols/main.zig @@ -0,0 +1,16 @@ +const std = @import("std"); +const expect = std.testing.expect; + +extern fn common_defined_externally() c_int; +extern fn incr_i() void; +extern fn add_to_i_and_j(x: c_int) c_int; + +test "undef shadows common symbol: issue #9937" { + try expect(common_defined_externally() == 0); +} + +test "import C common symbols" { + incr_i(); + const res = add_to_i_and_j(2); + try expect(res == 5); +} diff --git a/test/link/common_symbols_alignment/a.c b/test/link/common_symbols_alignment/a.c new file mode 100644 index 0000000000000000000000000000000000000000..adff9d15f3003fb9ffaf2ae4e267b8f0ba8bf509 --- /dev/null +++ b/test/link/common_symbols_alignment/a.c @@ -0,0 +1,2 @@ +int foo; +__attribute__((aligned(4096))) int bar; diff --git a/test/link/common_symbols_alignment/build.zig b/test/link/common_symbols_alignment/build.zig new file mode 100644 index 0000000000000000000000000000000000000000..a62d86af4fdfb9cf2142336ba91240a64b8a7bdd --- /dev/null +++ b/test/link/common_symbols_alignment/build.zig @@ -0,0 +1,16 @@ +const Builder = @import("std").build.Builder; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + + const lib_a = b.addStaticLibrary("a", null); + lib_a.addCSourceFiles(&.{"a.c"}, &.{"-fcommon"}); + lib_a.setBuildMode(mode); + + const test_exe = b.addTest("main.zig"); + test_exe.setBuildMode(mode); + test_exe.linkLibrary(lib_a); + + const test_step = b.step("test", "Test it"); + test_step.dependOn(&test_exe.step); +} diff --git a/test/link/common_symbols_alignment/main.zig b/test/link/common_symbols_alignment/main.zig new file mode 100644 index 0000000000000000000000000000000000000000..3d3457c76494a2a39aadc697362447124c182b28 --- /dev/null +++ b/test/link/common_symbols_alignment/main.zig @@ -0,0 +1,9 @@ +const std = @import("std"); + +extern var foo: i32; +extern var bar: i32; + +test { + try std.testing.expect(@ptrToInt(&foo) % 4 == 0); + try std.testing.expect(@ptrToInt(&bar) % 4096 == 0); +} diff --git a/test/link/dylib/a.c b/test/link/dylib/a.c new file mode 100644 index 0000000000000000000000000000000000000000..199b31e1a0a213affd535ef60e80b52ce040a32a --- /dev/null +++ b/test/link/dylib/a.c @@ -0,0 +1,7 @@ +#include + +char world[] = "world"; + +char* hello() { + return "Hello"; +} diff --git a/test/link/dylib/build.zig b/test/link/dylib/build.zig new file mode 100644 index 0000000000000000000000000000000000000000..a9dee4aafbe49c9ee301a24d520dc21a5f93c221 --- /dev/null +++ b/test/link/dylib/build.zig @@ -0,0 +1,29 @@ +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"); + + const dylib = b.addSharedLibrary("a", null, b.version(1, 0, 0)); + dylib.setBuildMode(mode); + dylib.addCSourceFile("a.c", &.{}); + dylib.linkLibC(); + dylib.install(); + + const exe = b.addExecutable("main", null); + exe.setBuildMode(mode); + exe.addCSourceFile("main.c", &.{}); + exe.linkSystemLibrary("a"); + exe.linkLibC(); + exe.addLibraryPath(b.pathFromRoot("zig-out/lib/")); + exe.addRPath(b.pathFromRoot("zig-out/lib")); + + const run = exe.run(); + run.cwd = b.pathFromRoot("."); + run.expectStdOutEqual("Hello world"); + + test_step.dependOn(b.getInstallStep()); + test_step.dependOn(&run.step); +} diff --git a/test/link/dylib/main.c b/test/link/dylib/main.c new file mode 100644 index 0000000000000000000000000000000000000000..be1647ddad887303b79225be54523615fcc251e4 --- /dev/null +++ b/test/link/dylib/main.c @@ -0,0 +1,9 @@ +#include + +char* hello(); +extern char world[]; + +int main() { + printf("%s %s", hello(), world); + return 0; +} diff --git a/test/link/frameworks/build.zig b/test/link/frameworks/build.zig new file mode 100644 index 0000000000000000000000000000000000000000..5700422a41c71a39199b37c1de15df644f44ee11 --- /dev/null +++ b/test/link/frameworks/build.zig @@ -0,0 +1,20 @@ +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 the program"); + + const exe = b.addExecutable("test", null); + b.default_step.dependOn(&exe.step); + exe.addCSourceFile("main.c", &[0][]const u8{}); + exe.setBuildMode(mode); + exe.linkLibC(); + // TODO when we figure out how to ship framework stubs for cross-compilation, + // populate paths to the sysroot here. + exe.linkFramework("Cocoa"); + + const run_cmd = exe.run(); + test_step.dependOn(&run_cmd.step); +} diff --git a/test/link/frameworks/main.c b/test/link/frameworks/main.c new file mode 100644 index 0000000000000000000000000000000000000000..b9dab990b2ffb70ec0616bf41a05c49b32f83ec5 --- /dev/null +++ b/test/link/frameworks/main.c @@ -0,0 +1,7 @@ +#include +#include + +int main() { + assert(objc_getClass("NSObject") > 0); + assert(objc_getClass("NSApplication") > 0); +} diff --git a/test/link/interdependent_static_c_libs/a.c b/test/link/interdependent_static_c_libs/a.c new file mode 100644 index 0000000000000000000000000000000000000000..ee9da97a3a8fea8449d0147736eb3093368af7a4 --- /dev/null +++ b/test/link/interdependent_static_c_libs/a.c @@ -0,0 +1,4 @@ +#include "a.h" +int32_t add(int32_t a, int32_t b) { + return a + b; +} diff --git a/test/link/interdependent_static_c_libs/a.h b/test/link/interdependent_static_c_libs/a.h new file mode 100644 index 0000000000000000000000000000000000000000..7b45d54d5675b148ee5a6caf92848909753f0f23 --- /dev/null +++ b/test/link/interdependent_static_c_libs/a.h @@ -0,0 +1,2 @@ +#include +int32_t add(int32_t a, int32_t b); diff --git a/test/link/interdependent_static_c_libs/b.c b/test/link/interdependent_static_c_libs/b.c new file mode 100644 index 0000000000000000000000000000000000000000..ac2cc4f9372484a3ab71b7e01bf12112d1396cf0 --- /dev/null +++ b/test/link/interdependent_static_c_libs/b.c @@ -0,0 +1,6 @@ +#include "a.h" +#include "b.h" + +int32_t sub(int32_t a, int32_t b) { + return add(a, -1 * b); +} diff --git a/test/link/interdependent_static_c_libs/b.h b/test/link/interdependent_static_c_libs/b.h new file mode 100644 index 0000000000000000000000000000000000000000..6047163145bbab2fbb7ac08379d4e4f39ac0d6e1 --- /dev/null +++ b/test/link/interdependent_static_c_libs/b.h @@ -0,0 +1,2 @@ +#include +int32_t sub(int32_t a, int32_t b); diff --git a/test/link/interdependent_static_c_libs/build.zig b/test/link/interdependent_static_c_libs/build.zig new file mode 100644 index 0000000000000000000000000000000000000000..bd1b6100daffd71d53876dcd8002866f9fac2f04 --- /dev/null +++ b/test/link/interdependent_static_c_libs/build.zig @@ -0,0 +1,24 @@ +const Builder = @import("std").build.Builder; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + + const lib_a = b.addStaticLibrary("a", null); + lib_a.addCSourceFile("a.c", &[_][]const u8{}); + lib_a.setBuildMode(mode); + lib_a.addIncludePath("."); + + const lib_b = b.addStaticLibrary("b", null); + lib_b.addCSourceFile("b.c", &[_][]const u8{}); + lib_b.setBuildMode(mode); + lib_b.addIncludePath("."); + + const test_exe = b.addTest("main.zig"); + test_exe.setBuildMode(mode); + test_exe.linkLibrary(lib_a); + test_exe.linkLibrary(lib_b); + test_exe.addIncludePath("."); + + const test_step = b.step("test", "Test it"); + test_step.dependOn(&test_exe.step); +} diff --git a/test/link/interdependent_static_c_libs/main.zig b/test/link/interdependent_static_c_libs/main.zig new file mode 100644 index 0000000000000000000000000000000000000000..cb5d2e7b77d0bab90d4d2585fc5d9e9e7a54f03e --- /dev/null +++ b/test/link/interdependent_static_c_libs/main.zig @@ -0,0 +1,8 @@ +const std = @import("std"); +const expect = std.testing.expect; +const c = @cImport(@cInclude("b.h")); + +test "import C sub" { + const result = c.sub(2, 1); + try expect(result == 1); +} diff --git a/test/link/objc/Foo.h b/test/link/objc/Foo.h new file mode 100644 index 0000000000000000000000000000000000000000..05cb7df39b9dc2cdb4b93a144dd5e9104f873772 --- /dev/null +++ b/test/link/objc/Foo.h @@ -0,0 +1,7 @@ +#import + +@interface Foo : NSObject + +- (NSString *)name; + +@end diff --git a/test/link/objc/Foo.m b/test/link/objc/Foo.m new file mode 100644 index 0000000000000000000000000000000000000000..6fc9b1edf0a9b0911062ae04ad4e17a11e9fa263 --- /dev/null +++ b/test/link/objc/Foo.m @@ -0,0 +1,11 @@ +#import "Foo.h" + +@implementation Foo + +- (NSString *)name +{ + NSString *str = [[NSString alloc] initWithFormat:@"Zig"]; + return str; +} + +@end diff --git a/test/link/objc/build.zig b/test/link/objc/build.zig new file mode 100644 index 0000000000000000000000000000000000000000..e41fd48e7164bae47d27534b7201140c8262b857 --- /dev/null +++ b/test/link/objc/build.zig @@ -0,0 +1,22 @@ +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 the program"); + + const exe = b.addExecutable("test", null); + b.default_step.dependOn(&exe.step); + exe.addIncludePath("."); + exe.addCSourceFile("Foo.m", &[0][]const u8{}); + exe.addCSourceFile("test.m", &[0][]const u8{}); + exe.setBuildMode(mode); + exe.linkLibC(); + // 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 = exe.run(); + test_step.dependOn(&run_cmd.step); +} diff --git a/test/link/objc/test.m b/test/link/objc/test.m new file mode 100644 index 0000000000000000000000000000000000000000..3c81316788d075a4eb3328b90e21a270c06257c8 --- /dev/null +++ b/test/link/objc/test.m @@ -0,0 +1,12 @@ +#import "Foo.h" +#import + +int main(int argc, char *argv[]) +{ + @autoreleasepool { + Foo *foo = [[Foo alloc] init]; + NSString *result = [foo name]; + assert([result isEqualToString:@"Zig"]); + return 0; + } +} diff --git a/test/link/objcpp/Foo.h b/test/link/objcpp/Foo.h new file mode 100644 index 0000000000000000000000000000000000000000..05cb7df39b9dc2cdb4b93a144dd5e9104f873772 --- /dev/null +++ b/test/link/objcpp/Foo.h @@ -0,0 +1,7 @@ +#import + +@interface Foo : NSObject + +- (NSString *)name; + +@end diff --git a/test/link/objcpp/Foo.mm b/test/link/objcpp/Foo.mm new file mode 100644 index 0000000000000000000000000000000000000000..6fc9b1edf0a9b0911062ae04ad4e17a11e9fa263 --- /dev/null +++ b/test/link/objcpp/Foo.mm @@ -0,0 +1,11 @@ +#import "Foo.h" + +@implementation Foo + +- (NSString *)name +{ + NSString *str = [[NSString alloc] initWithFormat:@"Zig"]; + return str; +} + +@end diff --git a/test/link/objcpp/build.zig b/test/link/objcpp/build.zig new file mode 100644 index 0000000000000000000000000000000000000000..767578e225adce2a787cb7c7bf07567ef2b2d6dc --- /dev/null +++ b/test/link/objcpp/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 the program"); + + const exe = b.addExecutable("test", null); + b.default_step.dependOn(&exe.step); + exe.addIncludePath("."); + exe.addCSourceFile("Foo.mm", &[0][]const u8{}); + exe.addCSourceFile("test.mm", &[0][]const u8{}); + exe.setBuildMode(mode); + 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 = exe.run(); + run_cmd.expectStdOutEqual("Hello from C++ and Zig"); + + test_step.dependOn(&run_cmd.step); +} diff --git a/test/link/objcpp/test.mm b/test/link/objcpp/test.mm new file mode 100644 index 0000000000000000000000000000000000000000..d27c543cdf351ad38903624991b3b6d9a4f5f07a --- /dev/null +++ b/test/link/objcpp/test.mm @@ -0,0 +1,14 @@ +#import "Foo.h" +#import +#include + +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; + } +} diff --git a/test/link/static_lib_as_system_lib/a.c b/test/link/static_lib_as_system_lib/a.c new file mode 100644 index 0000000000000000000000000000000000000000..ee9da97a3a8fea8449d0147736eb3093368af7a4 --- /dev/null +++ b/test/link/static_lib_as_system_lib/a.c @@ -0,0 +1,4 @@ +#include "a.h" +int32_t add(int32_t a, int32_t b) { + return a + b; +} diff --git a/test/link/static_lib_as_system_lib/a.h b/test/link/static_lib_as_system_lib/a.h new file mode 100644 index 0000000000000000000000000000000000000000..7b45d54d5675b148ee5a6caf92848909753f0f23 --- /dev/null +++ b/test/link/static_lib_as_system_lib/a.h @@ -0,0 +1,2 @@ +#include +int32_t add(int32_t a, int32_t b); diff --git a/test/link/static_lib_as_system_lib/build.zig b/test/link/static_lib_as_system_lib/build.zig new file mode 100644 index 0000000000000000000000000000000000000000..f39f3fac2ae871ba7f229e0e652fd89b55c4cd33 --- /dev/null +++ b/test/link/static_lib_as_system_lib/build.zig @@ -0,0 +1,23 @@ +const std = @import("std"); +const Builder = std.build.Builder; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + + const lib_a = b.addStaticLibrary("a", null); + lib_a.addCSourceFile("a.c", &[_][]const u8{}); + lib_a.setBuildMode(mode); + lib_a.addIncludePath("."); + lib_a.install(); + + const test_exe = b.addTest("main.zig"); + test_exe.setBuildMode(mode); + test_exe.linkSystemLibrary("a"); // force linking liba.a as -la + test_exe.addSystemIncludePath("."); + const search_path = std.fs.path.join(b.allocator, &[_][]const u8{ b.install_path, "lib" }) catch unreachable; + test_exe.addLibraryPath(search_path); + + const test_step = b.step("test", "Test it"); + test_step.dependOn(b.getInstallStep()); + test_step.dependOn(&test_exe.step); +} diff --git a/test/link/static_lib_as_system_lib/main.zig b/test/link/static_lib_as_system_lib/main.zig new file mode 100644 index 0000000000000000000000000000000000000000..0b9c46217fa05106ea8676cc33215930f69a5c19 --- /dev/null +++ b/test/link/static_lib_as_system_lib/main.zig @@ -0,0 +1,8 @@ +const std = @import("std"); +const expect = std.testing.expect; +const c = @cImport(@cInclude("a.h")); + +test "import C add" { + const result = c.add(2, 1); + try expect(result == 3); +} diff --git a/test/link/tls/a.c b/test/link/tls/a.c new file mode 100644 index 0000000000000000000000000000000000000000..8602d0241945132d6e1248398d0986f15e6255ac --- /dev/null +++ b/test/link/tls/a.c @@ -0,0 +1,5 @@ +_Thread_local int a; + +int getA() { + return a; +} diff --git a/test/link/tls/build.zig b/test/link/tls/build.zig new file mode 100644 index 0000000000000000000000000000000000000000..ebf15ca4399a349e29c8c9c5722b70dc25774cc6 --- /dev/null +++ b/test/link/tls/build.zig @@ -0,0 +1,18 @@ +const Builder = @import("std").build.Builder; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + + const lib = b.addSharedLibrary("a", null, b.version(1, 0, 0)); + lib.setBuildMode(mode); + lib.addCSourceFile("a.c", &.{}); + lib.linkLibC(); + + const test_exe = b.addTest("main.zig"); + test_exe.setBuildMode(mode); + test_exe.linkLibrary(lib); + test_exe.linkLibC(); + + const test_step = b.step("test", "Test it"); + test_step.dependOn(&test_exe.step); +} diff --git a/test/link/tls/main.zig b/test/link/tls/main.zig new file mode 100644 index 0000000000000000000000000000000000000000..ab01616e311ee7706b688fc2008ab7b056d4b124 --- /dev/null +++ b/test/link/tls/main.zig @@ -0,0 +1,15 @@ +const std = @import("std"); + +extern threadlocal var a: i32; +extern fn getA() i32; + +fn getA2() i32 { + return a; +} + +test { + a = 2; + try std.testing.expect(getA() == 2); + try std.testing.expect(2 == getA2()); + try std.testing.expect(getA() == getA2()); +} diff --git a/test/standalone.zig b/test/standalone.zig index c34f9467d674631abad52358a80760795cbecb92..92d0ea4aa3aef7fc9401bc5584b64d761e9a12e6 100644 --- a/test/standalone.zig +++ b/test/standalone.zig @@ -13,31 +13,12 @@ pub fn addCases(cases: *tests.StandaloneContext) void { cases.addBuildFile("test/standalone/main_pkg_path/build.zig", .{}); cases.addBuildFile("test/standalone/shared_library/build.zig", .{}); cases.addBuildFile("test/standalone/mix_o_files/build.zig", .{}); - if (builtin.os.tag == .macos) { - // Zig's macOS linker does not yet support LTO for LLVM IR files: - // https://github.com/ziglang/zig/issues/8680 - cases.addBuildFile("test/standalone/mix_c_files/build.zig", .{ - .build_modes = false, - .cross_targets = true, - }); - } else { - cases.addBuildFile("test/standalone/mix_c_files/build.zig", .{ - .build_modes = true, - .cross_targets = true, - }); - } + cases.addBuildFile("test/standalone/mix_c_files/build.zig", .{ + .build_modes = true, + .cross_targets = true, + }); cases.addBuildFile("test/standalone/global_linkage/build.zig", .{}); cases.addBuildFile("test/standalone/static_c_lib/build.zig", .{}); - cases.addBuildFile("test/standalone/link_interdependent_static_c_libs/build.zig", .{}); - cases.addBuildFile("test/standalone/link_static_lib_as_system_lib/build.zig", .{}); - cases.addBuildFile("test/standalone/link_common_symbols/build.zig", .{}); - cases.addBuildFile("test/standalone/link_frameworks/build.zig", .{ - .requires_macos_sdk = true, - }); - cases.addBuildFile("test/standalone/link_common_symbols_alignment/build.zig", .{}); - if (builtin.os.tag == .macos) { - cases.addBuildFile("test/standalone/link_import_tls_dylib/build.zig", .{}); - } cases.addBuildFile("test/standalone/issue_339/build.zig", .{}); cases.addBuildFile("test/standalone/issue_8550/build.zig", .{}); cases.addBuildFile("test/standalone/issue_794/build.zig", .{}); @@ -69,16 +50,6 @@ pub fn addCases(cases: *tests.StandaloneContext) void { if (builtin.os.tag == .linux) { cases.addBuildFile("test/standalone/pie/build.zig", .{}); } - // Try to build and run an Objective-C executable. - cases.addBuildFile("test/standalone/objc/build.zig", .{ - .build_modes = true, - .requires_macos_sdk = true, - }); - // Try to build and run an Objective-C++ executable. - cases.addBuildFile("test/standalone/objcpp/build.zig", .{ - .build_modes = true, - .requires_macos_sdk = true, - }); // Ensure the development tools are buildable. cases.add("tools/gen_spirv_spec.zig"); diff --git a/test/standalone/link_common_symbols/a.c b/test/standalone/link_common_symbols/a.c deleted file mode 100644 index 829a96e50725062964e97574c713a1cf783eca84..0000000000000000000000000000000000000000 --- a/test/standalone/link_common_symbols/a.c +++ /dev/null @@ -1,6 +0,0 @@ -int i; -int j; - -int add_to_i_and_j(int x) { - return x + i + j; -} diff --git a/test/standalone/link_common_symbols/b.c b/test/standalone/link_common_symbols/b.c deleted file mode 100644 index 18e8a8c23babf363a3da7c405cba5b6f4b8ea370..0000000000000000000000000000000000000000 --- a/test/standalone/link_common_symbols/b.c +++ /dev/null @@ -1,7 +0,0 @@ -long i; -int j = 2; -int k; - -void incr_i() { - i++; -} diff --git a/test/standalone/link_common_symbols/build.zig b/test/standalone/link_common_symbols/build.zig deleted file mode 100644 index 2f9f892e86c9f69bbd12df6712194bacd724ec50..0000000000000000000000000000000000000000 --- a/test/standalone/link_common_symbols/build.zig +++ /dev/null @@ -1,16 +0,0 @@ -const Builder = @import("std").build.Builder; - -pub fn build(b: *Builder) void { - const mode = b.standardReleaseOptions(); - - const lib_a = b.addStaticLibrary("a", null); - lib_a.addCSourceFiles(&.{ "c.c", "a.c", "b.c" }, &.{"-fcommon"}); - lib_a.setBuildMode(mode); - - const test_exe = b.addTest("main.zig"); - test_exe.setBuildMode(mode); - test_exe.linkLibrary(lib_a); - - const test_step = b.step("test", "Test it"); - test_step.dependOn(&test_exe.step); -} diff --git a/test/standalone/link_common_symbols/c.c b/test/standalone/link_common_symbols/c.c deleted file mode 100644 index fdf60b9ca84495d78d27e642eba94e64a3f64a54..0000000000000000000000000000000000000000 --- a/test/standalone/link_common_symbols/c.c +++ /dev/null @@ -1,5 +0,0 @@ -extern int k; - -int common_defined_externally() { - return k; -} diff --git a/test/standalone/link_common_symbols/main.zig b/test/standalone/link_common_symbols/main.zig deleted file mode 100644 index 255b5aa6215612f1a169c3169f9064d0e3fe3516..0000000000000000000000000000000000000000 --- a/test/standalone/link_common_symbols/main.zig +++ /dev/null @@ -1,16 +0,0 @@ -const std = @import("std"); -const expect = std.testing.expect; - -extern fn common_defined_externally() c_int; -extern fn incr_i() void; -extern fn add_to_i_and_j(x: c_int) c_int; - -test "undef shadows common symbol: issue #9937" { - try expect(common_defined_externally() == 0); -} - -test "import C common symbols" { - incr_i(); - const res = add_to_i_and_j(2); - try expect(res == 5); -} diff --git a/test/standalone/link_common_symbols_alignment/a.c b/test/standalone/link_common_symbols_alignment/a.c deleted file mode 100644 index adff9d15f3003fb9ffaf2ae4e267b8f0ba8bf509..0000000000000000000000000000000000000000 --- a/test/standalone/link_common_symbols_alignment/a.c +++ /dev/null @@ -1,2 +0,0 @@ -int foo; -__attribute__((aligned(4096))) int bar; diff --git a/test/standalone/link_common_symbols_alignment/build.zig b/test/standalone/link_common_symbols_alignment/build.zig deleted file mode 100644 index a62d86af4fdfb9cf2142336ba91240a64b8a7bdd..0000000000000000000000000000000000000000 --- a/test/standalone/link_common_symbols_alignment/build.zig +++ /dev/null @@ -1,16 +0,0 @@ -const Builder = @import("std").build.Builder; - -pub fn build(b: *Builder) void { - const mode = b.standardReleaseOptions(); - - const lib_a = b.addStaticLibrary("a", null); - lib_a.addCSourceFiles(&.{"a.c"}, &.{"-fcommon"}); - lib_a.setBuildMode(mode); - - const test_exe = b.addTest("main.zig"); - test_exe.setBuildMode(mode); - test_exe.linkLibrary(lib_a); - - const test_step = b.step("test", "Test it"); - test_step.dependOn(&test_exe.step); -} diff --git a/test/standalone/link_common_symbols_alignment/main.zig b/test/standalone/link_common_symbols_alignment/main.zig deleted file mode 100644 index 3d3457c76494a2a39aadc697362447124c182b28..0000000000000000000000000000000000000000 --- a/test/standalone/link_common_symbols_alignment/main.zig +++ /dev/null @@ -1,9 +0,0 @@ -const std = @import("std"); - -extern var foo: i32; -extern var bar: i32; - -test { - try std.testing.expect(@ptrToInt(&foo) % 4 == 0); - try std.testing.expect(@ptrToInt(&bar) % 4096 == 0); -} diff --git a/test/standalone/link_frameworks/build.zig b/test/standalone/link_frameworks/build.zig deleted file mode 100644 index 460e1675e0da83332eff6c3e451efdff3b8d2fa1..0000000000000000000000000000000000000000 --- a/test/standalone/link_frameworks/build.zig +++ /dev/null @@ -1,34 +0,0 @@ -const std = @import("std"); -const Builder = std.build.Builder; -const CrossTarget = std.zig.CrossTarget; - -fn isRunnableTarget(t: CrossTarget) bool { - // TODO I think we might be able to run this on Linux via Darling. - // Add a check for that here, and return true if Darling is available. - if (t.isNative() and t.getOsTag() == .macos) - return true - else - return false; -} - -pub fn build(b: *Builder) void { - const mode = b.standardReleaseOptions(); - const target = b.standardTargetOptions(.{}); - - const test_step = b.step("test", "Test the program"); - - const exe = b.addExecutable("test", null); - b.default_step.dependOn(&exe.step); - exe.addCSourceFile("main.c", &[0][]const u8{}); - exe.setBuildMode(mode); - exe.setTarget(target); - exe.linkLibC(); - // TODO when we figure out how to ship framework stubs for cross-compilation, - // populate paths to the sysroot here. - exe.linkFramework("Cocoa"); - - if (isRunnableTarget(target)) { - const run_cmd = exe.run(); - test_step.dependOn(&run_cmd.step); - } -} diff --git a/test/standalone/link_frameworks/main.c b/test/standalone/link_frameworks/main.c deleted file mode 100644 index b9dab990b2ffb70ec0616bf41a05c49b32f83ec5..0000000000000000000000000000000000000000 --- a/test/standalone/link_frameworks/main.c +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include - -int main() { - assert(objc_getClass("NSObject") > 0); - assert(objc_getClass("NSApplication") > 0); -} diff --git a/test/standalone/link_import_tls_dylib/a.c b/test/standalone/link_import_tls_dylib/a.c deleted file mode 100644 index 5c5aa5bae491cedb4a21a0f5b65931214bd6a94f..0000000000000000000000000000000000000000 --- a/test/standalone/link_import_tls_dylib/a.c +++ /dev/null @@ -1 +0,0 @@ -_Thread_local int a; diff --git a/test/standalone/link_import_tls_dylib/build.zig b/test/standalone/link_import_tls_dylib/build.zig deleted file mode 100644 index 332173fbb6ff9a6295cc80a7b08d2934d0b125b2..0000000000000000000000000000000000000000 --- a/test/standalone/link_import_tls_dylib/build.zig +++ /dev/null @@ -1,16 +0,0 @@ -const Builder = @import("std").build.Builder; - -pub fn build(b: *Builder) void { - const mode = b.standardReleaseOptions(); - - const lib = b.addSharedLibrary("a", null, b.version(1, 0, 0)); - lib.setBuildMode(mode); - lib.addCSourceFile("a.c", &.{}); - - const test_exe = b.addTest("main.zig"); - test_exe.setBuildMode(mode); - test_exe.linkLibrary(lib); - - const test_step = b.step("test", "Test it"); - test_step.dependOn(&test_exe.step); -} diff --git a/test/standalone/link_import_tls_dylib/main.zig b/test/standalone/link_import_tls_dylib/main.zig deleted file mode 100644 index 354c6f545e3ab33e679b777dd7fff9e0f0ac7a19..0000000000000000000000000000000000000000 --- a/test/standalone/link_import_tls_dylib/main.zig +++ /dev/null @@ -1,7 +0,0 @@ -const std = @import("std"); - -extern threadlocal var a: i32; - -test { - try std.testing.expect(a == 0); -} diff --git a/test/standalone/link_interdependent_static_c_libs/a.c b/test/standalone/link_interdependent_static_c_libs/a.c deleted file mode 100644 index ee9da97a3a8fea8449d0147736eb3093368af7a4..0000000000000000000000000000000000000000 --- a/test/standalone/link_interdependent_static_c_libs/a.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "a.h" -int32_t add(int32_t a, int32_t b) { - return a + b; -} diff --git a/test/standalone/link_interdependent_static_c_libs/a.h b/test/standalone/link_interdependent_static_c_libs/a.h deleted file mode 100644 index 7b45d54d5675b148ee5a6caf92848909753f0f23..0000000000000000000000000000000000000000 --- a/test/standalone/link_interdependent_static_c_libs/a.h +++ /dev/null @@ -1,2 +0,0 @@ -#include -int32_t add(int32_t a, int32_t b); diff --git a/test/standalone/link_interdependent_static_c_libs/b.c b/test/standalone/link_interdependent_static_c_libs/b.c deleted file mode 100644 index ac2cc4f9372484a3ab71b7e01bf12112d1396cf0..0000000000000000000000000000000000000000 --- a/test/standalone/link_interdependent_static_c_libs/b.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "a.h" -#include "b.h" - -int32_t sub(int32_t a, int32_t b) { - return add(a, -1 * b); -} diff --git a/test/standalone/link_interdependent_static_c_libs/b.h b/test/standalone/link_interdependent_static_c_libs/b.h deleted file mode 100644 index 6047163145bbab2fbb7ac08379d4e4f39ac0d6e1..0000000000000000000000000000000000000000 --- a/test/standalone/link_interdependent_static_c_libs/b.h +++ /dev/null @@ -1,2 +0,0 @@ -#include -int32_t sub(int32_t a, int32_t b); diff --git a/test/standalone/link_interdependent_static_c_libs/build.zig b/test/standalone/link_interdependent_static_c_libs/build.zig deleted file mode 100644 index bd1b6100daffd71d53876dcd8002866f9fac2f04..0000000000000000000000000000000000000000 --- a/test/standalone/link_interdependent_static_c_libs/build.zig +++ /dev/null @@ -1,24 +0,0 @@ -const Builder = @import("std").build.Builder; - -pub fn build(b: *Builder) void { - const mode = b.standardReleaseOptions(); - - const lib_a = b.addStaticLibrary("a", null); - lib_a.addCSourceFile("a.c", &[_][]const u8{}); - lib_a.setBuildMode(mode); - lib_a.addIncludePath("."); - - const lib_b = b.addStaticLibrary("b", null); - lib_b.addCSourceFile("b.c", &[_][]const u8{}); - lib_b.setBuildMode(mode); - lib_b.addIncludePath("."); - - const test_exe = b.addTest("main.zig"); - test_exe.setBuildMode(mode); - test_exe.linkLibrary(lib_a); - test_exe.linkLibrary(lib_b); - test_exe.addIncludePath("."); - - const test_step = b.step("test", "Test it"); - test_step.dependOn(&test_exe.step); -} diff --git a/test/standalone/link_interdependent_static_c_libs/main.zig b/test/standalone/link_interdependent_static_c_libs/main.zig deleted file mode 100644 index cb5d2e7b77d0bab90d4d2585fc5d9e9e7a54f03e..0000000000000000000000000000000000000000 --- a/test/standalone/link_interdependent_static_c_libs/main.zig +++ /dev/null @@ -1,8 +0,0 @@ -const std = @import("std"); -const expect = std.testing.expect; -const c = @cImport(@cInclude("b.h")); - -test "import C sub" { - const result = c.sub(2, 1); - try expect(result == 1); -} diff --git a/test/standalone/link_static_lib_as_system_lib/a.c b/test/standalone/link_static_lib_as_system_lib/a.c deleted file mode 100644 index ee9da97a3a8fea8449d0147736eb3093368af7a4..0000000000000000000000000000000000000000 --- a/test/standalone/link_static_lib_as_system_lib/a.c +++ /dev/null @@ -1,4 +0,0 @@ -#include "a.h" -int32_t add(int32_t a, int32_t b) { - return a + b; -} diff --git a/test/standalone/link_static_lib_as_system_lib/a.h b/test/standalone/link_static_lib_as_system_lib/a.h deleted file mode 100644 index 7b45d54d5675b148ee5a6caf92848909753f0f23..0000000000000000000000000000000000000000 --- a/test/standalone/link_static_lib_as_system_lib/a.h +++ /dev/null @@ -1,2 +0,0 @@ -#include -int32_t add(int32_t a, int32_t b); diff --git a/test/standalone/link_static_lib_as_system_lib/build.zig b/test/standalone/link_static_lib_as_system_lib/build.zig deleted file mode 100644 index f39f3fac2ae871ba7f229e0e652fd89b55c4cd33..0000000000000000000000000000000000000000 --- a/test/standalone/link_static_lib_as_system_lib/build.zig +++ /dev/null @@ -1,23 +0,0 @@ -const std = @import("std"); -const Builder = std.build.Builder; - -pub fn build(b: *Builder) void { - const mode = b.standardReleaseOptions(); - - const lib_a = b.addStaticLibrary("a", null); - lib_a.addCSourceFile("a.c", &[_][]const u8{}); - lib_a.setBuildMode(mode); - lib_a.addIncludePath("."); - lib_a.install(); - - const test_exe = b.addTest("main.zig"); - test_exe.setBuildMode(mode); - test_exe.linkSystemLibrary("a"); // force linking liba.a as -la - test_exe.addSystemIncludePath("."); - const search_path = std.fs.path.join(b.allocator, &[_][]const u8{ b.install_path, "lib" }) catch unreachable; - test_exe.addLibraryPath(search_path); - - const test_step = b.step("test", "Test it"); - test_step.dependOn(b.getInstallStep()); - test_step.dependOn(&test_exe.step); -} diff --git a/test/standalone/link_static_lib_as_system_lib/main.zig b/test/standalone/link_static_lib_as_system_lib/main.zig deleted file mode 100644 index 0b9c46217fa05106ea8676cc33215930f69a5c19..0000000000000000000000000000000000000000 --- a/test/standalone/link_static_lib_as_system_lib/main.zig +++ /dev/null @@ -1,8 +0,0 @@ -const std = @import("std"); -const expect = std.testing.expect; -const c = @cImport(@cInclude("a.h")); - -test "import C add" { - const result = c.add(2, 1); - try expect(result == 3); -} diff --git a/test/standalone/objc/Foo.h b/test/standalone/objc/Foo.h deleted file mode 100644 index 05cb7df39b9dc2cdb4b93a144dd5e9104f873772..0000000000000000000000000000000000000000 --- a/test/standalone/objc/Foo.h +++ /dev/null @@ -1,7 +0,0 @@ -#import - -@interface Foo : NSObject - -- (NSString *)name; - -@end diff --git a/test/standalone/objc/Foo.m b/test/standalone/objc/Foo.m deleted file mode 100644 index 6fc9b1edf0a9b0911062ae04ad4e17a11e9fa263..0000000000000000000000000000000000000000 --- a/test/standalone/objc/Foo.m +++ /dev/null @@ -1,11 +0,0 @@ -#import "Foo.h" - -@implementation Foo - -- (NSString *)name -{ - NSString *str = [[NSString alloc] initWithFormat:@"Zig"]; - return str; -} - -@end diff --git a/test/standalone/objc/build.zig b/test/standalone/objc/build.zig deleted file mode 100644 index 1b3a90f90fe363e22b3f2f04a02f2210150f7683..0000000000000000000000000000000000000000 --- a/test/standalone/objc/build.zig +++ /dev/null @@ -1,36 +0,0 @@ -const std = @import("std"); -const Builder = std.build.Builder; -const CrossTarget = std.zig.CrossTarget; - -fn isRunnableTarget(t: CrossTarget) bool { - // TODO I think we might be able to run this on Linux via Darling. - // Add a check for that here, and return true if Darling is available. - if (t.isNative() and t.getOsTag() == .macos) - return true - else - return false; -} - -pub fn build(b: *Builder) void { - const mode = b.standardReleaseOptions(); - const target = b.standardTargetOptions(.{}); - - const test_step = b.step("test", "Test the program"); - - const exe = b.addExecutable("test", null); - b.default_step.dependOn(&exe.step); - exe.addIncludePath("."); - exe.addCSourceFile("Foo.m", &[0][]const u8{}); - exe.addCSourceFile("test.m", &[0][]const u8{}); - exe.setBuildMode(mode); - exe.setTarget(target); - exe.linkLibC(); - // TODO when we figure out how to ship framework stubs for cross-compilation, - // populate paths to the sysroot here. - exe.linkFramework("Foundation"); - - if (isRunnableTarget(target)) { - const run_cmd = exe.run(); - test_step.dependOn(&run_cmd.step); - } -} diff --git a/test/standalone/objc/test.m b/test/standalone/objc/test.m deleted file mode 100644 index 3c81316788d075a4eb3328b90e21a270c06257c8..0000000000000000000000000000000000000000 --- a/test/standalone/objc/test.m +++ /dev/null @@ -1,12 +0,0 @@ -#import "Foo.h" -#import - -int main(int argc, char *argv[]) -{ - @autoreleasepool { - Foo *foo = [[Foo alloc] init]; - NSString *result = [foo name]; - assert([result isEqualToString:@"Zig"]); - return 0; - } -} diff --git a/test/standalone/objcpp/Foo.h b/test/standalone/objcpp/Foo.h deleted file mode 100644 index 05cb7df39b9dc2cdb4b93a144dd5e9104f873772..0000000000000000000000000000000000000000 --- a/test/standalone/objcpp/Foo.h +++ /dev/null @@ -1,7 +0,0 @@ -#import - -@interface Foo : NSObject - -- (NSString *)name; - -@end diff --git a/test/standalone/objcpp/Foo.mm b/test/standalone/objcpp/Foo.mm deleted file mode 100644 index 6fc9b1edf0a9b0911062ae04ad4e17a11e9fa263..0000000000000000000000000000000000000000 --- a/test/standalone/objcpp/Foo.mm +++ /dev/null @@ -1,11 +0,0 @@ -#import "Foo.h" - -@implementation Foo - -- (NSString *)name -{ - NSString *str = [[NSString alloc] initWithFormat:@"Zig"]; - return str; -} - -@end diff --git a/test/standalone/objcpp/build.zig b/test/standalone/objcpp/build.zig deleted file mode 100644 index 688592793afbf531382ec733d8f5fbdd88adbc6e..0000000000000000000000000000000000000000 --- a/test/standalone/objcpp/build.zig +++ /dev/null @@ -1,36 +0,0 @@ -const std = @import("std"); -const Builder = std.build.Builder; -const CrossTarget = std.zig.CrossTarget; - -fn isRunnableTarget(t: CrossTarget) bool { - // TODO I think we might be able to run this on Linux via Darling. - // Add a check for that here, and return true if Darling is available. - if (t.isNative() and t.getOsTag() == .macos) - return true - else - return false; -} - -pub fn build(b: *Builder) void { - const mode = b.standardReleaseOptions(); - const target = b.standardTargetOptions(.{}); - - const test_step = b.step("test", "Test the program"); - - const exe = b.addExecutable("test", null); - b.default_step.dependOn(&exe.step); - exe.addIncludePath("."); - exe.addCSourceFile("Foo.mm", &[0][]const u8{}); - exe.addCSourceFile("test.mm", &[0][]const u8{}); - exe.setBuildMode(mode); - exe.setTarget(target); - exe.linkLibCpp(); - // TODO when we figure out how to ship framework stubs for cross-compilation, - // populate paths to the sysroot here. - exe.linkFramework("Foundation"); - - if (isRunnableTarget(target)) { - const run_cmd = exe.run(); - test_step.dependOn(&run_cmd.step); - } -} diff --git a/test/standalone/objcpp/test.mm b/test/standalone/objcpp/test.mm deleted file mode 100644 index d27c543cdf351ad38903624991b3b6d9a4f5f07a..0000000000000000000000000000000000000000 --- a/test/standalone/objcpp/test.mm +++ /dev/null @@ -1,14 +0,0 @@ -#import "Foo.h" -#import -#include - -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; - } -} diff --git a/test/tests.zig b/test/tests.zig index 3666ef10289f888d728be96de0939ff1a1d13ab2..8bc415d28ba02db50f89b9483fef2449d19fe837 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -21,6 +21,7 @@ const assemble_and_link = @import("assemble_and_link.zig"); const translate_c = @import("translate_c.zig"); const run_translated_c = @import("run_translated_c.zig"); const gen_h = @import("gen_h.zig"); +const link = @import("link.zig"); // Implementations pub const TranslateCContext = @import("src/translate_c.zig").TranslateCContext; @@ -479,6 +480,27 @@ pub fn addStandaloneTests( return cases.step; } +pub fn addLinkTests( + b: *build.Builder, + test_filter: ?[]const u8, + modes: []const Mode, + enable_macos_sdk: bool, +) *build.Step { + const cases = b.allocator.create(StandaloneContext) catch unreachable; + cases.* = StandaloneContext{ + .b = b, + .step = b.step("test-link", "Run the linker tests"), + .test_index = 0, + .test_filter = test_filter, + .modes = modes, + .skip_non_native = true, + .enable_macos_sdk = enable_macos_sdk, + .target = .{}, + }; + link.addCases(cases); + return cases.step; +} + pub fn addCliTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step { _ = test_filter; _ = modes;