我在设置我的Kotlin多项目项目时遇到了困难。我已经花了几个小时阅读文档,但我觉得我毫无进展。也许这里有人可以帮助我,告诉我如何调整我的构建脚本。
我的项目设置是(或应该是):
root
|-> src
|-> commonMain
|-> kotlin
|-> commonTest
|-> kotlin
|-> jvmMain
|-> kotlin
|-> jvmTest
|-> kotlin
|-> nativeMain
|-> kotlin
|-> cpp
|-> nativeTest
|-> kotlin
|-> cpp
字符串
nativeMain和nativeTest下名为“cpp”的目录将包含用c++编写的其他平台特定代码,这些代码将取决于Kotlin/Native生成的C库。
目前,我正在尝试实现以下目标:生成一个jar文件,其中包含{commonMain,commonTest,jvmMain,jvmTest}中的所有类。具体来说,我想在我的test-jar中包含JUnit的ConsoleLauncher,因此我在jvmTest sourceSet中添加了对实现的依赖(“org.junit.platform:junit-platform-console-standalone:1.10.1”)。
运行gradle任务jvmTest成功启动了我的所有测试,但它没有生成jar文件(显然,至少我找不到它)。有没有一种方法可以用gradle任务生成jar?
下面是我的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任务时,它似乎找不到与Kotlin插件相同的sourceSets。在这个gradle任务中,我只看到sourceSets“main”和“test”,(我想)它们不包含任何代码:
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")
}
}
型
我觉得这很奇怪/令人困惑,我想知道,我将如何设置特定的任务来在某个阶段生成我的cpp代码(因为我需要在专用的cpp块中访问源代码集,而不是Kotlin块)。也许有人可以给我一个提示,以及给予?但也许这是一个单独的问题,一旦我到了编写额外的cpp代码的地步。
1条答案
按热度按时间fsi0uk1n1#
Gradle和Kotlin插件
Gradle是一个功能强大的构建工具,你需要的一切都在那里,但有时需要一点挖掘。实际上,你必须查看KotlinGradle插件的代码,看看它是如何组合在一起的,并按照你想要的方式编写额外的任务。
在Kotlin多平台项目中,所有配置都位于Kotlin multiplatform extension上,可以使用build.gradle.kts文件中的
kotlin
进行访问。该扩展是所有Kotlin多平台配置所在的中心位置,您想要的一切都应该在该对象中的某个位置。Kotlin源集
此外,当我创建一个单独的gradle任务时,它似乎找不到与Kotlin插件相同的sourceSets。
简短的回答是:当您在build.gradle.kts文件中使用顶级
sourceSets
访问器时,您访问的是 Java 源集,而不是Kotlin源集。正如你可能知道的,Gradle的初衷是成为Java程序的构建工具,Gradle提供了一系列为Java程序设计的插件,例如Java插件,它们遵循众所周知的约定。
当一个Kotlin多平台插件有一个JVM目标时,它会应用Java base plugin来利用其中的一些约定。但是Kotlin多平台也会建立自己的源集和编译的并行系统,通常这些应该用于编写额外的任务。
您可以在Kotlin扩展中访问Kotlin源代码集,如下所示(就像您在配置项目时所做的那样):
字符串
生成文件
有没有一种方法可以用gradle任务生成jar?
当然有。这种任务确实是Gradle存在的理由。
你是对的,测试任务在默认情况下是不会创建的,但是你可以通过编写一个
Jar
(docs)类型的任务来创建任何你想要的任务,就像你开始做的那样。在Kotlin中,你可以这样写:
型
添加依赖关系到一个示例
具体来说,我想在我的测试jar中包括JUnit的ConsoleLauncher
你很快就会发现,依赖项在默认情况下不会打包到一个包中。事实上,这是不鼓励的,因为一般来说,获取所需的依赖项是包的消费者的工作。但是,当然有一些很好的理由将依赖项打包到所谓的影子或胖包中。
这个答案已经太长了,所以我不会再建议你写更多的代码,但你可以开始阅读Gradle文档中的更多内容。只是要确保选择Kotlin编译输出,而不是Java插件。
您可能还想查看Gradle对依赖项进行分组的配置(以便控制哪些依赖项组进入您的队列,哪些不进入)。