The `com.android.kotlin.multiplatform.library` plu...
# build-tools
j
The
com.android.kotlin.multiplatform.library
plugin creates a
KotlinTarget
(
com.android.build.api.variant.impl.KotlinMultiplatformAndroidLibraryTargetImpl
) whose
platformType
is "jvm" as opposed to "androidJvm". @Sebastian Sellmair [JB] indicated on another Slack workspace that this was intentional. A few questions have come up related to this. How should we write code that operates on all targets (or a subset of them) and correctly differentiate JVM vs. Android. For example, Android differs from the JVM in having multiple variants by default, having two test compilations (times the number of product flavors), etc. Should we prefer doing type checks on the target instead of using
platformType
? And the fact that this comes with extra burden when you have a
compileOnly
dependency on AGP, since you can no longer do a simple
as? KotlinMultiplatformAndroidLibraryTarget
without a try/catch on
NoClassDefFoundException
, or otherwise doing a
Class.forName
and then reflective
isInstance
.
@ralf @mbonnin @zsmb
r
For example, Android differs from the JVM in having multiple variants by default
The new plugin doesn't support that. But there are still two compilations for unit tests and device tests.
s
cc @tapchicoma who is currently maintaining the external target API (maybe @Anton Lakotka [JB] ?) We should think about adding some idiomatic way for switching over different targets!
j
The new plugin doesn't support that.
Oh, yes. Thanks! I saw build types and flavors mentioned on the page for the new plugin, but it's in reference to migrating from the legacy one.
w
btw @tapchicoma is not available today (and yesterday) so expect a delayed response, but he's probably the best person to answer questions on this
👍 1
t
We will discuss these questions internally and come back to you. Changing
platformType
to
jvm
was intentional, but I would advice against relying on target type to detect if it is Android.
For external target types/compilation our suggested approach is to: • Do the relative code wrapped in the
plugins.withId(<id>) { }
block, where plugin id is external target plugin ID. For example for KMP/Android it is
com.android.kotlin.multiplatform.library
. • Check target and compilation types. For example for KMP/Android -
target is KotlinMultiplatformAndroidLibraryTarget
(docs) and
compilation is KotlinMultiplatformAndroidCompilation
(doc, there are more compilation types) • For
platformType
publication issue we've created the following issue: KT-81505 New Android Multiplatform plugin publishes Android variants with kotlinPlatformType:jvm In general you may expect in the future more external target types, so it is better to avoid on relying any external target is Android one.
And the fact that this comes with extra burden when you have a
compileOnly
dependency on AGP, since you can no longer do a simple
as? KotlinMultiplatformAndroidLibraryTarget
without a try/catch on
NoClassDefFoundException
, or otherwise doing a
Class.forName
and then reflective
isInstance
.
Could you file an issue for this with more detailed description of the problem? We need to think how to provide some help for this case.
1
m
you may expect in the future more external target types, so it is better to avoid on relying any external target is Android one.
Not sure I get that one. You mean new values in the
KotlinPlatformType
enum? It's OK if the changes are additives? Plugin authors will need a newer version of their plugins to support the new
KotlinPlatformType
but this is fine?
a
Yahor meant that concept of ExternalTargets implies that anyone can introduce its own target. It will extend kotlin's ExternalTarget interface (abstract class). And these external targets may share the same KotlinPlatformType as this enum should indicate what Kotlin Compiler Backend will be selected to produce output artifacts. And in case if other Plugins relies on this statement:
Copy code
fun KotlinTarget.isNewAndroidKMP() = this is ExternalTarget && this.platformType == jvm
may fail in some other cases if someone else decided to tweak KMP via ExternalTarget API. That is why this check should be rewritten into something like this:
Copy code
fun KotlinTarget.isNewAndroidKMP() = this === androidExtension.kmpTarget()
i.e. check against some API that AGP would provide, as they are owners of their target.
👀 1
m
Why not just
Copy code
fun KotlinTarget.isNewAndroidKMP() = this is KotlinMultiplatformAndroidLibraryTarget
?
a
it is possible, if AGP extends it in this way.
m
I think it does? And to avoid the
NoClassDefFoundException
that Jake mention, only call
isNewAndroidKMP()
from
plugins.withId("com.android.kotlin.multiplatform.library") { }
👌 1