Skip to content

[Gradle] Don't reinstall the K/N bundle over an existing installation - #7636

Open
Andrey Yastrebov (AYastrebov) wants to merge 1 commit into
masterfrom
rr/ayastrebov/KT-86251_master
Open

[Gradle] Don't reinstall the K/N bundle over an existing installation#7636
Andrey Yastrebov (AYastrebov) wants to merge 1 commit into
masterfrom
rr/ayastrebov/KT-86251_master

Conversation

@AYastrebov

@AYastrebov Andrey Yastrebov (AYastrebov) commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

The Kotlin/Native toolchain treats a bundle directory as installed only when it holds the provisioned.ok marker, and only the toolchain itself ever wrote that marker. A distribution installed by NativeCompilerDownloader -- the configuration-phase path, used whenever kotlin.native.distribution.downloadFromMaven is off -- has no marker, so the toolchain declares it unprovisioned and unpacks the archive on top of it.

That re-extraction is neither necessary nor safe. Extraction shells out to tar, which unlinks each existing file before recreating it, so every shipped file in the distribution briefly does not exist. A build reading the distribution at that moment gets a NoSuchFileException, which is what AndroidX has been hitting on files such as
klib/cache/<target>-gSTATIC-system/stdlib-per-file-cache/.../ir. They share one konan data dir between an outer build installing through 'NativeCompilerDownloader' and Gradle TestKit sub-builds installing through the toolchain, so the two paths meet routinely.

Write the marker from NativeCompilerDownloader as well, so that both installers agree on what a complete installation looks like and the toolchain leaves such a directory alone.

The configuration-phase path had a second way to rewrite a live distribution. When its atomic rename failed because the directory was already there, it fell back to copying on top of it, which rewrites files another build may be reading. Skip that copy and, since this build then installed nothing, leave the marker to whoever did.

^KT-86251

The Kotlin/Native toolchain treats a bundle directory as installed only
when it holds the 'provisioned.ok' marker, and only the toolchain itself
ever wrote that marker. A distribution installed by
'NativeCompilerDownloader' -- the configuration-phase path, used
whenever 'kotlin.native.distribution.downloadFromMaven' is off -- has no
marker, so the toolchain declares it unprovisioned and unpacks the
archive on top of it.

That re-extraction is neither necessary nor safe. Extraction shells out
to tar, which unlinks each existing file before recreating it, so every
shipped file in the distribution briefly does not exist. A build reading
the distribution at that moment gets a NoSuchFileException, which is
what AndroidX has been hitting on files such as
klib/cache/<target>-gSTATIC-system/stdlib-per-file-cache/.../ir. They
share one konan data dir between an outer build installing through
'NativeCompilerDownloader' and Gradle TestKit sub-builds installing
through the toolchain, so the two paths meet routinely.

Write the marker from 'NativeCompilerDownloader' as well, so that both
installers agree on what a complete installation looks like and the
toolchain leaves such a directory alone.

The configuration-phase path had a second way to rewrite a live
distribution. When its atomic rename failed because the directory was
already there, it fell back to copying on top of it, which rewrites
files another build may be reading. Skip that copy and, since this
build then installed nothing, leave the marker to whoever did.

^KT-86251
@kotlin-safemerge

kotlin-safemerge Bot commented Aug 21, 2026

Copy link
Copy Markdown

Code Owners

RuleOwnersApproval
/​libraries/​tools/​kotlin-​gradle-​plugin-​integration-​tests/​, /​libraries/​tools/​kotlin-​gradle-​plugin/​
kotlin-build-tools
🔄
Tapchicoma
PR commands for maintainers
CommandDescriptionParameters
/safe-mergeRebase-merges with automatic fixup commit squashing--fixup Autosquash fixup commits (on by default)
/safe-squash-mergeSquash-merges with optional commit title/body override--title Title of the squashed commit
--message Body of the squashed commit
/dry-runRuns the test pipeline with changes rebased on latest master--retry Retry the CI run on failure
/test-publicTriggers the public test suite without rebasing on latest master
/test-privateTriggers the private test suite without rebasing on latest master
/codeownersTriggers code owners check and comment update
/fixupSquashes fixup commits and force pushes the branch
/cancel-coordinatorCancels the merge coordinator currently running for this branch

@AYastrebov

Copy link
Copy Markdown
Contributor Author

/dry-run

@KotlinBuild

Build Server (KotlinBuild) commented Aug 21, 2026

Copy link
Copy Markdown

THIS IS A DRY RUN

Quality gate is triggered at https://buildserver.labs.intellij.net/build/1037930996 — use this link to get full insight.

Quality gate was triggered with the following revisions:

kotlin
Branch: refs/merge/GITHUB-7636/safe-merge
Commit: 6e050ba


Quality gate failed. See https://buildserver.labs.intellij.net/build/1037930996 to get full insight.

if (installed) {
// without the marker a toolchain build sharing this konan data dir unpacks the archive over the
// distribution again (KT-86251). Keep it the last thing written.
compilerDirectory.resolve(NativeVersionValueSource.MARKER_FILE).createNewFile()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I think the non-Gradle provisioner should also create such a file upon successful provisioning. And ideally, we should have only one provisioner implementation, which could be a BTA-X library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants