具有公共链接依赖关系的多个Kotlin MPP本机库

时间:2020-01-13 23:46:47

标签: gradle kotlin dynamic-linking ios-frameworks kotlin-multiplatform

我有多个Kotlin MPP项目,我希望将其编译并用作iOS和Android中的独立库。 MPP项目具有其自己的build.gradle文件,并被组合为复合的构建结构,因此一项任务将全部构建。这非常适合制作罐子。 iOS框架也已构建,但不是我想要的方式。

这些库之间有一个依赖关系结构,例如所有其他库都使用的核心库以及引用所有其他库的另一个库以及其中的一个。编译库时,它们以包含所有依赖项的胖框架形式出现。它们的类型以前缀according to their Kotlin project name命名,即使在Kotlin中类型相同,也使来自不同库的类型在使用的应用程序中不兼容。

这里是一个示例:假设我们有App,Lib_A和Lib_B。在Kotlin common_main中,Lib_A引用Lib_B的lib_b.Clazz。在Android中,可以从Lib_B和App以及Lib_A和Lib_B之间引用相同的lib_b.Clazz。但是,在iOS中,由于不存在命名空间,因此Clazz在Lib_A中称为Lib_ALib_BClazz,在Lib_B中称为LibBClazz。因此,对于应用程序而言,它们是不同的类型,不能一起使用。此外,在已编译的iOS框架中,每个框架都包含所有可见的传递依赖项。

问题:Gradle中是否有某种方法可以告诉MPP插件不要在每个已编译的iOS框架中包含所有依赖项,所以我可以改为从App提供它们,并且它们的类型兼容?

这是每个Kotlin MPP项目的基本build.gradle,然后将其包含在复合版本中:

plugins {
    id 'org.jetbrains.kotlin.multiplatform' version '1.3.61'
}

repositories {
    mavenCentral()
    mavenLocal()
    jcenter()
    google()
    maven { url "https://kotlin.bintray.com/kotlinx" }
    maven { url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" }
}

apply plugin: 'maven-publish'

kotlin {
    iosArm64 { 
        binaries.framework {
            baseName = project.name
        }
    }
    iosX64 { 
        binaries.framework {
            baseName = project.name
        }
    }
    sourceSets {
        commonMain {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
                implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.3.2'
                implementation 'Lib_B' // example
                implementation 'Lib_C' // example
            }
        }
        iosArm64Main {
            dependencies {
                implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core-native:1.3.2'
            }
        }
        iosX64Main {
            dependencies {
                implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core-native:1.3.2'
            }
        }
    }
}

task runBuildIosArm64(type: GradleBuild) {
    buildFile = 'ProjectName/build.gradle'
    tasks = ['linkReleaseFrameworkIos']
    startParameter.setProjectProperties([
            'IOS_TARGET': 'iosArm64',
            'XCODE_CONFIGURATION': 'RELEASE'
    ])
}

task runBuildIosX64(type: GradleBuild) {
    buildFile = 'ProjectName/build.gradle'
    tasks = ['linkReleaseFrameworkIos']
    startParameter.setProjectProperties([
            'IOS_TARGET': 'iosX64',
            'XCODE_CONFIGURATION': 'RELEASE'
    ])
}

task cleanFrameworksFolder(type: Delete) {
    delete 'ProjectName/build/xcode-frameworks'
}

task combineIosArchitectures(type: Exec) {
    executable 'lipo'
    args = [
            '-create',
            '-arch',  'arm64', 'ProjectName/build/xcode-frameworks/ProjectName_iosArm64.framework/ProjectName',
            '-arch', 'x86_64', 'ProjectName/build/xcode-frameworks/ProjectName_iosX64.framework/ProjectName',
            '-output', 'ProjectName/build/xcode-frameworks/ProjectName.framework/ProjectName',
    ]
}
combineIosArchitectures.dependsOn cleanFrameworksFolder
combineIosArchitectures.dependsOn runBuildIosArm64
combineIosArchitectures.dependsOn runBuildIosX64

0 个答案:

没有答案