Skip to content

Comments

Fix platform-agnostic native artifact check in build backend#326

Open
holodorum wants to merge 2 commits intokson-org:mainfrom
holodorum:build-issue
Open

Fix platform-agnostic native artifact check in build backend#326
holodorum wants to merge 2 commits intokson-org:mainfrom
holodorum:build-issue

Conversation

@holodorum
Copy link
Collaborator

@holodorum holodorum commented Feb 21, 2026

Summary

The build backend's native artifact check had three interrelated bugs that could produce broken wheels:

Stale cross-platform artifacts fooled the check. The old code used any() across all platform libraries (win32, darwin, linux), so a libkson.dylib left over from a macOS build on a Linux builder would satisfy the check, skipping the Gradle build entirely and leaving libkson.so uncompiled.

The header file check referenced kson_api.h, which isn't produced by the build. CopyNativeArtifactsTask produces jni_simplified.h, and the runtime loads jni_simplified.h. This meant fresh builds (without a stale kson_api.h on disk) would always think artifacts were missing and attempt a rebuild—or worse, silently succeed without the header.

Missing artifacts with no kson-sdist produced broken wheels silently. When both the artifacts and the kson-sdist build directory were absent, the function just returned without error. The resulting wheel would install but fail at import time.

The fix checks only the native library for the current platform plus jni_simplified.h, adds a post-condition that errors clearly when required artifacts are missing, and excludes platform-specific binaries from prepareSdistBuildEnvironment so sdists don't carry stale cross-platform artifacts. A few smaller improvements tag along: subprocess.run(cwd=...) replaces os.chdir for thread safety, and Gradle build failures now log both stdout and stderr.

Fixes #307

The build backend checked for native artifacts using `any()` across all
platforms (win32, darwin, linux), so a stale artifact from a different OS
(e.g. `libkson.dylib` left over on a Linux builder) would skip the
Gradle build, leaving the actually-needed native library uncompiled.

Additionally, the artifact check included `kson_api.h` which is not
produced by the build—the Gradle `CopyNativeArtifactsTask` produces
`jni_simplified.h` and the runtime loads `jni_simplified.h`. This would
have caused fresh wheel builds to always trigger a rebuild attempt.

Finally, when both artifacts and `kson-sdist` were absent, the function
silently returned, producing broken wheels with no error.

Fixes:
- Check only the native library for *this* platform, plus
  `jni_simplified.h` (the header actually produced and loaded at
  runtime)
- Add a post-condition that errors clearly when required artifacts are
  missing, guiding users to install from a pre-built wheel or ensure a
  JDK is available
- Use `subprocess.run(cwd=...)` instead of `os.chdir` for thread safety
- Log both stdout and stderr on Gradle build failure for easier
  debugging
- Exclude platform-specific native binaries from `prepareSdistBuildEnvironment`
  in build.gradle.kts so sdists don't bundle stale cross-platform
  artifacts

Fixes kson-org#307
@aochagavia
Copy link
Collaborator

aochagavia commented Feb 21, 2026

Ah, so this is why GraalVM builds would be constantly re-triggered! Thanks for fixing that!

Sorry, misunderstood what was going on. Now I see this is a Python only thing. Glad to see improvements, nevertheless :)

PixiExecTask only declares inputs (command strings, env vars) but no
outputs, so Gradle always considered this task out-of-date and re-ran
the full native-image build every time.

Add explicit input/output declarations so Gradle can properly cache
the task: the project JAR, runtime classpath, and JNI config as inputs,
and the native binary as the output. The output is the specific binary
file rather than the whole directory, since krossover's
generateJniBindingsJvm also writes into that directory.
@holodorum
Copy link
Collaborator Author

That's another problem indeed, but adding an output directory in b50ac89 for the build artifacts stops the re-triggering

@holodorum holodorum changed the title Fix platform-agnostic native artifact check in build backend Fix build backend and centralize cibuildwheel config Feb 21, 2026
@holodorum holodorum changed the title Fix build backend and centralize cibuildwheel config Fix platform-agnostic native artifact check in build backend Feb 21, 2026
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.

Source build skipped due to platform-agnostic native artifact check

2 participants