Make KotlinNativeLinkArtifactTask configuration lazy with gradle properties.

It is needed for lazy configuration the 'embedBitcode' mode for example.
Because it requires Xcode invocation.
This commit is contained in:
konstantin.tskhovrebov
2022-09-27 14:15:29 +02:00
committed by Space Team
parent 7ca5750255
commit 321e436132
5 changed files with 77 additions and 88 deletions
@@ -114,7 +114,7 @@ class KotlinNativeFatFrameworkImpl(
taskNameSuffix = nameSuffix taskNameSuffix = nameSuffix
) )
fatTask.dependsOn(targetTask) fatTask.dependsOn(targetTask)
val frameworkFileProvider = targetTask.map { it.outputFile } val frameworkFileProvider = targetTask.flatMap { it.outputFile }
FrameworkDescriptor(frameworkFileProvider.get(), isStatic, target) FrameworkDescriptor(frameworkFileProvider.get(), isStatic, target)
} }
fatTask.configure { it.fromFrameworkDescriptors(frameworkDescriptors) } fatTask.configure { it.fromFrameworkDescriptors(frameworkDescriptors) }
@@ -116,16 +116,20 @@ internal fun KotlinNativeArtifact.registerLinkFrameworkTask(
) { task -> ) { task ->
task.description = "Assemble ${kind.description} '$name' for a target '${target.name}'." task.description = "Assemble ${kind.description} '$name' for a target '${target.name}'."
task.enabled = target.enabledOnCurrentHost task.enabled = target.enabledOnCurrentHost
task.baseName = name task.baseName.set(name)
task.destinationDir = destinationDir task.destinationDir.set(destinationDir)
task.optimized = buildType.optimized task.optimized.set(buildType.optimized)
task.debuggable = buildType.debuggable task.debuggable.set(buildType.debuggable)
task.linkerOptions = linkerOptions task.linkerOptions.set(linkerOptions)
task.binaryOptions = binaryOptions task.binaryOptions.set(binaryOptions)
task.isStaticFramework = isStatic task.staticFramework.set(isStatic)
task.embedBitcode = embedBitcode ?: Xcode.defaultBitcodeEmbeddingMode(target, buildType) if (embedBitcode != null) {
task.librariesConfiguration = librariesConfigurationName task.embedBitcode.set(embedBitcode)
task.exportLibrariesConfiguration = exportConfigurationName } 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) task.kotlinOptions(kotlinOptionsFn)
} }
project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(resultTask) project.tasks.named(LifecycleBasePlugin.ASSEMBLE_TASK_NAME).dependsOn(resultTask)
@@ -88,13 +88,13 @@ class KotlinNativeLibraryImpl(
) { task -> ) { task ->
task.description = "Assemble ${kind.description} '$artifactName' for a target '${target.name}'." task.description = "Assemble ${kind.description} '$artifactName' for a target '${target.name}'."
task.enabled = target.enabledOnCurrentHost task.enabled = target.enabledOnCurrentHost
task.baseName = artifactName task.baseName.set(artifactName)
task.optimized = buildType.optimized task.optimized.set(buildType.optimized)
task.debuggable = buildType.debuggable task.debuggable.set(buildType.debuggable)
task.linkerOptions = linkerOptions task.linkerOptions.set(linkerOptions)
task.binaryOptions = binaryOptions task.binaryOptions.set(binaryOptions)
task.librariesConfiguration = librariesConfigurationName task.libraries.setFrom(project.configurations.getByName(librariesConfigurationName))
task.exportLibrariesConfiguration = exportConfigurationName task.exportLibraries.setFrom(project.configurations.getByName(exportConfigurationName))
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
task.kotlinOptions(kotlinOptionsFn) task.kotlinOptions(kotlinOptionsFn)
task.toolOptions(toolOptionsConfigure) task.toolOptions(toolOptionsConfigure)
@@ -7,9 +7,15 @@ package org.jetbrains.kotlin.gradle.targets.native.tasks.artifact
import org.gradle.api.Action import org.gradle.api.Action
import org.gradle.api.DefaultTask 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.FileCollection
import org.gradle.api.file.ProjectLayout import org.gradle.api.file.ProjectLayout
import org.gradle.api.model.ObjectFactory 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.api.tasks.*
import org.gradle.process.ExecOperations import org.gradle.process.ExecOperations
import org.jetbrains.kotlin.compilerRunner.KotlinNativeCompilerRunner import org.jetbrains.kotlin.compilerRunner.KotlinNativeCompilerRunner
@@ -29,7 +35,8 @@ import org.jetbrains.kotlin.konan.util.visibleName
import java.io.File import java.io.File
import javax.inject.Inject import javax.inject.Inject
open class KotlinNativeLinkArtifactTask @Inject constructor( @Suppress("LeakingThis")
abstract class KotlinNativeLinkArtifactTask @Inject constructor(
@get:Input val konanTarget: KonanTarget, @get:Input val konanTarget: KonanTarget,
@get:Input val outputKind: CompilerOutputKind, @get:Input val outputKind: CompilerOutputKind,
private val objectFactory: ObjectFactory, private val objectFactory: ObjectFactory,
@@ -39,84 +46,51 @@ open class KotlinNativeLinkArtifactTask @Inject constructor(
KotlinToolTask<CompilerCommonToolOptions> { KotlinToolTask<CompilerCommonToolOptions> {
@get:Input @get:Input
var baseName: String = project.name abstract val baseName: Property<String>
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
@get:OutputDirectory @get:OutputDirectory
var destinationDir: File abstract val destinationDir: DirectoryProperty
get() = customDestinationDir ?: defaultDestinationDir
set(value) {
customDestinationDir = value
}
@get:Input @get:Input
var optimized: Boolean = false abstract val optimized: Property<Boolean>
@get:Input @get:Input
var debuggable: Boolean = true abstract val debuggable: Property<Boolean>
@Deprecated("Please declare explicit dependency on kotlinx-cli. This option is scheduled to be removed in 1.9.0") @Deprecated("Please declare explicit dependency on kotlinx-cli. This option is scheduled to be removed in 1.9.0")
@get:Input @get:Input
var enableEndorsedLibs: Boolean = false abstract val enableEndorsedLibs: Property<Boolean>
@get:Input @get:Input
var processTests: Boolean = false abstract val processTests: Property<Boolean>
@get:Optional @get:Optional
@get:Input @get:Input
var entryPoint: String? = null abstract val entryPoint: Property<String>
@get:Input @get:Input
var isStaticFramework: Boolean = false abstract val staticFramework: Property<Boolean>
@get:Input @get:Input
var embedBitcode: BitcodeEmbeddingMode = BitcodeEmbeddingMode.DISABLE abstract val embedBitcode: Property<BitcodeEmbeddingMode>
@get:Internal
var librariesConfiguration: String? = null
@get:Classpath @get:Classpath
val libraries: FileCollection by lazy { abstract val libraries: ConfigurableFileCollection
librariesConfiguration?.let {
project.configurations.getByName(it)
} ?: project.objects.fileCollection()
}
@get:Internal
var exportLibrariesConfiguration: String? = null
@get:Classpath @get:Classpath
val exportLibraries: FileCollection by lazy { abstract val exportLibraries: ConfigurableFileCollection
exportLibrariesConfiguration?.let {
project.configurations.getByName(it)
} ?: project.objects.fileCollection()
}
@get:Internal
var includeLibrariesConfiguration: String? = null
@get:Classpath @get:Classpath
val includeLibraries: FileCollection by lazy { abstract val includeLibraries: ConfigurableFileCollection
includeLibrariesConfiguration?.let {
project.configurations.getByName(it)
} ?: project.objects.fileCollection()
}
@get:Input @get:Input
var linkerOptions: List<String> = emptyList() abstract val linkerOptions: ListProperty<String>
@get:Input @get:Input
var binaryOptions: Map<String, String> = emptyMap() abstract val binaryOptions: MapProperty<String, String>
private val nativeBinaryOptions = PropertiesProvider(project).nativeBinaryOptions @get:Input
internal val allBinaryOptions get() = PropertiesProvider(project).nativeBinaryOptions + binaryOptions.get()
override val toolOptions: CompilerCommonToolOptions = objectFactory override val toolOptions: CompilerCommonToolOptions = objectFactory
.newInstance<CompilerCommonToolOptionsDefault>() .newInstance<CompilerCommonToolOptionsDefault>()
@@ -186,42 +160,53 @@ open class KotlinNativeLinkArtifactTask @Inject constructor(
get() = toolOptions.freeCompilerArgs.get() get() = toolOptions.freeCompilerArgs.get()
@get:Internal @get:Internal
val outputFile: File val outputFile: Provider<File> = project.provider {
get() { val outFileName = "${outputKind.prefix(konanTarget)}${baseName.get()}${outputKind.suffix(konanTarget)}".replace('-', '_')
val outFileName = "${outputKind.prefix(konanTarget)}$baseName${outputKind.suffix(konanTarget)}".replace('-', '_') destinationDir.asFile.get().resolve(outFileName)
return destinationDir.resolve(outFileName) }
}
private val runnerSettings = KotlinNativeCompilerRunner.Settings.fromProject(project) 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 @TaskAction
fun link() { fun link() {
val outFile = outputFile val outFile = outputFile.get()
outFile.ensureParentDirsCreated() outFile.ensureParentDirsCreated()
fun FileCollection.klibs() = files.filter { it.extension == "klib" } 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( val buildArgs = buildKotlinNativeBinaryLinkerArgs(
outFile = outFile, outFile = outFile,
optimized = optimized, optimized = optimized.get(),
debuggable = debuggable, debuggable = debuggable.get(),
target = konanTarget, target = konanTarget,
outputKind = outputKind, outputKind = outputKind,
libraries = libraries.klibs(), libraries = libraries.klibs(),
friendModules = emptyList(), //FriendModules aren't needed here because it's no test artifact 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, toolOptions = toolOptions,
compilerPlugins = emptyList(),//CompilerPlugins aren't needed here because it's no compilation but linking compilerPlugins = emptyList(),//CompilerPlugins aren't needed here because it's no compilation but linking
processTests = processTests, processTests = processTests.get(),
entryPoint = entryPoint, entryPoint = entryPoint.getOrNull(),
embedBitcode = embedBitcode, embedBitcode = embedBitcode.get(),
linkerOpts = linkerOptions, linkerOpts = linkerOptions.get(),
binaryOptions = localBinaryOptions, binaryOptions = allBinaryOptions,
isStaticFramework = isStaticFramework, isStaticFramework = staticFramework.get(),
exportLibraries = exportLibraries.klibs(), exportLibraries = exportLibraries.klibs(),
includeLibraries = includeLibraries.klibs(), includeLibraries = includeLibraries.klibs(),
additionalOptions = emptyList()//todo support org.jetbrains.kotlin.gradle.tasks.CacheBuilder and org.jetbrains.kotlin.gradle.tasks.ExternalDependenciesBuilder additionalOptions = emptyList()//todo support org.jetbrains.kotlin.gradle.tasks.CacheBuilder and org.jetbrains.kotlin.gradle.tasks.ExternalDependenciesBuilder
@@ -110,7 +110,7 @@ class KotlinNativeXCFrameworkImpl(
taskNameSuffix = nameSuffix taskNameSuffix = nameSuffix
) )
holder.task.dependsOn(targetTask) holder.task.dependsOn(targetTask)
val frameworkFileProvider = targetTask.map { it.outputFile } val frameworkFileProvider = targetTask.flatMap { it.outputFile }
val descriptor = FrameworkDescriptor(frameworkFileProvider.get(), isStatic, target) val descriptor = FrameworkDescriptor(frameworkFileProvider.get(), isStatic, target)
val group = AppleTarget.values().firstOrNull { it.targets.contains(target) } val group = AppleTarget.values().firstOrNull { it.targets.contains(target) }