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

Kotlin多平台项目构建脚本调整:生成测试Jar及源集问题

Kotlin多平台项目构建脚本调整求助

项目结构规划

root
|-> src
    |-> commonMain
        |-> kotlin
    |-> commonTest
        |-> kotlin
    |-> jvmMain
        |-> kotlin
    |-> jvmTest
        |-> kotlin
    |-> nativeMain
        |-> kotlin
        |-> cpp
    |-> nativeTest
        |-> kotlin
        |-> cpp

其中nativeMain和nativeTest下的cpp目录用于存放依赖Kotlin/Native生成C库的平台特定C++代码。

当前需求

  • 生成包含commonMain、commonTest、jvmMain、jvmTest所有类的Jar包
  • 测试Jar中需包含JUnit ConsoleLauncher,已为jvmTest源集添加依赖:implementation("org.junit.platform:junit-platform-console-standalone:1.10.1")

遇到的问题

  • 执行gradle jvmTest可成功运行所有测试,但未生成Jar包
  • 自定义Gradle任务仅能识别"main"和"test"源集,无法找到Kotlin多平台的源集(如jvmTest)
  • 后续需配置任务生成C++代码,不知如何在独立的cpp块中访问源集

现有build.gradle.kts脚本

plugins {
    java
    id("java-library")
    kotlin("multiplatform") version "1.9.20"
}

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib"))
}

kotlin {

    jvm("jvm") {
        compilations.all {
            kotlinOptions {
                jvmTarget = "17"
            }
        }
    }

    linuxX64("linux")
    mingwX64("windows")

    targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget> {
        binaries {
            sharedLib {
                baseName = if(name == "windows") "libnative" else "native"
            }
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation(kotlin("stdlib"))
                implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.6")
                implementation("org.junit.platform:junit-platform-console-standalone:1.10.1")
            }
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }
        val windowsMain by getting {
            dependsOn(sourceSets["commonMain"])
        }
        val windowsTest by getting {
            dependsOn(sourceSets["commonTest"])
        }
        val linuxMain by getting {
            dependsOn(sourceSets["commonMain"])
        }
        val linuxTest by getting {
            dependsOn(sourceSets["commonTest"])
            dependencies {
                implementation(kotlin("test"))
            }
        }
        val jvmMain by getting {
            dependsOn(sourceSets["commonMain"])
        }
        val jvmTest by getting {
            dependsOn(sourceSets["commonTest"])
            dependencies {
                implementation("org.junit.platform:junit-platform-console-standalone:1.10.1")

                implementation(kotlin("test"))
                implementation(kotlin("test-junit5"))

                // needed by IDEA?
                implementation("org.junit.jupiter:junit-jupiter-engine:5.10.1")
                implementation("org.junit.jupiter:junit-jupiter-params:5.10.1")
                implementation("org.junit.jupiter:junit-jupiter-api:5.10.1")
            }
        }
    }
}

tasks.withType<Wrapper> {
    gradleVersion = "8.4"
    distributionType = Wrapper.DistributionType.ALL
}


tasks.named<Test>("jvmTest") {
    useJUnitPlatform()
    filter {
        isFailOnNoMatchingTests = false
    }
    testLogging {
        showExceptions = true
        showStandardStreams = true
        events = setOf(
            org.gradle.api.tasks.testing.logging.TestLogEvent.FAILED,
            //org.gradle.api.tasks.testing.logging.TestLogEvent.PASSED,
            org.gradle.api.tasks.testing.logging.TestLogEvent.SKIPPED
        )
        exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
        afterSuite(
            KotlinClosure2({
                desc: TestDescriptor, result: TestResult ->
                    if (desc.parent == null) {
                        // Only execute on the outermost suite
                        val color = if(result.resultType == TestResult.ResultType.SUCCESS) Colors.green else Colors.red
                        val reset = Colors.reset

                        println("")
                        println(" **** Result: $color ${result.resultType} $reset ****")
                        println("  >    Tests: ${result.testCount}")
                        println("  >   Passed: ${result.successfulTestCount}")
                        println("  >   Failed: ${result.failedTestCount}")
                        println("  >  Skipped: ${result.skippedTestCount}")
                    }
            })
        )
    }
}

自定义Gradle任务代码

tasks.register("printSourceSetsInfo") {
    doLast {
        sourceSets.all { sourceSet ->
            println("Source set: ${sourceSet.name}")
            println("   - Output directory: ${sourceSet.output}")
            println("   - Source directories: ${sourceSet.allSource.srcDirs}")
            println("   - Resources directories: ${sourceSet.resources.srcDirs}")
            println("   - Compile classpath: ${sourceSet.compileClasspath}")
            println("   - Runtime classpath: ${sourceSet.runtimeClasspath}")
            println()
           true
        }
    }
}

tasks.register("packageTests", Jar::class) {
    val jvmTestSourceSet = sourceSets.findByName("jvmTest") ?: sourceSets.findByName("testJvm") ?: sourceSets.findByName("test")

    if (jvmTestSourceSet != null) {
        from(jvmTestSourceSet.output)
       archiveFileName = "acteo-kotlin-tests.jar"
       destinationDirectory = file("build/libs/")
    } else {
       println("JVM test source set not found. Check your project configuration.")
       println("Available source sets: ${sourceSets.names.joinToString(", ")}")
        //throw GradleException("JVM test source set not found")
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 10:17:29