Compare commits

..

32 commits

Author SHA1 Message Date
Alex Rønne Petersen
d22231c039
Compilation: track indirect file system inputs from clang's depfile
Co-authored-by: Matthew Lugg <mlugg@mlugg.co.uk>
2025-12-05 11:22:10 +01:00
Alex Rønne Petersen
38415911c1
compiler: handle -Xlinker args similarly to -Wl args 2025-12-05 11:04:51 +01:00
Alex Rønne Petersen
34f88722cd
compiler: support --dependency-file linker option
closes https://github.com/ziglang/zig/issues/22213
2025-12-05 11:04:48 +01:00
Alex Rønne Petersen
4724774433
ci: apply workaround for #22213 to x86_64-linux scripts
This should be reverted on the next CI tarballs update.
2025-12-05 07:32:43 +01:00
Alex Rønne Petersen
78cba86928
ci: set maxrss from $ZSF_MAX_RSS if provided by the runner
Some checks are pending
ci / aarch64-linux-debug (push) Waiting to run
ci / aarch64-linux-release (push) Waiting to run
ci / aarch64-macos-debug (push) Waiting to run
ci / aarch64-macos-release (push) Waiting to run
ci / loongarch64-linux-debug (push) Waiting to run
ci / loongarch64-linux-release (push) Waiting to run
ci / riscv64-linux-debug (push) Waiting to run
ci / riscv64-linux-release (push) Waiting to run
ci / s390x-linux-debug (push) Waiting to run
ci / s390x-linux-release (push) Waiting to run
ci / x86_64-freebsd-debug (push) Waiting to run
ci / x86_64-freebsd-release (push) Waiting to run
ci / x86_64-linux-debug (push) Waiting to run
ci / x86_64-linux-debug-llvm (push) Waiting to run
ci / x86_64-linux-release (push) Waiting to run
ci / x86_64-windows-debug (push) Waiting to run
ci / x86_64-windows-release (push) Waiting to run
All of our runners now define this. When running a CI script locally, this will
not be set, so we default to 0, aka "all available system memory".
2025-12-04 20:06:48 +01:00
Alex Rønne Petersen
2728eb5d5e
build: adjust max_rss on a per-CI-host basis
This avoids pessimizing concurrency on all machines due to e.g. the macOS
machine having high memory usage across the board due to 16K page size.

