fix(shared): build only host-compatible targets

This commit is contained in:
2026-07-13 10:17:40 +02:00
parent fe97ad1b8a
commit 76dbff5a7c
4 changed files with 82 additions and 17 deletions

View File

@@ -44,8 +44,7 @@ concurrency:
jobs: jobs:
jvm-test: jvm-test:
# Host Rust embedding is enabled only for the current Gobley host target. # 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 # This job stays on macOS to cover the Apple targets as well as JVM tests.
# jvmTest must run on macOS (arm64) to match local development.
runs-on: macos-latest runs-on: macos-latest
timeout-minutes: 75 timeout-minutes: 75
steps: steps:

View File

@@ -100,9 +100,10 @@ Other targets (slower / machine-dependent):
./gradlew :desktopApp:run ./gradlew :desktopApp:run
``` ```
**Note:** `jvmTest` CI runs on **macOS** because Gobley host cargo is enabled for **Note:** `jvmTest` CI currently runs on **macOS**. Gobley host cargo is enabled
the current Gobley host; Linux JVM cargo may be disabled in for the current host and architecture, so local Linux and Windows builds embed
`shared/build.gradle.kts`. Prefer macOS for local parity with CI. their matching desktop Rust library. Prefer macOS only when exact CI parity is
required.
### What to run before finishing ### What to run before finishing

View File

@@ -58,8 +58,9 @@ Optional:
./gradlew :androidApp:assembleDebug ./gradlew :androidApp:assembleDebug
``` ```
CI `:shared:jvmTest` runs on **macOS** (Gobley host cargo). Prefer macOS for CI `:shared:jvmTest` currently runs on **macOS**. Gobley host cargo follows the
local parity. 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 When Kotlin changes touch UniFFI-generated APIs, rebuild/test with a full
`jvmTest` so Gobley/native pieces stay aligned. `jvmTest` so Gobley/native pieces stay aligned.

View File

@@ -2,11 +2,31 @@
import gobley.gradle.cargo.dsl.appleMobile import gobley.gradle.cargo.dsl.appleMobile
import gobley.gradle.cargo.dsl.jvm 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.GobleyHost
import gobley.gradle.rust.targets.RustAndroidTarget 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.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.JvmTarget
abstract class VerifyHostCargoTaskSelection : DefaultTask() {
@get:Input
abstract val mismatches: ListProperty<String>
@TaskAction
fun verify() {
check(mismatches.get().isEmpty()) {
"Cargo tasks do not match the current host: ${mismatches.get().joinToString()}"
}
}
}
plugins { plugins {
alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidLibrary) alias(libs.plugins.androidLibrary)
@@ -18,13 +38,15 @@ plugins {
} }
kotlin { kotlin {
listOf( if (GobleyHost.current.platform == GobleyHost.Platform.MacOS) {
iosArm64(), listOf(
iosSimulatorArm64() iosArm64(),
).forEach { iosTarget -> iosSimulatorArm64()
iosTarget.binaries.framework { ).forEach { iosTarget ->
baseName = "Shared" iosTarget.binaries.framework {
isStatic = true baseName = "Shared"
isStatic = true
}
} }
} }
@@ -86,6 +108,14 @@ android {
} }
} }
val hostCargoTargets = buildSet<RustTarget> {
add(GobleyHost.current.rustTarget)
addAll(RustAndroidTarget.entries)
if (GobleyHost.current.platform == GobleyHost.Platform.MacOS) {
addAll(RustAppleMobileTarget.entries)
}
}
cargo { cargo {
packageDirectory = layout.projectDirectory.dir("../crates/vnidrop") packageDirectory = layout.projectDirectory.dir("../crates/vnidrop")
publishJvmArtifacts = true 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 { uniffi {
@@ -114,6 +156,31 @@ uniffi {
} }
} }
val verifyHostCargoTaskSelection = tasks.register<VerifyHostCargoTaskSelection>(
"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<CargoBuildTask>().forEach {
if (it.enabled != (it.target.get() in hostCargoTargets)) add(it.path)
}
tasks.withType<CargoCheckTask>().forEach {
if (it.enabled != (it.target.get() in hostCargoTargets)) add(it.path)
}
})
}
}
tasks.named("check") {
dependsOn(verifyHostCargoTaskSelection)
}
tasks.configureEach { tasks.configureEach {
// Gobley does not currently treat every Rust source/API change as an input of // 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 // all platform cargo tasks. Without these inputs an incremental Android build
@@ -127,7 +194,4 @@ tasks.configureEach {
layout.projectDirectory.file("../Cargo.lock"), layout.projectDirectory.file("../Cargo.lock"),
).withPathSensitivity(PathSensitivity.RELATIVE) ).withPathSensitivity(PathSensitivity.RELATIVE)
} }
if (name.contains("Linux") || name.contains("MinGW") || name.contains("MacOSX64")) {
enabled = false
}
} }