-
-
Notifications
You must be signed in to change notification settings - Fork 93
Description
Problem
When using Skip with Android Studio, the generated Kotlin project (skipstone) is included as a composite build via includeBuild. However, the path to skipstone is only known at Gradle configuration time — it's computed dynamically from the Skip plugin's output directory.
Android Studio requires a static, pre-configured settings.gradle.kts to properly index composite builds. When the skipstone path is computed dynamically, AS fails to index Skip modules, resulting in:
- All Skip-generated types showing as unresolved (red) in the Android app module
- No code completion for Skip module APIs
- No navigation to Skip module source
- The IDE being effectively unusable for the Android side of a Skip project
Root Cause
The skip-build-plugin generates the Gradle project configuration dynamically. When Skip's Gradle plugin is applied, the skipstone includeBuild path is added at runtime. This works for command-line Gradle builds but not for Android Studio's indexing, which requires the composite build structure to be statically declared in settings.gradle.kts before any plugin resolution occurs.
Workaround
We worked around this by maintaining a custom static settings.gradle.kts in the Android project that:
- Resolves the skipstone path from Xcode's DerivedData (always authoritative since the project is built from Xcode)
- Reads version configuration from skipstone's auto-generated
settings.gradle.kts - Calls
includeBuild(skipstonePath)statically so AS can index it
val skipstonePath = run {
val derivedDataDir = file("${System.getProperty("user.home")}/Library/Developer/Xcode/DerivedData/")
derivedDataDir.listFiles()
?.filter { it.name.startsWith("WhatWatt-") }
?.maxByOrNull { it.lastModified() }
?.resolve("Build/Intermediates.noindex/BuildToolPluginIntermediaries/whatwatthybrid.output/WhatWatt/skipstone")
?.takeIf { it.exists() }
?: error("Skipstone not found in DerivedData — build the project from Xcode first")
}.pathThis workaround has some rough edges — though we mitigate them:
- It hardcodes the DerivedData path structure (which may change between Xcode versions)
- Version information is read directly from skipstone's own auto-generated
settings.gradle.ktsat sync time, so it stays in sync without manual duplication - Multiple WhatWatt DerivedData entries are handled by picking the most recently modified one, which is always the active build
Suggested Fix
The ideal fix would be for Skip to either:
-
Generate a static
includeBuildentry — write a stable, path-resolvedincludeBuild(...)call into the Android project'ssettings.gradle.ktsafter transpilation, so AS can see it without dynamic evaluation. -
Document the
includeBuildrequirement — clarify in the Skip docs that AS users need to manually add theincludeBuildpath and explain how to find it.
Environment
- Skip: 1.7.0
- Xcode: 26.2 (Build 17C52)
- Android Studio: 2025.2 (Meerkat)
- Gradle: 8.14.3
- Android Gradle Plugin: 8.13.0
- Kotlin: 2.2.0