This also adds max_rss to test-unit and test-c-abi since those tend to eat a
decent chunk of memory too.
2025-12-04 20:06:12 +01:00
Alex Rønne Petersen
44543800a5
std.process.Child: enable rusage collection for dragonfly, netbsd, openbsd 2025-12-04 03:46:36 +01:00
Alex Rønne Petersen
2659fadb95
std.c: add rusage for dragonfly, netbsd, openbsd 2025-12-04 03:46:36 +01:00
Alex Rønne Petersen
9eed87f93e
std.process.Child: enable rusage collection for freebsd, illumos, serenity 2025-12-04 03:46:36 +01:00
Alex Rønne Petersen
e270c97ed1
ci: don't skip release mode tests on x86_64-windows-debug
pulsar is much faster than george so we don't need to do this anymore.
2025-12-04 03:46:36 +01:00
Alex Rønne Petersen
c21ce53494
ci: skip spirv and wasm tests on x86_64-freebsd
These are already built and run on x86_64-linux.
2025-12-04 03:46:36 +01:00
Alex Rønne Petersen
e2a9e568b4
build: add -Dskip-spirv and -Dskip-wasm options 2025-12-04 03:46:35 +01:00
Alex Rønne Petersen
ad9a5187ac
build: add some missing darwin tags 2025-12-04 03:46:35 +01:00
jedisct1
d73fbcc3ae Merge pull request 'Argon2: use the std.Io interface' (#30084) from jedisct1/zig:argon2 into master
Some checks failed
ci / aarch64-linux-debug (push) Has been cancelled
ci / aarch64-linux-release (push) Has been cancelled
ci / aarch64-macos-debug (push) Has been cancelled
ci / aarch64-macos-release (push) Has been cancelled
ci / loongarch64-linux-debug (push) Has been cancelled
ci / loongarch64-linux-release (push) Has been cancelled
ci / riscv64-linux-debug (push) Has been cancelled
ci / riscv64-linux-release (push) Has been cancelled
ci / s390x-linux-debug (push) Has been cancelled
ci / s390x-linux-release (push) Has been cancelled
ci / x86_64-freebsd-debug (push) Has been cancelled
ci / x86_64-freebsd-release (push) Has been cancelled
ci / x86_64-linux-debug (push) Has been cancelled
ci / x86_64-linux-debug-llvm (push) Has been cancelled
ci / x86_64-linux-release (push) Has been cancelled
ci / x86_64-windows-debug (push) Has been cancelled
ci / x86_64-windows-release (push) Has been cancelled
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/30084
2025-12-03 12:18:09 +01:00
Zihad
cb115cf73a std.process.ArgIteratorWasi: fix no-args deinit 2025-12-03 08:35:24 +01:00
Alex Rønne Petersen
be9649f4ea
ci: set a sensible maxrss in x86_64-windows scripts
Some checks are pending
ci / aarch64-linux-debug (push) Waiting to run
ci / aarch64-linux-release (push) Waiting to run
ci / aarch64-macos-debug (push) Waiting to run
ci / aarch64-macos-release (push) Waiting to run
ci / loongarch64-linux-debug (push) Waiting to run
ci / loongarch64-linux-release (push) Waiting to run
ci / riscv64-linux-debug (push) Waiting to run
ci / riscv64-linux-release (push) Waiting to run
ci / s390x-linux-debug (push) Waiting to run
ci / s390x-linux-release (push) Waiting to run
ci / x86_64-freebsd-debug (push) Waiting to run
ci / x86_64-freebsd-release (push) Waiting to run
ci / x86_64-linux-debug (push) Waiting to run
ci / x86_64-linux-debug-llvm (push) Waiting to run
ci / x86_64-linux-release (push) Waiting to run
ci / x86_64-windows-debug (push) Waiting to run
ci / x86_64-windows-release (push) Waiting to run
2025-12-03 00:24:58 +01:00
Frank Denis
6fe95c28cf Argon2: use the std.Io interface
Also reduce the memory required by tests.

4GB for every test is way too much and doesn't provide much benefits
in testing the algorithms.
2025-12-02 23:03:52 +01:00
Andrew Kelley
52ad126bb4 Merge pull request 'std.Io.Threaded: rework cancellation' (#30033) from cancellation into master
Some checks are pending
ci / aarch64-linux-debug (push) Waiting to run
ci / aarch64-linux-release (push) Waiting to run
ci / aarch64-macos-debug (push) Waiting to run
ci / aarch64-macos-release (push) Waiting to run
ci / loongarch64-linux-debug (push) Waiting to run
ci / loongarch64-linux-release (push) Waiting to run
ci / riscv64-linux-debug (push) Waiting to run
ci / riscv64-linux-release (push) Waiting to run
ci / s390x-linux-debug (push) Waiting to run
ci / s390x-linux-release (push) Waiting to run
ci / x86_64-freebsd-debug (push) Waiting to run
ci / x86_64-freebsd-release (push) Waiting to run
ci / x86_64-linux-debug (push) Waiting to run
ci / x86_64-linux-debug-llvm (push) Waiting to run
ci / x86_64-linux-release (push) Waiting to run
ci / x86_64-windows-debug (push) Waiting to run
ci / x86_64-windows-release (push) Waiting to run
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/30033
2025-12-02 17:58:29 +01:00
Andrew Kelley
bb3f56d5d5 std.Io.Threaded: separate out ECANCELED handling again
If ECANCELED occurs, it's from pthread_cancel which will *permanently*
set that thread to be in a "canceling" state, which means the cancel
cannot be ignored. That means it cannot be retried, like EINTR. It must
be acknowledged.
2025-12-01 19:17:52 -08:00
Andrew Kelley
cf82064ebc std.Io.Threaded: don't use pthread_cancel with musl
It doesn't support setting the "canceled" status to false, so once a
thread has been canceled, all operations on the thread start permanently
failing.
2025-12-01 19:17:52 -08:00
Andrew Kelley
bf0ffc45b9 std.Io.Threaded: musl: handle ECANCELED same as EINTR
Otherwise the pthread_cancel can affect unrelated tasks.
2025-12-01 19:17:52 -08:00
Andrew Kelley
54a84964f8 std.os.linux: SIG enum is non-exhaustive 2025-12-01 19:17:52 -08:00
Andrew Kelley
57f5de5b77 std.Io.Threaded: use the correct mmsghdr struct 2025-12-01 19:17:52 -08:00
Andrew Kelley
103467fa6c std.Io.Threaded: make is_musl linux-only 2025-12-01 19:17:52 -08:00
David Rubin
85053a6a36 link.Elf: implement aarch64 relocation 2025-12-01 19:17:52 -08:00
Andrew Kelley
c4f5dda135 std.Io.Threaded: re-introduce retry logic behind config 2025-12-01 19:17:52 -08:00
Andrew Kelley
de87bad4c3 std.Io.Threaded: don't solve the cancel race after all
Unfortunately, trying again until the cancellation request is
acknowledged has been observed to incur a large amount of overhead,
and usually strong cancellation guarantees are not needed, so the
race condition is not handled here. Users who want to avoid this
have this menu of options instead:
* Use no libc, in which case Zig std lib can avoid the race (tracking
  issue: https://codeberg.org/ziglang/zig/issues/30049)
* Use musl libc
* Use `std.Io.Evented`. But this is not implemented yet. Tracked by
  - https://codeberg.org/ziglang/zig/issues/30050
  - https://codeberg.org/ziglang/zig/issues/30051

glibc + threaded is the only problematic combination.
2025-12-01 19:17:52 -08:00
Andrew Kelley
144206856e std.Io.Threaded: fix compilation for riscv32-linux 2025-12-01 19:17:52 -08:00
Andrew Kelley
9e981c3ae5 std.os.linux: delete unnecessary @compileError
Without this, it already fails to compile with a sufficiently helpful
error message.
2025-12-01 19:17:52 -08:00
Andrew Kelley
39ac40209b std.Io.Threaded: use musl's beautiful pthread_cancel semantics 2025-12-01 19:17:52 -08:00
Andrew Kelley
d60760d61e std.Io.Threaded: tune requestCancel
On a heavily loaded Linux 6.17.5, I observed a maximum of 20 attempts
not acknowledged before the timeout (including exponential backoff) was
sufficient, despite the heavy load.

The time wasted here sleeping is mitigated by the fact that, later on,
the system will likely wait for the canceled task, causing it to
indefinitely yield until the canceled task finishes, and the task must
acknowledge the cancel before it proceeds to that point.
2025-12-01 19:17:52 -08:00
Andrew Kelley
29e418cbfb std.Io.Threaded: fix the cancellation race
Now, before a syscall is entered, beginSyscall is called, which may
return error.Canceled. After syscall returns, whether error or success,
endSyscall is called. If the syscall returns EINTR then checkCancel is
called.

`cancelRequested` is removed from the std.Io VTable for now, with plans
to replace it with a more powerful API that allows protection against
cancellation requests.

closes #25751
2025-12-01 19:17:52 -08:00
38 changed files with 2574 additions and 1386 deletions

182
build.zig
View file

@ -91,6 +91,8 @@ pub fn build(b: *std.Build) !void {
const skip_libc = b.option(bool, "skip-libc", "Main test suite skips tests that link libc") orelse false;
const skip_single_threaded = b.option(bool, "skip-single-threaded", "Main test suite skips tests that are single-threaded") orelse false;
const skip_compile_errors = b.option(bool, "skip-compile-errors", "Main test suite skips compile error tests") orelse false;
const skip_spirv = b.option(bool, "skip-spirv", "Main test suite skips targets with spirv32/spirv64 architecture") orelse false;
const skip_wasm = b.option(bool, "skip-wasm", "Main test suite skips targets with wasm32/wasm64 architecture") orelse false;
const skip_freebsd = b.option(bool, "skip-freebsd", "Main test suite skips targets with freebsd OS") orelse false;
const skip_netbsd = b.option(bool, "skip-netbsd", "Main test suite skips targets with netbsd OS") orelse false;
const skip_windows = b.option(bool, "skip-windows", "Main test suite skips targets with windows OS") orelse false;
@ -421,6 +423,8 @@ pub fn build(b: *std.Build) !void {
.test_target_filters = test_target_filters,
.skip_compile_errors = skip_compile_errors,
.skip_non_native = skip_non_native,
.skip_spirv = skip_spirv,
.skip_wasm = skip_wasm,
.skip_freebsd = skip_freebsd,
.skip_netbsd = skip_netbsd,
.skip_windows = skip_windows,
@ -452,6 +456,8 @@ pub fn build(b: *std.Build) !void {
.skip_single_threaded = skip_single_threaded,
.skip_non_native = skip_non_native,
.test_default_only = no_matrix,
.skip_spirv = skip_spirv,
.skip_wasm = skip_wasm,
.skip_freebsd = skip_freebsd,
.skip_netbsd = skip_netbsd,
.skip_windows = skip_windows,
@ -459,8 +465,29 @@ pub fn build(b: *std.Build) !void {
.skip_linux = skip_linux,
.skip_llvm = skip_llvm,
.skip_libc = skip_libc,
// 3888779264 was observed on an x86_64-linux-gnu host.
.max_rss = 4000000000,
.max_rss = switch (b.graph.host.result.os.tag) {
.freebsd => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 1_060_217_241,
else => 1_100_000_000,
},
.linux => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 659_809_075,
.loongarch64 => 598_902_374,
.riscv64 => 731_258_880,
.s390x => 580_596_121,
.x86_64 => 3_290_894_745,
else => 3_300_000_000,
},
.macos => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 767_736_217,
else => 800_000_000,
},
.windows => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 603_070_054,
else => 700_000_000,
},
else => 3_300_000_000,
},
}));
test_modules_step.dependOn(tests.addModuleTests(b, .{
@ -475,6 +502,8 @@ pub fn build(b: *std.Build) !void {
.skip_single_threaded = true,
.skip_non_native = skip_non_native,
.test_default_only = no_matrix,
.skip_spirv = skip_spirv,
.skip_wasm = skip_wasm,
.skip_freebsd = skip_freebsd,
.skip_netbsd = skip_netbsd,
.skip_windows = skip_windows,
@ -483,6 +512,29 @@ pub fn build(b: *std.Build) !void {
.skip_llvm = skip_llvm,
.skip_libc = true,
.no_builtin = true,
.max_rss = switch (b.graph.host.result.os.tag) {
.freebsd => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 743_802_470,
else => 800_000_000,
},
.linux => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 639_565_414,
.loongarch64 => 598_884_352,
.riscv64 => 636_429_516,
.s390x => 574_166_630,
.x86_64 => 764_861_644,
else => 800_000_000,
},
.macos => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 701_413_785,
else => 800_000_000,
},
.windows => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 536_414_208,
else => 600_000_000,
},
else => 800_000_000,
},
}));
test_modules_step.dependOn(tests.addModuleTests(b, .{
@ -497,6 +549,8 @@ pub fn build(b: *std.Build) !void {
.skip_single_threaded = true,
.skip_non_native = skip_non_native,
.test_default_only = no_matrix,
.skip_spirv = skip_spirv,
.skip_wasm = skip_wasm,
.skip_freebsd = skip_freebsd,
.skip_netbsd = skip_netbsd,
.skip_windows = skip_windows,
@ -505,6 +559,29 @@ pub fn build(b: *std.Build) !void {
.skip_llvm = skip_llvm,
.skip_libc = true,
.no_builtin = true,
.max_rss = switch (b.graph.host.result.os.tag) {
.freebsd => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 557_892_403,
else => 600_000_000,
},
.linux => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 615_302_758,
.loongarch64 => 598_974_464,
.riscv64 => 382_786_764,
.s390x => 395_555_635,
.x86_64 => 692_348_518,
else => 700_000_000,
},
.macos => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 451_389_030,
else => 500_000_000,
},
.windows => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 367_747_072,
else => 400_000_000,
},
else => 700_000_000,
},
}));
test_modules_step.dependOn(tests.addModuleTests(b, .{
@ -519,6 +596,8 @@ pub fn build(b: *std.Build) !void {
.skip_single_threaded = skip_single_threaded,
.skip_non_native = skip_non_native,
.test_default_only = no_matrix,
.skip_spirv = skip_spirv,
.skip_wasm = skip_wasm,
.skip_freebsd = skip_freebsd,
.skip_netbsd = skip_netbsd,
.skip_windows = skip_windows,
@ -526,8 +605,29 @@ pub fn build(b: *std.Build) !void {
.skip_linux = skip_linux,
.skip_llvm = skip_llvm,
.skip_libc = skip_libc,
// I observed a value of 5605064704 on the M2 CI.
.max_rss = 6165571174,
.max_rss = switch (b.graph.host.result.os.tag) {
.freebsd => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 3_756_422_348,
else => 3_800_000_000,
},
.linux => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 6_732_817_203,
.loongarch64 => 3_216_349_593,
.riscv64 => 3_570_899_763,
.s390x => 3_652_514_201,
.x86_64 => 3_249_546_854,
else => 6_800_000_000,
},
.macos => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 8_273_795_481,
else => 8_300_000_000,
},
.windows => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 3_750_236_160,
else => 3_800_000_000,
},
else => 8_300_000_000,
},
}));
const unit_tests_step = b.step("test-unit", "Run the compiler source unit tests");
@ -543,6 +643,29 @@ pub fn build(b: *std.Build) !void {
.use_llvm = use_llvm,
.use_lld = use_llvm,
.zig_lib_dir = b.path("lib"),
.max_rss = switch (b.graph.host.result.os.tag) {
.freebsd => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 2_188_099_584,
else => 2_200_000_000,
},
.linux => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 1_991_934_771,
.loongarch64 => 1_844_538_572,
.riscv64 => 2_459_003_289,
.s390x => 1_781_248_409,
.x86_64 => 977_192_550,
else => 2_500_000_000,
},
.macos => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 2_062_393_344,
else => 2_100_000_000,
},
.windows => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 1_953_087_488,
else => 2_000_000_000,
},
else => 2_500_000_000,
},
});
if (link_libc) {
unit_tests.root_module.link_libc = true;
@ -560,6 +683,7 @@ pub fn build(b: *std.Build) !void {
test_step.dependOn(tests.addCAbiTests(b, .{
.test_target_filters = test_target_filters,
.skip_non_native = skip_non_native,
.skip_wasm = skip_wasm,
.skip_freebsd = skip_freebsd,
.skip_netbsd = skip_netbsd,
.skip_windows = skip_windows,
@ -567,6 +691,29 @@ pub fn build(b: *std.Build) !void {
.skip_linux = skip_linux,
.skip_llvm = skip_llvm,
.skip_release = skip_release,
.max_rss = switch (b.graph.host.result.os.tag) {
.freebsd => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 727_221_862,
else => 800_000_000,
},
.linux => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 1_318_185_369,
.loongarch64 => 1_422_904_524,
.riscv64 => 449_924_710,
.s390x => 1_946_743_603,
.x86_64 => 2_139_993_292,
else => 2_200_000_000,
},
.macos => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 1_813_612_134,
else => 1_900_000_000,
},
.windows => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 386_287_616,
else => 400_000_000,
},
else => 2_200_000_000,
},
}));
test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));
test_step.dependOn(tests.addStackTraceTests(b, test_filters, skip_non_native));
@ -616,6 +763,7 @@ pub fn build(b: *std.Build) !void {
.optimize_modes = optimization_modes,
.test_filters = test_filters,
.test_target_filters = test_target_filters,
.skip_wasm = skip_wasm,
// Highest RSS observed in any test case was exactly 1802878976 on x86_64-linux.
.max_rss = 2253598720,
})) |test_libc_step| test_step.dependOn(test_libc_step);
@ -721,7 +869,29 @@ fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Modu
fn addCompilerStep(b: *std.Build, options: AddCompilerModOptions) *std.Build.Step.Compile {
const exe = b.addExecutable(.{
.name = "zig",
.max_rss = 7_800_000_000,
.max_rss = switch (b.graph.host.result.os.tag) {
.freebsd => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 6_044_158_771,
else => 6_100_000_000,
},
.linux => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 6_240_805_683,
.loongarch64 => 5_024_158_515,
.riscv64 => 6_996_309_196,
.s390x => 4_997_174_476,
.x86_64 => 5_486_090_649,
else => 7_000_000_000,
},
.macos => switch (b.graph.host.result.cpu.arch) {
.aarch64 => 6_639_145_779,
else => 6_700_000_000,
},
.windows => switch (b.graph.host.result.cpu.arch) {
.x86_64 => 5_770_394_009,
else => 5_800_000_000,
},
else => 7_000_000_000,
},
.root_module = addCompilerMod(b, options),
});
exe.stack_size = stack_size;
@ -798,7 +968,7 @@ fn addCmakeCfgOptionsToExe(
};
mod.linkSystemLibrary("unwind", .{});
},
.ios, .macos, .watchos, .tvos, .visionos => {
.driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => {
mod.link_libcpp = true;
},
.windows => {

View file

@ -44,7 +44,7 @@ ninja install
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
stage3-debug/bin/zig build test docs \
--maxrss 44918199637 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dstatic-llvm \
-Dskip-non-native \
-Dtarget=native-native-musl \

View file

@ -44,7 +44,7 @@ ninja install
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
stage3-release/bin/zig build test docs \
--maxrss 44918199637 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dstatic-llvm \
-Dskip-non-native \
-Dtarget=native-native-musl \

View file

@ -42,6 +42,7 @@ cmake .. \
ninja install
stage3-debug/bin/zig build test docs \
--maxrss ${ZSF_MAX_RSS:-0} \
--zig-lib-dir "$PWD/../lib" \
-Denable-macos-sdk \
-Dstatic-llvm \

View file

@ -51,6 +51,7 @@ stage3-release/bin/zig build test docs \
# Ensure that stage3 and stage4 are byte-for-byte identical.
stage3-release/bin/zig build \
--maxrss ${ZSF_MAX_RSS:-0} \
--prefix stage4-release \
-Denable-llvm \
-Dno-lib \

View file

@ -5,6 +5,7 @@ $ZIG_LLVM_CLANG_LLD_URL = "https://ziglang.org/deps/$ZIG_LLVM_CLANG_LLD_NAME.zip
$PREFIX_PATH = "$(Get-Location)\..\$ZIG_LLVM_CLANG_LLD_NAME"
$ZIG = "$PREFIX_PATH\bin\zig.exe"
$ZIG_LIB_DIR = "$(Get-Location)\lib"
$ZSF_MAX_RSS = if ($Env:ZSF_MAX_RSS) { $Env:ZSF_MAX_RSS } else { 0 }
if (!(Test-Path "..\$ZIG_LLVM_CLANG_LLD_NAME.zip")) {
Write-Output "Downloading $ZIG_LLVM_CLANG_LLD_URL"
@ -54,6 +55,7 @@ CheckLastExitCode
Write-Output "Main test suite..."
& "stage3-release\bin\zig.exe" build test docs `
--maxrss $ZSF_MAX_RSS `
--zig-lib-dir "$ZIG_LIB_DIR" `
--search-prefix "$PREFIX_PATH" `
-Dstatic-llvm `

View file

@ -45,7 +45,7 @@ ninja install
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
stage3-debug/bin/zig build test docs \
--maxrss 60129542144 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dstatic-llvm \
-Dskip-non-native \
-Dtarget=native-native-musl \

View file

@ -45,7 +45,7 @@ ninja install
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
stage3-release/bin/zig build test docs \
--maxrss 60129542144 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dstatic-llvm \
-Dskip-non-native \
-Dtarget=native-native-musl \

View file

@ -44,7 +44,7 @@ ninja install
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
stage3-debug/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-error-traces test-llvm-ir \
--maxrss 68719476736 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dstatic-llvm \
-Dskip-non-native \
-Dskip-single-threaded \

View file

@ -44,7 +44,7 @@ ninja install
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
stage3-release/bin/zig build test-cases test-modules test-unit test-c-abi test-stack-traces test-error-traces test-llvm-ir \
--maxrss 68719476736 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dstatic-llvm \
-Dskip-non-native \
-Dskip-single-threaded \

View file

@ -45,7 +45,7 @@ ninja install
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
stage3-debug/bin/zig build test docs \
--maxrss 30064771072 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dstatic-llvm \
-Dskip-non-native \
-Dtarget=native-native-musl \

View file

@ -45,7 +45,7 @@ ninja install
# No -fqemu and -fwasmtime here as they're covered by the x86_64-linux scripts.
stage3-release/bin/zig build test docs \
--maxrss 30064771072 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dstatic-llvm \
-Dskip-non-native \
-Dtarget=native-native-musl \

View file

@ -44,8 +44,10 @@ unset CXX
ninja install
stage3-debug/bin/zig build test docs \
--maxrss 42949672960 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dstatic-llvm \
-Dskip-spirv \
-Dskip-wasm \
-Dskip-linux \
-Dskip-netbsd \
-Dskip-windows \

View file

@ -44,8 +44,10 @@ unset CXX
ninja install
stage3-release/bin/zig build test docs \
--maxrss 42949672960 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dstatic-llvm \
-Dskip-spirv \
-Dskip-wasm \
-Dskip-linux \
-Dskip-netbsd \
-Dskip-windows \

View file

@ -52,7 +52,7 @@ stage3-debug/bin/zig build \
-Dno-lib
stage3-debug/bin/zig build test docs \
--maxrss 21000000000 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dlldb=$HOME/deps/lldb-zig/Debug-e0a42bb34/bin/lldb \
-fqemu \
-fwasmtime \

View file

@ -51,7 +51,7 @@ stage3-debug/bin/zig build \
-Dno-lib
stage3-debug/bin/zig build test docs \
--maxrss 21000000000 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dlldb=$HOME/deps/lldb-zig/Debug-e0a42bb34/bin/lldb \
-fqemu \
-fwasmtime \

View file

@ -57,7 +57,7 @@ stage3-release/bin/zig build \
-Dno-lib
stage3-release/bin/zig build test docs \
--maxrss 21000000000 \
--maxrss ${ZSF_MAX_RSS:-0} \
-Dlldb=$HOME/deps/lldb-zig/Release-e0a42bb34/bin/lldb \
-fqemu \
-fwasmtime \

View file

@ -5,6 +5,7 @@ $ZIG_LLVM_CLANG_LLD_URL = "https://ziglang.org/deps/$ZIG_LLVM_CLANG_LLD_NAME.zip
$PREFIX_PATH = "$($Env:USERPROFILE)\$ZIG_LLVM_CLANG_LLD_NAME"
$ZIG = "$PREFIX_PATH\bin\zig.exe"
$ZIG_LIB_DIR = "$(Get-Location)\lib"
$ZSF_MAX_RSS = if ($Env:ZSF_MAX_RSS) { $Env:ZSF_MAX_RSS } else { 0 }
if (!(Test-Path "$PREFIX_PATH.zip")) {
Write-Output "Downloading $ZIG_LLVM_CLANG_LLD_URL"
@ -54,11 +55,11 @@ CheckLastExitCode
Write-Output "Main test suite..."
& "stage3-debug\bin\zig.exe" build test docs `
--maxrss $ZSF_MAX_RSS `
--zig-lib-dir "$ZIG_LIB_DIR" `
--search-prefix "$PREFIX_PATH" `
-Dstatic-llvm `
-Dskip-non-native `
-Dskip-release `
-Dskip-test-incremental `
-Denable-symlinks-windows `
--test-timeout 30m

View file

@ -5,6 +5,7 @@ $ZIG_LLVM_CLANG_LLD_URL = "https://ziglang.org/deps/$ZIG_LLVM_CLANG_LLD_NAME.zip
$PREFIX_PATH = "$($Env:USERPROFILE)\$ZIG_LLVM_CLANG_LLD_NAME"
$ZIG = "$PREFIX_PATH\bin\zig.exe"
$ZIG_LIB_DIR = "$(Get-Location)\lib"
$ZSF_MAX_RSS = if ($Env:ZSF_MAX_RSS) { $Env:ZSF_MAX_RSS } else { 0 }
if (!(Test-Path "$PREFIX_PATH.zip")) {
Write-Output "Downloading $ZIG_LLVM_CLANG_LLD_URL"
@ -54,6 +55,7 @@ CheckLastExitCode
Write-Output "Main test suite..."
& "stage3-release\bin\zig.exe" build test docs `
--maxrss $ZSF_MAX_RSS `
--zig-lib-dir "$ZIG_LIB_DIR" `
--search-prefix "$PREFIX_PATH" `
-Dstatic-llvm `

View file

@ -123,7 +123,7 @@ pub const HexDigest = [hex_digest_len]u8;
/// This is currently just an arbitrary non-empty string that can't match another manifest line.
const manifest_header = "0";
const manifest_file_size_max = 100 * 1024 * 1024;
pub const manifest_file_size_max = 100 * 1024 * 1024;
/// The type used for hashing file contents. Currently, this is SipHash128(1, 3), because it
/// provides enough collision resistance for the Manifest use cases, while being one of our

View file

@ -620,11 +620,6 @@ pub const VTable = struct {
result: []u8,
result_alignment: std.mem.Alignment,
) void,
/// Returns whether the current thread of execution is known to have
/// been requested to cancel.
///
/// Thread-safe.
cancelRequested: *const fn (?*anyopaque) bool,
/// When this function returns, implementation guarantees that `start` has
/// either already been called, or a unit of concurrency has been assigned

File diff suppressed because it is too large Load diff

View file

@ -4471,7 +4471,7 @@ pub const rusage = switch (native_os) {
pub const SELF = 1;
pub const CHILDREN = 2;
},
.freebsd => extern struct {
.freebsd, .openbsd => extern struct {
utime: timeval,
stime: timeval,
maxrss: c_long,
@ -4493,6 +4493,27 @@ pub const rusage = switch (native_os) {
pub const CHILDREN = -1;
pub const THREAD = 1;
},
.dragonfly, .netbsd => extern struct {
utime: timeval,
stime: timeval,
maxrss: c_long,
ixrss: c_long,
idrss: c_long,
isrss: c_long,
minflt: c_long,
majflt: c_long,
nswap: c_long,
inblock: c_long,
oublock: c_long,
msgsnd: c_long,
msgrcv: c_long,
nsignals: c_long,
nvcsw: c_long,
nivcsw: c_long,
pub const SELF = 0;
pub const CHILDREN = -1;
},
else => void,
};
@ -10881,6 +10902,23 @@ pub extern "c" fn pthread_create(
start_routine: *const fn (?*anyopaque) callconv(.c) ?*anyopaque,
noalias arg: ?*anyopaque,
) E;
pub const pthread_cancelstate = switch (native_os) {
.ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => enum(c_int) {
ENABLE = 1,
DISABLE = 0,
},
.linux => if (native_abi.isMusl()) enum(c_int) {
ENABLE = 0,
DISABLE = 1,
MASKED = 2,
} else if (native_abi.isGnu()) enum(c_int) {
ENABLE = 0,
DISABLE = 1,
},
else => void,
};
pub extern "c" fn pthread_setcancelstate(pthread_cancelstate, ?*pthread_cancelstate) E;
pub extern "c" fn pthread_cancel(pthread_t) E;
pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) E;
pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *anyopaque, stacksize: usize) E;
pub extern "c" fn pthread_attr_setstacksize(attr: *pthread_attr_t, stacksize: usize) E;

View file

@ -7,12 +7,11 @@ const builtin = @import("builtin");
const blake2 = crypto.hash.blake2;
const crypto = std.crypto;
const Io = std.Io;
const math = std.math;
const mem = std.mem;
const phc_format = pwhash.phc_format;
const pwhash = crypto.pwhash;
const Thread = std.Thread;
const Blake2b512 = blake2.Blake2b512;
const Blocks = std.array_list.AlignedManaged([block_length]u64, .@"16");
const H0 = [Blake2b512.digest_length + 8]u8;
@ -204,20 +203,20 @@ fn initBlocks(
}
fn processBlocks(
allocator: mem.Allocator,
blocks: *Blocks,
time: u32,
memory: u32,
threads: u24,
mode: Mode,
) KdfError!void {
io: Io,
) void {
const lanes = memory / threads;
const segments = lanes / sync_points;
if (builtin.single_threaded or threads == 1) {
processBlocksSt(blocks, time, memory, threads, mode, lanes, segments);
} else {
try processBlocksMt(allocator, blocks, time, memory, threads, mode, lanes, segments);
processBlocksMt(blocks, time, memory, threads, mode, lanes, segments, io);
}
}
@ -243,7 +242,6 @@ fn processBlocksSt(
}
fn processBlocksMt(
allocator: mem.Allocator,
blocks: *Blocks,
time: u32,
memory: u32,
@ -251,26 +249,20 @@ fn processBlocksMt(
mode: Mode,
lanes: u32,
segments: u32,
) KdfError!void {
var threads_list = try std.array_list.Managed(Thread).initCapacity(allocator, threads);
defer threads_list.deinit();
io: Io,
) void {
var n: u32 = 0;
while (n < time) : (n += 1) {
var slice: u32 = 0;
while (slice < sync_points) : (slice += 1) {
var group: Io.Group = .init;
var lane: u24 = 0;
while (lane < threads) : (lane += 1) {
const thread = try Thread.spawn(.{}, processSegment, .{
group.async(io, processSegment, .{
blocks, time, memory, threads, mode, lanes, segments, n, slice, lane,
});
threads_list.appendAssumeCapacity(thread);
}
lane = 0;
while (lane < threads) : (lane += 1) {
threads_list.items[lane].join();
}
threads_list.clearRetainingCapacity();
group.wait(io);
}
}
}
@ -489,6 +481,7 @@ pub fn kdf(
salt: []const u8,
params: Params,
mode: Mode,
io: Io,
) KdfError!void {
if (derived_key.len < 4) return KdfError.WeakParameters;
if (derived_key.len > max_int) return KdfError.OutputTooLong;
@ -510,7 +503,7 @@ pub fn kdf(
blocks.appendNTimesAssumeCapacity(@splat(0), memory);
initBlocks(&blocks, &h0, memory, params.p);
try processBlocks(allocator, &blocks, params.t, memory, params.p, mode);
processBlocks(&blocks, params.t, memory, params.p, mode, io);
finalize(&blocks, memory, params.p, derived_key);
}
@ -533,6 +526,7 @@ const PhcFormatHasher = struct {
params: Params,
mode: Mode,
buf: []u8,
io: Io,
) HasherError![]const u8 {
if (params.secret != null or params.ad != null) return HasherError.InvalidEncoding;
@ -540,7 +534,7 @@ const PhcFormatHasher = struct {
crypto.random.bytes(&salt);
var hash: [default_hash_len]u8 = undefined;
try kdf(allocator, &hash, password, &salt, params, mode);
try kdf(allocator, &hash, password, &salt, params, mode, io);
return phc_format.serialize(HashResult{
.alg_id = @tagName(mode),
@ -557,6 +551,7 @@ const PhcFormatHasher = struct {
allocator: mem.Allocator,
str: []const u8,
password: []const u8,
io: Io,
) HasherError!void {
const hash_result = try phc_format.deserialize(HashResult, str);
@ -572,7 +567,7 @@ const PhcFormatHasher = struct {
if (expected_hash.len > hash_buf.len) return HasherError.InvalidEncoding;
const hash = hash_buf[0..expected_hash.len];
try kdf(allocator, hash, password, hash_result.salt.constSlice(), params, mode);
try kdf(allocator, hash, password, hash_result.salt.constSlice(), params, mode, io);
if (!mem.eql(u8, hash, expected_hash)) return HasherError.PasswordVerificationFailed;
}
};
@ -595,6 +590,7 @@ pub fn strHash(
password: []const u8,
options: HashOptions,
out: []u8,
io: Io,
) Error![]const u8 {
const allocator = options.allocator orelse return Error.AllocatorRequired;
switch (options.encoding) {
@ -604,6 +600,7 @@ pub fn strHash(
options.params,
options.mode,
out,
io,
),
.crypt => return Error.InvalidEncoding,
}
@ -621,9 +618,10 @@ pub fn strVerify(
str: []const u8,
password: []const u8,
options: VerifyOptions,
io: Io,
) Error!void {
const allocator = options.allocator orelse return Error.AllocatorRequired;
return PhcFormatHasher.verify(allocator, str, password);
return PhcFormatHasher.verify(allocator, str, password, io);
}
test "argon2d" {
@ -640,6 +638,7 @@ test "argon2d" {
&salt,
.{ .t = 3, .m = 32, .p = 4, .secret = &secret, .ad = &ad },
.argon2d,
std.testing.io,
);
const want = [_]u8{
@ -665,6 +664,7 @@ test "argon2i" {
&salt,
.{ .t = 3, .m = 32, .p = 4, .secret = &secret, .ad = &ad },
.argon2i,
std.testing.io,
);
const want = [_]u8{
@ -690,6 +690,7 @@ test "argon2id" {
&salt,
.{ .t = 3, .m = 32, .p = 4, .secret = &secret, .ad = &ad },
.argon2id,
std.testing.io,
);
const want = [_]u8{
@ -800,44 +801,44 @@ test "kdf" {
.{
.mode = .argon2i,
.time = 4,
.memory = 4096,
.memory = 256,
.threads = 4,
.hash = "a11f7b7f3f93f02ad4bddb59ab62d121e278369288a0d0e7",
.hash = "f7dbbacbf16999e3700817a7e06f65a8db2e9fa9504ede4c",
},
.{
.mode = .argon2d,
.time = 4,
.memory = 4096,
.memory = 256,
.threads = 4,
.hash = "935598181aa8dc2b720914aa6435ac8d3e3a4210c5b0fb2d",
.hash = "ea2970501cf49faa5ba1d2e6370204e9b57ca90a8fea937b",
},
.{
.mode = .argon2id,
.time = 4,
.memory = 4096,
.memory = 256,
.threads = 4,
.hash = "145db9733a9f4ee43edf33c509be96b934d505a4efb33c5a",
.hash = "fbd40d5a8cb92f88c20bda4b3cdb1f9d5af1efa937032410",
},
.{
.mode = .argon2i,
.time = 4,
.memory = 1024,
.memory = 256,
.threads = 8,
.hash = "0cdd3956aa35e6b475a7b0c63488822f774f15b43f6e6e17",
.hash = "15d3c398364e53f68fd12d19baf3f21432d964254fe27467",
},
.{
.mode = .argon2d,
.time = 4,
.memory = 1024,
.memory = 256,
.threads = 8,
.hash = "83604fc2ad0589b9d055578f4d3cc55bc616df3578a896e9",
.hash = "23c9adc06f06e21e4612c1466a1be02627690932b02c0df0",
},
.{
.mode = .argon2id,
.time = 4,
.memory = 1024,
.memory = 256,
.threads = 8,
.hash = "8dafa8e004f8ea96bf7c0f93eecf67a6047476143d15577f",
.hash = "f22802f8ca47be93f9954e4ce20c1e944e938fbd4a125d9d",
},
.{
.mode = .argon2i,
@ -863,23 +864,23 @@ test "kdf" {
.{
.mode = .argon2i,
.time = 3,
.memory = 1024,
.memory = 256,
.threads = 6,
.hash = "d236b29c2b2a09babee842b0dec6aa1e83ccbdea8023dced",
.hash = "ebc8f91964abd8ceab49a12963b0a9e57d635bfa2aad2884",
},
.{
.mode = .argon2d,
.time = 3,
.memory = 1024,
.memory = 256,
.threads = 6,
.hash = "a3351b0319a53229152023d9206902f4ef59661cdca89481",
.hash = "1dd7202fd68da6675f769f4034b7a1db30d8785331954117",
},
.{
.mode = .argon2id,
.time = 3,
.memory = 1024,
.memory = 256,
.threads = 6,
.hash = "1640b932f4b60e272f5d2207b9a9c626ffa1bd88d2349016",
.hash = "424436b6ee22a66b04b9d0cf78f190305c5c166bae8baa09",
},
};
for (test_vectors) |v| {
@ -894,6 +895,7 @@ test "kdf" {
salt,
.{ .t = v.time, .m = v.memory, .p = v.threads },
v.mode,
std.testing.io,
);
try std.testing.expectEqualSlices(u8, &dk, &want);
@ -903,6 +905,7 @@ test "kdf" {
test "phc format hasher" {
const allocator = std.testing.allocator;
const password = "testpass";
const io = std.testing.io;
var buf: [128]u8 = undefined;
const hash = try PhcFormatHasher.create(
@ -911,25 +914,29 @@ test "phc format hasher" {
.{ .t = 3, .m = 32, .p = 4 },
.argon2id,
&buf,
io,
);
try PhcFormatHasher.verify(allocator, hash, password);
try PhcFormatHasher.verify(allocator, hash, password, io);
}
test "password hash and password verify" {
const allocator = std.testing.allocator;
const password = "testpass";
const io = std.testing.io;
var buf: [128]u8 = undefined;
const hash = try strHash(
password,
.{ .allocator = allocator, .params = .{ .t = 3, .m = 32, .p = 4 } },
&buf,
io,
);
try strVerify(hash, password, .{ .allocator = allocator });
try strVerify(hash, password, .{ .allocator = allocator }, io);
}
test "kdf derived key length" {
const allocator = std.testing.allocator;
const io = std.testing.io;
const password = "testpass";
const salt = "saltsalt";
@ -937,11 +944,11 @@ test "kdf derived key length" {
const mode = Mode.argon2id;
var dk1: [11]u8 = undefined;
try kdf(allocator, &dk1, password, salt, params, mode);
try kdf(allocator, &dk1, password, salt, params, mode, io);
var dk2: [77]u8 = undefined;
try kdf(allocator, &dk2, password, salt, params, mode);
try kdf(allocator, &dk2, password, salt, params, mode, io);
var dk3: [111]u8 = undefined;
try kdf(allocator, &dk3, password, salt, params, mode);
try kdf(allocator, &dk3, password, salt, params, mode, io);
}

View file

@ -450,6 +450,7 @@ fn benchmarkPwhash(
comptime ty: anytype,
comptime params: *const anyopaque,
comptime count: comptime_int,
io: std.Io,
) !f64 {
const password = "testpass" ** 2;
const opts = ty.HashOptions{
@ -459,12 +460,20 @@ fn benchmarkPwhash(
};
var buf: [256]u8 = undefined;
const strHash = ty.strHash;
const strHashFnInfo = @typeInfo(@TypeOf(strHash)).@"fn";
const needs_io = strHashFnInfo.params.len == 4;
var timer = try Timer.start();
const start = timer.lap();
{
var i: usize = 0;
while (i < count) : (i += 1) {
_ = try ty.strHash(password, opts, &buf);
if (needs_io) {
_ = try strHash(password, opts, &buf, io);
} else {
_ = try strHash(password, opts, &buf);
}
mem.doNotOptimizeAway(&buf);
}
}
@ -623,7 +632,7 @@ pub fn main() !void {
inline for (pwhashes) |H| {
if (filter == null or std.mem.indexOf(u8, H.name, filter.?) != null) {
const throughput = try benchmarkPwhash(arena_allocator, H.ty, H.params, mode(64));
const throughput = try benchmarkPwhash(arena_allocator, H.ty, H.params, mode(64), io);
try stdout.print("{s:>17}: {d:10.3} s/ops\n", .{ H.name, throughput });
try stdout.flush();
}

View file

@ -1748,9 +1748,7 @@ pub fn settimeofday(tv: *const timeval, tz: *const timezone) usize {
}
pub fn nanosleep(req: *const timespec, rem: ?*timespec) usize {
if (native_arch == .riscv32) {
@compileError("No nanosleep syscall on this architecture.");
} else return syscall2(.nanosleep, @intFromPtr(req), @intFromPtr(rem));
return syscall2(.nanosleep, @intFromPtr(req), @intFromPtr(rem));
}
pub fn pause() usize {
@ -3773,6 +3771,7 @@ pub const SIG = if (is_mips) enum(u32) {
PROF = 29,
XCPU = 30,
XFZ = 31,
_,
} else if (is_sparc) enum(u32) {
pub const BLOCK = 1;
pub const UNBLOCK = 2;
@ -3818,6 +3817,7 @@ pub const SIG = if (is_mips) enum(u32) {
LOST = 29,
USR1 = 30,
USR2 = 31,
_,
} else enum(u32) {
pub const BLOCK = 0;
pub const UNBLOCK = 1;
@ -3861,6 +3861,7 @@ pub const SIG = if (is_mips) enum(u32) {
IO = 29,
PWR = 30,
SYS = 31,
_,
};
pub const kernel_rwf = u32;

View file

@ -1360,6 +1360,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!usize {
.PIPE => return error.BrokenPipe,
.CONNRESET => return error.ConnectionResetByPeer,
.BUSY => return error.DeviceBusy,
.CANCELED => return error.Canceled,
else => |err| return unexpectedErrno(err),
}
}

View file

@ -690,6 +690,9 @@ pub const ArgIteratorWasi = struct {
/// Call to free the internal buffer of the iterator.
pub fn deinit(self: *ArgIteratorWasi) void {
// Nothing is allocated when there are no args
if (self.args.len == 0) return;
const last_item = self.args[self.args.len - 1];
const last_byte_addr = @intFromPtr(last_item.ptr) + last_item.len + 1; // null terminated
const first_item_ptr = self.args[0].ptr;

View file

@ -122,7 +122,7 @@ pub const ResourceUsageStatistics = struct {
/// if available.
pub inline fn getMaxRss(rus: ResourceUsageStatistics) ?usize {
switch (native_os) {
.linux => {
.dragonfly, .freebsd, .netbsd, .openbsd, .illumos, .linux, .serenity => {
if (rus.rusage) |ru| {
return @as(usize, @intCast(ru.maxrss)) * 1024;
} else {
@ -149,7 +149,21 @@ pub const ResourceUsageStatistics = struct {
}
const rusage_init = switch (native_os) {
.linux, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => @as(?posix.rusage, null),
.dragonfly,
.freebsd,
.netbsd,
.openbsd,
.illumos,
.linux,
.serenity,
.driverkit,
.ios,
.maccatalyst,
.macos,
.tvos,
.visionos,
.watchos,
=> @as(?posix.rusage, null),
.windows => @as(?windows.VM_COUNTERS, null),
else => {},
};
@ -486,7 +500,21 @@ fn waitUnwrappedPosix(self: *ChildProcess) void {
const res: posix.WaitPidResult = res: {
if (self.request_resource_usage_statistics) {
switch (native_os) {
.linux, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => {
.dragonfly,
.freebsd,
.netbsd,
.openbsd,
.illumos,
.linux,
.serenity,
.driverkit,
.ios,
.maccatalyst,
.macos,
.tvos,
.visionos,
.watchos,
=> {
var ru: posix.rusage = undefined;
const res = posix.wait4(self.id, 0, &ru);
self.resource_usage_statistics.rusage = ru;

View file

@ -3103,6 +3103,15 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
}
}
if (comp.link_depfile) |depfile_path| if (comp.bin_file) |lf| {
assert(comp.file_system_inputs != null);
comp.createDepFile(depfile_path, lf.emit) catch |err| comp.setMiscFailure(
.link_depfile,
"unable to write linker dependency file: {t}",
.{err},
);
};
if (anyErrors(comp)) {
// Skip flushing and keep source files loaded for error reporting.
return;
@ -5212,6 +5221,43 @@ pub fn separateCodegenThreadOk(comp: *const Compilation) bool {
return zcu.backendSupportsFeature(.separate_thread);
}
fn createDepFile(
comp: *Compilation,
depfile: []const u8,
binfile: Cache.Path,
) anyerror!void {
var buf: [4096]u8 = undefined;
var af = try std.fs.cwd().atomicFile(depfile, .{ .write_buffer = &buf });
defer af.deinit();
comp.writeDepFile(binfile, &af.file_writer.interface) catch return af.file_writer.err.?;
try af.finish();
}
fn writeDepFile(
comp: *Compilation,
binfile: Cache.Path,
w: *std.Io.Writer,
) std.Io.Writer.Error!void {
const prefixes = comp.cache_parent.prefixes();
const fsi = comp.file_system_inputs.?.items;
try w.print("{f}:", .{binfile});
{
var it = std.mem.splitScalar(u8, fsi, 0);
while (it.next()) |input| try w.print(" \\\n {f}{s}", .{ prefixes[input[0] - 1], input[1..] });
}
{
var it = std.mem.splitScalar(u8, fsi, 0);
while (it.next()) |input| try w.print("\n\n{f}{s}:", .{ prefixes[input[0] - 1], input[1..] });
}
try w.writeByte('\n');
}
fn workerDocsCopy(comp: *Compilation) void {
docsCopyFallible(comp) catch |err| return comp.lockAndSetMiscFailure(
.docs_copy,
@ -5446,7 +5492,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU
.verbose_generic_instances = comp.verbose_intern_pool,
.verbose_llvm_ir = comp.verbose_llvm_ir,
.verbose_llvm_bc = comp.verbose_llvm_bc,
.link_depfile = comp.link_depfile,
.verbose_cimport = comp.verbose_cimport,
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
}) catch |err| switch (err) {
@ -6374,6 +6419,38 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
if (out_dep_path) |dep_file_path| {
const dep_basename = fs.path.basename(dep_file_path);
if (comp.file_system_inputs != null) {
// Use the same file size limit as the cache code does for dependency files.
const dep_file_contents = try zig_cache_tmp_dir.readFileAlloc(dep_basename, gpa, .limited(Cache.manifest_file_size_max));
defer gpa.free(dep_file_contents);
var str_buf: std.ArrayList(u8) = .empty;
defer str_buf.deinit(gpa);
var it: std.Build.Cache.DepTokenizer = .{ .bytes = dep_file_contents };
while (it.next()) |token| {
const input_path: Compilation.Path = switch (token) {
.target, .target_must_resolve => continue,
.prereq => |file_path| try .fromUnresolved(arena, comp.dirs, &.{file_path}),
.prereq_must_resolve => p: {
try token.resolve(gpa, &str_buf);
break :p try .fromUnresolved(arena, comp.dirs, &.{str_buf.items});
},
else => |err| {
try err.printError(gpa, &str_buf);
log.err("failed parsing {s}: {s}", .{ dep_basename, str_buf.items });
return error.InvalidDepFile;
},
};
// There may be concurrent calls to `appendFileSystemInput` from other C objects.
comp.mutex.lock();
defer comp.mutex.unlock();
try comp.appendFileSystemInput(input_path);
}
}
// Add the files depended on to the cache system.
try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);
switch (comp.cache_use) {
@ -7883,7 +7960,6 @@ fn buildOutputFromZig(
.verbose_generic_instances = comp.verbose_intern_pool,
.verbose_llvm_ir = comp.verbose_llvm_ir,
.verbose_llvm_bc = comp.verbose_llvm_bc,
.link_depfile = comp.link_depfile,
.verbose_cimport = comp.verbose_cimport,
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
.clang_passthrough_mode = comp.clang_passthrough_mode,
@ -8021,7 +8097,6 @@ pub fn build_crt_file(
.verbose_generic_instances = comp.verbose_generic_instances,
.verbose_llvm_ir = comp.verbose_llvm_ir,
.verbose_llvm_bc = comp.verbose_llvm_bc,
.link_depfile = comp.link_depfile,
.verbose_cimport = comp.verbose_cimport,
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
.clang_passthrough_mode = comp.clang_passthrough_mode,

View file

@ -384,9 +384,6 @@ pub const File = struct {
comp: *Compilation,
emit: Path,
/// Only populated if `comp.link_depfile != null`.
depfile_inputs: std.ArrayList([]const u8) = .empty,
file: ?fs.File,
/// When using the LLVM backend, the emitted object is written to a file with this name. This
/// object file then becomes a normal link input to LLD or a self-hosted linker.
@ -862,7 +859,6 @@ pub const File = struct {
pub fn destroy(base: *File) void {
base.releaseLock();
if (base.file) |f| f.close();
base.depfile_inputs.deinit(base.comp.gpa);
switch (base.tag) {
.plan9 => unreachable,
inline else => |tag| {
@ -1146,15 +1142,6 @@ pub const File = struct {
pub fn loadInput(base: *File, input: Input) anyerror!void {
if (base.tag == .lld) return;
if (base.comp.link_depfile != null) if (input.path()) |p| {
try base.depfile_inputs.append(base.comp.gpa, try std.fs.path.resolve(base.comp.arena, &.{
base.comp.dirs.cwd,
p.root_dir.path orelse ".",
p.sub_path,
}));
};
switch (base.tag) {
inline .elf, .elf2, .wasm => |tag| {
dev.check(tag.devFeature());
@ -1169,10 +1156,6 @@ pub const File = struct {
pub fn prelink(base: *File) FlushError!void {
assert(!base.post_prelink);
if (base.tag != .lld) if (base.comp.link_depfile) |depfile_path| {
base.comp.thread_pool.spawnWg(&base.comp.link_task_wait_group, workerCreateDepFile, .{ base, depfile_path });
};
// In this case, an object file is created by the LLVM backend, so
// there is no prelink phase. The Zig code is linked as a standard
// object along with the others.
@ -1187,38 +1170,6 @@ pub const File = struct {
}
}
fn workerCreateDepFile(base: *File, path: []const u8) void {
createDepFile(base, path) catch |err| base.comp.lockAndSetMiscFailure(
.link_depfile,
"unable to write linker dependency file: {t}",
.{err},
);
}
fn createDepFile(base: *File, path: []const u8) anyerror!void {
var buf: [4096]u8 = undefined;
var af = try std.fs.cwd().atomicFile(path, .{ .write_buffer = &buf });
defer af.deinit();
writeDepFile(base, &af.file_writer.interface) catch return af.file_writer.err.?;
try af.finish();
}
fn writeDepFile(base: *File, w: *std.Io.Writer) std.Io.Writer.Error!void {
try w.print("{f}:", .{base.emit});
for (base.depfile_inputs.items) |p| {
try w.print(" \\\n {s}", .{p});
}
for (base.depfile_inputs.items) |p| {
try w.print("\n\n{s}:", .{p});
}
try w.writeByte('\n');
}
pub const Tag = enum {
coff2,
elf,

View file

@ -1499,22 +1499,18 @@ const aarch64 = struct {
.ABS64 => {
try atom.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file);
},
.ADR_PREL_PG_HI21 => {
try atom.scanReloc(symbol, rel, pcRelocAction(symbol, elf_file), elf_file);
},
.ADR_GOT_PAGE => {
// TODO: relax if possible
symbol.flags.needs_got = true;
},
.LD64_GOT_LO12_NC,
.LD64_GOTPAGE_LO15,
=> {
symbol.flags.needs_got = true;
},
.CALL26,
.JUMP26,
=> {
@ -1522,25 +1518,21 @@ const aarch64 = struct {
symbol.flags.needs_plt = true;
}
},
.TLSLE_ADD_TPREL_HI12,
.TLSLE_ADD_TPREL_LO12_NC,
=> {
if (is_dyn_lib) try atom.reportPicError(symbol, rel, elf_file);
},
.TLSIE_ADR_GOTTPREL_PAGE21,
.TLSIE_LD64_GOTTPREL_LO12_NC,
=> {
symbol.flags.needs_gottp = true;
},
.TLSGD_ADR_PAGE21,
.TLSGD_ADD_LO12_NC,
=> {
symbol.flags.needs_tlsgd = true;
},
.TLSDESC_ADR_PAGE21,
.TLSDESC_LD64_LO12,
.TLSDESC_ADD_LO12,
@ -1551,18 +1543,17 @@ const aarch64 = struct {
symbol.flags.needs_tlsdesc = true;
}
},
.ADD_ABS_LO12_NC,
.ADR_PREL_LO21,
.LDST8_ABS_LO12_NC,
.CONDBR19,
.LDST128_ABS_LO12_NC,
.LDST16_ABS_LO12_NC,
.LDST32_ABS_LO12_NC,
.LDST64_ABS_LO12_NC,
.LDST128_ABS_LO12_NC,
.LDST8_ABS_LO12_NC,
.PREL32,
.PREL64,
=> {},
else => try atom.reportUnhandledRelocError(rel, elf_file),
}
}
@ -1599,7 +1590,6 @@ const aarch64 = struct {
r_offset,
);
},
.CALL26,
.JUMP26,
=> {
@ -1611,27 +1601,26 @@ const aarch64 = struct {
};
util.writeBranchImm(disp, code);
},
.CONDBR19 => {
const value = math.cast(i19, S + A - P) orelse return error.Overflow;
util.writeCondBrImm(value, code);
},
.PREL32 => {
const value = math.cast(i32, S + A - P) orelse return error.Overflow;
mem.writeInt(u32, code, @bitCast(value), .little);
},
.PREL64 => {
const value = S + A - P;
mem.writeInt(u64, code_buffer[r_offset..][0..8], @bitCast(value), .little);
},
.ADR_PREL_LO21 => {
const value = math.cast(i21, S + A - P) orelse return error.Overflow;
util.writeAdrInst(value, code);
},
.ADR_PREL_PG_HI21 => {
// TODO: check for relaxation of ADRP+ADD
util.writeAdrInst(try util.calcNumberOfPages(P, S + A), code);
},
.ADR_GOT_PAGE => if (target.flags.has_got) {
util.writeAdrInst(try util.calcNumberOfPages(P, G + GOT + A), code);
} else {
@ -1644,18 +1633,15 @@ const aarch64 = struct {
r_offset,
});
},
.LD64_GOT_LO12_NC => {
assert(target.flags.has_got);
const taddr = @as(u64, @intCast(G + GOT + A));
util.writeLoadStoreRegInst(@divExact(@as(u12, @truncate(taddr)), 8), code);
},
.ADD_ABS_LO12_NC => {
const taddr = @as(u64, @intCast(S + A));
util.writeAddImmInst(@truncate(taddr), code);
},
.LDST8_ABS_LO12_NC,
.LDST16_ABS_LO12_NC,
.LDST32_ABS_LO12_NC,
@ -1674,44 +1660,37 @@ const aarch64 = struct {
};
util.writeLoadStoreRegInst(off, code);
},
.TLSLE_ADD_TPREL_HI12 => {
const value = math.cast(i12, (S + A - TP) >> 12) orelse
return error.Overflow;
util.writeAddImmInst(@bitCast(value), code);
},
.TLSLE_ADD_TPREL_LO12_NC => {
const value: i12 = @truncate(S + A - TP);
util.writeAddImmInst(@bitCast(value), code);
},
.TLSIE_ADR_GOTTPREL_PAGE21 => {
const S_ = target.gotTpAddress(elf_file);
relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
util.writeAdrInst(try util.calcNumberOfPages(P, S_ + A), code);
},
.TLSIE_LD64_GOTTPREL_LO12_NC => {
const S_ = target.gotTpAddress(elf_file);
relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
const off: u12 = try math.divExact(u12, @truncate(@as(u64, @bitCast(S_ + A))), 8);
util.writeLoadStoreRegInst(off, code);
},
.TLSGD_ADR_PAGE21 => {
const S_ = target.tlsGdAddress(elf_file);
relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
util.writeAdrInst(try util.calcNumberOfPages(P, S_ + A), code);
},
.TLSGD_ADD_LO12_NC => {
const S_ = target.tlsGdAddress(elf_file);
relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
const off: u12 = @truncate(@as(u64, @bitCast(S_ + A)));
util.writeAddImmInst(off, code);
},
.TLSDESC_ADR_PAGE21 => {
if (target.flags.has_tlsdesc) {
const S_ = target.tlsDescAddress(elf_file);
@ -1722,7 +1701,6 @@ const aarch64 = struct {
util.encoding.Instruction.nop().write(code);
}
},
.TLSDESC_LD64_LO12 => {
if (target.flags.has_tlsdesc) {
const S_ = target.tlsDescAddress(elf_file);
@ -1734,7 +1712,6 @@ const aarch64 = struct {
util.encoding.Instruction.nop().write(code);
}
},
.TLSDESC_ADD_LO12 => {
if (target.flags.has_tlsdesc) {
const S_ = target.tlsDescAddress(elf_file);
@ -1747,13 +1724,11 @@ const aarch64 = struct {
util.encoding.Instruction.movz(.x0, value, .{ .lsl = .@"16" }).write(code);
}
},
.TLSDESC_CALL => if (!target.flags.has_tlsdesc) {
relocs_log.debug(" relaxing br => movk(x0, {x})", .{S + A - TP});
const value: u16 = @bitCast(@as(i16, @truncate(S + A - TP)));
util.encoding.Instruction.movk(.x0, value, .{}).write(code);
},
else => try atom.reportUnhandledRelocError(rel, elf_file),
}
}

View file

@ -1009,10 +1009,6 @@ fn elfLink(lld: *Lld, arena: Allocator) !void {
try argv.append("-znorelro");
}
if (comp.link_depfile) |depfile_path| {
try argv.append(try allocPrint(arena, "--dependency-file={s}", .{depfile_path}));
}
try argv.append("-o");
try argv.append(full_out_path);

View file

@ -29,6 +29,12 @@ pub fn writeBranchImm(disp: i28, code: *[4]u8) void {
inst.write(code);
}
pub fn writeCondBrImm(disp: i19, code: *[4]u8) void {
var inst: encoding.Instruction = .read(code);
inst.branch_exception_generating_system.conditional_branch_immediate.group.imm19 = @intCast(@shrExact(disp, 2));
inst.write(code);
}
const assert = std.debug.assert;
const builtin = @import("builtin");
const math = std.math;

View file

@ -2071,6 +2071,8 @@ fn buildOutputType(
.wl => {
var split_it = mem.splitScalar(u8, it.only_arg, ',');
while (split_it.next()) |linker_arg| {
// Unfortunately duplicated with the `for_linker` handling below.
// Handle nested-joined args like `-Wl,-rpath=foo`.
// Must be prefixed with 1 or 2 dashes.
if (linker_arg.len >= 3 and
@ -2080,6 +2082,10 @@ fn buildOutputType(
if (mem.indexOfScalar(u8, linker_arg, '=')) |equals_pos| {
const key = linker_arg[0..equals_pos];
const value = linker_arg[equals_pos + 1 ..];
// We have to handle these here because they would be ambiguous
// if split and added to `linker_args`, as there are argument-less
// variants of them.
if (mem.eql(u8, key, "--build-id")) {
build_id = std.zig.BuildId.parse(value) catch |err| {
fatal("unable to parse --build-id style '{s}': {s}", .{
@ -2092,22 +2098,19 @@ fn buildOutputType(
// is done below.
continue;
}
try linker_args.append(key);
try linker_args.append(value);
continue;
}
}
if (mem.eql(u8, linker_arg, "--build-id")) {
build_id = .fast;
} else if (mem.eql(u8, linker_arg, "--as-needed")) {
// These options are handled inline because their order matters for
// other non-linker options.
if (mem.eql(u8, linker_arg, "--as-needed")) {
needed = false;
} else if (mem.eql(u8, linker_arg, "--no-as-needed")) {
needed = true;
} else if (mem.eql(u8, linker_arg, "-no-pie")) {
create_module.opts.pie = false;
} else if (mem.eql(u8, linker_arg, "--sort-common")) {
// from ld.lld(1): --sort-common is ignored for GNU compatibility,
// this ignores plain --sort-common
} else if (mem.eql(u8, linker_arg, "--whole-archive") or
mem.eql(u8, linker_arg, "-whole-archive"))
{
@ -2280,7 +2283,74 @@ fn buildOutputType(
disable_c_depfile = true;
try cc_argv.append(arena, "-###");
},
.for_linker => try linker_args.append(it.only_arg),
.for_linker => blk: {
// Unfortunately duplicated with the `wl` handling above.
// Handle joined args like `--dependency-file=foo.d`.
// Must be prefixed with 1 or 2 dashes.
if (it.only_arg.len >= 3 and it.only_arg[0] == '-' and it.only_arg[2] != '-') {
if (mem.indexOfScalar(u8, it.only_arg, '=')) |equals_pos| {
const key = it.only_arg[0..equals_pos];
const value = it.only_arg[equals_pos + 1 ..];
// We have to handle these here because they would be ambiguous
// if split and added to `linker_args`, as there are argument-less
// variants of them.
if (mem.eql(u8, key, "--build-id")) {
build_id = std.zig.BuildId.parse(value) catch |err| {
fatal("unable to parse --build-id style '{s}': {s}", .{
value, @errorName(err),
});
};
continue;
} else if (mem.eql(u8, key, "--sort-common")) {
// this ignores --sort-common=<anything>
continue;
}
try linker_args.append(key);
try linker_args.append(value);
break :blk;
}
}
// These options are handled inline because their order matters for
// other non-linker options.
if (mem.eql(u8, it.only_arg, "--as-needed")) {
needed = false;
} else if (mem.eql(u8, it.only_arg, "--no-as-needed")) {
needed = true;
} else if (mem.eql(u8, it.only_arg, "--whole-archive") or
mem.eql(u8, it.only_arg, "-whole-archive"))
{
must_link = true;
} else if (mem.eql(u8, it.only_arg, "--no-whole-archive") or
mem.eql(u8, it.only_arg, "-no-whole-archive"))
{
must_link = false;
} else if (mem.eql(u8, it.only_arg, "-Bdynamic") or
mem.eql(u8, it.only_arg, "-dy") or
mem.eql(u8, it.only_arg, "-call_shared"))
{
lib_search_strategy = .no_fallback;
lib_preferred_mode = .dynamic;
} else if (mem.eql(u8, it.only_arg, "-Bstatic") or
mem.eql(u8, it.only_arg, "-dn") or
mem.eql(u8, it.only_arg, "-non_shared") or
mem.eql(u8, it.only_arg, "-static"))
{
lib_search_strategy = .no_fallback;
lib_preferred_mode = .static;
} else if (mem.eql(u8, it.only_arg, "-search_paths_first")) {
lib_search_strategy = .paths_first;
lib_preferred_mode = .dynamic;
} else if (mem.eql(u8, it.only_arg, "-search_dylibs_first")) {
lib_search_strategy = .mode_first;
lib_preferred_mode = .dynamic;
} else {
try linker_args.append(it.only_arg);
}
},
.linker_input_z => {
try linker_args.append("-z");
try linker_args.append(it.only_arg);
@ -2410,6 +2480,13 @@ fn buildOutputType(
}
}
provided_name = name[prefix..end];
} else if (mem.eql(u8, arg, "--build-id")) {
build_id = .fast;
} else if (mem.eql(u8, arg, "-no-pie")) {
create_module.opts.pie = false;
} else if (mem.eql(u8, arg, "--sort-common")) {
// from ld.lld(1): --sort-common is ignored for GNU compatibility,
// this ignores plain --sort-common
} else if (mem.eql(u8, arg, "-rpath") or mem.eql(u8, arg, "--rpath") or mem.eql(u8, arg, "-R")) {
try create_module.rpath_list.append(arena, linker_args_it.nextOrFatal());
} else if (mem.eql(u8, arg, "--subsystem")) {

View file

@ -444,6 +444,8 @@ pub const CaseTestOptions = struct {
test_target_filters: []const []const u8,
skip_compile_errors: bool,
skip_non_native: bool,
skip_spirv: bool,
skip_wasm: bool,
skip_freebsd: bool,
skip_netbsd: bool,
skip_windows: bool,
@ -472,6 +474,9 @@ pub fn lowerToBuildSteps(
if (options.skip_non_native and !case.target.query.isNative())
continue;
if (options.skip_spirv and case.target.query.cpu_arch != null and case.target.query.cpu_arch.?.isSpirV()) continue;
if (options.skip_wasm and case.target.query.cpu_arch != null and case.target.query.cpu_arch.?.isWasm()) continue;
if (options.skip_freebsd and case.target.query.os_tag == .freebsd) continue;
if (options.skip_netbsd and case.target.query.os_tag == .netbsd) continue;
if (options.skip_windows and case.target.query.os_tag == .windows) continue;

View file

@ -10,6 +10,7 @@ pub const Options = struct {
optimize_modes: []const std.builtin.OptimizeMode,
test_filters: []const []const u8,
test_target_filters: []const []const u8,
skip_wasm: bool,
max_rss: usize,
};
@ -41,6 +42,8 @@ pub fn addLibcTestCase(
}
pub fn addTarget(libc: *const Libc, target: std.Build.ResolvedTarget) void {
if (libc.options.skip_wasm and target.query.cpu_arch != null and target.query.cpu_arch.?.isWasm()) return;
if (libc.options.test_target_filters.len > 0) {
const triple_txt = target.query.zigTriple(libc.b.allocator) catch @panic("OOM");
for (libc.options.test_target_filters) |filter| {

View file

@ -2246,6 +2246,8 @@ const ModuleTestOptions = struct {
test_default_only: bool,
skip_single_threaded: bool,
skip_non_native: bool,
skip_spirv: bool,
skip_wasm: bool,
skip_freebsd: bool,
skip_netbsd: bool,
skip_windows: bool,
@ -2281,6 +2283,9 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
if (options.skip_non_native and !test_target.target.isNative())
continue;
if (options.skip_spirv and test_target.target.cpu_arch != null and test_target.target.cpu_arch.?.isSpirV()) continue;
if (options.skip_wasm and test_target.target.cpu_arch != null and test_target.target.cpu_arch.?.isWasm()) continue;
if (options.skip_freebsd and test_target.target.os_tag == .freebsd) continue;
if (options.skip_netbsd and test_target.target.os_tag == .netbsd) continue;
if (options.skip_windows and test_target.target.os_tag == .windows) continue;
@ -2339,8 +2344,11 @@ fn addOneModuleTest(
const libc_suffix = if (test_target.link_libc == true) "-libc" else "";
const model_txt = target.cpu.model.name;
// wasm32-wasi builds need more RAM, idk why
const max_rss = if (target.os.tag == .wasi)
// These emulated targets need a lot more RAM for unknown reasons.
const max_rss = if (mem.eql(u8, options.name, "std") and
(target.cpu.arch == .hexagon or
(target.cpu.arch.isRISCV() and !resolved_target.query.isNative()) or
target.cpu.arch.isWasm()))
options.max_rss * 2
else
options.max_rss;
@ -2519,6 +2527,7 @@ pub fn wouldUseLlvm(use_llvm: ?bool, query: std.Target.Query, optimize_mode: Opt
const CAbiTestOptions = struct {
test_target_filters: []const []const u8,
skip_non_native: bool,
skip_wasm: bool,
skip_freebsd: bool,
skip_netbsd: bool,
skip_windows: bool,
@ -2526,6 +2535,7 @@ const CAbiTestOptions = struct {
skip_linux: bool,
skip_llvm: bool,
skip_release: bool,
max_rss: usize = 0,
};
pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step {
@ -2538,6 +2548,9 @@ pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step {
for (c_abi_targets) |c_abi_target| {
if (options.skip_non_native and !c_abi_target.target.isNative()) continue;
if (options.skip_wasm and c_abi_target.target.cpu_arch != null and c_abi_target.target.cpu_arch.?.isWasm()) continue;
if (options.skip_freebsd and c_abi_target.target.os_tag == .freebsd) continue;
if (options.skip_netbsd and c_abi_target.target.os_tag == .netbsd) continue;
if (options.skip_windows and c_abi_target.target.os_tag == .windows) continue;
@ -2595,6 +2608,7 @@ pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step {
.root_module = test_mod,
.use_llvm = c_abi_target.use_llvm,
.use_lld = c_abi_target.use_lld,
.max_rss = options.max_rss,
});
// This test is intentionally trying to check if the external ABI is