kotlin multiplatform:如何减少构建时间?

时间:2019-07-05 14:05:28

标签: android ios gradle kotlin kotlin-multiplatform

我有一个kotlin多平台项目,可以制作针对iOS和Android的共享库。我有一些多平台外部库:sqldelight,kodein-di,ktor,klock,kotlinx-协程和kotlinx-串行化。

使用命令行./gradlew :SharedCode:build将共享库构建为Apple框架大约需要5分钟

是否可以减少构建时间?

我的SharedCode多平台库 build.gradle

apply plugin: 'kotlinx-serialization'
apply plugin: 'com.android.library'
apply plugin: 'org.jetbrains.kotlin.multiplatform'
apply plugin: "com.squareup.sqldelight"
apply plugin: "org.jetbrains.dokka"

group = 'com.example.multiplatform'
version = '1.0'

android {
    compileSdkVersion 28
    defaultConfig {
        minSdkVersion 15
    }
    buildTypes {
        release {
            minifyEnabled false
        }
    }
    compileOptions {
        sourceCompatibility = '1.8'
        targetCompatibility = '1.8'
    }
}

sqldelight {
    MyDB {
        packageName = "com.example.multiplatform"
    }
}

dokka {
    outputFormat = "markdown"
    impliedPlatforms = ["common"] // This will force platform tags for all non-common sources e.g. "JVM"
    kotlinTasks {
        // dokka fails to retrieve sources from MPP-tasks so they must be set empty to avoid exception
        // use sourceRoot instead (see below)
        []
    }
    sourceRoot {
        // assuming there is only a single source dir...
        path = kotlin.sourceSets.commonMain.kotlin.srcDirs[0]
        platforms = ["common"]
    }
}

dependencies {
    // Specify Kotlin/JVM stdlib dependency.
    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'

    testImplementation 'junit:junit:4.12'
    testImplementation 'org.jetbrains.kotlin:kotlin-test'
    testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'

    androidTestImplementation 'junit:junit:4.12'
    androidTestImplementation 'org.jetbrains.kotlin:kotlin-test'
    androidTestImplementation 'org.jetbrains.kotlin:kotlin-test-junit'

    androidTestImplementation "io.ktor:ktor-client-serialization-jvm:$ktor_version"

    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

kotlin {
    targets {
        final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos")   \
                            ? presets.iosArm64 : presets.iosX64

        fromPreset(iOSTarget, 'ios') {
            binaries {
                framework('SharedCode')
            }
        }

        fromPreset(presets.android, 'android')
    }

    sourceSets {
       all {
            dependencies {
                implementation "org.kodein.di:kodein-di-core:$kodein_version"
                implementation "org.kodein.di:kodein-di-erased:$kodein_version"
            }
        }

        commonMain {
            dependencies {
                //HTTP
                implementation "io.ktor:ktor-client-json:$ktor_json_version"
                implementation "io.ktor:ktor-client-serialization:$ktor_version"
                //Coroutines
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$kotlinx_coroutines_version"
                //Kotlinx serialization
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
                //kclock
                implementation "com.soywiz.korlibs.klock:klock:$klock_version"
            }
        }

        commonTest {
            dependencies {
                implementation 'org.jetbrains.kotlin:kotlin-test-common'
                implementation 'org.jetbrains.kotlin:kotlin-test-annotations-common'

                implementation "io.ktor:ktor-client-mock:$ktor_version"
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$kotlinx_coroutines_version"
                implementation "org.kodein.di:kodein-di-core:$kodein_version"
                implementation "org.kodein.di:kodein-di-erased:$kodein_version"
            }
        }

        androidMain {
            dependencies {
                //HTTP
                implementation "io.ktor:ktor-client-json-jvm:$ktor_json_version"
                implementation "io.ktor:ktor-client-serialization-jvm:$ktor_version"
                //Coroutines
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinx_coroutines_version"
                //Kotlinx serialization
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
                //sqldelight
                implementation "com.squareup.sqldelight:android-driver:$sqldelight_version"
            }
        }

        androidTest {
            dependencies {
                implementation 'junit:junit:4.12'
                implementation 'org.jetbrains.kotlin:kotlin-test'
                implementation 'org.jetbrains.kotlin:kotlin-test-junit'
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
                implementation "io.ktor:ktor-client-mock-jvm:$ktor_version"
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinx_coroutines_version"
            }
        }

        iosMain {
            dependencies {
                //HTTP
                implementation "io.ktor:ktor-client-ios:$ktor_version"
                implementation "io.ktor:ktor-client-json-native:$ktor_json_version"
                implementation "io.ktor:ktor-client-serialization-native:$ktor_version"
                //Coroutines
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$kotlinx_coroutines_version"
                //kotlinx serialization
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"
                //sqldelight
                implementation "com.squareup.sqldelight:ios-driver:$sqldelight_version"
            }
        }

        iosTest {
            dependencies {
                implementation "io.ktor:ktor-client-mock-native:$ktor_version"
                implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$kotlinx_coroutines_version"
            }
        }
    }
}

task iosTest {
    def device = project.findProperty("iosDevice")?.toString() ?: "iPhone X"
    def isDevice = System.getenv('SDK_NAME')?.startsWith("iphoneos")
    dependsOn 'linkTestDebugExecutableIos'
    group = JavaBasePlugin.VERIFICATION_GROUP
    description = "Runs tests for target 'ios' on an iOS simulator"

    doLast {
        if (!isDevice) {
            def binary = kotlin.targets.ios.binaries.getExecutable('test', 'DEBUG').outputFile
            exec {
                commandLine 'xcrun', 'simctl', 'spawn', device, binary.absolutePath
            }
        }
    }

}

tasks.check.dependsOn iosTest

tasks.withType(Test) {
    testLogging {
        exceptionFormat "full"
        events "passed", "failed"
        showStandardStreams true
    }
}

task packForXCode(type: Sync) {
    final File frameworkDir = new File(buildDir, "xcode-frameworks")
    final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
    final def framework = kotlin.targets.ios.binaries.getFramework("SharedCode", mode)

    inputs.property "mode", mode
    dependsOn framework.linkTask

    from { framework.outputFile.parentFile }
    into frameworkDir

    doLast {
        new File(frameworkDir, 'gradlew').with {
            text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
            setExecutable(true)
        }
    }
}
tasks.build.dependsOn packForXCode

1 个答案:

答案 0 :(得分:1)

当我积极地进行编码和测试时,我只是构建框架目标,而不是使用build构建整个项目。通常,调用build会构成调试和发布框架以及两者的测试框架。

因此,就我而言,我运行linkMainDebugFrameworkIos而不是完整的build。这大大减少了时间。 1m 35s与至少5m(如果不是更长)进行完整构建。

该任务名称可能会随1.3.40+一起更改,并且sqldelight和其他库应该很快就位于1.3.40上。仅供参考。