zig

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

commit 72bc140ad16a4a2dbe632129ea9068630e019277 (tree)
parent 7f0b5787fb1db871501bc4b03629d68dc378e038
Author: kcbanner <kcbanner@gmail.com>
Date:   Fri,  5 Jun 2026 01:55:37 -0400

test/link: separate out shared lib tests

- Fixup snapshot naming
- Fixup verifyObjdumps so we can dump other artifacts
- Add llvm link_targets for comparison

Diffstat:
Mlib/compiler/objdump.zig | 13+++++++------
Mtest/link.zig | 132+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Dtest/link/snapshots/abs-symbol-x86_64.dmp | 1-
Atest/link/snapshots/dynamic-lib-code.implib-windows.dmp | 32++++++++++++++++++++++++++++++++
Atest/link/snapshots/dynamic-lib-code.windows.dmp | 13+++++++++++++
Dtest/link/snapshots/emit-static-lib.dmp | 10----------
Dtest/link/snapshots/exports-dynamic.dmp | 14--------------
Dtest/link/snapshots/exports-static.dmp | 3---
Mtest/src/Link.zig | 47++++++++++++++++++++++++++++++++---------------
Mtest/tests.zig | 38++++++++++++++++++++++++++++++++++++++
10 files changed, 218 insertions(+), 85 deletions(-)

