Thibault Seisel
Thibault Seisel

Reputation: 1257

Configure compiler arguments

I'm looking for a way to configure Kotlin compiler arguments in the build.gradle file of my Android Application project.

I've seen on the Kotlin official documentation that it is possible to configure compiler arguments for each build flavor (such as debug, release).

Project-level build.gradle

buildscript {
    ext.kotlin_version = '1.1.51'
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0-rc1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

App-level build.gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.2"
    defaultConfig {
        applicationId "com.myapp.myapplication"
        minSdkVersion 16
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

// The interesting part : configure the compileReleaseKotlin task
// to include compiler arguments when building releases
compileReleaseKotlin {
    kotlinOptions {
        freeCompilerArgs = [
                'Xno-param-assertions',
                'Xno-call-assertions',
                'Xno-receiver-assertions'
        ]
    }
}

dependencies {
    // The usual Android dependencies, omitted for brievety
}

When building the project, I get the following error :

Could not find method compileReleaseKotlin() for arguments [build_7b4e2sfm3830f9z4br95gfme2$_run_closure2@7ed96f28] on project ':app' of type org.gradle.api.Project.

Is the compileReleaseKotlin block misplaced, or mispelled ? Android Studio suggests me this method, though.

Upvotes: 11

Views: 12157

Answers (3)

Thibault Seisel
Thibault Seisel

Reputation: 1257

Edit 2022

A lot have changed for Android and Kotlin since I posted this answer. Kotlin Gradle Scripts are now a safer way of configuring Gradle builds. Here is the equivalent *.gradle.kts for the below snippet, with additional fixes because it's been wrong for the whole time!

android {
    // Options are applied to all build types
    kotlinOptions {
        freeCompilerArgs += listOf(
            "-Xno-param-assertions",
            "-Xno-call-assertions",
            "-Xno-receiver-assertions",
        )
    }
}

A pointed out by @gmk57, you can't configure specific compiler arguments specific to a given build type from within the buildTypes block. kotlinOptions should be defined directly within the android block, and is applied for all build types.

At the time of writing, the only way to have a build-type-specific configuration is to configure the compileReleaseKotlin task (and flavor variants, if any) in afterEvaluate:

afterEvaluate {
    tasks.compileReleaseKotlin {
        kotlinOptions {
            freeCompilerArgs += listOf(
                "-Xno-param-assertions",
                "-Xno-call-assertions",
                "-Xno-receiver-assertions",
            )
        }
    }
    
    // For flavor dimension full + release
    tasks.named<KotlinCompile>("compileFullReleaseKotlin") {
        kotlinOptions {
            // Same options as above, omitted for brevity
        }
    }
}

Note that the as of Android Gradle Plugin 7.0.0, there are interesting new extensions points allowing to configure build variants at the time of their creation by the plugin. DslExtension may allow the Kotlin Android plugin to seamlessly integrate with build types.


Original answer

After a few days of search and experimentation, I finally found a way to configure the compiler based on the build variant.

Here is what worked for me :

buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            // Configure Kotlin compiler optimisations for releases
            kotlinOptions {
                freeCompilerArgs += [
                        '-Xno-param-assertions',
                        '-Xno-call-assertions',
                        '-Xno-receiver-assertions'
                ]
            }
        }
    }
}

It seems like the documentation for the Gradle Kotlin Android plugin is not correct: while it says that the compiler can be configured by adding, for instance, the compileReleaseKotlin closure for release builds, for Android you have to put a kotlinOptions block in release, as shown above.

Note that for a regular Kotlin project (without Android), the compileKotlin block described in the documentation works as intented.

Hope it helps !

Edit Added - prefix for arguments, as the compiler would silently ignore them otherwise.

Edit 2 Changed = to += to avoid overwriting compiler options from other configurations.

Upvotes: 30

gmk57
gmk57

Reputation: 939

Kotlin compiler options for all build types should be specified in the android closure. This is where Android Studio 4.1 places kotlinOptions { jvmTarget = '1.8' } by default:

android {
    ...
    kotlinOptions {
        jvmTarget = '1.8'
        freeCompilerArgs += ['-Xno-param-assertions']
    }
}

Compiler options for specific build type should be configured at the root level, wrapped in afterEvaluate, because the task is only registered once the Android Gradle plugin creates specific build variant, which is only done at the afterEvaluate phase:

afterEvaluate {
    compileReleaseKotlin {
        kotlinOptions {
            freeCompilerArgs += ['-Xno-param-assertions']
        }
    }
}

Upvotes: 6

Ruslan
Ruslan

Reputation: 2799

For anyone looking for quick info in 2020 on how to add a compiler arg to a Kotlin Android project (I needed it to enable the experimental serialization API), this is how I did it:

(app build.gradle file)

android {
    ...
    compileOptions {
        ...
        kotlin {
            kotlinOptions {
                freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
            }
        }
    }
}

Android Studio doesn't provide those as suggestions.

Upvotes: 13

Related Questions