Promote linker test cases to packages

This commit is contained in:
Carl Åstholm 2024-02-17 17:47:13 +01:00 committed by Andrew Kelley
parent 33b8fdb6bc
commit 5d5e89aa8d
6 changed files with 144 additions and 142 deletions

View File

@ -524,7 +524,7 @@ pub fn build(b: *std.Build) !void {
enable_symlinks_windows, enable_symlinks_windows,
)); ));
test_step.dependOn(tests.addCAbiTests(b, skip_non_native, skip_release)); test_step.dependOn(tests.addCAbiTests(b, skip_non_native, skip_release));
test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, false, enable_symlinks_windows)); test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));
test_step.dependOn(tests.addStackTraceTests(b, test_filters, optimization_modes)); test_step.dependOn(tests.addStackTraceTests(b, test_filters, optimization_modes));
test_step.dependOn(tests.addCliTests(b)); test_step.dependOn(tests.addCliTests(b));
test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filters, optimization_modes)); test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filters, optimization_modes));

View File

@ -7,6 +7,9 @@
.standalone_test_cases = .{ .standalone_test_cases = .{
.path = "test/standalone", .path = "test/standalone",
}, },
.link_test_cases = .{
.path = "test/link",
},
}, },
.paths = .{""}, .paths = .{""},
} }

View File

@ -1,94 +0,0 @@
pub const Case = struct {
build_root: []const u8,
import: type,
};
pub const cases = [_]Case{
.{
.build_root = "test/link",
.import = @import("link/link.zig"),
},
.{
.build_root = "test/link/bss",
.import = @import("link/bss/build.zig"),
},
.{
.build_root = "test/link/common_symbols",
.import = @import("link/common_symbols/build.zig"),
},
.{
.build_root = "test/link/common_symbols_alignment",
.import = @import("link/common_symbols_alignment/build.zig"),
},
.{
.build_root = "test/link/interdependent_static_c_libs",
.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"),
},
// WASM Cases
.{
.build_root = "test/link/wasm/archive",
.import = @import("link/wasm/archive/build.zig"),
},
.{
.build_root = "test/link/wasm/basic-features",
.import = @import("link/wasm/basic-features/build.zig"),
},
.{
.build_root = "test/link/wasm/bss",
.import = @import("link/wasm/bss/build.zig"),
},
.{
.build_root = "test/link/wasm/export",
.import = @import("link/wasm/export/build.zig"),
},
.{
.build_root = "test/link/wasm/export-data",
.import = @import("link/wasm/export-data/build.zig"),
},
.{
.build_root = "test/link/wasm/extern",
.import = @import("link/wasm/extern/build.zig"),
},
.{
.build_root = "test/link/wasm/extern-mangle",
.import = @import("link/wasm/extern-mangle/build.zig"),
},
.{
.build_root = "test/link/wasm/function-table",
.import = @import("link/wasm/function-table/build.zig"),
},
.{
.build_root = "test/link/wasm/infer-features",
.import = @import("link/wasm/infer-features/build.zig"),
},
.{
.build_root = "test/link/wasm/producers",
.import = @import("link/wasm/producers/build.zig"),
},
.{
.build_root = "test/link/wasm/segments",
.import = @import("link/wasm/segments/build.zig"),
},
.{
.build_root = "test/link/wasm/shared-memory",
.import = @import("link/wasm/shared-memory/build.zig"),
},
.{
.build_root = "test/link/wasm/stack_pointer",
.import = @import("link/wasm/stack_pointer/build.zig"),
},
.{
.build_root = "test/link/wasm/type",
.import = @import("link/wasm/type/build.zig"),
},
};

54
test/link/build.zig Normal file
View File

