Generate protos into commonMain for multiplatform projects with an Android target - #3698
Draft
oldergod wants to merge 1 commit into
Draft
Generate protos into commonMain for multiplatform projects with an Android target#3698oldergod wants to merge 1 commit into
oldergod wants to merge 1 commit into
Conversation
…droid target Since 6.0.0-alpha02, a Kotlin multiplatform project with an Android target gets no generateCommonMainProtos task. Wire generates into the Android variants only, and commonMain plus every non-Android target see no generated code. Two causes, both from the #3503 rewrite. First, forEachWireSource checks hasAndroid before the Kotlin multiplatform arm, so any project with an Android plugin takes the Android path. Second, the rewrite removed the afterEvaluate deferral for Android projects. The setup now runs at android-plugin-apply time, before the build script evaluates the wire {} block. The Android path tolerates this because onVariants defers its callbacks. The multiplatform path reads extension.outputs eagerly, so it would wire nothing into the compilations. Fix both: the multiplatform arm now precedes the hasAndroid arm, and the android handler defers applyWirePlugin to afterEvaluate when the KotlinMultiplatformExtension is present. That path does not use the Android variant API, so the deferral is safe. Pure Android projects keep the synchronous call that onVariants requires. Add the kotlin-multiplatform-android fixture. The only multiplatform fixture had no Android target, which is why CI never caught this. Fixes #3688 Co-authored-by: Benoît Quenaudon <benoit@quenaudon.com> Signed-off-by: Benoît Quenaudon <benoit@quenaudon.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3688.
Problem
Since 6.0.0-alpha02, a Kotlin multiplatform project with an Android target gets no
generateCommonMainProtostask. Wire generates into the Android variants only (generateDebugProtos,generateReleaseProtos).commonMainand every non-Android target see no generated code. In 5.5.0, Wire generated once intocommonMainand every target consumed it.The trigger is the Android target:
com.android.libraryplusandroidTarget(). A multiplatform project without an Android plugin is not affected. The issue's wire block alone does not reproduce; the Android target does.Root cause, two parts
SourceRoots.kt.forEachWireSourcecheckshasAndroidbefore the Kotlin multiplatform arm. Any project with an Android plugin is treated as an Android-only project.afterEvaluatedeferral that 5.5.0 used for Android projects.applyWirePlugin()now runs at android-plugin-apply time, before the build script evaluates thewire {}block. The Android path tolerates this becauseonVariantsdefers its callbacks. The multiplatform path readsextension.outputseagerly, so reordering the arms alone wires nothing into the compilations.Fix
SourceRoots.kt: the Kotlin multiplatform arm now precedes thehasAndroidarm. This restores the 5.5.0 semantics: generate once intocommonMain, the Android target consumescommonMainlike every other target.WirePlugin.kt: when theKotlinMultiplatformExtensionis present at android-plugin-apply time, the android handler defersapplyWirePlugin()toafterEvaluate. This path does not use the Android variant API, so the deferral is safe, and thewire {}block is evaluated by then. Pure Android projects keep the synchronous call thatonVariantsrequires.Known limit: if the build script declares
com.squareup.wireand the Android plugin beforekotlin("multiplatform"), the extension is not visible yet when the android handler runs, and Wire still takes the Android path. Declaring the Kotlin plugin first, the common convention, works.Test coverage
CI never caught this because the only multiplatform fixture has no Android target. This PR adds the
kotlin-multiplatform-androidfixture (KMP,com.android.library,androidTarget(), jvm) and akotlinMultiplatformWithAndroidTargettest. The test assertsgenerateCommonMainProtosexists, no per-variant generate task exists, andassemblecompiles the generated code.Verification
:generateCommonMainProtosis null) and passes with it.:wire-gradle-plugin:testsuite green locally, test task forced fresh (--rerun --no-build-cache): 104 tests, 0 failures, 5 pre-existing ignores.generateCommonMainProtosis back, 12 files generate into the commonMain output, andcompileKotlinJvm,compileKotlinJs,compileDebugKotlinAndroid, andcompileReleaseKotlinAndroidall compile them.