Search code examples
androidkotlinbuild.gradledependency-managementgradle-kotlin-dsl

Unresolved reference: Libraries - buildSrc


I'm trying to switch to using Kotlin DSL to get dependencies versions from an object Kotlin file instead of gradle files. When I do a gradle sync it is unable to resolve reference, but I'm able to click on file (Libraries) from build.gradle.kts . I haven't made any other changes to build.gradle or settings.gradle . The issue isn't specific to Jackson and I tried this in multiple projects and read documentation and searched for answers before posting the question.

I get a build.gradle.kts:15:20: Unresolved reference: Libraries

This is the structure of my project

build.gradle
settings.gradle
+buildSrc
    build.gradle.kts
    +src
        +main
            +kotlin
                Libraries.kt

This is the my build.gradle.kts file

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

plugins {
    `kotlin-dsl`
    java
    `java-gradle-plugin`
}


repositories {
    mavenCentral()
}

dependencies {
    implementation(Libraries.Jackson.core)
//    implementation(Libraries.anotherJackson)
}

This is the kotlin Libraries.kt file

object Libraries {
    val Jackson = JacksonLibraries
    const val anotherJackson = "com.fasterxml.jackson.core:jackson-core:2.11.1"

}

object JacksonLibraries {
    const val core = "com.fasterxml.jackson.core:jackson-core:${Versions.Jackson.core}"
}

object Versions {
    object Jackson {
        const val core = "2.11.1"
        const val annotations = "2.11.1"
        const val databind = "2.11.1"
    }
}

If I try it without the Libraries file it works fine.

implementation("com.fasterxml.jackson.core:jackson-core:2.11.1")

But neither of these two work

implementation(Libraries.Jackson.core)
implementation(Libraries.anotherJackson)

Thanks in advance!


Solution

  • Are you trying to access ./buildSrc/src/main/kotlin/Libraries.kt in ./buildSrc/build.gradle.kts? Because that's not possible, and isn't necessary.

    Basically it's not possible to use ./buildSrc/src/main/kotlin/Libraries.kt in ./buildSrc/build.gradle.kts for the same reason you can't use <root>/src/main/kotlin/Libraries.kt in ./<root>/build.gradle.kts. The Gradle build scripts can't use the output of the projects they're trying to build.

    However buildSrc is treated as included build, so the contents of ./buildSrc/src/main/... will be available in <root>/build.gradle.kts

    Version alignment

    Version Catalogs

    It's possible to share versions between ./buildSrc/build.gradle.kts and <root>/build.gradle.kts with Version Catalogs.

    The libs.versions.toml file is the easiest way to do this.

    In short,

    1. Use Gradle 7.4+
    2. Create a <root>/gradle/libs.versions.toml file
    3. Define your dependencies, e.g.
      [versions]
      groovy = "3.0.5"
      
      [libraries]
      groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }
      
    4. In <root>/build.gradle.kts, or any <root>/settings.gradle.kts include(...)-ed subproject, you can now access the dependencies (you might need to refresh IntelliJ a few times for the auto-complete to load).
      dependencies {
        implementation(libs.groovy.core)
      }
      

    You can use the same Version Catalog in any project by loading the file. If you wanted to host it and download it, that would work too!

    Version Platform

    If you want to align versions across several separated projects, you can follow the documentation here: https://docs.gradle.org/current/userguide/platforms.html

    Version Platforms are a little more structured than Version Catalogs. They're kind of like Gradle's versions of Maven BOMs, except they're more flexible of course!

    In short,

    1. Create a Gradle project, and apply the Java Platform Plugin and Maven Publish Plugin
    2. Define your constraints
    3. Publish it to a Maven repo
    4. Apply it to any project as a platform dependency
      dependencies {
        implementation(platform("my.company:our-own-version-platform:1.2.3"))
      
        // no need for a version, if our-own-version-platform provides it!
        implementation("org.codehaus.groovy:groovy") 
      }