Android unable to resolve dependency on common module

I’m attempting to set up a Kotlin multiplatform project inside an existing Android project, and I’m having some issues getting my Gradle files configured properly. I’m in a state where my common module builds, but the original Android project can’t resolve the common module:

build.gradle: Unable to resolve dependency for ':app@preview/compileClasspath': Could not resolve project :common.
build.gradle: Unable to resolve dependency for ':app@previewUnitTest/compileClasspath': Could not resolve project :common.
build.gradle: Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve project :common.
build.gradle: Unable to resolve dependency for ':app@debugAndroidTest/compileClasspath': Could not resolve project :common.
build.gradle: Unable to resolve dependency for ':app@debugUnitTest/compileClasspath': Could not resolve project :common.
build.gradle: Unable to resolve dependency for ':app@release/compileClasspath': Could not resolve project :common.
build.gradle: Unable to resolve dependency for ':app@releaseUnitTest/compileClasspath': Could not resolve project :common.

I was originally following this tutorial here for guidance, and adapted it a bit so that the Android part could access core Android classes like Context.

Is there something I’m missing in my approach? Should I be configuring this so that the Android project in its entirety is compiled as part of the multiplatform project, instead of keeping the Android app code separate? My current understanding of the setup is that everything should be in their own project (common, android, and ios), and that common has modules inside for each of the platforms its intended to support (commonAndroid, commonIos) in addition to the platform-agnostic stuff (common).

common module build.gradle.kts:

import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget

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

android {
    compileSdkVersion(28)
    defaultConfig {
        minSdkVersion(21)
        targetSdkVersion(28)
    }
}

kotlin {
    //select iOS target platform depending on the Xcode environment variables
    val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
        if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
            ::iosArm64
        else
            ::iosX64

    iOSTarget("ios") {
        binaries {
            framework {
                baseName = "life4common"
            }
        }
    }

    android()

    sourceSets["commonMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
    }

    sourceSets["androidMain"].dependencies {
        implementation("org.jetbrains.kotlin:kotlin-stdlib")
    }
}


val packForXcode by tasks.creating(Sync::class) {
    group = "build"

    //selecting the right configuration for the iOS framework depending on the Xcode environment variables
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val framework = kotlin.targets.getByName<KotlinNativeTarget>("ios").binaries.getFramework(mode)

    inputs.property("mode", mode)
    dependsOn(framework.linkTask)

    val targetDir = File(buildDir, "xcode-frameworks")
    from({ framework.outputDirectory })
    into(targetDir)

    doLast {
        val gradlew = File(targetDir, "gradlew")
        gradlew.writeText("#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n")
        gradlew.setExecutable(true)
    }
}

tasks.getByName("build").dependsOn(packForXcode)

Original Android build.gradle:

plugins {
    id "com.android.application"
    id "kotlin-android"
    id "kotlin-android-extensions"
    id "kotlin-kapt"
    id "io.fabric"

    id "com.google.gms.google-services"
    id "io.objectbox"
}

android {
    compileSdkVersion = 28
    defaultConfig {
        applicationId "com.perrigogames.life4trials"
        minSdkVersion(18)
        targetSdkVersion(28)
        versionCode = 52
        versionName = "3.1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
        signingConfig signingConfigs.upload
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
            signingConfig signingConfigs.upload
            manifestPlaceholders = [providerName: "com.perrigogames.fileprovider"]
        }
        preview {
            initWith(release)
        }
        debug {
            applicationIdSuffix = ".debug"
            signingConfig = signingConfigs.debug
            manifestPlaceholders = [providerName: "com.perrigogames.fileprovider.debug"]
        }
    }
    compileOptions {
        sourceCompatibility = "1.8"
        targetCompatibility = "1.8"
    }
    packagingOptions {
        exclude("META-INF/DEPENDENCIES")
        exclude("META-INF/LICENSE")
        exclude("META-INF/LICENSE.txt")
        exclude("META-INF/license.txt")
        exclude("META-INF/NOTICE")
        exclude("META-INF/NOTICE.txt")
        exclude("META-INF/notice.txt")
        exclude("META-INF/ASL2.0")
    }
    lintOptions {
        abortOnError = false
    }
    testOptions {
        unitTests {
            includeAndroidResources = true
        }
    }
}

dependencies {
    implementation(project(":common"))
    implementation(fileTree(include: ["*.jar"], dir: "libs"))
    implementation(dep.kotlin_stdlib_jre7)
    implementation(dep.multidex)
    implementation(dep.androidx)
    implementation(dep.glide)
    implementation(dep.eventbus)
    implementation(dep.dexter)
    implementation(dep.firebase)
    implementation(dep.retrofit)
    implementation(dep.coroutines_android)
    implementation(dep.coroutines_jvm)
    implementation(dep.lottie)

    debugImplementation(dep.objectbox_debug)
    releaseImplementation(dep.objectbox_release)

    implementation("com.google.guava:guava:27.0.1-android")

    kapt(dep.glide_compiler)

    testImplementation(dep.junit)
    testImplementation(dep.androidx_test)
    testImplementation(dep.robolectric)
    androidTestImplementation(dep.espresso)
}

Update, been trying to play with the structure of the Android Gradle file, even going so far as to make it utilize kotlin-multiplatform instead of kotlin-android and putting all the dependencies into source sets a la this configuration, to no avail.

Interestingly, I tried to change the imported project name in the Android gradle file, and it failed immediately:

Build file ‘C:\Users\avata\Development\Life4Trials\app\build.gradle’ line: 81
A problem occurred evaluating project ‘:app’.
Project with path ‘l:common’ could not be found in project ‘:app’.

Hardly took any time to process, so it obviously saw the project the first time, but not during that build that happens right after the sync finishes. So what’s different about the environment at this phase?

Another update, commenting out the line importing the common project into the Android project gave me an error notification, but the build still finished fine:

Compilation is not supported for following modules: Life4-common_iosTest, common_commonMain, Life4-common_commonTest, common_iosMain, common_commonTest, Life4-common_iosMain, common_iosTest, Life4Trials-common, common, Life4-common_commonMain, Development-Life4Trials-common, Life4Trials-common_commonMain, Life4Trials-common_commonTest. Unfortunately you can’t have non-Gradle Java modules and Android-Gradle modules in one project.

For this particular issue, this was being caused by an extra kotlin-multiplatform plugin declaration in the root project when it should have only been used in the common project.

I’m currently dealing with other build issues now, but my primary roadblock has been resolved.