Repository navigation
Retain sub-second modification time precision on non-Darwin platforms - #2228
Merged
jakepetroules merged 1 commit intoOct 8, 2026
Merged
Conversation
On non-Darwin platforms, lastModificationTime(for:) obtained modification times from Foundation and truncated them to whole seconds. This makes ordering comparisons between files written within the same second ambiguous. In particular, the incremental build only skips an emit-module job when every source is strictly older than every emit-module output, so emit-module was spuriously re-run whenever a source and the module outputs were written in the same second. Use stat directly on Glibc, Musl, and Android (as on Darwin) to retain the nanosecond component. stat follows symbolic links, so the modification time of the linked file continues to be returned.
jakepetroules
requested review from
DougGregor,
artemcm,
compnerd and
owenv
as code owners
October 7, 2026 18:07
Contributor
Author
|
@swift-ci test |
jakepetroules
added a commit
to swiftlang/swift-build
that referenced
this pull request
Oct 7, 2026
…hosts The C file compile depends on the target's Swift generated headers, so the Swift driver is re-planned and decides whether emit-module is up to date by checking that every source is strictly older than every emit-module output. swift-driver truncates modification times to whole seconds on non-Darwin platforms, so when SwiftFile.swift and the module outputs from the first build are written within the same second, emit-module is re-run. The existing workaround only applied to Linux, so the test was still flaky on FreeBSD. Apply it to every non-macOS host, and document the root cause in place of the FIXME. The underlying driver fix is swiftlang/swift-driver#2228.
Teemperor
pushed a commit
to Teemperor/swift-mono
that referenced
this pull request
Oct 7, 2026
…n all non-Darwin hosts The C file compile depends on the target's Swift generated headers, so the Swift driver is re-planned and decides whether emit-module is up to date by checking that every source is strictly older than every emit-module output. swift-driver truncates modification times to whole seconds on non-Darwin platforms, so when SwiftFile.swift and the module outputs from the first build are written within the same second, emit-module is re-run. The existing workaround only applied to Linux, so the test was still flaky on FreeBSD. Apply it to every non-macOS host, and document the root cause in place of the FIXME. The underlying driver fix is swiftlang/swift-driver#2228.
artemcm
approved these changes
Oct 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On non-Darwin platforms,
lastModificationTime(for:)obtained modification times from Foundation and truncated them to whole seconds (nanoseconds: 0). This makes ordering comparisons between files written within the same second ambiguous.In particular,
FirstWaveComputer.computeCanSkipEmitModuleTasksonly skips the emit-module job when every source is strictly older than the oldest emit-module output. When a source and the module outputs were written in the same second, both truncate to the same value,<is false, and emit-module is spuriously re-run even though nothing changed. This was the cause of a long-standing nondeterministic failure in swift-build'sBuildCommandTests.singleFileCompileon Linux and FreeBSD (most recently seen in CI for swiftlang/swift-build#638); instrumenting the driver confirmed it fails exactly when the source and outputs share a whole-second timestamp.This change uses
statdirectly on Glibc, Musl, and Android, as is already done on Darwin, to retain the nanosecond component.statfollows symbolic links, so the modification time of the linked file continues to be returned. Windows is unchanged.Testing
Added
LastModificationTimeTests:retainsSubSecondPrecision: checks the driver's modification time agrees with Foundation's to within 1ms. Fails on Linux without this change (expected 1791395602.9011889, got 1791395602.0), passes with it.followsSymbolicLinks: checks a symlink reports its target's modification time.Ran the new tests on macOS and Linux (aarch64), and the incremental, module dependency graph, build record, and output job test suites on Linux. With this change, swift-build's
singleFileCompilepassed 15/15 runs on Linux with its workaround disabled, versus failing roughly two thirds of the time before.