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

3.9k views Asked by At

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?

2

There are 2 answers

0
Daan On BEST ANSWER

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")
}
5
Joffrey On

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.