aboutsummaryrefslogtreecommitdiff
path: root/test/link
diff options
context:
space:
mode:
Diffstat (limited to 'test/link')
-rw-r--r--test/link/bss/build.zig14
-rw-r--r--test/link/bss/main.zig13
-rw-r--r--test/link/common_symbols/a.c6
-rw-r--r--test/link/common_symbols/b.c7
-rw-r--r--test/link/common_symbols/build.zig16
-rw-r--r--test/link/common_symbols/c.c5
-rw-r--r--test/link/common_symbols/main.zig16
-rw-r--r--test/link/common_symbols_alignment/a.c2
-rw-r--r--test/link/common_symbols_alignment/build.zig16
-rw-r--r--test/link/common_symbols_alignment/main.zig9
-rw-r--r--test/link/dylib/a.c7
-rw-r--r--test/link/dylib/build.zig29
-rw-r--r--test/link/dylib/main.c9
-rw-r--r--test/link/frameworks/build.zig20
-rw-r--r--test/link/frameworks/main.c7
-rw-r--r--test/link/interdependent_static_c_libs/a.c4
-rw-r--r--test/link/interdependent_static_c_libs/a.h2
-rw-r--r--test/link/interdependent_static_c_libs/b.c6
-rw-r--r--test/link/interdependent_static_c_libs/b.h2
-rw-r--r--test/link/interdependent_static_c_libs/build.zig24
-rw-r--r--test/link/interdependent_static_c_libs/main.zig8
-rw-r--r--test/link/objc/Foo.h7
-rw-r--r--test/link/objc/Foo.m11
-rw-r--r--test/link/objc/build.zig22
-rw-r--r--test/link/objc/test.m12
-rw-r--r--test/link/objcpp/Foo.h7
-rw-r--r--test/link/objcpp/Foo.mm11
-rw-r--r--test/link/objcpp/build.zig24
-rw-r--r--test/link/objcpp/test.mm14
-rw-r--r--test/link/static_lib_as_system_lib/a.c4
-rw-r--r--test/link/static_lib_as_system_lib/a.h2
-rw-r--r--test/link/static_lib_as_system_lib/build.zig23
-rw-r--r--test/link/static_lib_as_system_lib/main.zig8
-rw-r--r--test/link/tls/a.c5
-rw-r--r--test/link/tls/build.zig18
-rw-r--r--test/link/tls/main.zig15
36 files changed, 405 insertions, 0 deletions
diff --git a/test/link/bss/build.zig b/test/link/bss/build.zig
new file mode 100644
index 0000000000..76e9bdb305
--- /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 0000000000..c901f0bb27
--- /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 0000000000..829a96e507
--- /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 0000000000..18e8a8c23b
--- /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 0000000000..2f9f892e86
--- /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 0000000000..fdf60b9ca8
--- /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 0000000000..255b5aa621
--- /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 0000000000..adff9d15f3
--- /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 0000000000..a62d86af4f
--- /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 0000000000..3d3457c764
--- /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 0000000000..199b31e1a0
--- /dev/null
+++ b/test/link/dylib/a.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+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 0000000000..a9dee4aafb
--- /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 0000000000..be1647ddad
--- /dev/null
+++ b/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;
+}
diff --git a/test/link/frameworks/build.zig b/test/link/frameworks/build.zig
new file mode 100644
index 0000000000..5700422a41
--- /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 0000000000..b9dab990b2
--- /dev/null
+++ b/test/link/frameworks/main.c
@@ -0,0 +1,7 @@
+#include <assert.h>
+#include <objc/runtime.h>
+
+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 0000000000..ee9da97a3a
--- /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 0000000000..7b45d54d56
--- /dev/null
+++ b/test/link/interdependent_static_c_libs/a.h
@@ -0,0 +1,2 @@
+#include <stdint.h>
+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 0000000000..ac2cc4f937
--- /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 0000000000..6047163145
--- /dev/null
+++ b/test/link/interdependent_static_c_libs/b.h
@@ -0,0 +1,2 @@
+#include <stdint.h>
+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 0000000000..bd1b6100da
--- /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 0000000000..cb5d2e7b77
--- /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 0000000000..05cb7df39b
--- /dev/null
+++ b/test/link/objc/Foo.h
@@ -0,0 +1,7 @@
+#import <Foundation/Foundation.h>
+
+@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 0000000000..6fc9b1edf0
--- /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 0000000000..e41fd48e71
--- /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 0000000000..3c81316788
--- /dev/null
+++ b/test/link/objc/test.m
@@ -0,0 +1,12 @@
+#import "Foo.h"
+#import <assert.h>
+
+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 0000000000..05cb7df39b
--- /dev/null
+++ b/test/link/objcpp/Foo.h
@@ -0,0 +1,7 @@
+#import <Foundation/Foundation.h>
+
+@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 0000000000..6fc9b1edf0
--- /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 0000000000..767578e225
--- /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 0000000000..d27c543cdf
--- /dev/null
+++ b/test/link/objcpp/test.mm
@@ -0,0 +1,14 @@
+#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;
+ }
+}
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 0000000000..ee9da97a3a
--- /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 0000000000..7b45d54d56
--- /dev/null
+++ b/test/link/static_lib_as_system_lib/a.h
@@ -0,0 +1,2 @@
+#include <stdint.h>
+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 0000000000..f39f3fac2a
--- /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 0000000000..0b9c46217f
--- /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 0000000000..8602d02419
--- /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 0000000000..ebf15ca439
--- /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 0000000000..ab01616e31
--- /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());
+}