使用带有Kotlin多平台的Gradle子项目

Mar*_*ark 7 gradle kotlin gradle-dependencies kotlin-multiplatform

我使用科特林多平台(JVM和JS),这在IDEA创建三个项目:demo,demo-jsdemo-jvm.

我想将公共代码拆分为更多子项目/子模块.让我们说我补充commonmod; 我如何编译?

现在的错误gradle run -p demo-jvm是:

demo/demo-js/src/main/kotlin/demo/commonmod/example.kt: (3, 12): Actual function 'getPlatform' has no corresponding expected declaration
Run Code Online (Sandbox Code Playgroud)

但我认为我这样做根本就是错误的,因为我不知道应该依赖什么(虽然我尝试过一些迭代).如果我解决了这个错误,我会得到其他的,然后是其他的,直到我回到这个.


作为一个最小但仍然很大的例子,我有:

demo/settings.gradle:

rootProject.name = 'demo'

include 'demo-jvm', 'demo-js', 'commonmod'
Run Code Online (Sandbox Code Playgroud)

demo/build.gradle:

buildscript { ... }

apply plugin: 'kotlin-platform-common'

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
    testCompile "org.jetbrains.kotlin:kotlin-test-annotations-common:$kotlin_version"
    testCompile "org.jetbrains.kotlin:kotlin-test-common:$kotlin_version"
    compile project(':commonmod')
}
Run Code Online (Sandbox Code Playgroud)

demo/demo-jvm/settings.gradle:

rootProject.name = 'demo'
Run Code Online (Sandbox Code Playgroud)

demo/demo-jvm/build.gradle:

buildscript { ... }

apply plugin: 'kotlin-platform-jvm'
apply plugin: 'application'

repositories {
    mavenCentral()
}

mainClassName = "demo.MainKt"

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    expectedBy project(":")
    testCompile "junit:junit:4.12"
    testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
    testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
}
Run Code Online (Sandbox Code Playgroud)

demo/demo-js/settings.gradle:

rootProject.name = 'demo'
Run Code Online (Sandbox Code Playgroud)

demo/demo-js/build.gradle:

buildscript { ... }

apply plugin: 'kotlin-platform-js'

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
    expectedBy project(":")
    testCompile "org.jetbrains.kotlin:kotlin-test-js:$kotlin_version"
}
Run Code Online (Sandbox Code Playgroud)

demo/commonmod/settings.gradle:

rootProject.name = 'demo'

include 'demo-jvm', 'demo-js'
Run Code Online (Sandbox Code Playgroud)

demo/commonmod/build.gradle:

buildscript { ... }

apply plugin: 'kotlin-platform-common'

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
    testCompile "org.jetbrains.kotlin:kotlin-test-annotations-common:$kotlin_version"
    testCompile "org.jetbrains.kotlin:kotlin-test-common:$kotlin_version"
    compile project(':demo-js')
    compile project(':demo-jvm')
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ark 9

这花了很多时间,所以我希望这对某人有用!

Github上有一个功能示例:kotlin_multiplatform_gradle_demo

有几个消息来源有帮助,但很多都是试错,所以如果有什么不好的做法,请告诉我!


对于最小的例子,结构是这样的:

??? alpha
?   ??? alpha-js
?   ?   ??? build.gradle
?   ??? alpha-jvm
?   ?   ??? build.gradle
?   ??? build.gradle
?   ??? src
?       ??? main
?           ??? kotlin
?           ?   ??? demo
?           ?       ??? alpha
?           ?           ??? main.kt
??? beta
?   ??? beta-js
?   ?   ??? build.gradle
?   ?   ??? src
?   ?       ??? main
?   ?           ??? kotlin
?   ?               ??? demo
?   ?                   ??? beta
?   ?                       ??? platform.kt
?   ??? beta-jvm
?   ?   ??? build.gradle
?   ?   ??? src
?   ?       ??? main
?   ?           ??? kotlin
?   ?               ??? demo
?   ?                   ??? beta
?   ?                       ??? platform.kt
?   ??? build.gradle
?   ??? src
?       ??? main
?           ??? kotlin
?               ??? demo
?                   ??? beta
?                       ??? platform.kt
??? build.gradle
??? settings.gradle
Run Code Online (Sandbox Code Playgroud)

通用模块(alphabeta)需要每个平台至少有一个`build.gradle``的平台模块.

settings.gradle文件导入所有模块,包括平台模块.

依赖关系,例如来自alpha on beta,在公共alpha模块和所有alpha平台模块中声明.


我学到的一些模式:

  • 每个"普通"(通用)模块都为每个平台配备一个平台模块.
  • 对于通用模块alpha,必须调用javascript平台模块alpha-js(类似于-jvm).
  • 如果没有特定于平台的代码,则此模块可以只是目录中的gradle文件.
  • 平台模块可以方便地放在公共模块目录(so alpha:alpha-js)中.
  • 通用模块不应该引用平台模块; 平台模块具有依赖性expectedBy project(":the_common_module").
  • 如果模块alpha依赖于beta,那么

    • alpha 一定有 dependencies { compile project(":beta") }
    • alpha-js必须dependencies { compile project(":beta:beta-js") }(除此之外expectedBy)
    • alpha-jvm必须dependencies { compile project(":beta:beta-jvm") }(除了expectedBy)等
  • 只有顶级模块settings.gradle,包括所有子模块(包括平台模块).

  • 确保正确的名称,因为不正确的名称不会导致错误,他们只是默默地失败.(这似乎很荒谬,但我想有一个原因.)
  • 不要将所有输出放入单个共享构建目录中 - 这会导致几个奇怪的非确定性错误.

我以前在这里有完整的配置文件,但最好只检查Github上的代码,因为它真的很长.