Skip to content

Commit

Permalink
feat(multiplatform): support manual KMP target hierarchy
Browse files Browse the repository at this point in the history
- Add support for manual configuration of Kotlin Multiplatform targets.
- Allow not setting up fluxo-kmp-conf containers and use the default KMP hierarchy instead + make this the default.
- Enhance Gradle scripts for better plugin and dependency management.

Signed-off-by: Art Shendrik <artyom.shendrik@gmail.com>
  • Loading branch information
amal committed Nov 18, 2024
1 parent 3c40c9e commit 9ea3726
Show file tree
Hide file tree
Showing 20 changed files with 561 additions and 950 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

[//]: # (Removed, Added, Changed, Fixed, Updated)

### Added
- allow not setting up `fluxo-kmp-conf` containers and use the default KMP hierarchy instead.

### Fixed
- return support for Kotlin's `-Xjdk-release=18+` in JDK 23+.
- fix bundled shrinker loading.
Expand Down
1 change: 0 additions & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
<details>
<summary>Show</summary>

* Allow not set up containers and use the default KMP hierarchy instead + make this the default.
* Interesting KMP architecture sample
* https://github.com/VasilyRylov/architecture-samples/tree/main
* Compose Multiplatform lib that prints the reason for recomposition in Logcat
Expand Down
1,329 changes: 424 additions & 905 deletions checks/kmp/.kotlin-js-store/yarn.lock

Large diffs are not rendered by default.

54 changes: 50 additions & 4 deletions checks/kmp/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate

plugins {
alias(libs.plugins.kotlin.multiplatform) apply false
alias(libs.plugins.android.lib) apply false
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.android.lib)
alias(libs.plugins.gradle.doctor) apply false
alias(libs.plugins.vanniktech.mvn.publish)
id("io.github.fluxo-kt.fluxo-kmp-conf")
}

val manual = true

fkcSetupMultiplatform(
config = {
kotlinLangVersion = "last"
Expand All @@ -19,5 +25,45 @@ fkcSetupMultiplatform(
enableGradleDoctor = true
enablePublication = true
},
kmp = { allDefaultTargets() },
)
kmp = { if (!manual) allDefaultTargets() },
) {
if (manual) {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
applyDefaultHierarchyTemplate(KotlinHierarchyTemplate.fluxoKmpConf)

jvm()
androidTarget()

js {
browser()
nodejs()
}
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
nodejs()
d8()
}

iosX64()
iosArm64()
iosSimulatorArm64()

watchosArm64()
watchosArm32()
watchosX64()
watchosSimulatorArm64()

tvosArm64()
tvosX64()
tvosSimulatorArm64()

macosArm64()
macosX64()

linuxX64()
linuxArm64()

mingwX64()
}
}
2 changes: 2 additions & 0 deletions fluxo-kmp-conf/api/plugin.api
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ public abstract interface class fluxo/conf/dsl/FluxoConfigurationExtensionKotlin
public abstract fun getSetupKapt ()Ljava/lang/Boolean;
public abstract fun getSetupKotlinXSerialization ()Z
public abstract fun getSetupKsp ()Ljava/lang/Boolean;
public abstract fun getSetupLegacyKotlinHierarchy ()Z
public abstract fun getSuppressKotlinComposeCompatibilityCheck ()Ljava/lang/Boolean;
public abstract fun getUseDokka ()Z
public fun onConfiguration (Lkotlin/jvm/functions/Function1;)V
Expand All @@ -272,6 +273,7 @@ public abstract interface class fluxo/conf/dsl/FluxoConfigurationExtensionKotlin
public abstract fun setSetupKapt (Ljava/lang/Boolean;)V
public abstract fun setSetupKotlinXSerialization (Z)V
public abstract fun setSetupKsp (Ljava/lang/Boolean;)V
public abstract fun setSetupLegacyKotlinHierarchy (Z)V
public abstract fun setSuppressKotlinComposeCompatibilityCheck (Ljava/lang/Boolean;)V
public abstract fun setUseDokka (Z)V
}
Expand Down
2 changes: 0 additions & 2 deletions fluxo-kmp-conf/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@
<ID>ForbiddenComment:SetupDetekt.kt$DetectedTaskPlatform$// TODO: Detect common/metadata tasks?</ID>
<ID>ForbiddenComment:SetupKotlin.kt$// FIXME: Configure common compilerOptions via KotlinProjectExtension.compilerOptions</ID>
<ID>ForbiddenComment:SetupKotlin.kt$// TODO: Check KSP setup for KMP modules</ID>
<ID>ForbiddenComment:SetupKotlin.kt$// TODO: Detect if KMP is already applied and what targets are already configured.</ID>
<ID>ForbiddenComment:SetupKotlinDependencies.kt$// TODO: Use `compileOnlyApi` for transitively included compile-only dependencies.</ID>
<ID>ForbiddenComment:SetupKotlinDependencies.kt$// TODO: With coil-bom:2.2.2 doesn't work as enforcedPlatform for Android and/or KMP</ID>
<ID>ForbiddenComment:SetupKotlinExperimentalTestCompilation.kt$// TODO: Find a solution for KMP 2.0</ID>
Expand All @@ -137,7 +136,6 @@
<ID>ForbiddenComment:SetupKotlinOptions.kt$// TODO: Allow -Xjdk-release=1.6 with -jvm-target 1.8 for Kotlin 2.0+</ID>
<ID>ForbiddenComment:SetupKotlinOptions.kt$// TODO: Guard conditions for when-with-subject (Kotlin 2.0.20)</ID>
<ID>ForbiddenComment:SetupKotlinOptions.kt$// TODO: Support for -Xemit-jvm-type-annotations</ID>
<ID>ForbiddenComment:SetupKotlinOptions.kt$// TODO: Verify ct.sym fix later.</ID>
<ID>ForbiddenComment:SetupPublication.kt$// FIXME: Disambiguate existing javadoc and sources tasks</ID>
<ID>ForbiddenComment:SetupPublication.kt$// FIXME: provide sources for KMP publications</ID>
<ID>ForbiddenComment:SetupPublication.kt$// TODO: Add support for multiple developers</ID>
Expand Down
4 changes: 3 additions & 1 deletion fluxo-kmp-conf/pg/keep-api-autogenerated.pro
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# ProGuard/R8 keep rules
# Auto-generated by Fluxo task :generateShrinkerKeepRulesFromApi
# From API reports (with sha256short):
# - api/plugin.api (0ae79c2)
# - api/plugin.api (1ca3a64)
# DO NOT EDIT MANUALLY!

