How to apply -Xopt-in=kotlin.ExperimentalUnsignedTypes to all subprojects?
Asked Answered
S

2

10

I have a project with multiple subprojects that use the kotlin-multiplatform plugin or the kotlin-js plugin and I want to use the experimental unsigned types in all of them.

So far I've tried this, which doesn't work:

subprojects {
    tasks.withType<KotlinCompile>().all {
        kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.ExperimentalUnsignedTypes"
    }

    extensions.findByType<KotlinMultiplatformExtension>()?.sourceSets {
        all {
            languageSettings.useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes")
        }
    }
}

Is there a way to add the kotlin compiler arg -Xopt-in=kotlin.ExperimentalUnsignedTypes to all subprojects in Gradle?

Saxen answered 3/10, 2020 at 12:17 Comment(0)
S
4

The recommended way to share configuration is via a convention plugin.

I.e. create a file in buildSrc/src/main/kotlin/package/name/kotlin-mpp-conventions.kts with the contents:

plugins {
    kotlin("jvm")
}

kotlin {
    sourceSets {
        all {
            languageSettings.useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes")
        }
    }
}

Then depend on this plugin from your Kotlin MPP subprojects by adding a reference to it in the plugins block: id("package.name.kotlin-mpp-conventions").

Add more plugins for e.g. Kotlin JS projects. If there's some configuration you want to share between all types of projects you can create a common plugin that the other plugins depend on. You can also share data structures between plugins by simply putting them in a separate file and referencing them from the plugin files (like you would with normal code), I use this mechanism to share the list of Kotlin experimental annotations I want to allow in all plugins.

Be sure to set up buildSrc/build.gradle.kts for plugins:

plugins {
    `kotlin-dsl`
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21")
}
Saxen answered 19/8, 2021 at 9:16 Comment(0)
W
8

I've reached this point with trial and error, so I'm not sure this is the right approach.

I had a multiproject build with some multiplatform, JVM, and JS subprojects, and I wanted to enable the kotlin.RequiresOptIn annotation. So I ended up setting this compiler argument for all kinds of kotlin compilation tasks:

subprojects {
    val compilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn")
    tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
        kotlinOptions.jvmTarget = "1.8"
        kotlinOptions.freeCompilerArgs += compilerArgs
    }

    tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile> {
        kotlinOptions.freeCompilerArgs = compilerArgs
    }

    tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon> {
        kotlinOptions.freeCompilerArgs = compilerArgs
    }
}

I guess the same approach could work for ExperimentalUnsignedTypes.

Wiersma answered 3/10, 2020 at 12:55 Comment(5)
This works for the Kotlin JS (and probably Java and common) projects but not the multiplatform projects. Thanks for the first part of the solution though!Saxen
This is most likely because my own multiplatform subprojects only support JS and JVM targets at the moment. For native there might be other compile tasks. I would hope for a more general approach though, this is kind of hacky.Wiersma
This simply doesn't work for multiplatform projects with languageSettings.useExperimentalAnnotation (my own projects only have common and js code atm)Saxen
There is a common supertype for all these tasks. Maybe this will do the thing: tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>>().configureEach { kotlinOptions.freeCompilerArgs += compilerArgs }?Autobahn
org.jetbrains.kotlin.gradle.dsl.KotlinCompile did the job thank youTilla
S
4

The recommended way to share configuration is via a convention plugin.

I.e. create a file in buildSrc/src/main/kotlin/package/name/kotlin-mpp-conventions.kts with the contents:

plugins {
    kotlin("jvm")
}

kotlin {
    sourceSets {
        all {
            languageSettings.useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes")
        }
    }
}

Then depend on this plugin from your Kotlin MPP subprojects by adding a reference to it in the plugins block: id("package.name.kotlin-mpp-conventions").

Add more plugins for e.g. Kotlin JS projects. If there's some configuration you want to share between all types of projects you can create a common plugin that the other plugins depend on. You can also share data structures between plugins by simply putting them in a separate file and referencing them from the plugin files (like you would with normal code), I use this mechanism to share the list of Kotlin experimental annotations I want to allow in all plugins.

Be sure to set up buildSrc/build.gradle.kts for plugins:

plugins {
    `kotlin-dsl`
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21")
}
Saxen answered 19/8, 2021 at 9:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.