From 76dbff5a7cbf4b9d856163fede5928c6b21d18ea Mon Sep 17 00:00:00 2001 From: Hammed Abass Date: Mon, 13 Jul 2026 10:17:40 +0200 Subject: [PATCH] fix(shared): build only host-compatible targets --- .github/workflows/shared-kmp.yml | 3 +- AGENTS.md | 7 +-- shared/AGENTS.md | 5 +- shared/build.gradle.kts | 84 ++++++++++++++++++++++++++++---- 4 files changed, 82 insertions(+), 17 deletions(-) diff --git a/.github/workflows/shared-kmp.yml b/.github/workflows/shared-kmp.yml index b1211cf..b057b98 100644 --- a/.github/workflows/shared-kmp.yml +++ b/.github/workflows/shared-kmp.yml @@ -44,8 +44,7 @@ concurrency: jobs: jvm-test: # Host Rust embedding is enabled only for the current Gobley host target. - # Linux/Windows JVM cargo builds are disabled in shared/build.gradle.kts, so - # jvmTest must run on macOS (arm64) to match local development. + # This job stays on macOS to cover the Apple targets as well as JVM tests. runs-on: macos-latest timeout-minutes: 75 steps: diff --git a/AGENTS.md b/AGENTS.md index c210366..ddf1ccc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -100,9 +100,10 @@ Other targets (slower / machine-dependent): ./gradlew :desktopApp:run ``` -**Note:** `jvmTest` CI runs on **macOS** because Gobley host cargo is enabled for -the current Gobley host; Linux JVM cargo may be disabled in -`shared/build.gradle.kts`. Prefer macOS for local parity with CI. +**Note:** `jvmTest` CI currently runs on **macOS**. Gobley host cargo is enabled +for the current host and architecture, so local Linux and Windows builds embed +their matching desktop Rust library. Prefer macOS only when exact CI parity is +required. ### What to run before finishing diff --git a/shared/AGENTS.md b/shared/AGENTS.md index 26ecea6..e9c3f10 100644 --- a/shared/AGENTS.md +++ b/shared/AGENTS.md @@ -58,8 +58,9 @@ Optional: ./gradlew :androidApp:assembleDebug ``` -CI `:shared:jvmTest` runs on **macOS** (Gobley host cargo). Prefer macOS for -local parity. +CI `:shared:jvmTest` currently runs on **macOS**. Gobley host cargo follows the +current host and architecture, including Linux and Windows; use macOS only when +exact CI parity is required. When Kotlin changes touch UniFFI-generated APIs, rebuild/test with a full `jvmTest` so Gobley/native pieces stay aligned. diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 2220fd4..5a7b285 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -2,11 +2,31 @@ import gobley.gradle.cargo.dsl.appleMobile import gobley.gradle.cargo.dsl.jvm +import gobley.gradle.cargo.tasks.CargoBuildTask +import gobley.gradle.cargo.tasks.CargoCheckTask import gobley.gradle.GobleyHost import gobley.gradle.rust.targets.RustAndroidTarget +import gobley.gradle.rust.targets.RustAppleMobileTarget +import gobley.gradle.rust.targets.RustTarget +import org.gradle.api.DefaultTask +import org.gradle.api.provider.ListProperty +import org.gradle.api.tasks.Input import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.gradle.dsl.JvmTarget +abstract class VerifyHostCargoTaskSelection : DefaultTask() { + @get:Input + abstract val mismatches: ListProperty + + @TaskAction + fun verify() { + check(mismatches.get().isEmpty()) { + "Cargo tasks do not match the current host: ${mismatches.get().joinToString()}" + } + } +} + plugins { alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.androidLibrary) @@ -18,13 +38,15 @@ plugins { } kotlin { - listOf( - iosArm64(), - iosSimulatorArm64() - ).forEach { iosTarget -> - iosTarget.binaries.framework { - baseName = "Shared" - isStatic = true + if (GobleyHost.current.platform == GobleyHost.Platform.MacOS) { + listOf( + iosArm64(), + iosSimulatorArm64() + ).forEach { iosTarget -> + iosTarget.binaries.framework { + baseName = "Shared" + isStatic = true + } } } @@ -86,6 +108,14 @@ android { } } +val hostCargoTargets = buildSet { + add(GobleyHost.current.rustTarget) + addAll(RustAndroidTarget.entries) + if (GobleyHost.current.platform == GobleyHost.Platform.MacOS) { + addAll(RustAppleMobileTarget.entries) + } +} + cargo { packageDirectory = layout.projectDirectory.dir("../crates/vnidrop") publishJvmArtifacts = true @@ -106,6 +136,18 @@ cargo { } } } + builds.configureEach { + val buildOnCurrentHost = rustTarget in hostCargoTargets + installTargetBeforeBuild.set(buildOnCurrentHost) + variants { + buildTaskProvider.configure { + enabled = buildOnCurrentHost + } + checkTaskProvider.configure { + enabled = buildOnCurrentHost + } + } + } } uniffi { @@ -114,6 +156,31 @@ uniffi { } } +val verifyHostCargoTaskSelection = tasks.register( + "verifyHostCargoTaskSelection" +) { + group = "verification" + description = "Verifies that Cargo tasks are enabled only for targets supported by this host." + mismatches.convention(emptyList()) +} + +afterEvaluate { + verifyHostCargoTaskSelection.configure { + mismatches.set(buildList { + tasks.withType().forEach { + if (it.enabled != (it.target.get() in hostCargoTargets)) add(it.path) + } + tasks.withType().forEach { + if (it.enabled != (it.target.get() in hostCargoTargets)) add(it.path) + } + }) + } +} + +tasks.named("check") { + dependsOn(verifyHostCargoTaskSelection) +} + tasks.configureEach { // Gobley does not currently treat every Rust source/API change as an input of // all platform cargo tasks. Without these inputs an incremental Android build @@ -127,7 +194,4 @@ tasks.configureEach { layout.projectDirectory.file("../Cargo.lock"), ).withPathSensitivity(PathSensitivity.RELATIVE) } - if (name.contains("Linux") || name.contains("MinGW") || name.contains("MacOSX64")) { - enabled = false - } }