diff --git a/lib/compiler/objdump.zig b/lib/compiler/objdump.zig @@ -401,12 +401,13 @@ const coff = struct { , .{ expected_kind, num_symbols }); if (d.opts.linker_member == .first_linker) { - try w.writeAll( - \\ - \\Archive symbols: - \\& Member Symbol - \\ - ); + if (d.element(.@"table-header")) + try w.writeAll( + \\ + \\Archive symbols: + \\& Member Symbol + \\ + ); const offsets = try r.readAlloc(gpa, num_symbols * 4); defer gpa.free(offsets); diff --git a/test/link.zig b/test/link.zig @@ -1,29 +1,5 @@ pub fn addCases(ctx: *LinkContext) void { - if (ctx.includeTest("exports-static")) |case| { - const lib = case.addLibrary(.static, .{ - .name = "lib", - .zig_source_file = ctx.sourcePath("exports.zig"), - }); - case.verifyObjdump(lib, &.{ - "-s", - "--symbols", - "--only-symbol=foo", - }, .{}); - } - - if (ctx.includeTest("exports-dynamic")) |case| { - const lib = case.addLibrary(.dynamic, .{ - .name = "lib", - .zig_source_file = ctx.sourcePath("exports.zig"), - }); - case.verifyObjdump(lib, &.{ - "-s", - "--exports", - "--only-symbol=foo", - }, .{}); - } - - if (ctx.includeTest("emit-static-lib")) |case| { + if (ctx.includeTest("static-lib")) |case| { const obj1 = case.addObject(.{ .name = "obj1", .name_prefix = false, @@ -43,14 +19,14 @@ pub fn addCases(ctx: *LinkContext) void { .name_prefix = false, .name_target = false, .zig_source_bytes = - \\fn weakFoo() callconv(.c) usize { + \\fn fooWeak() callconv(.c) usize { \\ return 0xaabbccddaabbccdd; \\} - \\export var array_foo: [2]u16 = .{ 0xffff, 0xabcd }; - \\export var strong_foo: usize = 0x1122334411223344; + \\export var foo_array: [2]u16 = .{ 0xffff, 0xabcd }; + \\export var foo_strong: usize = 0x1122334411223344; \\comptime { - \\ @export(&weakFoo, .{ .name = "weakFoo", .linkage = .weak }); - \\ @export(&strong_foo, .{ .name = "strong_foo_alias", .linkage = .strong }); + \\ @export(&fooWeak, .{ .name = "fooWeak", .linkage = .weak }); + \\ @export(&foo_strong, .{ .name = "foo_strong_alias", .linkage = .strong }); \\} , }); @@ -63,25 +39,109 @@ pub fn addCases(ctx: *LinkContext) void { lib.root_module.addObject(obj1); lib.root_module.addObject(obj2); - case.verifyObjdump(lib, &.{ + case.verifyObjdump(lib.getEmittedBin(), &.{ "-s", "--elements=file-type", "--symbols", "--only-symbol=foo", - "--only-symbol=Foo", }, .{}); const exe = case.addExecutable(.{ .name = "test", .zig_source_bytes = \\extern fn fooBar() c_uint; - \\extern fn weakFoo() usize; + \\extern fn fooWeak() usize; + \\extern var foo_array: [2]u16; + \\extern var foo_strong: usize; + \\extern var foo_strong_alias: usize; + \\pub fn main() !u8 { + \\ return @intFromBool(0xcd003365cd00df35 != fooBar() + + \\ fooWeak() + + \\ foo_array[1] + + \\ foo_strong + + \\ foo_strong_alias); + \\} + , + }); + exe.root_module.linkLibrary(lib); + + const run = case.addRunArtifact(exe); + run.addCheck(.{ .expect_term = .{ .exited = 0 } }); + } + + if (ctx.includeTest("dynamic-lib-code")) |case| { + const lib = case.addLibrary(.dynamic, .{ + .name = "lib", + .zig_source_bytes = + \\export fn foo1() callconv(.c) u64 { + \\ return 0x1122334411223344; + \\} + \\export fn foo2() callconv(.c) u64 { + \\ return 0xaabbccddaabbccdd; + \\} + , + }); + + case.verifyObjdump(lib.getEmittedBin(), &.{ + "-s", + "--exports", + "--only-symbol=foo", + }, .{ .os = true }); + + if (ctx.target.result.os.tag == .windows) { + case.verifyObjdump(lib.getEmittedImplib(), &.{ + "-s", + "--exports", + "--only-symbol=foo", + }, .{ .sub_name = "implib", .os = true }); + } + + const exe = case.addExecutable(.{ + .name = "test", + .zig_source_bytes = + \\extern fn foo1() u64; + \\pub fn main() !u8 { + \\ const foo2 = @extern( + \\ *const fn () callconv(.c) u64, + \\ .{ .name = "foo2", .is_dll_import = true }, + \\ ); + \\ return @intFromBool(0xbbde0021bbde0021 != foo1() + foo2()); + \\} + , + }); + exe.root_module.linkLibrary(lib); + + const run = case.addRunArtifact(exe); + run.addCheck(.{ .expect_term = .{ .exited = 0 } }); + } + + if (ctx.includeTest("dynamic-lib-data")) |case| { + const lib = case.addLibrary(.dynamic, .{ + .name = "lib", + .zig_source_bytes = + \\export var array_foo: [2]u16 = .{ 0xffff, 0xabcd }; + \\export var strong_foo: usize = 0x1122334411223344; + , + }); + + case.verifyObjdump(lib.getEmittedBin(), &.{ + "-s", + "--exports", + "--only-symbol=foo", + }, .{}); + + if (ctx.target.result.os.tag == .windows) { + // TODO: objdump implib on windows + } + + const exe = case.addExecutable(.{ + .name = "test", + .zig_source_bytes = \\extern var array_foo: [2]u16; \\extern var strong_foo: usize; \\extern var strong_foo_alias: usize; \\pub fn main() !u8 { - \\ return @intFromBool(0xcd003365cd00df35 != fooBar() + - \\ weakFoo() + + \\ return @intFromBool(0x2244668822451255 != \\ array_foo[1] + \\ strong_foo + \\ strong_foo_alias); @@ -118,7 +178,7 @@ pub fn addCases(ctx: *LinkContext) void { , }); - case.verifyObjdump(abs_reloc, &.{ + case.verifyObjdump(abs_reloc.getEmittedBin(), &.{ "-s", "--relocs", }, .{ .arch = true }); diff --git a/test/link/snapshots/abs-symbol-x86_64.dmp b/test/link/snapshots/abs-symbol-x86_64.dmp @@ -1 +0,0 @@ -xxxxxxxx ADDR32 xxxxxxxx UNDEF | foo diff --git a/test/link/snapshots/dynamic-lib-code.implib-windows.dmp b/test/link/snapshots/dynamic-lib-code.implib-windows.dmp @@ -0,0 +1,32 @@ + 0 date + 0 user_id + 0 group_id + 0 file_mode +xxxxxxxxxxxxxxxx size + second_linker type + | 7 symbols + | 5 members +xxxxxxxx __imp_foo1 +xxxxxxxx __imp_foo2 +xxxxxxxx foo1 +xxxxxxxx foo2 + 0 version + 8664 machine (AMD64) + 0 time_date_stamp +xxxxxxxxxxxxxxxx size_of_data + 0 hint + CODE import_type + NAME name_type + symbol name | foo1 + import name | foo1 + dll | dynamic-lib-code-lib-x86_64-windows.win10...win11_dt-msvc-Debug-llvm-lld-libc.dll + 0 version + 8664 machine (AMD64) + 0 time_date_stamp +xxxxxxxxxxxxxxxx size_of_data + 0 hint + CODE import_type + NAME name_type + symbol name | foo2 + import name | foo2 + dll | dynamic-lib-code-lib-x86_64-windows.win10...win11_dt-msvc-Debug-llvm-lld-libc.dll diff --git a/test/link/snapshots/dynamic-lib-code.windows.dmp b/test/link/snapshots/dynamic-lib-code.windows.dmp @@ -0,0 +1,13 @@ +Export directory: + 0 flags + 0 time_date_stamp + 0.00 version +xxxxxxxxxxxxxxxx name_rva + 1 ordinal_base +xxxxxxxxxxxxxxxx number_of_entries +xxxxxxxxxxxxxxxx number_of_names +xxxxxxxxxxxxxxxx export_address_table_rva +xxxxxxxxxxxxxxxx name_pointer_table_rva +xxxxxxxxxxxxxxxx ordinal_table_rva +xxxx xxxx xxxxxxxx | foo1 +xxxx xxxx xxxxxxxx | foo2 diff --git a/test/link/snapshots/emit-static-lib.dmp b/test/link/snapshots/emit-static-lib.dmp @@ -1,10 +0,0 @@ -lib.lib: COFF archive -lib.lib(obj1.obj): COFF object -xxxx 00000000 1 NULL() EXTERNAL | fooBar -xxxx 00000000 2 NULL EXTERNAL | foo1 -xxxx 00000004 2 NULL EXTERNAL | foo2 -lib.lib(this_is_a_long_name.obj): COFF object -xxxx 00000000 4 NULL() EXTERNAL | weakFoo -xxxx 00000010 2 NULL EXTERNAL | array_foo -xxxx 00000000 2 NULL EXTERNAL | strong_foo_alias -xxxx 00000000 2 NULL EXTERNAL | strong_foo diff --git a/test/link/snapshots/exports-dynamic.dmp b/test/link/snapshots/exports-dynamic.dmp @@ -1,14 +0,0 @@ -Export directory: - 0 flags - 0 time_date_stamp - 0.00 version -xxxxxxxxxxxxxxxx name_rva - 1 ordinal_base -xxxxxxxxxxxxxxxx number_of_entries -xxxxxxxxxxxxxxxx number_of_names -xxxxxxxxxxxxxxxx export_address_table_rva -xxxxxxxxxxxxxxxx name_pointer_table_rva -xxxxxxxxxxxxxxxx ordinal_table_rva -xxxx xxxx xxxxxxxx | foo_const -xxxx xxxx xxxxxxxx | foo_fn -xxxx xxxx xxxxxxxx | foo_var diff --git a/test/link/snapshots/exports-static.dmp b/test/link/snapshots/exports-static.dmp @@ -1,3 +0,0 @@ -xxxx 00000000 4 NULL() EXTERNAL | foo_fn -xxxx 00000000 2 NULL EXTERNAL | foo_var -xxxx 00000008 3 NULL EXTERNAL | foo_const diff --git a/test/src/Link.zig b/test/src/Link.zig @@ -101,7 +101,7 @@ pub const Case = struct { } const SnapshotScope = struct { - /// If a test case has multiple verifyObjdump calls, `opt_sub_name` can + /// If a test case has multiple verifyObjdump calls, `opt_sub_name` should /// be used to differentiate them. sub_name: ?[]const u8 = null, arch: bool = false, @@ -120,7 +120,7 @@ pub const Case = struct { /// pub fn verifyObjdump( self: *const Case, - compile: *Step.Compile, + file: Build.LazyPath, args: []const []const u8, scope: SnapshotScope, ) void { @@ -140,7 +140,7 @@ pub const Case = struct { .{ snapshot_name, ctx.target_desc }, )); run_step.addArgs(&.{ ctx.b.graph.zig_exe, "objdump" }); - run_step.addArtifactArg(compile); + run_step.addFileArg(file); run_step.addArgs(args); run_step.addCheck(.{ .expect_term = .{ .exited = 0 } }); @@ -166,22 +166,39 @@ pub const Case = struct { const w = &snapshot_name.writer; try w.writeAll(self.prefix); - if (scope.sub_name) |sub_name| { - try w.writeByte('.'); - try w.writeAll(sub_name); - } + var sep: u8 = '.'; + + if (try snapshotNameInner(w, scope.sub_name != null, &sep)) + try w.writeAll(scope.sub_name.?); + if (try snapshotNameInner(w, scope.arch, &sep)) + try w.print("{t}", .{ctx.target.result.cpu.arch}); + if (try snapshotNameInner(w, scope.os, &sep)) + try w.print("{t}", .{ctx.target.result.os.tag}); + if (try snapshotNameInner(w, scope.abi, &sep)) + try w.print("{t}", .{ctx.target.result.abi}); + if (try snapshotNameInner(w, scope.optimize, &sep)) + try w.print("{t}", .{ctx.optimize}); + if (try snapshotNameInner(w, scope.use_llvm, &sep)) + try w.writeAll(if (ctx.use_llvm) "llvm" else "no-llvm"); + if (try snapshotNameInner(w, scope.use_lld, &sep)) + try w.writeAll(if (ctx.use_lld) "lld" else "no-lld"); + if (try snapshotNameInner(w, scope.link_libc, &sep)) + try w.writeAll(if (ctx.link_libc) "libc" else "no-libc"); - if (scope.arch) try w.print("-{t}", .{ctx.target.result.cpu.arch}); - if (scope.os) try w.print("-{t}", .{ctx.target.result.os.tag}); - if (scope.abi) try w.print("-{t}", .{ctx.target.result.abi}); - if (scope.optimize) try w.print("-{t}", .{ctx.optimize}); - if (scope.use_llvm) try w.writeAll(if (ctx.use_llvm) "-llvm" else "-no-llvm"); - if (scope.use_lld) try w.writeAll(if (ctx.use_lld) "-lld" else "-no-lld"); - if (scope.link_libc) try w.writeAll(if (ctx.link_libc) "-libc" else "-no-libc"); - try w.writeAll(".dmp"); + if (sep == '-') try w.writeByte('.'); + try w.writeAll("dmp"); return try snapshot_name.toOwnedSlice(); } + + fn snapshotNameInner(w: *std.Io.Writer, cond: bool, sep: *u8) !bool { + if (cond) { + try w.writeByte(sep.*); + sep.* = '-'; + } + + return cond; + } }; fn createModule(self: *const Link, overlay: OverlayOptions) *Build.Module { diff --git a/test/tests.zig b/test/tests.zig @@ -2098,6 +2098,25 @@ const link_targets = blk: { .target = .{ .cpu_arch = .x86_64, .os_tag = .windows, + .abi = .gnu, + }, + .use_llvm = true, + .use_lld = true, + }, + .{ + .target = .{ + .cpu_arch = .x86_64, + .os_tag = .windows, + .abi = .gnu, + }, + .link_libc = true, + .use_llvm = true, + .use_lld = true, + }, + .{ + .target = .{ + .cpu_arch = .x86_64, + .os_tag = .windows, .abi = .msvc, }, }, @@ -2109,6 +2128,25 @@ const link_targets = blk: { }, .link_libc = true, }, + .{ + .target = .{ + .cpu_arch = .x86_64, + .os_tag = .windows, + .abi = .msvc, + }, + .use_llvm = true, + .use_lld = true, + }, + .{ + .target = .{ + .cpu_arch = .x86_64, + .os_tag = .windows, + .abi = .msvc, + }, + .link_libc = true, + .use_llvm = true, + .use_lld = true, + }, }; };