@ -0,0 +1,54 @@
const std = @import("std");
const builtin = @import("builtin");
const link = @import("link.zig");
pub fn build(b: *std.Build) void {
const step = b.step("test", "Run link test cases");
b.default_step = step;
const enable_ios_sdk = b.option(bool, "enable_ios_sdk", "Run tests requiring presence of iOS SDK and frameworks") orelse false;
const enable_macos_sdk = b.option(bool, "enable_macos_sdk", "Run tests requiring presence of macOS SDK and frameworks") orelse enable_ios_sdk;
const enable_symlinks_windows = b.option(bool, "enable_symlinks_windows", "Run tests requiring presence of symlinks on Windows") orelse false;
const omit_symlinks = builtin.os.tag == .windows and !enable_symlinks_windows;
const build_opts: link.BuildOptions = .{
.has_ios_sdk = enable_ios_sdk,
.has_macos_sdk = enable_macos_sdk,
.has_symlinks_windows = omit_symlinks,
};
step.dependOn(@import("elf.zig").testAll(b, build_opts));
step.dependOn(@import("macho.zig").testAll(b, build_opts));
add_dep_steps: for (b.available_deps) |available_dep| {
const dep_name, const dep_hash = available_dep;
const all_pkgs = @import("root").dependencies.packages;
inline for (@typeInfo(all_pkgs).Struct.decls) |decl| {
const pkg_hash = decl.name;
if (std.mem.eql(u8, dep_hash, pkg_hash)) {
const pkg = @field(all_pkgs, pkg_hash);
if (!@hasDecl(pkg, "build_zig")) {
std.debug.panic("link test case '{s}' is missing a 'build.zig' file", .{dep_name});
}
const requires_ios_sdk = @hasDecl(pkg.build_zig, "requires_ios_sdk") and
pkg.build_zig.requires_ios_sdk;
const requires_macos_sdk = @hasDecl(pkg.build_zig, "requires_macos_sdk") and
pkg.build_zig.requires_macos_sdk;
const requires_symlinks = @hasDecl(pkg.build_zig, "requires_symlinks") and
pkg.build_zig.requires_symlinks;
if ((requires_symlinks and omit_symlinks) or
(requires_macos_sdk and !enable_macos_sdk) or
(requires_ios_sdk and !enable_ios_sdk))
{
continue :add_dep_steps;
}
break;
}
} else unreachable;
const dep = b.dependency(dep_name, .{});
const dep_step = dep.builder.default_step;
dep_step.name = b.fmt("link_test_cases.{s}", .{dep_name});
step.dependOn(dep_step);
}
}

69
test/link/build.zig.zon Normal file
View File

@ -0,0 +1,69 @@
.{
.name = "link_test_cases",
.version = "0.0.0",
.dependencies = .{
.bss = .{
.path = "bss",
},
.common_symbols_alignment = .{
.path = "common_symbols_alignment",
},
.interdependent_static_c_libs = .{
.path = "interdependent_static_c_libs",
},
.static_libs_from_object_files = .{
.path = "static_libs_from_object_files",
},
.glibc_compat = .{
.path = "glibc_compat",
},
// WASM Cases
.wasm_archive = .{
.path = "wasm/archive",
},
.wasm_basic_features = .{
.path = "wasm/basic-features",
},
.wasm_bss = .{
.path = "wasm/bss",
},
.wasm_export = .{
.path = "wasm/export",
},
.wasm_export_data = .{
.path = "wasm/export-data",
},
.wasm_extern = .{
.path = "wasm/extern",
},
.wasm_extern_mangle = .{
.path = "wasm/extern-mangle",
},
.wasm_function_table = .{
.path = "wasm/function-table",
},
.wasm_infer_features = .{
.path = "wasm/infer-features",
},
.wasm_producers = .{
.path = "wasm/producers",
},
.wasm_segments = .{
.path = "wasm/segments",
},
.wasm_shared_memory = .{
.path = "wasm/shared-memory",
},
.wasm_stack_pointer = .{
.path = "wasm/stack_pointer",
},
.wasm_type = .{
.path = "wasm/type",
},
},
.paths = .{
"build.zig",
"build.zig.zon",
"link.zig",
},
}

View File

