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
)
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) }
@@ -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)
@@ -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)
@@ -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<CompilerCommonToolOptions> {
@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<String>
@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<Boolean>
@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")
@get:Input
var enableEndorsedLibs: Boolean = false
abstract val enableEndorsedLibs: Property<Boolean>
@get:Input
var processTests: Boolean = false
abstract val processTests: Property<Boolean>
@get:Optional
@get:Input
var entryPoint: String? = null
abstract val entryPoint: Property<String>
@get:Input
var isStaticFramework: Boolean = false
abstract val staticFramework: Property<Boolean>
@get:Input
var embedBitcode: BitcodeEmbeddingMode = BitcodeEmbeddingMode.DISABLE
@get:Internal
var librariesConfiguration: String? = null
abstract val embedBitcode: Property<BitcodeEmbeddingMode>
@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<String> = emptyList()
abstract val linkerOptions: ListProperty<String>
@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
.newInstance<CompilerCommonToolOptionsDefault>()
@@ -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<File> = 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
@@ -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) }