-keep,includedescriptorclasses public final class Fkc {
Expand Down Expand Up @@ -267,6 +267,7 @@
public abstract java.lang.Boolean getSetupKapt();
public abstract boolean getSetupKotlinXSerialization();
public abstract java.lang.Boolean getSetupKsp();
public abstract boolean getSetupLegacyKotlinHierarchy();
public abstract java.lang.Boolean getSuppressKotlinComposeCompatibilityCheck();
public abstract boolean getUseDokka();
public void onConfiguration(kotlin.jvm.functions.Function1);
Expand All @@ -279,6 +280,7 @@
public abstract void setSetupKapt(java.lang.Boolean);
public abstract void setSetupKotlinXSerialization(boolean);
public abstract void setSetupKsp(java.lang.Boolean);
public abstract void setSetupLegacyKotlinHierarchy(boolean);
public abstract void setSuppressKotlinComposeCompatibilityCheck(java.lang.Boolean);
public abstract void setUseDokka(boolean);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public class FluxoKmpConfPlugin : Plugin<Project> {
}

/**
* Make sure there's a `clean`, and a `check` tasks in root project.
* Make sure there's a `clean`, and a `check` tasks in a root project.
*
* @see org.gradle.api.plugins.BasePlugin ('base')
* @see org.gradle.language.base.plugins.LifecycleBasePlugin
Expand Down Expand Up @@ -171,7 +171,7 @@ public class FluxoKmpConfPlugin : Plugin<Project> {
}

/**
* Make sure there's a Kotlin plugin in the classpath.
* Make sure there is a Kotlin plugin in the classpath.
*
* @see org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin
* @see org.jetbrains.kotlin.gradle.plugin.AbstractKotlinPlugin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,32 @@ public interface FluxoConfigurationExtensionKotlin : FluxoConfigurationExtension


/**
* Flag to set up the KSP plugin.
* Flag to set up the KSP plugin,
* Auto-detected by the presence of the `kotlin-ksp` plugin.
*
* Inherited from the parent project if not set.
* Default value: `false`.
*/
public var setupKsp: Boolean?

/**
* Flag to set up the Kapt plugin.
* Auto-detected by the presence of the `kotlin-kapt` plugin.
*
* Inherited from the parent project if not set.
* Default value: `false`.
*/
public var setupKapt: Boolean?

/**
* Flag to set up the Kotlin source sets additionally with the sophisticated,
* but now legacy hierarchy.
*
* Inherited from the parent project if not set.
* Default value: `false`.
*/
public var setupLegacyKotlinHierarchy: Boolean


// region Compose

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,11 @@ public interface FluxoConfigurationExtensionKotlinOptions : FluxoConfigurationEx

/**
* Flag that allows to disable kotlin plugin configuration completely.
* **Feature is disabled at the moment!**
*
* Inherited from the parent project if not set. Default value: `true`.
*/
@Deprecated("Feature is disabled at the moment!")
public var setupKotlin: Boolean


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public interface KmpConfigurationContainerDsl :

/**
*
* Also you can just use `KotlinHierarchyTemplate.fluxoKmpConf`
* instead of Kotlin's `defaultKotlinHierarchyTemplate` directly.
*
* @see org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate.Templates.default
* @see org.jetbrains.kotlin.gradle.plugin.defaultKotlinHierarchyTemplate
* @see org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension.targetHierarchy
* @see org.jetbrains.kotlin.gradle.dsl.KotlinTargetHierarchyDsl.default
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ internal class KmpConfigurationContainerDslImpl(

/**
*
* @see org.jetbrains.kotlin.gradle.plugin.KotlinHierarchyTemplate.Templates.default
* @see org.jetbrains.kotlin.gradle.plugin.defaultKotlinHierarchyTemplate
* @see org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension.targetHierarchy
* @see org.jetbrains.kotlin.gradle.dsl.KotlinTargetHierarchyDsl.default
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ internal abstract class KmpTargetContainerImpl<T : KotlinTarget>(
}

override fun setupParentSourceSet(k: KotlinMultiplatformExtension, child: SourceSetBundle) {
if (!allowManualHierarchy) return
val bundle = k.commonJvm

// Fix the broken test-main dependencies in the intermediate KMP source sets.
bundle.test.dependsOn(bundle.main)

if (!allowManualHierarchy) return
@Suppress("DEPRECATION")
child dependsOn bundle
super.setupParentSourceSet(k, bundle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,10 @@ internal abstract class FluxoConfigurationExtensionImpl
// User configuration
action(dsl)

val containers = holder.containers.sorted()

/** @see fluxo.conf.FluxoKmpConfPlugin.configureContainers */
configureContainers(this, holder.containers.sorted())
configureContainers(this, containers)

val elapsed = currentTimeMillis() - start
project.logger.i(":${type.builderMethod} configuration took $elapsed ms")
Expand Down Expand Up @@ -183,7 +185,8 @@ internal abstract class FluxoConfigurationExtensionImpl
// Apply defaults
defaults.asReversed().forEach {
(it as? FluxoConfigurationExtensionImpl)
?.defaultConfiguration?.orNull?.invoke(dsl)
?.defaultConfiguration?.orNull
?.invoke(dsl)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ internal interface FluxoConfigurationExtensionKotlinImpl :

@get:Input
val setupKotlinProp: Property<Boolean>

@Suppress("OVERRIDE_DEPRECATION", "DEPRECATION")
override var setupKotlin: Boolean
get() = setupKotlinProp.orNull ?: parent?.setupKotlin ?: true
set(value) = setupKotlinProp.set(value)
Expand All @@ -129,6 +131,13 @@ internal interface FluxoConfigurationExtensionKotlinImpl :
set(value) = setupKaptProp.set(value)


@get:Input
val setupLegacyKotlinHierarchyProp: Property<Boolean?>
override var setupLegacyKotlinHierarchy: Boolean
get() = setupLegacyKotlinHierarchyProp.orNull ?: parent?.setupLegacyKotlinHierarchy ?: false
set(value) = setupLegacyKotlinHierarchyProp.set(value)


@get:Input
val optInProp: ListProperty<String>
override var optIns: List<String>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal fun FluxoKmpConfContext.prepareBuildConfigKmpPlugin(project: Project) {
}

// Since 5.3.0 it generates build config class at Gradle Sync (IDEA) itself.
// But only `prepareKotlinIdeaImport` task is used.
// But only the ` prepareKotlinIdeaImport ` task is used.
// https://github.com/gmazzo/gradle-buildconfig-plugin/pull/113/files
// https://github.com/gmazzo/gradle-buildconfig-plugin/pull/114/files
// tasks.maybeRegister(KOTLIN_IDEA_IMPORT_TASK, configureSyncTasks)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal fun FluxoConfigurationExtensionImpl.KotlinConfig(
if (api != null && lang != null && api > lang) {
project.logger.w(
"Kotlin API version is downgraded from $api to $lang" +
", as it can't be greater than the language version!"
", as it can't be greater than the language version!",
)
api = null
}
Expand Down Expand Up @@ -96,7 +96,8 @@ internal fun FluxoConfigurationExtensionImpl.KotlinConfig(
// As of Kotlin 1.9.20,
// none of the source sets can depend on the compilation default source sets.
val allowManualHierarchy = pluginVersion < KOTLIN_1_9_20 &&
!project.noManualHierarchy()
!project.noManualHierarchy() &&
setupLegacyKotlinHierarchy

// Experimental test compilation with the latest Kotlin settings.
// Don't try it for sources with old compatibility settings.
Expand Down Expand Up @@ -218,7 +219,7 @@ private fun Logger.logKotlinProjectCompatibility(
"without significant advantages for the most JVM projects. \n" +
"Atm, in Fluxo Conf it also disables granular JVM target configuration" +
"for different project targets, sources, compilations and tasks! \n" +
"See https://jakewharton.com/gradle-toolchains-are-rarely-a-good-idea/"
"See https://jakewharton.com/gradle-toolchains-are-rarely-a-good-idea/",
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ internal fun Project.setupKmpYarnPlugin(ctx: FluxoKmpConfContext) = afterEvaluat
checkIsRootProject("setupKmpYarnPlugin")
plugins.withType<YarnPlugin> configuration@{
val conf = fluxoConfiguration
@Suppress("DEPRECATION")
if (conf?.setupKotlin != true) {
logger.l("YarnPlugin configuration disabled!")
return@configuration
Expand Down
Loading

0 comments on commit 9ea3726

Please sign in to comment.