与Kotlin多平台一起使用Gradle子项目

我正在使用Kotlin多平台(JVM&JS),它在IDEA中创建了三个项目: demodemo-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 

但我认为我做这个根本错误,因为我不知道什么应该取决于什么(尽管我尝试了一些迭代)。 如果我解决了这个错误,我会得到其他的,然后再一个,直到我回到这个。


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

演示/ settings.gradle

 rootProject.name = 'demo' include 'demo-jvm', 'demo-js', '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(':commonmod') } 

demo / demo-jvm / settings.gradle

 rootProject.name = 'demo' 

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" } 

demo / demo-js / settings.gradle

 rootProject.name = 'demo' 

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" } 

demo / commonmod / settings.gradle

 rootProject.name = 'demo' include 'demo-jvm', 'demo-js' 

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') } 

这花了一个疯狂的时间,所以我希望这是有用的人!

在Github上有一个function性的例子: 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 

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

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

依赖项,例如从alpha到beta,在公共的alpha模块和所有的alpha平台模块中声明。


我学到的一些模式:

  • 每个“常规”(通用)模块为每个平台都有一个平台模块。
  • 对于通用模块alpha ,JavaScript平台模块必须被称为alpha-js (类似于-jvm )。
  • 如果没有特定于平台的代码,那么这个模块可能只是一个目录中的一个gradle文件。
  • 平台模块可以方便地放置在公共模块目录(如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上的代码,因为它很长。

Interesting Posts