Skip to content

Commit

Permalink
Add hidden workaround for native dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
IgnatBeresnev committed Aug 31, 2023
1 parent 9d7c372 commit 4096e7d
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 1 deletion.
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-c
#### Gradle plugins ####
# The Maven coordinates of Gradle plugins that are either used in convention plugins, or in Dokka subprojects
gradlePlugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "gradlePlugin-kotlin" }
gradlePlugin-kotlin-klibCommonizerApi = { module = "org.jetbrains.kotlin:kotlin-klib-commonizer-api", version.ref = "gradlePlugin-kotlin" }
gradlePlugin-android = { module = "com.android.tools.build:gradle", version.ref = "gradlePlugin-android" }
gradlePlugin-dokka = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "gradlePlugin-dokka" }
gradlePlugin-shadow = { module = "gradle.plugin.com.github.johnrengelman:shadow", version.ref = "gradlePlugin-shadow" }
Expand Down
2 changes: 2 additions & 0 deletions runners/gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ dependencies {
api(projects.core)

compileOnly(libs.gradlePlugin.kotlin)
compileOnly(libs.gradlePlugin.kotlin.klibCommonizerApi)
compileOnly(libs.gradlePlugin.android)

testImplementation(libs.gradlePlugin.kotlin)
testImplementation(libs.gradlePlugin.kotlin.klibCommonizerApi)
testImplementation(libs.gradlePlugin.android)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@file:Suppress("INVISIBLE_REFERENCE")
package org.jetbrains.dokka.gradle.kotlin

import java.io.File
import org.gradle.api.Project
import org.jetbrains.kotlin.commonizer.KonanDistribution
import org.jetbrains.kotlin.commonizer.platformLibsDir
import org.jetbrains.kotlin.commonizer.stdlib
import org.jetbrains.kotlin.compilerRunner.konanHome
import org.jetbrains.kotlin.konan.target.KonanTarget

/**
* Provides access to the Kotlin/Native distribution components:
* * [stdlibDir] -- stdlib directory
* * [platformDependencies] -- list of directories to platform dependencies
*
* It uses Kotlin Gradle Plugin API that is guaranteed to be present in:
* 1.5 <= kotlinVersion <= 1.9
*
* It should not be used with Kotlin versions later than 1.9
*/
// https://github.com/Kotlin/dokka/pull/3147
internal class KotlinNativeDistributionAccessor(
project: Project
) {
private val konanDistribution = KonanDistribution(
@Suppress("INVISIBLE_MEMBER")
project.konanHome
)

val stdlibDir: File = konanDistribution.stdlib

fun platformDependencies(target: KonanTarget): List<File> = konanDistribution
.platformLibsDir
.resolve(target.name)
.listLibraryFiles()

private fun File.listLibraryFiles(): List<File> = listFiles().orEmpty()
.filter { it.isDirectory || it.extension == "klib" }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.mpp.AbstractKotlinNativeCompilation
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTool
import org.jetbrains.kotlin.gradle.utils.NativeCompilerDownloader
import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_COMMON_LIBS_DIR
import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_KLIB_DIR
import org.jetbrains.kotlin.konan.library.KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
import org.jetbrains.kotlin.konan.target.KonanTarget
import java.io.File

internal fun Project.classpathOf(sourceSet: KotlinSourceSet): FileCollection {
val compilations = compilationsOf(sourceSet)
Expand Down Expand Up @@ -78,13 +85,67 @@ private fun KotlinCompilation.getKotlinCompileTask(kgpVersion: KotlinGradlePlugi

private fun KotlinCompilation.platformDependencyFiles(project: Project): FileCollection {
val excludePlatformDependencyFiles = project.classpathProperty("excludePlatformDependencyFiles", default = false)

if (excludePlatformDependencyFiles) return project.files()

val useNativeDistributionAccessor = project.classpathProperty("useNativeDistributionAccessor", default = false)
if (useNativeDistributionAccessor) return this.getPlatformDependenciesFromNativeDistributionAccessor(project)

val useKonanDistribution = project.classpathProperty("useKonanDistribution", default = false)
if (useKonanDistribution) return this.getPlatfromDependenciesFromKonanDistribution(project)

return (this as? AbstractKotlinNativeCompilation)
?.target?.project?.configurations
?.findByName(@Suppress("DEPRECATION") this.defaultSourceSet.implementationMetadataConfigurationName) // KT-58640
?: project.files()
}

// https://github.com/Kotlin/dokka/pull/3147
private fun KotlinCompilation.getPlatformDependenciesFromNativeDistributionAccessor(project: Project): FileCollection {
return if (this is AbstractKotlinNativeCompilation) {
val result = project.objects.fileCollection()
val kotlinNativeDistributionAccessor = KotlinNativeDistributionAccessor(project)
result.from(kotlinNativeDistributionAccessor.stdlibDir)
result.from(kotlinNativeDistributionAccessor.platformDependencies(konanTarget))
result
} else {
project.files()
}
}

// -------- The hack for platform dependencies from compiler ------------------
// adapted from https://github.com/jetbrains/kotlin/blob/b6a215d681695a2fe0cc798308966c5675de447f/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/KotlinNativePlatformDependencies.kt#L39
// https://github.com/Kotlin/dokka/pull/3145
private fun KotlinCompilation.getPlatfromDependenciesFromKonanDistribution(project: Project): FileCollection {
return if (this is AbstractKotlinNativeCompilation)
project.files(project.getStdLibFromKonanDistribution()) + project.files(project.getPlatformLibsFromKonanDistribution(this.konanTarget))
else
project.files()
}

private fun Project.getStdLibFromKonanDistribution(): File {
val root = file(this.konanHome())
val konanCommonLibraries = root.resolve(KONAN_DISTRIBUTION_KLIB_DIR).resolve(KONAN_DISTRIBUTION_COMMON_LIBS_DIR)
val stdlib = konanCommonLibraries.resolve(KONAN_STDLIB_NAME)
return stdlib
}

// copy-pasted from https://github.com/jetbrains/kotlin/blob/c9aeadd31f763646237faffab38a57923c520fa1/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/nativeToolRunners.kt#L29
private fun Project.konanHome(): String {
return nativeHome()?.let { file(it).absolutePath }
?: NativeCompilerDownloader(project).compilerDirectory.absolutePath
}

private fun Project.nativeHome(): String? =
this.findProperty("org.jetbrains.kotlin.native.home") as? String

//copy-pasted from https://github.com/jetbrains/kotlin/blob/05a6d89151e6a7230faf733e51161b5f07ae10a7/native/commonizer/src/org/jetbrains/kotlin/commonizer/repository/KonanDistributionRepository.kt#L20
// https://github.com/jetbrains/kotlin/blob/b6a215d681695a2fe0cc798308966c5675de447f/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/internal/KotlinNativePlatformDependencies.kt#L83
private fun Project.getPlatformLibsFromKonanDistribution(target: KonanTarget): Array<out File>? {
val root = file(this.konanHome())
val platformLibsDir = root.resolve(KONAN_DISTRIBUTION_KLIB_DIR).resolve(KONAN_DISTRIBUTION_PLATFORM_LIBS_DIR)
val libs = platformLibsDir.resolve(target.name).takeIf { it.isDirectory }?.listFiles()
return libs
}

private fun Project.classpathProperty(name: String, default: Boolean): Boolean =
(findProperty("org.jetbrains.dokka.classpath.$name") as? String)?.toBoolean() ?: default

0 comments on commit 4096e7d

Please sign in to comment.