[Gradle] Pass stdlib explicitly as K/native dependency. Keep original...
... platform dependencies while filter out them from actual compiler invocation. So kotlin native compiler will provide them implicitly from kotlin native bundle. Since K/Native compiler is not yet optimised to consume platform dependencies explicitly and simply slow. More details in related issue: KT-61559 ^KT-61430 Verification Pending ^KT-61559 Verification Pending
This commit is contained in:
committed by
Space Team
parent
90a47e0488
commit
9acb9ff2b7
+1
@@ -72,6 +72,7 @@ internal fun Project.registerKotlinPluginExtensions() {
|
||||
register(project, KotlinRegisterCompilationArchiveTasksExtension)
|
||||
register(project, IdeMultiplatformImportActionSetupAction)
|
||||
register(project, KotlinLLDBScriptSetupAction)
|
||||
register(project, ExcludeDefaultPlatformDependenciesFromKotlinNativeCompileTasks)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+24
-2
@@ -9,13 +9,18 @@ import org.gradle.api.Project
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.jetbrains.kotlin.commonizer.*
|
||||
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtensionOrNull
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupAction
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinProjectSetupCoroutine
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationSideEffectCoroutine
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.targets.metadata.isNativeSourceSet
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
|
||||
import org.jetbrains.kotlin.gradle.tasks.withType
|
||||
import org.jetbrains.kotlin.gradle.utils.filesProvider
|
||||
import org.jetbrains.kotlin.gradle.utils.konanDistribution
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import java.io.File
|
||||
|
||||
internal val SetupKotlinNativePlatformDependenciesAndStdlib =
|
||||
@@ -31,6 +36,20 @@ internal val SetupKotlinNativePlatformDependenciesAndStdlib =
|
||||
compilation.compileDependencyFiles += stdlib
|
||||
}
|
||||
|
||||
internal val ExcludeDefaultPlatformDependenciesFromKotlinNativeCompileTasks = KotlinProjectSetupAction {
|
||||
tasks.withType<KotlinNativeLink>().configureEach { task ->
|
||||
@Suppress("DEPRECATION")
|
||||
val konanTarget = task.compilation.konanTarget
|
||||
task.excludeOriginalPlatformLibraries = task.project.getOriginalPlatformLibrariesFor(konanTarget)
|
||||
}
|
||||
tasks.withType<KotlinNativeCompile>().configureEach { task ->
|
||||
// metadata compilations should have commonized platform libraries in the classpath i.e. they are not "original"
|
||||
if (task.isMetadataCompilation) return@configureEach
|
||||
val konanTarget = task.konanTarget
|
||||
task.excludeOriginalPlatformLibraries = task.project.getOriginalPlatformLibrariesFor(konanTarget)
|
||||
}
|
||||
}
|
||||
|
||||
internal val SetupKotlinNativePlatformDependenciesForLegacyImport = KotlinProjectSetupCoroutine {
|
||||
val multiplatform = multiplatformExtensionOrNull ?: return@KotlinProjectSetupCoroutine
|
||||
val sourceSets = multiplatform
|
||||
@@ -60,8 +79,11 @@ internal fun Project.getNativeDistributionDependencies(target: CommonizerTarget)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.getOriginalPlatformLibrariesFor(target: LeafCommonizerTarget): FileCollection = project.filesProvider {
|
||||
konanDistribution.platformLibsDir.resolve(target.konanTarget.name).listLibraryFiles().toSet()
|
||||
private fun Project.getOriginalPlatformLibrariesFor(target: LeafCommonizerTarget): FileCollection =
|
||||
getOriginalPlatformLibrariesFor(target.konanTarget)
|
||||
|
||||
private fun Project.getOriginalPlatformLibrariesFor(konanTarget: KonanTarget): FileCollection = project.filesProvider {
|
||||
konanDistribution.platformLibsDir.resolve(konanTarget.name).listLibraryFiles().toSet()
|
||||
}
|
||||
|
||||
private fun getCommonizedPlatformLibrariesFor(rootOutputDirectory: File, target: SharedCommonizerTarget): List<File> {
|
||||
|
||||
+8
-2
@@ -78,6 +78,11 @@ constructor(
|
||||
}
|
||||
)
|
||||
|
||||
@get:InputFiles
|
||||
@get:Optional
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
internal var excludeOriginalPlatformLibraries: FileCollection? = null
|
||||
|
||||
@get:Input
|
||||
val outputKind: CompilerOutputKind by lazyConvention { binary.outputKind.compilerOutputKind }
|
||||
|
||||
@@ -239,7 +244,6 @@ constructor(
|
||||
args.produce = outputKind.name.toLowerCaseAsciiOnly()
|
||||
args.multiPlatform = true
|
||||
args.noendorsedlibs = true
|
||||
args.nodefaultlibs = true
|
||||
args.nostdlib = true
|
||||
args.pluginOptions = compilerPlugins.flatMap { it.options.arguments }.toTypedArray()
|
||||
args.generateTestRunner = processTests
|
||||
@@ -263,7 +267,9 @@ constructor(
|
||||
}
|
||||
|
||||
dependencyClasspath { args ->
|
||||
args.libraries = runSafe { libraries.files.filterKlibsPassedToCompiler() }?.toPathsArray()
|
||||
args.libraries = runSafe {
|
||||
libraries.exclude(excludeOriginalPlatformLibraries).files.filterKlibsPassedToCompiler()
|
||||
}?.toPathsArray()
|
||||
args.exportedLibraries = runSafe { exportLibraries.files.filterKlibsPassedToCompiler() }?.toPathsArray()
|
||||
args.friendModules = runSafe { friendModule.files.toList().takeIf { it.isNotEmpty() } }
|
||||
?.joinToString(File.pathSeparator) { it.absolutePath }
|
||||
|
||||
+17
-5
@@ -157,7 +157,7 @@ abstract class AbstractKotlinNativeCompile<
|
||||
internal abstract val explicitApiMode: Property<ExplicitApiMode>
|
||||
|
||||
@get:Internal
|
||||
protected val konanTarget by project.provider {
|
||||
internal val konanTarget by project.provider {
|
||||
when (val compilation = compilation) {
|
||||
is KotlinCompilationInfo.TCS -> (compilation.compilation as AbstractKotlinNativeCompilation).konanTarget
|
||||
}
|
||||
@@ -425,6 +425,16 @@ internal constructor(
|
||||
)
|
||||
// endregion.
|
||||
|
||||
/**
|
||||
* This is utility property that contains list of native platform dependencies that are present in [compileDependencyFiles]
|
||||
* but should be excluded from actual classpath because they are included by default by Kotlin Native Compiler.
|
||||
* this behaviour will be fixed as part of KT-65232
|
||||
*/
|
||||
@get:InputFiles
|
||||
@get:Optional
|
||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||
internal var excludeOriginalPlatformLibraries: FileCollection? = null
|
||||
|
||||
@Suppress("DeprecatedCallableAddReplaceWith")
|
||||
@Deprecated("KTIJ-25227: Necessary override for IDEs < 2023.2", level = DeprecationLevel.ERROR)
|
||||
override fun setupCompilerArgs(args: K2NativeCompilerArguments, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
|
||||
@@ -452,7 +462,7 @@ internal constructor(
|
||||
args.target = konanTarget.name
|
||||
args.produce = outputKind.name.toLowerCaseAsciiOnly()
|
||||
args.metadataKlib = sharedCompilationData != null
|
||||
args.nodefaultlibs = true
|
||||
args.nodefaultlibs = sharedCompilationData != null
|
||||
args.nostdlib = true
|
||||
args.manifestFile = sharedCompilationData?.manifestFile?.absolutePath
|
||||
args.nopack = produceUnpackedKlib.get()
|
||||
@@ -475,7 +485,9 @@ internal constructor(
|
||||
}
|
||||
|
||||
dependencyClasspath { args ->
|
||||
args.libraries = runSafe { libraries.files.filterKlibsPassedToCompiler().toPathsArray() }
|
||||
args.libraries = runSafe {
|
||||
libraries.exclude(excludeOriginalPlatformLibraries).files.filterKlibsPassedToCompiler().toPathsArray()
|
||||
}
|
||||
args.friendModules = runSafe {
|
||||
friendModule.files.takeIf { it.isNotEmpty() }?.map { it.absolutePath }?.joinToString(File.pathSeparator)
|
||||
}
|
||||
@@ -496,8 +508,8 @@ internal constructor(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val isMetadataCompilation: Boolean = when (compilation) {
|
||||
@get:Internal
|
||||
internal val isMetadataCompilation: Boolean = when (compilation) {
|
||||
is KotlinCompilationInfo.TCS -> compilation.compilation is KotlinMetadataCompilation<*>
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.utils
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.Directory
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.RegularFile
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.jetbrains.kotlin.gradle.plugin.internal.CustomPropertiesFileValueSource
|
||||
@@ -144,3 +145,8 @@ internal val Project.localProperties: Provider<Map<String, String>>
|
||||
)
|
||||
}
|
||||
.usedAtConfigurationTime(configurationTimePropertiesAccessor)
|
||||
|
||||
/**
|
||||
* Returns file collection [this] excluding files from [excludes] if not null
|
||||
*/
|
||||
internal fun FileCollection.exclude(excludes: FileCollection?): FileCollection = if (excludes != null) minus(excludes) else this
|
||||
+49
@@ -7,6 +7,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.unitTests.compilerArgumetns
|
||||
|
||||
import org.gradle.api.file.FileCollection
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments
|
||||
import org.jetbrains.kotlin.compilerRunner.ArgumentUtils
|
||||
import org.jetbrains.kotlin.gradle.dependencyResolutionTests.mavenCentralCacheRedirector
|
||||
@@ -15,6 +16,7 @@ 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.tasks.KotlinNativeLink
|
||||
import org.jetbrains.kotlin.gradle.util.buildProjectWithMPP
|
||||
import org.jetbrains.kotlin.gradle.util.main
|
||||
import java.io.File
|
||||
@@ -223,4 +225,51 @@ class KotlinNativeCompileArgumentsTest {
|
||||
|
||||
assertEquals(expectedDependencies, actualDependencies)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `native compile tasks SHOULD NOT have native platform dependencies but SHOULD have stdlib`() {
|
||||
val project = buildProjectWithMPP()
|
||||
project.repositories.mavenLocal()
|
||||
project.repositories.mavenCentralCacheRedirector()
|
||||
val kotlin = project.multiplatformExtension
|
||||
|
||||
kotlin.linuxX64().binaries.executable()
|
||||
kotlin.linuxArm64().binaries.executable()
|
||||
|
||||
project.evaluate()
|
||||
|
||||
val compileLinuxX64 = project.tasks.getByName("compileKotlinLinuxX64") as KotlinNativeCompile
|
||||
val compileLinuxArm64 = project.tasks.getByName("compileKotlinLinuxArm64") as KotlinNativeCompile
|
||||
val compileLinuxMainMetadata = project.tasks.getByName("compileLinuxMainKotlinMetadata") as KotlinNativeCompile
|
||||
|
||||
val linkLinuxX64 = project.tasks.getByName("linkDebugExecutableLinuxX64") as KotlinNativeLink
|
||||
val linkLinuxArm64 = project.tasks.getByName("linkDebugExecutableLinuxArm64") as KotlinNativeLink
|
||||
|
||||
fun FileCollection?.assertIsPlatformDependencies(target: String) {
|
||||
if (this == null) fail("Expected to have platform dependencies of target $target but got null")
|
||||
for (file in this) {
|
||||
if (!file.path.contains("platform${File.separator}$target")) fail("File $file is expected to be a platform dependency of $target")
|
||||
}
|
||||
}
|
||||
compileLinuxX64.excludeOriginalPlatformLibraries.assertIsPlatformDependencies("linux_x64")
|
||||
compileLinuxArm64.excludeOriginalPlatformLibraries.assertIsPlatformDependencies("linux_arm64")
|
||||
if (compileLinuxMainMetadata.excludeOriginalPlatformLibraries != null) fail(
|
||||
"Native metadata compilation should not exclude platform libraries because they are coming from commonizer. " +
|
||||
"And is not included by default by Kotlin/Native compiler like default platform libraries."
|
||||
)
|
||||
linkLinuxX64.excludeOriginalPlatformLibraries.assertIsPlatformDependencies("linux_x64")
|
||||
linkLinuxArm64.excludeOriginalPlatformLibraries.assertIsPlatformDependencies("linux_arm64")
|
||||
|
||||
fun Array<String>?.assertFilePathsDontContain(pathSubString: String) {
|
||||
if (this == null) return
|
||||
val badFiles = filter { it.contains(pathSubString) }
|
||||
if (badFiles.isEmpty()) return
|
||||
fail("Following files contain unexpected '$pathSubString' substring in their paths: \n${badFiles.joinToString("\n")}")
|
||||
}
|
||||
|
||||
compileLinuxX64.createCompilerArguments(default).libraries.assertFilePathsDontContain("linux_x64")
|
||||
compileLinuxArm64.createCompilerArguments(default).libraries.assertFilePathsDontContain("linux_arm64")
|
||||
linkLinuxX64.createCompilerArguments(default).libraries.assertFilePathsDontContain("linux_x64")
|
||||
linkLinuxArm64.createCompilerArguments(default).libraries.assertFilePathsDontContain("linux_arm64")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user