gradle buildscript can't resolve objects defined in buildSrc

Viewed 1441

I've created a new project in Android Studio and converted the gradle buildscript to use the kotlin dsl, like so:

build.gradle.kts (project)

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:4.1.1")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10")

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

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

tasks.register("clean", Delete::class) {
    delete(rootProject.buildDir)
}

build.gradle.kts (app)

plugins {
    id("com.android.application")
    kotlin("android")
}

android {
    compileSdkVersion(30)
    buildToolsVersion = "30.0.2"

    defaultConfig {
        applicationId = "com.myproject"
        minSdkVersion(16)
        targetSdkVersion(30)
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        named("release").configure {
            isMinifyEnabled = false
            proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-stdlib:1.4.10")
    implementation( "androidx.core:core-ktx:1.3.2")
    implementation( "androidx.appcompat:appcompat:1.2.0")
    implementation( "com.google.android.material:material:1.2.1")
    implementation( "androidx.constraintlayout:constraintlayout:2.0.4")
    testImplementation( "junit:junit:4.+")
    androidTestImplementation( "androidx.test.ext:junit:1.1.2")
    androidTestImplementation( "androidx.test.espresso:espresso-core:3.3.0")
}

And finally, build.gradle.kts (BuildSrc)

import org.gradle.kotlin.dsl.`kotlin-dsl`

plugins {
    `kotlin-dsl`
}

repositories {
    jcenter()
}

dependencies {
    implementation(kotlin("script-runtime"))
}

This works and the project builds as expected.

Now I would like extract some of these hard-coded version numbers and names into constants. For example, I'd like to change this line: implementation("org.jetbrains.kotlin:kotlin-stdlib:1.4.10") to: implementation("org.jetbrains.kotlin:${ProjectConfig.KOTLIN_VERSION}")

So I've created a new file at buildSrc/src/main/java/ProjectConfig.kt that looks like this:

object ProjectConfig {
    const val KOTLIN_VERSION:String = "1.4.10"
}

But when I try to reference this object from my gradle scripts and do a gradle sync, I get the following error:

e: E:\projects\MyProject\build.gradle.kts:11:58: Unresolved reference: ProjectConfig

What is the proper way to define objects that can be referenced from all of my build.gradle files?

1 Answers

Here's what I found regarding availability of classes in the root build.gradle.kts:

On the root level:

  • buildSrc classes: Available
  • composite project classes: Available only if you declare a plugin from the composite project in the plugins {} block.

In the "buildscript" block:

  • buildSrc classes: Available BUT if the class is in a package you must use the fully qualified class name e.g. com.example.MyClass (can't use import)
  • composite project classes: Not available at all

This was determined with Gradle 7.

Related