Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 760
Thibault Seisel Avatar asked Oct 18 '17 19:10

Thibault Seisel


2 Answers

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.

like image 141
Thibault Seisel Avatar answered Sep 21 '22 17:09

Thibault Seisel


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.

like image 38
Ruslan Avatar answered Sep 25 '22 17:09

Ruslan