Support static and shared libraries for native in kotlin-mpp

This commit is contained in:
Ilya Matveev
2018-08-24 16:59:12 +07:00
committed by Ilya Matveev
parent 0a685d57c2
commit cfe7858229
4 changed files with 91 additions and 41 deletions
@@ -389,6 +389,9 @@ open class KotlinNativeTargetConfigurator(
""
}
private val KotlinNativeCompilation.isMainCompilation: Boolean
get() = name == KotlinCompilation.MAIN_COMPILATION_NAME
private fun Project.createTestTask(compilation: KotlinNativeCompilation, testExecutableLinkTask: KotlinNativeCompile) {
val compilationSuffix = compilation.name.takeIf { it != KotlinCompilation.TEST_COMPILATION_NAME }.orEmpty()
val taskName = lowerCamelCaseName(compilation.target.targetName, compilationSuffix, testTaskNameSuffix)
@@ -412,6 +415,58 @@ open class KotlinNativeTargetConfigurator(
}
}
private fun Project.binaryOutputDirectory(
buildType: NativeBuildType,
kind: NativeOutputKind,
compilation: KotlinNativeCompilation
): File {
val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
val buildTypeSubDirectory = buildType.name.toLowerCase()
val kindSubDirectory = kind.outputDirectoryName
return buildDir.resolve("bin/$targetSubDirectory${compilation.name}/$buildTypeSubDirectory/$kindSubDirectory")
}
private fun Project.klibOutputDirectory(
compilation: KotlinNativeCompilation
): File {
val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.name}")
}
private fun KotlinNativeCompile.registerOutputFiles(outputDirectory: File) {
val konanTarget = compilation.target.konanTarget
val prefix = outputKind.prefix(konanTarget)
val suffix = outputKind.suffix(konanTarget)
val baseName = if (compilation.isMainCompilation) project.name else compilation.name
outputFile.set(project.provider {
var filename = "$prefix$baseName$suffix"
if (outputKind == CompilerOutputKind.FRAMEWORK ||
outputKind == CompilerOutputKind.STATIC ||
outputKind == CompilerOutputKind.DYNAMIC) {
filename = filename.replace('-', '_')
}
outputDirectory.resolve(filename)
})
// Register outputs
if (outputKind == CompilerOutputKind.FRAMEWORK) {
outputs.dir(outputFile)
} else {
outputs.file(outputFile)
}
if (outputKind == CompilerOutputKind.STATIC || outputKind == CompilerOutputKind.DYNAMIC) {
outputs.file(project.provider {
val apiFileName = "$prefix${baseName}_api.h".replace('-', '_')
outputDirectory.resolve(apiFileName)
})
}
}
private fun Project.createBinaryLinkTasks(compilation: KotlinNativeCompilation) = whenEvaluated {
val konanTarget = compilation.target.konanTarget
val buildTypes = compilation.buildTypes
@@ -442,25 +497,7 @@ open class KotlinNativeTargetConfigurator(
optimized = buildType.optimized
debuggable = buildType.debuggable
if (outputKind == CompilerOutputKind.FRAMEWORK) {
outputs.dir(outputFile)
} else {
outputs.file(outputFile)
}
outputFile.set(provider {
val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
val buildTypeSubDirectory = buildType.name.toLowerCase()
val compilationName = compilation.compilationName
val prefix = compilerOutputKind.prefix(konanTarget)
val suffix = compilerOutputKind.suffix(konanTarget)
var filename = "$prefix$compilationName$suffix"
if (outputKind == CompilerOutputKind.FRAMEWORK) {
filename = filename.replace('-', '_')
}
File(project.buildDir, "bin/$targetSubDirectory$compilationName/$buildTypeSubDirectory/$filename")
})
registerOutputFiles(binaryOutputDirectory(buildType, kind, compilation))
dependsOnCompilerDownloading()
linkAll.dependsOn(this)
}
@@ -511,17 +548,7 @@ open class KotlinNativeTargetConfigurator(
"compilation for target '${compilation.platformType.name}'"
enabled = compilation.target.konanTarget.enabledOnCurrentHost
outputs.file(outputFile)
outputFile.set(provider {
val targetSubDirectory = compilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
val compilationName = compilation.compilationName
val klibName = if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME)
project.name
else
compilationName
File(project.buildDir, "classes/kotlin/$targetSubDirectory$compilationName/$klibName.klib")
})
registerOutputFiles(klibOutputDirectory(compilation))
dependsOnCompilerDownloading()
compilation.output.tryAddClassesDir {
project.files(this.outputFile).builtBy(this)
@@ -21,18 +21,40 @@ enum class NativeBuildType(val optimized: Boolean, val debuggable: Boolean): Nam
enum class NativeOutputKind(
val compilerOutputKind: CompilerOutputKind,
val taskNameClassifier: String,
val outputDirectoryName: String = taskNameClassifier,
val description: String = taskNameClassifier,
val additionalCompilerFlags: List<String> = emptyList(),
val runtimeUsageName: String? = null,
val linkUsageName: String? = null,
val publishable: Boolean = true
val publishable: Boolean = true // Not used yet.
) {
EXECUTABLE(
CompilerOutputKind.PROGRAM,
"executable",
description = "an executable",
runtimeUsageName = Usage.NATIVE_RUNTIME
runtimeUsageName = Usage.NATIVE_RUNTIME,
publishable = false
),
DYNAMIC(
CompilerOutputKind.DYNAMIC,
"shared",
description = "a dynamic library",
runtimeUsageName = Usage.NATIVE_RUNTIME,
linkUsageName = Usage.NATIVE_LINK,
publishable = false
) {
override fun availableFor(target: KonanTarget) = target != KonanTarget.WASM32
},
STATIC(
CompilerOutputKind.STATIC,
"static",
description = "a static library",
runtimeUsageName = Usage.NATIVE_RUNTIME,
linkUsageName = Usage.NATIVE_LINK,
publishable = false
) {
override fun availableFor(target: KonanTarget) = target != KonanTarget.WASM32
},
FRAMEWORK(
CompilerOutputKind.FRAMEWORK,
"framework",
@@ -309,15 +309,6 @@ class KotlinNativeCompilation(
allSources += sourceSet.kotlin
}
// TODO: Can we do it better?
companion object {
val DEBUG = NativeBuildType.DEBUG
val RELEASE = NativeBuildType.RELEASE
val EXECUTABLE = NativeOutputKind.EXECUTABLE
val FRAMEWORK = NativeOutputKind.FRAMEWORK
}
}
private object CompilationSourceSetUtil {
@@ -150,6 +150,16 @@ class KotlinNativeTarget(
"org.jetbrains.kotlin.native.target",
String::class.java
)
// TODO: Can we do it better?
// User-visible constants
val DEBUG = NativeBuildType.DEBUG
val RELEASE = NativeBuildType.RELEASE
val EXECUTABLE = NativeOutputKind.EXECUTABLE
val FRAMEWORK = NativeOutputKind.FRAMEWORK
val DYNAMIC = NativeOutputKind.DYNAMIC
val STATIC = NativeOutputKind.STATIC
}
}