Commit 38edef35bf
Changed files (43)
lib
std
build
test
link
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),
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);
+}
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],
+ });
+}
test/standalone/link_common_symbols/a.c → test/link/common_symbols/a.c
File renamed without changes
test/standalone/link_common_symbols/b.c → test/link/common_symbols/b.c
File renamed without changes
test/standalone/link_common_symbols/build.zig → test/link/common_symbols/build.zig
File renamed without changes
test/standalone/link_common_symbols/c.c → test/link/common_symbols/c.c
File renamed without changes
test/standalone/link_common_symbols/main.zig → test/link/common_symbols/main.zig
File renamed without changes
test/standalone/link_common_symbols_alignment/a.c → test/link/common_symbols_alignment/a.c
File renamed without changes
test/standalone/link_common_symbols_alignment/build.zig → test/link/common_symbols_alignment/build.zig
File renamed without changes
test/standalone/link_common_symbols_alignment/main.zig → test/link/common_symbols_alignment/main.zig
File renamed without changes
test/link/dylib/a.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+char world[] = "world";
+
+char* hello() {
+ return "Hello";
+}
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);
+}
test/link/dylib/main.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+char* hello();
+extern char world[];
+
+int main() {
+ printf("%s %s", hello(), world);
+ return 0;
+}
test/standalone/link_frameworks/build.zig → test/link/frameworks/build.zig
@@ -1,19 +1,8 @@
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");
@@ -21,14 +10,11 @@ pub fn build(b: *Builder) void {
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);
- }
+ const run_cmd = exe.run();
+ test_step.dependOn(&run_cmd.step);
}
test/standalone/link_frameworks/main.c → test/link/frameworks/main.c
File renamed without changes
test/standalone/link_interdependent_static_c_libs/a.c → test/link/interdependent_static_c_libs/a.c
File renamed without changes
test/standalone/link_interdependent_static_c_libs/a.h → test/link/interdependent_static_c_libs/a.h
File renamed without changes
test/standalone/link_interdependent_static_c_libs/b.c → test/link/interdependent_static_c_libs/b.c
File renamed without changes
test/standalone/link_interdependent_static_c_libs/b.h → test/link/interdependent_static_c_libs/b.h
File renamed without changes
test/standalone/link_interdependent_static_c_libs/build.zig → test/link/interdependent_static_c_libs/build.zig
File renamed without changes
test/standalone/link_interdependent_static_c_libs/main.zig → test/link/interdependent_static_c_libs/main.zig
File renamed without changes
test/standalone/objc/build.zig → test/link/objc/build.zig
@@ -1,19 +1,8 @@
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");
@@ -23,14 +12,11 @@ pub fn build(b: *Builder) void {
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);
- }
+ const run_cmd = exe.run();
+ test_step.dependOn(&run_cmd.step);
}
test/standalone/objc/Foo.h → test/link/objc/Foo.h
File renamed without changes
test/standalone/objc/Foo.m → test/link/objc/Foo.m
File renamed without changes
test/standalone/objc/test.m → test/link/objc/test.m
File renamed without changes
test/standalone/objcpp/build.zig → test/link/objcpp/build.zig
@@ -1,19 +1,8 @@
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");
@@ -23,14 +12,13 @@ pub fn build(b: *Builder) void {
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);
- }
+ const run_cmd = exe.run();
+ run_cmd.expectStdOutEqual("Hello from C++ and Zig");
+
+ test_step.dependOn(&run_cmd.step);
}
test/standalone/objcpp/Foo.h → test/link/objcpp/Foo.h
File renamed without changes
test/standalone/objcpp/Foo.mm → test/link/objcpp/Foo.mm
File renamed without changes
test/standalone/objcpp/test.mm → test/link/objcpp/test.mm
File renamed without changes
test/standalone/link_static_lib_as_system_lib/a.c → test/link/static_lib_as_system_lib/a.c
File renamed without changes
test/standalone/link_static_lib_as_system_lib/a.h → test/link/static_lib_as_system_lib/a.h
File renamed without changes
test/standalone/link_static_lib_as_system_lib/build.zig → test/link/static_lib_as_system_lib/build.zig
File renamed without changes
test/standalone/link_static_lib_as_system_lib/main.zig → test/link/static_lib_as_system_lib/main.zig
File renamed without changes
test/link/tls/a.c
@@ -0,0 +1,5 @@
+_Thread_local int a;
+
+int getA() {
+ return a;
+}
test/standalone/link_import_tls_dylib/build.zig → test/link/tls/build.zig
@@ -6,10 +6,12 @@ pub fn build(b: *Builder) void {
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);
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());
+}
test/standalone/link_import_tls_dylib/a.c
@@ -1,1 +0,0 @@
-_Thread_local int a;
test/standalone/link_import_tls_dylib/main.zig
@@ -1,7 +0,0 @@
-const std = @import("std");
-
-extern threadlocal var a: i32;
-
-test {
- try std.testing.expect(a == 0);
-}
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,
+ });
+ }
+}
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");
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;
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));