[Gradle] KotlinNativeCompile: Implement KotlinCompilerArgumentsProducer
KTIJ-24976
This commit is contained in:
committed by
Space Team
parent
16cce7516e
commit
30a4911a51
+78
-4
@@ -30,6 +30,9 @@ import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated
|
|||||||
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
|
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext.Companion.create
|
||||||
import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName
|
import org.jetbrains.kotlin.gradle.plugin.cocoapods.asValidFrameworkName
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
import org.jetbrains.kotlin.gradle.plugin.mpp.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmMetadataCompilationData
|
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.GradleKpmMetadataCompilationData
|
||||||
@@ -52,6 +55,7 @@ import org.jetbrains.kotlin.library.*
|
|||||||
import org.jetbrains.kotlin.project.model.LanguageSettings
|
import org.jetbrains.kotlin.project.model.LanguageSettings
|
||||||
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
|
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
|
||||||
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
import org.jetbrains.kotlin.statistics.metrics.StringMetrics
|
||||||
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -319,6 +323,7 @@ internal constructor(
|
|||||||
private val execOperations: ExecOperations
|
private val execOperations: ExecOperations
|
||||||
) : AbstractKotlinNativeCompile<KotlinCommonOptions, StubK2NativeCompilerArguments>(objectFactory),
|
) : AbstractKotlinNativeCompile<KotlinCommonOptions, StubK2NativeCompilerArguments>(objectFactory),
|
||||||
KotlinCompile<KotlinCommonOptions>,
|
KotlinCompile<KotlinCommonOptions>,
|
||||||
|
KotlinCompilerArgumentsProducer,
|
||||||
K2MultiplatformCompilationTask,
|
K2MultiplatformCompilationTask,
|
||||||
KotlinCompilationTask<KotlinNativeCompilerOptions> {
|
KotlinCompilationTask<KotlinNativeCompilerOptions> {
|
||||||
|
|
||||||
@@ -450,6 +455,72 @@ internal constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun createCompilerArguments(context: CreateCompilerArgumentsContext) = context.create<K2NativeCompilerArguments> {
|
||||||
|
val sharedCompilationData = createSharedCompilationDataOrNull()
|
||||||
|
|
||||||
|
val compilerPlugins = listOfNotNull(
|
||||||
|
compilerPluginClasspath?.let { CompilerPluginData(it, compilerPluginOptions) },
|
||||||
|
kotlinPluginData?.orNull?.let { CompilerPluginData(it.classpath, it.options) }
|
||||||
|
)
|
||||||
|
|
||||||
|
contribute(KotlinCompilerArgumentsProducer.ArgumentType.Primitive) { args ->
|
||||||
|
args.moduleName = compilerOptions.moduleName.get()
|
||||||
|
args.shortModuleName = shortModuleName
|
||||||
|
args.multiPlatform = true
|
||||||
|
args.noendorsedlibs = true
|
||||||
|
args.outputName = outputFile.get().absolutePath
|
||||||
|
args.optimization = optimized
|
||||||
|
args.debug = debuggable
|
||||||
|
args.enableAssertions = debuggable
|
||||||
|
args.target = konanTarget.name
|
||||||
|
args.produce = outputKind.name.toLowerCaseAsciiOnly()
|
||||||
|
args.expectActualLinker = sharedCompilationData != null
|
||||||
|
args.metadataKlib = sharedCompilationData != null
|
||||||
|
args.nodefaultlibs = sharedCompilationData != null
|
||||||
|
args.manifestFile = sharedCompilationData?.manifestFile?.absolutePath
|
||||||
|
|
||||||
|
args.pluginOptions = compilerPlugins.flatMap { it.options.arguments }.toTypedArray()
|
||||||
|
|
||||||
|
if (compilerOptions.usesK2.get()) {
|
||||||
|
args.fragments = multiplatformStructure.fragmentsCompilerArgs
|
||||||
|
args.fragmentRefines = multiplatformStructure.fragmentRefinesCompilerArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
KotlinNativeCompilerOptionsHelper.fillCompilerArguments(compilerOptions, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
contribute(KotlinCompilerArgumentsProducer.ArgumentType.PluginClasspath) { args ->
|
||||||
|
args.pluginClasspaths = compilerPlugins.flatMap { classpath -> tryLenient { classpath.files } ?: emptySet() }.toPathsArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
contribute(KotlinCompilerArgumentsProducer.ArgumentType.DependencyClasspath) { args ->
|
||||||
|
args.libraries = tryLenient { libraries.files.filterKlibsPassedToCompiler().toPathsArray() }
|
||||||
|
args.friendModules = tryLenient {
|
||||||
|
friendModule.files.takeIf { it.isNotEmpty() }?.map { it.absolutePath }?.joinToString(File.pathSeparator)
|
||||||
|
}
|
||||||
|
args.refinesPaths = tryLenient {
|
||||||
|
sharedCompilationData?.refinesPaths?.files?.takeIf { it.isNotEmpty() }?.toPathsArray()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contribute(KotlinCompilerArgumentsProducer.ArgumentType.Sources) { args ->
|
||||||
|
if (compilerOptions.usesK2.get()) {
|
||||||
|
/*
|
||||||
|
For now, we only pass multiplatform structure to K2 for platform compilations
|
||||||
|
Metadata compilations will compile against pre-compiled klibs from their dependsOn
|
||||||
|
*/
|
||||||
|
if (sharedCompilationData == null) {
|
||||||
|
args.fragmentSources = multiplatformStructure.fragmentSourcesCompilerArgs
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args.commonSources = commonSourcesTree.files.takeIf { it.isNotEmpty() }?.toPathsArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
args.freeArgs += sources.asFileTree.map { it.absolutePath }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private val isMetadataCompilation: Boolean = when (compilation) {
|
private val isMetadataCompilation: Boolean = when (compilation) {
|
||||||
is KotlinCompilationInfo.KPM -> compilation.compilationData is GradleKpmMetadataCompilationData<*>
|
is KotlinCompilationInfo.KPM -> compilation.compilationData is GradleKpmMetadataCompilationData<*>
|
||||||
is KotlinCompilationInfo.TCS -> compilation.compilation is KotlinMetadataCompilation<*>
|
is KotlinCompilationInfo.TCS -> compilation.compilation is KotlinMetadataCompilation<*>
|
||||||
@@ -467,12 +538,14 @@ internal constructor(
|
|||||||
return SharedCompilationData(manifestFile, isAllowCommonizer, refinesModule)
|
return SharedCompilationData(manifestFile, isAllowCommonizer, refinesModule)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun buildCompilerArgs(): List<String> = buildKotlinNativeKlibCompilerArgs(
|
internal fun buildCompilerArgs(isLenient: Boolean = false): List<String> = buildKotlinNativeKlibCompilerArgs(
|
||||||
outFile = outputFile.get(),
|
outFile = outputFile.get(),
|
||||||
optimized = optimized,
|
optimized = optimized,
|
||||||
debuggable = debuggable,
|
debuggable = debuggable,
|
||||||
target = konanTarget,
|
target = konanTarget,
|
||||||
libraries = libraries.files.filterKlibsPassedToCompiler(),
|
libraries = runCatching { libraries.files.filterKlibsPassedToCompiler() }.getOrElse {
|
||||||
|
if (isLenient) emptyList() else throw it
|
||||||
|
},
|
||||||
languageSettings = languageSettings,
|
languageSettings = languageSettings,
|
||||||
compilerOptions = compilerOptions,
|
compilerOptions = compilerOptions,
|
||||||
compilerPlugins = listOfNotNull(
|
compilerPlugins = listOfNotNull(
|
||||||
@@ -494,12 +567,13 @@ internal constructor(
|
|||||||
output.parentFile.mkdirs()
|
output.parentFile.mkdirs()
|
||||||
|
|
||||||
collectCommonCompilerStats()
|
collectCommonCompilerStats()
|
||||||
val buildArgs = buildCompilerArgs()
|
val arguments = createCompilerArguments()
|
||||||
|
val buildArguments = ArgumentUtils.convertArgumentsToStringList(arguments)
|
||||||
|
|
||||||
KotlinNativeCompilerRunner(
|
KotlinNativeCompilerRunner(
|
||||||
settings = runnerSettings,
|
settings = runnerSettings,
|
||||||
executionContext = KotlinToolRunner.GradleExecutionContext.fromTaskContext(objectFactory, execOperations, logger)
|
executionContext = KotlinToolRunner.GradleExecutionContext.fromTaskContext(objectFactory, execOperations, logger)
|
||||||
).run(buildArgs)
|
).run(buildArguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectCommonCompilerStats() {
|
private fun collectCommonCompilerStats() {
|
||||||
|
|||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("FunctionName")
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.gradle.unitTests.compilerArgumetns
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
|
||||||
|
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext.Companion.default
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerArgumentsProducer.CreateCompilerArgumentsContext.Companion.lenient
|
||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
||||||
|
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
|
||||||
|
import org.jetbrains.kotlin.gradle.util.main
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertFails
|
||||||
|
import kotlin.test.assertNull
|
||||||
|
|
||||||
|
class KotlinNativeCompileArgumentsTest {
|
||||||
|
@Test
|
||||||
|
fun `test - simple project - old buildCompilerArgs and new CompilerArgumentsProducer - return same arguments`() {
|
||||||
|
val project = buildProjectWithMPP()
|
||||||
|
project.repositories.mavenLocal()
|
||||||
|
|
||||||
|
val kotlin = project.multiplatformExtension
|
||||||
|
|
||||||
|
kotlin.linuxArm64()
|
||||||
|
val linuxX64Target = kotlin.linuxX64()
|
||||||
|
|
||||||
|
project.evaluate()
|
||||||
|
|
||||||
|
/* Check linuxX64 main compilation as 'native platform compilation' */
|
||||||
|
run {
|
||||||
|
val linuxX64MainCompilation = linuxX64Target.compilations.main
|
||||||
|
val linuxX64MainCompileTask = linuxX64MainCompilation.compileTaskProvider.get()
|
||||||
|
`assert buildCompilerArgs and createCompilerArgs are equal`(linuxX64MainCompileTask)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check commonMain compilation as 'shared native compilation' */
|
||||||
|
run {
|
||||||
|
val commonMainCompilation = kotlin.metadata().compilations.getByName("commonMain")
|
||||||
|
val commonMainCompileTask = commonMainCompilation.compileTaskProvider.get() as KotlinNativeCompile
|
||||||
|
`assert buildCompilerArgs and createCompilerArgs are equal`(commonMainCompileTask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun `assert buildCompilerArgs and createCompilerArgs are equal`(compile: KotlinNativeCompile) {
|
||||||
|
val argumentsFromCompilerArgumentsProducer = compile.createCompilerArguments(lenient)
|
||||||
|
val argumentsFromBuildCompilerArgs = K2NativeCompilerArguments().apply {
|
||||||
|
parseCommandLineArguments(compile.buildCompilerArgs(true), this)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
ArgumentUtils.convertArgumentsToStringList(argumentsFromBuildCompilerArgs),
|
||||||
|
ArgumentUtils.convertArgumentsToStringList(argumentsFromCompilerArgumentsProducer)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test - simple project - failing dependency - lenient`() {
|
||||||
|
val project = buildProjectWithMPP()
|
||||||
|
val kotlin = project.multiplatformExtension
|
||||||
|
val linuxX64Target = kotlin.linuxX64()
|
||||||
|
kotlin.sourceSets.getByName("commonMain").dependencies { implementation("not-a:dependency:1.0.0") }
|
||||||
|
project.evaluate()
|
||||||
|
|
||||||
|
val commonMainCompileTask = linuxX64Target.compilations.main.compileTaskProvider.get()
|
||||||
|
assertNull(commonMainCompileTask.createCompilerArguments(lenient).libraries)
|
||||||
|
assertFails { commonMainCompileTask.createCompilerArguments(default) }
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user