zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 8142bc20ea8bcffc076fcbde074a7e315ff0060a (tree)
parent 6bc9c4f716afbb15465f79f84f61221f394fa5b6
Author: Xavier Bouchoux <xavierb@gmail.com>
Date:   Sun,  9 Jul 2023 20:46:39 +0200

test: linking static libraries built from intermediary object files

Diffstat:
Mtest/link.zig | 4++++
Atest/link/static_libs_from_object_files/build.zig | 148+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/link/static_libs_from_object_files/main.zig | 20++++++++++++++++++++
3 files changed, 172 insertions(+), 0 deletions(-)

diff --git a/test/link.zig b/test/link.zig @@ -21,6 +21,10 @@ pub const cases = [_]Case{ .import = @import("link/interdependent_static_c_libs/build.zig"), }, .{ + .build_root = "test/link/static_libs_from_object_files", + .import = @import("link/static_libs_from_object_files/build.zig"), + }, + .{ .build_root = "test/link/glibc_compat", .import = @import("link/glibc_compat/build.zig"), }, diff --git a/test/link/static_libs_from_object_files/build.zig b/test/link/static_libs_from_object_files/build.zig @@ -0,0 +1,148 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +const Build = std.Build; +const FileSource = Build.FileSource; +const Step = Build.Step; +const Run = Step.Run; +const WriteFile = Step.WriteFile; + +pub fn build(b: *Build) void { + const nb_files = b.option(u32, "nb_files", "Number of c files to generate.") orelse 10; + + const test_step = b.step("test", "Test it"); + b.default_step = test_step; + + // generate c files + const files = b.allocator.alloc(std.Build.FileSource, nb_files) catch unreachable; + defer b.allocator.free(files); + { + for (files[0 .. nb_files - 1], 1..nb_files) |*file, i| { + const wf = WriteFile.create(b); + file.* = wf.add(b.fmt("src_{}.c", .{i}), b.fmt( + \\extern int foo_0(); + \\extern int bar_{}(); + \\extern int one_{}; + \\int one_{} = 1; + \\int foo_{}() {{ return one_{} + foo_0(); }} + \\int bar_{}() {{ return bar_{}(); }} + , .{ i - 1, i - 1, i, i, i - 1, i, i - 1 })); + } + + { + const wf = WriteFile.create(b); + files[nb_files - 1] = wf.add("src_last.c", b.fmt( + \\extern int foo_0(); + \\extern int bar_{}(); + \\extern int one_{}; + \\int foo_last() {{ return one_{} + foo_0(); }} + \\int bar_last() {{ return bar_{}(); }} + , .{ nb_files - 1, nb_files - 1, nb_files - 1, nb_files - 1 })); + } + } + + add(b, test_step, files, .Debug); + add(b, test_step, files, .ReleaseSafe); + add(b, test_step, files, .ReleaseSmall); + add(b, test_step, files, .ReleaseFast); +} + +fn add(b: *Build, test_step: *Step, files: []const std.Build.FileSource, optimize: std.builtin.OptimizeMode) void { + const flags = [_][]const u8{ + "-Wall", + "-std=c11", + }; + + // all files at once + { + const exe = b.addExecutable(.{ + .name = "test1", + .root_source_file = .{ .path = "main.zig" }, + .optimize = optimize, + .target = .{}, + }); + + for (files) |file| { + exe.addCSourceFileSource(.{ .source = file, .args = &flags }); + } + + const run_cmd = b.addRunArtifact(exe); + run_cmd.skip_foreign_checks = true; + run_cmd.expectExitCode(0); + + test_step.dependOn(&run_cmd.step); + } + + // using static librairies + { + const lib_a = b.addStaticLibrary(.{ + .name = "test2_a", + .target = .{}, + .optimize = optimize, + }); + const lib_b = b.addStaticLibrary(.{ + .name = "test2_b", + .target = .{}, + .optimize = optimize, + }); + + for (files, 1..) |file, i| { + const lib = if (i & 1 == 0) lib_a else lib_b; + lib.addCSourceFileSource(.{ .source = file, .args = &flags }); + } + + const exe = b.addExecutable(.{ + .name = "test2", + .root_source_file = .{ .path = "main.zig" }, + .optimize = optimize, + }); + exe.linkLibrary(lib_a); + exe.linkLibrary(lib_b); + + const run_cmd = b.addRunArtifact(exe); + run_cmd.skip_foreign_checks = true; + run_cmd.expectExitCode(0); + + test_step.dependOn(&run_cmd.step); + } + + // using static librairies and object files + { + const lib_a = b.addStaticLibrary(.{ + .name = "test3_a", + .target = .{}, + .optimize = optimize, + }); + const lib_b = b.addStaticLibrary(.{ + .name = "test3_b", + .target = .{}, + .optimize = optimize, + }); + + for (files, 1..) |file, i| { + const obj = b.addObject(.{ + .name = b.fmt("obj_{}", .{i}), + .target = .{}, + .optimize = optimize, + }); + obj.addCSourceFileSource(.{ .source = file, .args = &flags }); + + const lib = if (i & 1 == 0) lib_a else lib_b; + lib.addObject(obj); + } + + const exe = b.addExecutable(.{ + .name = "test3", + .root_source_file = .{ .path = "main.zig" }, + .optimize = optimize, + }); + exe.linkLibrary(lib_a); + exe.linkLibrary(lib_b); + + const run_cmd = b.addRunArtifact(exe); + run_cmd.skip_foreign_checks = true; + run_cmd.expectExitCode(0); + + test_step.dependOn(&run_cmd.step); + } +} diff --git a/test/link/static_libs_from_object_files/main.zig b/test/link/static_libs_from_object_files/main.zig @@ -0,0 +1,20 @@ +const std = @import("std"); + +extern fn foo_last() i32; +extern fn bar_last() i32; + +export const one_0: i32 = 1; + +export fn foo_0() i32 { + return 1234; +} +export fn bar_0() i32 { + return 5678; +} + +pub fn main() anyerror!void { + const foo_expected: i32 = 1 + 1234; + const bar_expected: i32 = 5678; + try std.testing.expectEqual(foo_expected, foo_last()); + try std.testing.expectEqual(bar_expected, bar_last()); +}