You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gradle KMM自定义属性无法传递至下级项目依赖的解决方法咨询

问题描述

现有三个Gradle项目::sub1(KMM项目)、:sub2(依赖:sub1的KMM项目)、:parent(依赖:sub2的JVM项目)。构建:parent时出现依赖解析错误,原因是:parent指定的customAttribute仅传递到:sub2,未传递至:sub1,导致Gradle无法确定选择:sub1的哪个JVM变体。


项目代码

:sub1(KMM项目)

plugins {
    kotlin("multiplatform")
}

val customAttribute = Attribute.of("custom", String::class.java)

@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
kotlin {
    targetHierarchy.default()

    jvm {
        attributes {
            attribute(customAttribute, "normal")
        }
    }
    jvm("custom") {
        attributes {
            attribute(customAttribute, "customValue")
        }
    }

    sourceSets {
        val commonMain by getting
    }
}

:sub2(依赖:sub1的KMM项目)

plugins {
    kotlin("multiplatform")
}

val customAttribute = Attribute.of("custom", String::class.java)

@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
kotlin {
    targetHierarchy.default()

    jvm {
        attributes {
            attribute(customAttribute, "normal")
        }
    }
    jvm("custom") {
        attributes {
            attribute(customAttribute, "customValue")
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                api(project(":sub1"))
            }
        }
    }
}

:parent(依赖:sub2的JVM项目)

plugins {
    id("kotlin")
    id("org.jetbrains.kotlin.jvm")
}

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

val customAttribute = Attribute.of("custom", String::class.java)

dependencies {
    api(project(":sub2")) {
        attributes {
            attribute(customAttribute, "customValue")
        }
    }
}

构建错误

> Could not resolve project :sub1.
     Required by:
         project :project > project :sub2
      > The consumer was configured to find a library for use during compile-time, compatible with Java 17, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm'. However we cannot choose between the following variants of project :sub1
          - jvmApiElements
          - jvmRuntimeElements
          - customApiElements
          - customRuntimeElements

解决方案

要让:parent指定的customAttribute传递到:sub1,需要让中间层:sub2在解析:sub1依赖时,传递自身的customAttribute值。以下是两种可靠实现方式:

方式1:在:sub2中配置属性传递(推荐)

修改:sub2的build.gradle.kts,添加依赖解析策略,让:sub2的变体自动将自身的customAttribute传递给:sub1:

val customAttribute = Attribute.of("custom", String::class.java)

// 为所有可解析的配置设置依赖解析策略,传递custom属性
configurations.filter { it.isCanBeResolved }.forEach { config ->
    // 仅处理带有custom属性的配置
    config.attributes.maybeGet(customAttribute)?.let { currentValue ->
        config.resolutionStrategy.eachDependency { details ->
            // 匹配依赖的:sub1项目
            if (details.requested.group.isBlank() && details.requested.name == "sub1") {
                // 为:sub1依赖设置当前配置的custom属性值
                details.useTarget(mapOf(
                    customAttribute.name to currentValue,
                    "org.jetbrains.kotlin.platform.type" to "jvm"
                ))
            }
        }
    }
}

原理:遍历:sub2中所有可解析的配置(如customCompileClasspath),若配置带有custom属性,则强制解析:sub1时使用相同属性值,实现属性逐层传递。

方式2:在:parent中全局配置属性

修改:parent的build.gradle.kts,直接为:sub1和:sub2设置全局属性规则:

dependencies {
    api(project(":sub2")) {
        attributes {
            attribute(customAttribute, "customValue")
        }
    }
}

val customAttribute = Attribute.of("custom", String::class.java)
configurations.all {
    resolutionStrategy.eachDependency { details ->
        // 为:sub2和:sub1都设置custom属性
        if (details.requested.name in listOf("sub2", "sub1")) {
            details.attributes {
                attribute(customAttribute, "customValue")
            }
        }
    }
}

原理:在:parent的全局解析策略中,直接指定:sub1和:sub2的customAttribute值,跳过中间传递环节,适合属性值固定的场景。

内容的提问来源于stack exchange,提问作者Mirage

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 00:14:57