@ -11,7 +11,6 @@ const stack_traces = @import("stack_traces.zig");
const assemble_and_link = @import("assemble_and_link.zig"); const assemble_and_link = @import("assemble_and_link.zig");
const translate_c = @import("translate_c.zig"); const translate_c = @import("translate_c.zig");
const run_translated_c = @import("run_translated_c.zig"); const run_translated_c = @import("run_translated_c.zig");
const link = @import("link.zig");
// Implementations // Implementations
pub const TranslateCContext = @import("src/TranslateC.zig"); pub const TranslateCContext = @import("src/TranslateC.zig");
@ -662,6 +661,12 @@ pub fn addStackTraceTests(
return cases.step; return cases.step;
} }
fn compilerHasPackageManager(b: *std.Build) bool {
// We can only use dependencies if the compiler was built with support for package management.
// (zig2 doesn't support it, but we still need to construct a build graph to build stage3.)
return b.available_deps.len != 0;
}
pub fn addStandaloneTests( pub fn addStandaloneTests(
b: *std.Build, b: *std.Build,
optimize_modes: []const OptimizeMode, optimize_modes: []const OptimizeMode,
@ -670,12 +675,7 @@ pub fn addStandaloneTests(
enable_symlinks_windows: bool, enable_symlinks_windows: bool,
) *Step { ) *Step {
const step = b.step("test-standalone", "Run the standalone tests"); const step = b.step("test-standalone", "Run the standalone tests");
if (compilerHasPackageManager(b)) {
// We can only use dependencies if the compiler was built with support for package management.
// (zig2 doesn't support it, but we still need to construct a build graph to build stage3.)
const package_management_available = b.available_deps.len != 0;
if (package_management_available) {
const test_cases_dep_name = "standalone_test_cases"; const test_cases_dep_name = "standalone_test_cases";
const test_cases_dep = b.dependency(test_cases_dep_name, .{ const test_cases_dep = b.dependency(test_cases_dep_name, .{
.enable_ios_sdk = enable_ios_sdk, .enable_ios_sdk = enable_ios_sdk,
@ -690,7 +690,6 @@ pub fn addStandaloneTests(
test_cases_dep_step.name = b.dupe(test_cases_dep_name); test_cases_dep_step.name = b.dupe(test_cases_dep_name);
step.dependOn(test_cases_dep.builder.default_step); step.dependOn(test_cases_dep.builder.default_step);
} }
return step; return step;
} }
@ -698,49 +697,20 @@ pub fn addLinkTests(
b: *std.Build, b: *std.Build,
enable_macos_sdk: bool, enable_macos_sdk: bool,
enable_ios_sdk: bool, enable_ios_sdk: bool,
omit_stage2: bool,
enable_symlinks_windows: bool, enable_symlinks_windows: bool,
) *Step { ) *Step {
const step = b.step("test-link", "Run the linker tests"); const step = b.step("test-link", "Run the linker tests");
const omit_symlinks = builtin.os.tag == .windows and !enable_symlinks_windows; if (compilerHasPackageManager(b)) {
const test_cases_dep_name = "link_test_cases";
inline for (link.cases) |case| { const test_cases_dep = b.dependency(test_cases_dep_name, .{
if (mem.eql(u8, @typeName(case.import), "test.link.link")) { .enable_ios_sdk = enable_ios_sdk,
const dep = b.anonymousDependency(case.build_root, case.import, .{ .enable_macos_sdk = enable_macos_sdk,
.has_macos_sdk = enable_macos_sdk, .enable_symlinks_windows = enable_symlinks_windows,
.has_ios_sdk = enable_ios_sdk, });
.has_symlinks_windows = !omit_symlinks, const test_cases_dep_step = test_cases_dep.builder.default_step;
}); test_cases_dep_step.name = b.dupe(test_cases_dep_name);
const dep_step = dep.builder.default_step; step.dependOn(test_cases_dep.builder.default_step);
assert(mem.startsWith(u8, dep.builder.dep_prefix, "test."));
const dep_prefix_adjusted = dep.builder.dep_prefix["test.".len..];
dep_step.name = b.fmt("{s}{s}", .{ dep_prefix_adjusted, dep_step.name });
step.dependOn(dep_step);
} else {
const requires_stage2 = @hasDecl(case.import, "requires_stage2") and
case.import.requires_stage2;
const requires_symlinks = @hasDecl(case.import, "requires_symlinks") and
case.import.requires_symlinks;
const requires_macos_sdk = @hasDecl(case.import, "requires_macos_sdk") and
case.import.requires_macos_sdk;
const requires_ios_sdk = @hasDecl(case.import, "requires_ios_sdk") and
case.import.requires_ios_sdk;
const bad =
(requires_stage2 and omit_stage2) or
(requires_symlinks and omit_symlinks) or
(requires_macos_sdk and !enable_macos_sdk) or
(requires_ios_sdk and !enable_ios_sdk);
if (!bad) {
const dep = b.anonymousDependency(case.build_root, case.import, .{});
const dep_step = dep.builder.default_step;
assert(mem.startsWith(u8, dep.builder.dep_prefix, "test."));
const dep_prefix_adjusted = dep.builder.dep_prefix["test.".len..];
dep_step.name = b.fmt("{s}{s}", .{ dep_prefix_adjusted, dep_step.name });
step.dependOn(dep_step);
}
}
} }
return step; return step;
} }