mirror of
https://github.com/ziglang/zig.git
synced 2024-12-04 02:48:50 +00:00
cbaaf6477f
The strlcpy symbol was added in v2.38, so this is a handy symbol for creating binaries that won't run on relatively modern systems (e.g., mine, that has glibc 2.36 installed).
122 lines
4.5 KiB
Zig
122 lines
4.5 KiB
Zig
const std = @import("std");
|
|
const builtin = @import("builtin");
|
|
|
|
// To run executables linked against a specific glibc version, the
|
|
// run-time glibc version needs to be new enough. Check the host's glibc
|
|
// version. Note that this does not allow for translation/vm/emulation
|
|
// services to run these tests.
|
|
const running_glibc_ver: ?std.SemanticVersion = switch (builtin.os.tag) {
|
|
.linux => builtin.os.version_range.linux.glibc,
|
|
else => null,
|
|
};
|
|
|
|
pub fn build(b: *std.Build) void {
|
|
const test_step = b.step("test", "Test");
|
|
b.default_step = test_step;
|
|
|
|
for ([_][]const u8{ "aarch64-linux-gnu.2.27", "aarch64-linux-gnu.2.34" }) |t| {
|
|
const exe = b.addExecutable(.{
|
|
.name = t,
|
|
.target = b.resolveTargetQuery(std.Target.Query.parse(
|
|
.{ .arch_os_abi = t },
|
|
) catch unreachable),
|
|
});
|
|
exe.addCSourceFile(.{ .file = .{ .path = "main.c" } });
|
|
exe.linkLibC();
|
|
// TODO: actually test the output
|
|
_ = exe.getEmittedBin();
|
|
test_step.dependOn(&exe.step);
|
|
}
|
|
|
|
// Build & run against a sampling of supported glibc versions
|
|
for ([_][]const u8{
|
|
"native-linux-gnu.2.17", // Currently oldest supported, see #17769
|
|
"native-linux-gnu.2.23",
|
|
"native-linux-gnu.2.28",
|
|
"native-linux-gnu.2.33",
|
|
"native-linux-gnu.2.38",
|
|
"native-linux-gnu",
|
|
}) |t| {
|
|
const target = b.resolveTargetQuery(std.Target.Query.parse(
|
|
.{ .arch_os_abi = t },
|
|
) catch unreachable);
|
|
|
|
const glibc_ver = target.result.os.version_range.linux.glibc;
|
|
|
|
const exe = b.addExecutable(.{
|
|
.name = t,
|
|
.root_source_file = .{ .path = "glibc_runtime_check.zig" },
|
|
.target = target,
|
|
});
|
|
exe.linkLibC();
|
|
|
|
// Only try running the test if the host glibc is known to be good enough. Ideally, the Zig
|
|
// test runner would be able to check this, but see https://github.com/ziglang/zig/pull/17702#issuecomment-1831310453
|
|
if (running_glibc_ver) |running_ver| {
|
|
if (glibc_ver.order(running_ver) == .lt) {
|
|
const run_cmd = b.addRunArtifact(exe);
|
|
run_cmd.skip_foreign_checks = true;
|
|
run_cmd.expectExitCode(0);
|
|
|
|
test_step.dependOn(&run_cmd.step);
|
|
}
|
|
}
|
|
const check = exe.checkObject();
|
|
|
|
// __errno_location is always a dynamically linked symbol
|
|
check.checkInDynamicSymtab();
|
|
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT __errno_location");
|
|
|
|
// before v2.32 fstatat redirects through __fxstatat, afterwards its a
|
|
// normal dynamic symbol
|
|
if (glibc_ver.order(.{ .major = 2, .minor = 32, .patch = 0 }) == .lt) {
|
|
check.checkInDynamicSymtab();
|
|
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT __fxstatat");
|
|
|
|
check.checkInSymtab();
|
|
check.checkContains("FUNC LOCAL HIDDEN fstatat");
|
|
} else {
|
|
check.checkInDynamicSymtab();
|
|
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT fstatat");
|
|
|
|
check.checkInSymtab();
|
|
check.checkNotPresent("FUNC LOCAL HIDDEN fstatat");
|
|
}
|
|
|
|
// before v2.26 reallocarray is not supported
|
|
if (glibc_ver.order(.{ .major = 2, .minor = 26, .patch = 0 }) == .lt) {
|
|
check.checkInDynamicSymtab();
|
|
check.checkNotPresent("reallocarray");
|
|
} else {
|
|
check.checkInDynamicSymtab();
|
|
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT reallocarray");
|
|
}
|
|
|
|
// before v2.38 strlcpy is not supported
|
|
if (glibc_ver.order(.{ .major = 2, .minor = 38, .patch = 0 }) == .lt) {
|
|
check.checkInDynamicSymtab();
|
|
check.checkNotPresent("strlcpy");
|
|
} else {
|
|
check.checkInDynamicSymtab();
|
|
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT strlcpy");
|
|
}
|
|
|
|
// v2.16 introduced getauxval(), so always present
|
|
check.checkInDynamicSymtab();
|
|
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT getauxval");
|
|
|
|
// Always have a dynamic "exit" reference
|
|
check.checkInDynamicSymtab();
|
|
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT exit");
|
|
|
|
// An atexit local symbol is defined, and depends on undefined dynamic
|
|
// __cxa_atexit.
|
|
check.checkInSymtab();
|
|
check.checkContains("FUNC LOCAL HIDDEN atexit");
|
|
check.checkInDynamicSymtab();
|
|
check.checkExact("0 0 UND FUNC GLOBAL DEFAULT __cxa_atexit");
|
|
|
|
test_step.dependOn(&check.step);
|
|
}
|
|
}
|