From 321e436132feee46dff9bc5404d1b78ed9806312 Mon Sep 17 00:00:00 2001 From: "konstantin.tskhovrebov" Date: Tue, 27 Sep 2022 14:15:29 +0200 Subject: [PATCH] Make KotlinNativeLinkArtifactTask configuration lazy with gradle properties. It is needed for lazy configuration the 'embedBitcode' mode for example. Because it requires Xcode invocation. --- .../artifact/KotlinNativeFatFramework.kt | 2 +- .../tasks/artifact/KotlinNativeFramework.kt | 24 ++-- .../tasks/artifact/KotlinNativeLibrary.kt | 14 +- .../artifact/KotlinNativeLinkArtifactTask.kt | 123 ++++++++---------- .../tasks/artifact/KotlinNativeXCFramework.kt | 2 +- 5 files changed, 77 insertions(+), 88 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFatFramework.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFatFramework.kt index de54d1aeece..df1b90a37ae 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFatFramework.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFatFramework.kt @@ -114,7 +114,7 @@ class KotlinNativeFatFrameworkImpl( taskNameSuffix = nameSuffix ) fatTask.dependsOn(targetTask) - val frameworkFileProvider = targetTask.map { it.outputFile } + val frameworkFileProvider = targetTask.flatMap { it.outputFile } FrameworkDescriptor(frameworkFileProvider.get(), isStatic, target) } fatTask.configure { it.fromFrameworkDescriptors(frameworkDescriptors) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFramework.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFramework.kt index bd9bb0dbe48..8fa174af075 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFramework.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeFramework.kt @@ -116,16 +116,20 @@ internal fun KotlinNativeArtifact.registerLinkFrameworkTask( ) { task -> task.description = "Assemble ${kind.description} '$name' for a target '${target.name}'." task.enabled = target.enabledOnCurrentHost - task.baseName = name - task.destinationDir = destinationDir - task.optimized = buildType.optimized - task.debuggable = buildType.debuggable - task.linkerOptions = linkerOptions - task.binaryOptions = binaryOptions - task.isStaticFramework = isStatic - task.embedBitcode = embedBitcode ?: Xcode.defaultBitcodeEmbeddingMode(target, buildType) - task.librariesConfiguration = librariesConfigurationName - task.exportLibrariesConfiguration = exportConfigurationName + task.baseName.set(name) + task.destinationDir.set(destinationDir) + task.optimized.set(buildType.optimized) + task.debuggable.set(buildType.debuggable) + task.linkerOptions.set(linkerOptions) + task.binaryOptions.set(binaryOptions) + task.staticFramework.set(isStatic) + if (embedBitcode != null) { + task.embedBitcode.set(embedBitcode) + } else { + task.embedBitcode.set(project.provider { Xcode.defaultBitcodeEmbeddingMode(target, buildType) }) + } + task.libraries.setFrom(project.configurations.getByName(librariesConfigurationName)) + task.exportLibraries.setFrom(project.configurations.getByName(exportConfigurationName)) task.kotlinOptions(kotlinOptionsFn) } project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(resultTask) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLibrary.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLibrary.kt index 9564cea717e..592aec5b871 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLibrary.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLibrary.kt @@ -88,13 +88,13 @@ class KotlinNativeLibraryImpl( ) { task -> task.description = "Assemble ${kind.description} '$artifactName' for a target '${target.name}'." task.enabled = target.enabledOnCurrentHost - task.baseName = artifactName - task.optimized = buildType.optimized - task.debuggable = buildType.debuggable - task.linkerOptions = linkerOptions - task.binaryOptions = binaryOptions - task.librariesConfiguration = librariesConfigurationName - task.exportLibrariesConfiguration = exportConfigurationName + task.baseName.set(artifactName) + task.optimized.set(buildType.optimized) + task.debuggable.set(buildType.debuggable) + task.linkerOptions.set(linkerOptions) + task.binaryOptions.set(binaryOptions) + task.libraries.setFrom(project.configurations.getByName(librariesConfigurationName)) + task.exportLibraries.setFrom(project.configurations.getByName(exportConfigurationName)) @Suppress("DEPRECATION") task.kotlinOptions(kotlinOptionsFn) task.toolOptions(toolOptionsConfigure) diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLinkArtifactTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLinkArtifactTask.kt index eb38afda28f..f7f5688cf07 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLinkArtifactTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeLinkArtifactTask.kt @@ -7,9 +7,15 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact import org.gradle.api.Action import org.gradle.api.DefaultTask +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileCollection import org.gradle.api.file.ProjectLayout import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.MapProperty +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider import org.gradle.api.tasks.* import org.gradle.process.ExecOperations import org.jetbrains.kotlin.compilerRunner.KotlinNativeCompilerRunner @@ -29,7 +35,8 @@ import org.jetbrains.kotlin.konan.util.visibleName import java.io.File import javax.inject.Inject -open class KotlinNativeLinkArtifactTask @Inject constructor( +@Suppress("LeakingThis") +abstract class KotlinNativeLinkArtifactTask @Inject constructor( @get:Input val konanTarget: KonanTarget, @get:Input val outputKind: CompilerOutputKind, private val objectFactory: ObjectFactory, @@ -39,84 +46,51 @@ open class KotlinNativeLinkArtifactTask @Inject constructor( KotlinToolTask { @get:Input - var baseName: String = project.name - - private val defaultDestinationDir: File get() { - val kind = outputKind.visibleName - val target = konanTarget.visibleName - val type = if (debuggable) "debug" else "release" - return projectLayout.buildDirectory.get().asFile.resolve("out/$kind/$target/$type") - } - - private var customDestinationDir: File? = null + abstract val baseName: Property @get:OutputDirectory - var destinationDir: File - get() = customDestinationDir ?: defaultDestinationDir - set(value) { - customDestinationDir = value - } + abstract val destinationDir: DirectoryProperty @get:Input - var optimized: Boolean = false + abstract val optimized: Property @get:Input - var debuggable: Boolean = true + abstract val debuggable: Property @Deprecated("Please declare explicit dependency on kotlinx-cli. This option is scheduled to be removed in 1.9.0") @get:Input - var enableEndorsedLibs: Boolean = false + abstract val enableEndorsedLibs: Property @get:Input - var processTests: Boolean = false + abstract val processTests: Property @get:Optional @get:Input - var entryPoint: String? = null + abstract val entryPoint: Property @get:Input - var isStaticFramework: Boolean = false + abstract val staticFramework: Property @get:Input - var embedBitcode: BitcodeEmbeddingMode = BitcodeEmbeddingMode.DISABLE - - @get:Internal - var librariesConfiguration: String? = null + abstract val embedBitcode: Property @get:Classpath - val libraries: FileCollection by lazy { - librariesConfiguration?.let { - project.configurations.getByName(it) - } ?: project.objects.fileCollection() - } - - @get:Internal - var exportLibrariesConfiguration: String? = null + abstract val libraries: ConfigurableFileCollection @get:Classpath - val exportLibraries: FileCollection by lazy { - exportLibrariesConfiguration?.let { - project.configurations.getByName(it) - } ?: project.objects.fileCollection() - } - - @get:Internal - var includeLibrariesConfiguration: String? = null + abstract val exportLibraries: ConfigurableFileCollection @get:Classpath - val includeLibraries: FileCollection by lazy { - includeLibrariesConfiguration?.let { - project.configurations.getByName(it) - } ?: project.objects.fileCollection() - } + abstract val includeLibraries: ConfigurableFileCollection @get:Input - var linkerOptions: List = emptyList() + abstract val linkerOptions: ListProperty @get:Input - var binaryOptions: Map = emptyMap() + abstract val binaryOptions: MapProperty - private val nativeBinaryOptions = PropertiesProvider(project).nativeBinaryOptions + @get:Input + internal val allBinaryOptions get() = PropertiesProvider(project).nativeBinaryOptions + binaryOptions.get() override val toolOptions: CompilerCommonToolOptions = objectFactory .newInstance() @@ -186,42 +160,53 @@ open class KotlinNativeLinkArtifactTask @Inject constructor( get() = toolOptions.freeCompilerArgs.get() @get:Internal - val outputFile: File - get() { - val outFileName = "${outputKind.prefix(konanTarget)}$baseName${outputKind.suffix(konanTarget)}".replace('-', '_') - return destinationDir.resolve(outFileName) - } + val outputFile: Provider = project.provider { + val outFileName = "${outputKind.prefix(konanTarget)}${baseName.get()}${outputKind.suffix(konanTarget)}".replace('-', '_') + destinationDir.asFile.get().resolve(outFileName) + } private val runnerSettings = KotlinNativeCompilerRunner.Settings.fromProject(project) + init { + baseName.convention(project.name) + debuggable.convention(true) + optimized.convention(false) + enableEndorsedLibs.convention(false) + processTests.convention(false) + staticFramework.convention(false) + embedBitcode.convention(BitcodeEmbeddingMode.DISABLE) + destinationDir.convention(debuggable.flatMap { + val kind = outputKind.visibleName + val target = konanTarget.visibleName + val type = if (it) "debug" else "release" + projectLayout.buildDirectory.dir("out/$kind/$target/$type") + }) + } + @TaskAction fun link() { - val outFile = outputFile + val outFile = outputFile.get() outFile.ensureParentDirsCreated() fun FileCollection.klibs() = files.filter { it.extension == "klib" } - val localBinaryOptions = nativeBinaryOptions + binaryOptions - - @Suppress("DEPRECATION") val enableEndorsedLibs = this.enableEndorsedLibs // TODO: remove before 1.9.0, see KT-54098 - val buildArgs = buildKotlinNativeBinaryLinkerArgs( outFile = outFile, - optimized = optimized, - debuggable = debuggable, + optimized = optimized.get(), + debuggable = debuggable.get(), target = konanTarget, outputKind = outputKind, libraries = libraries.klibs(), friendModules = emptyList(), //FriendModules aren't needed here because it's no test artifact - enableEndorsedLibs = enableEndorsedLibs, + enableEndorsedLibs = enableEndorsedLibs.get(), // TODO: remove before 1.9.0, see KT-54098 toolOptions = toolOptions, compilerPlugins = emptyList(),//CompilerPlugins aren't needed here because it's no compilation but linking - processTests = processTests, - entryPoint = entryPoint, - embedBitcode = embedBitcode, - linkerOpts = linkerOptions, - binaryOptions = localBinaryOptions, - isStaticFramework = isStaticFramework, + processTests = processTests.get(), + entryPoint = entryPoint.getOrNull(), + embedBitcode = embedBitcode.get(), + linkerOpts = linkerOptions.get(), + binaryOptions = allBinaryOptions, + isStaticFramework = staticFramework.get(), exportLibraries = exportLibraries.klibs(), includeLibraries = includeLibraries.klibs(), additionalOptions = emptyList()//todo support org.jetbrains.kotlin.gradle.tasks.CacheBuilder and org.jetbrains.kotlin.gradle.tasks.ExternalDependenciesBuilder diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeXCFramework.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeXCFramework.kt index ee0cf16c9f8..ee6a342a455 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeXCFramework.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/artifact/KotlinNativeXCFramework.kt @@ -110,7 +110,7 @@ class KotlinNativeXCFrameworkImpl( taskNameSuffix = nameSuffix ) holder.task.dependsOn(targetTask) - val frameworkFileProvider = targetTask.map { it.outputFile } + val frameworkFileProvider = targetTask.flatMap { it.outputFile } val descriptor = FrameworkDescriptor(frameworkFileProvider.get(), isStatic, target) val group = AppleTarget.values().firstOrNull { it.targets.contains(target) }