如何在多平台 Android 模块中配置 Kotlin jvmTarget?

Posted

技术标签:

【中文标题】如何在多平台 Android 模块中配置 Kotlin jvmTarget?【英文标题】:How to configure Kotlin jvmTarget in a Multiplatform Android module? 【发布时间】:2021-07-04 15:12:22 【问题描述】:

我收到此构建错误:

无法将使用 JVM 目标 1.8 构建的字节码内联到使用 JVM 目标 1.6 构建的字节码中。请指定正确的“-jvm-target”选项 添加对 Java 8 语言特性的支持可以解决这个问题。

尝试在 android Studio 中为多平台模块编译此构建脚本:

import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget

plugins 
    kotlin("multiplatform")
    id("com.android.library")


repositories 
    mavenCentral()


kotlin 
    android()
    ios 
        binaries 
            framework 
                baseName = "bandit"
            
        
    
    sourceSets 
        val commonMain by getting 
            dependencies 
                implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.1.1")
                implementation("com.squareup.okio:okio-multiplatform:3.0.0-alpha.3")
                implementation("com.squareup.okio:okio-fakefilesystem-multiplatform:3.0.0-alpha.3")
            
        
        val commonTest by getting 
            dependencies 
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            
        
        val androidMain by getting
        val androidTest by getting 
            dependencies 
                implementation(kotlin("test-junit"))
                implementation("junit:junit:4.13.2")
            
        
        val iosMain by getting
        val iosTest by getting

        all 
            languageSettings.apply 
                enableLanguageFeature("InlineClasses")
                useExperimentalAnnotation("kotlin.time.ExperimentalTime")
                useExperimentalAnnotation("okio.ExperimentalFileSystem")
            
        
    


android 
    compileSdkVersion(30)
    defaultConfig 
        minSdkVersion(23)
        targetSdkVersion(30)
    
    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    compileOptions 
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    


val packForXcode by tasks.creating(Sync::class) 
    group = "build"
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
    val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
    val framework =
        kotlin.targets.getByName<KotlinNativeTarget>(targetName).binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)
    val targetDir = File(buildDir, "xcode-frameworks")
    from( framework.outputDirectory )
    into(targetDir)

tasks.getByName("build").dependsOn(packForXcode)

这是一个非常普通的多平台构建脚本,主要由 Jetbrain 的移动插件自动生成。我无法通过将其插入到 Android 块的底部来以通常的方式解决这个问题:

    kotlinOptions 
        jvmTarget = "1.8"
    

kotlinOptions 在这里是一个未解决的参考。考虑到这个错误的普遍性,我很惊讶互联网上几乎没有解决它。有一些相同或相似的 jvmTarget 错误的帖子,但它们都是从与此不同的构建上下文发布的。唯一出现完全相同错误的人在这里:

kotlinOptions in kotlin multiplatform project

奇怪的是,据说最初的发帖人只是通过修补他的 androidx 导入来解决这个问题。可能值得注意的是,我的所有六个“不能内联字节码”都与对新的多平台 Okio 库的方法调用相关联。但肯定更有可能是我自己的设置有问题,而不是杰克沃顿帮所做的事情。

【问题讨论】:

【参考方案1】:

根据文档: https://kotlinlang.org/docs/mpp-dsl-reference.html#compilation-parameters

不要被 Gradle 文档的代码示例所迷惑,认为很多这种编译语法仅适用于 Java 块。这是为 Android 构建指定 jvm 版本目标的方式:

kotlin 
    android 
        compilations.all 
            kotlinOptions.jvmTarget = "1.8"
        
    
    ios 
        ...

【讨论】:

以上是关于如何在多平台 Android 模块中配置 Kotlin jvmTarget?的主要内容,如果未能解决你的问题,请参考以下文章

如何在多模块项目中配置 Flutter 模块

如何在多平台多项目 Kotlin 构建中向另一个项目的测试添加依赖项

如何在多模块 Gradle 项目中构建分发包?

在多模块化项目中查看解析器配置

@Parcelize 在多平台项目中

maven ::在多模块项目中仅运行单个测试