Gradle, native: Produce binaries from klibs and bump K/N version
Earlier all native binaries were produced directly from sources of corresponding compilations. This patch changes this behavior. Now a klibrary produced by a compilation is used to build a final binary instead of sources. This allows us to avoid parsing the same sources several times and reduces build time. This patch also updates K/N version to 1.3.60-dev-11975, to get the corresponding support from the compiler side. Issue #KT-33076 Fixed
This commit is contained in:
+1
-1
@@ -169,7 +169,7 @@ extra["versions.trove4j"] = "1.0.20181211"
|
||||
extra["versions.ktor-network"] = "1.0.1"
|
||||
|
||||
if (!project.hasProperty("versions.kotlin-native")) {
|
||||
extra["versions.kotlin-native"] = "1.3.50-dev-11052"
|
||||
extra["versions.kotlin-native"] = "1.3.60-dev-11975"
|
||||
}
|
||||
|
||||
val isTeamcityBuild = project.kotlinBuildProperties.isTeamcityBuild
|
||||
|
||||
+38
-14
@@ -911,7 +911,6 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
|
||||
// Remove outputs and check that they are rebuilt.
|
||||
assertTrue(projectDir.resolve(headerPaths[0]).delete())
|
||||
assertTrue(projectDir.resolve(klibPath).delete())
|
||||
if (HostManager.hostIsMac) {
|
||||
assertTrue(projectDir.resolve(frameworkPaths[0]).deleteRecursively())
|
||||
}
|
||||
@@ -919,8 +918,8 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
build("assemble") {
|
||||
assertSuccessful()
|
||||
assertTasksUpToDate(linkTasks.drop(1))
|
||||
assertTasksUpToDate(klibTask)
|
||||
assertTasksExecuted(linkTasks[0])
|
||||
assertTasksExecuted(klibTask)
|
||||
|
||||
if (HostManager.hostIsMac) {
|
||||
assertTasksUpToDate(frameworkTasks.drop(1))
|
||||
@@ -939,6 +938,16 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
projectName: String,
|
||||
gradleVersionRequired: GradleVersionRequired = gradleVersion
|
||||
) = with(transformProjectWithPluginsDsl(projectName, gradleVersionRequired, "new-mpp-native-binaries")) {
|
||||
|
||||
fun CompiledProject.checkCommandLineFor(vararg taskPaths: String, check: (String) -> Unit) = taskPaths.forEach { taskPath ->
|
||||
val commandLine = output.lineSequence().dropWhile {
|
||||
!it.contains("Executing actions for task '$taskPath'")
|
||||
}.first {
|
||||
it.contains("Run tool: konanc")
|
||||
}
|
||||
check(commandLine)
|
||||
}
|
||||
|
||||
val hostSuffix = nativeHostTargetName.capitalize()
|
||||
val binaries = mutableListOf(
|
||||
"debugExecutable" to "native-binary",
|
||||
@@ -973,10 +982,14 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
|
||||
val binariesTasks = arrayOf("${nativeHostTargetName}MainBinaries", "${nativeHostTargetName}TestBinaries")
|
||||
|
||||
val compileTask = "compileKotlin$hostSuffix"
|
||||
val compileTestTask = "compileTestKotlin$hostSuffix"
|
||||
|
||||
// Check that all link and run tasks are generated.
|
||||
build(*binariesTasks) {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(linkTasks.map { ":$it" })
|
||||
assertTasksExecuted(":$compileTask", ":$compileTestTask")
|
||||
outputFiles.forEach {
|
||||
assertFileExists(it)
|
||||
}
|
||||
@@ -997,6 +1010,14 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
// Check that kotlinOptions work fine for a compilation.
|
||||
build(compileTask) {
|
||||
assertSuccessful()
|
||||
checkCommandLineFor(":$compileTask") {
|
||||
assertTrue(it.contains("-verbose"))
|
||||
}
|
||||
}
|
||||
|
||||
// Check that run tasks work fine and an entry point can be specified.
|
||||
build("runDebugExecutable$hostSuffix") {
|
||||
assertSuccessful()
|
||||
@@ -1010,6 +1031,13 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
|
||||
build("runTest2ReleaseExecutable$hostSuffix") {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(":$compileTestTask")
|
||||
checkCommandLineFor(":linkTest2ReleaseExecutable$hostSuffix") {
|
||||
assertTrue(it.contains("-tr"))
|
||||
assertTrue(it.contains("-Xtime"))
|
||||
// Check that kotlinOptions of the compilation don't affect the binary.
|
||||
assertFalse(it.contains("-verbose"))
|
||||
}
|
||||
assertTrue(output.contains("tests.foo"))
|
||||
}
|
||||
|
||||
@@ -1019,13 +1047,6 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
assertTrue(output.contains("tests.foo"))
|
||||
}
|
||||
|
||||
fun CompiledProject.checkFrameworkCompilationCommandLine(check: (String) -> Unit) {
|
||||
output.lineSequence().filter {
|
||||
it.contains("Run tool: konanc") && it.contains("-p framework")
|
||||
}.toList().also {
|
||||
assertTrue(it.isNotEmpty())
|
||||
}.forEach(check)
|
||||
}
|
||||
if (HostManager.hostIsMac) {
|
||||
|
||||
// Check dependency exporting and bitcode embedding in frameworks.
|
||||
@@ -1036,7 +1057,7 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
fileInWorkingDir("build/bin/ios/releaseFramework/native_binary.framework/Headers/native_binary.h")
|
||||
.readText().contains("+ (int32_t)exported")
|
||||
// Check that by default release frameworks have bitcode embedded.
|
||||
checkFrameworkCompilationCommandLine {
|
||||
checkCommandLineFor(":linkReleaseFrameworkIos") {
|
||||
assertTrue(it.contains("-Xembed-bitcode"))
|
||||
assertTrue(it.contains("-opt"))
|
||||
}
|
||||
@@ -1049,7 +1070,7 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
fileInWorkingDir("build/bin/ios/debugFramework/native_binary.framework/Headers/native_binary.h")
|
||||
.readText().contains("+ (int32_t)exported")
|
||||
// Check that by default debug frameworks have bitcode marker embedded.
|
||||
checkFrameworkCompilationCommandLine {
|
||||
checkCommandLineFor(":linkDebugFrameworkIos") {
|
||||
assertTrue(it.contains("-Xembed-bitcode-marker"))
|
||||
assertTrue(it.contains("-g"))
|
||||
}
|
||||
@@ -1058,7 +1079,7 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
// Check manual disabling bitcode embedding, custom command line args and building a static framework.
|
||||
build("linkCustomReleaseFrameworkIos") {
|
||||
assertSuccessful()
|
||||
checkFrameworkCompilationCommandLine {
|
||||
checkCommandLineFor(":linkCustomReleaseFrameworkIos") {
|
||||
assertTrue(it.contains("-linker-option -L."))
|
||||
assertTrue(it.contains("-Xtime"))
|
||||
assertTrue(it.contains("-Xstatic-framework"))
|
||||
@@ -1072,18 +1093,21 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
assertSuccessful()
|
||||
assertFileExists("build/bin/iosSim/releaseFramework/native_binary.framework")
|
||||
assertFileExists("build/bin/iosSim/debugFramework/native_binary.framework")
|
||||
checkFrameworkCompilationCommandLine {
|
||||
checkCommandLineFor(":linkReleaseFrameworkIosSim", ":linkDebugFrameworkIosSim") {
|
||||
assertFalse(it.contains("-Xembed-bitcode"))
|
||||
assertFalse(it.contains("-Xembed-bitcode-marker"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check that plugin doesn't allow exporting dependencies not added in the API configuration.
|
||||
val buildFile = listOf("build.gradle", "build.gradle.kts").map { projectDir.resolve(it) }.single { it.exists() }
|
||||
buildFile.modify {
|
||||
it.replace("api(project(\":exported\"))", "")
|
||||
}
|
||||
projectDir.resolve("src/commonMain/kotlin/PackageMain.kt").modify {
|
||||
// Remove usages of the ":exported" dependency to be able to compile the sources.
|
||||
it.replace("import com.example.exported", "").replace("val exp = exported()", "val exp = 42")
|
||||
}
|
||||
build("linkReleaseFrameworkIos") {
|
||||
assertFailed()
|
||||
val failureMsg = "Following dependencies exported in the releaseFramework binary " +
|
||||
|
||||
+4
@@ -37,6 +37,7 @@ kotlin {
|
||||
mingwX64("mingw64")
|
||||
|
||||
configure([macos64, linux64, mingw64]) {
|
||||
compilations.main.kotlinOptions.verbose = true
|
||||
binaries {
|
||||
|
||||
executable() // Executable with default name.
|
||||
@@ -54,6 +55,9 @@ kotlin {
|
||||
executable("test2", [RELEASE]) {
|
||||
compilation = compilations["test"]
|
||||
freeCompilerArgs.add("-tr")
|
||||
linkTask.kotlinOptions {
|
||||
freeCompilerArgs += "-Xtime"
|
||||
}
|
||||
}
|
||||
|
||||
sharedLib([RELEASE])
|
||||
|
||||
+4
-1
@@ -27,7 +27,7 @@ kotlin {
|
||||
val windows = mingwX64("mingw64")
|
||||
|
||||
configure(listOf(macos, linux, windows)) {
|
||||
|
||||
compilations["main"].kotlinOptions.verbose = true
|
||||
binaries {
|
||||
|
||||
executable() // Executable with default name.
|
||||
@@ -45,6 +45,9 @@ kotlin {
|
||||
executable("test2") {
|
||||
compilation = compilations["test"]
|
||||
freeCompilerArgs.add("-tr")
|
||||
linkTask.kotlinOptions {
|
||||
freeCompilerArgs += "-Xtime"
|
||||
}
|
||||
}
|
||||
|
||||
sharedLib(listOf(RELEASE))
|
||||
|
||||
+2
-2
@@ -70,7 +70,7 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder {
|
||||
val pluginOptionsTask = compilerPluginOptionsTask.value ?: return null
|
||||
return when (pluginOptionsTask) {
|
||||
is AbstractKotlinCompile<*> -> pluginOptionsTask.pluginOptions
|
||||
is AbstractKotlinNativeCompile -> pluginOptionsTask.compilerPluginOptions
|
||||
is AbstractKotlinNativeCompile<*> -> pluginOptionsTask.compilerPluginOptions
|
||||
else -> error("Unexpected task: $pluginOptionsTask")
|
||||
}.arguments
|
||||
}
|
||||
@@ -80,7 +80,7 @@ internal class DefaultLanguageSettingsBuilder : LanguageSettingsBuilder {
|
||||
val pluginClasspathTask = compilerPluginOptionsTask.value ?: return null
|
||||
return when (pluginClasspathTask) {
|
||||
is AbstractKotlinCompile<*> -> pluginClasspathTask.pluginClasspath
|
||||
is AbstractKotlinNativeCompile -> pluginClasspathTask.compilerPluginClasspath ?: pluginClasspathTask.project.files()
|
||||
is AbstractKotlinNativeCompile<*> -> pluginClasspathTask.compilerPluginClasspath ?: pluginClasspathTask.project.files()
|
||||
else -> error("Unexpected task: $pluginClasspathTask")
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ open class KotlinNativeTargetConfigurator(
|
||||
return buildDir.resolve("classes/kotlin/$targetSubDirectory${compilation.name}")
|
||||
}
|
||||
|
||||
private fun AbstractKotlinNativeCompile.addCompilerPlugins() {
|
||||
private fun AbstractKotlinNativeCompile<*>.addCompilerPlugins() {
|
||||
SubpluginEnvironment
|
||||
.loadSubplugins(project, kotlinPluginVersion)
|
||||
.addSubpluginOptions(project, this, compilerPluginOptions)
|
||||
|
||||
+5
-1
@@ -58,7 +58,11 @@ sealed class NativeBinary(
|
||||
}
|
||||
|
||||
/** Additional arguments passed to the Kotlin/Native compiler. */
|
||||
var freeCompilerArgs: MutableList<String> = mutableListOf()
|
||||
var freeCompilerArgs: List<String>
|
||||
get() = linkTask.kotlinOptions.freeCompilerArgs
|
||||
set(value) {
|
||||
linkTask.kotlinOptions.freeCompilerArgs = value
|
||||
}
|
||||
|
||||
// Link task access.
|
||||
val linkTaskName: String
|
||||
|
||||
+175
-122
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.compilerRunner.KonanInteropRunner
|
||||
import org.jetbrains.kotlin.compilerRunner.konanHome
|
||||
import org.jetbrains.kotlin.compilerRunner.konanVersion
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonToolOptions
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
||||
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
|
||||
@@ -85,7 +86,7 @@ private fun Collection<File>.filterExternalKlibs(project: Project) = filter {
|
||||
}
|
||||
|
||||
// endregion
|
||||
abstract class AbstractKotlinNativeCompile : AbstractCompile(), KotlinCompile<KotlinCommonOptions> {
|
||||
abstract class AbstractKotlinNativeCompile<T : KotlinCommonToolOptions> : AbstractCompile() {
|
||||
|
||||
init {
|
||||
sourceCompatibility = "1.6"
|
||||
@@ -109,20 +110,9 @@ abstract class AbstractKotlinNativeCompile : AbstractCompile(), KotlinCompile<Ko
|
||||
abstract val baseName: String
|
||||
|
||||
// Inputs and outputs
|
||||
@InputFiles
|
||||
@SkipWhenEmpty
|
||||
override fun getSource(): FileTree = project.files(compilation.allSources).asFileTree
|
||||
|
||||
private val commonSources: FileCollection
|
||||
// Already taken into account in getSources method.
|
||||
get() = project.files(compilation.commonSources).asFileTree
|
||||
|
||||
val libraries: FileCollection
|
||||
@InputFiles get() = compilation.compileDependencyFiles.filterOutPublishableInteropLibs(project)
|
||||
|
||||
private val friendModule: FileCollection?
|
||||
get() = compilation.friendCompilation?.output?.allOutputs
|
||||
|
||||
override fun getClasspath(): FileCollection = libraries
|
||||
override fun setClasspath(configuration: FileCollection?) {
|
||||
throw UnsupportedOperationException("Setting classpath directly is unsupported.")
|
||||
@@ -134,60 +124,11 @@ abstract class AbstractKotlinNativeCompile : AbstractCompile(), KotlinCompile<Ko
|
||||
val additionalCompilerOptions: Collection<String>
|
||||
@Input get() = kotlinOptions.freeCompilerArgs
|
||||
|
||||
// region Language settings imported from a SourceSet.
|
||||
val languageSettings: LanguageSettingsBuilder?
|
||||
@Internal get() = project.kotlinExtension.sourceSets.findByName(compilation.defaultSourceSetName)?.languageSettings
|
||||
|
||||
val languageVersion: String?
|
||||
@Optional @Input get() = languageSettings?.languageVersion
|
||||
|
||||
val apiVersion: String?
|
||||
@Optional @Input get() = languageSettings?.apiVersion
|
||||
|
||||
val progressiveMode: Boolean
|
||||
@Input get() = languageSettings?.progressiveMode ?: false
|
||||
|
||||
val enabledLanguageFeatures: Set<String>
|
||||
@Input get() = languageSettings?.enabledLanguageFeatures ?: emptySet()
|
||||
|
||||
val experimentalAnnotationsInUse: Set<String>
|
||||
@Input get() = languageSettings?.experimentalAnnotationsInUse.orEmpty()
|
||||
// endregion.
|
||||
|
||||
// region DSL for compiler options
|
||||
private inner class NativeCompilerOpts : KotlinCommonOptions {
|
||||
override var apiVersion: String?
|
||||
get() = languageSettings?.apiVersion
|
||||
set(value) { languageSettings!!.apiVersion = value }
|
||||
|
||||
override var languageVersion: String?
|
||||
get() = this@AbstractKotlinNativeCompile.languageVersion
|
||||
set(value) { languageSettings!!.languageVersion = value }
|
||||
|
||||
override var allWarningsAsErrors: Boolean = false
|
||||
override var suppressWarnings: Boolean = false
|
||||
override var verbose: Boolean = false
|
||||
|
||||
// TODO: Drop extraOpts in 1.3.70 and create a list here directly
|
||||
// Delegate for compilations's extra options.
|
||||
override var freeCompilerArgs: List<String>
|
||||
get() = compilation.extraOptsNoWarn
|
||||
set(value) {
|
||||
compilation.extraOptsNoWarn = value.toMutableList()
|
||||
}
|
||||
}
|
||||
|
||||
@Internal
|
||||
override val kotlinOptions: KotlinCommonOptions = NativeCompilerOpts()
|
||||
|
||||
override fun kotlinOptions(fn: KotlinCommonOptions.() -> Unit) {
|
||||
kotlinOptions.fn()
|
||||
}
|
||||
|
||||
override fun kotlinOptions(fn: Closure<*>) {
|
||||
fn.delegate = kotlinOptions
|
||||
fn.call()
|
||||
}
|
||||
@get:Internal
|
||||
abstract val kotlinOptions: T
|
||||
abstract fun kotlinOptions(fn: T.() -> Unit)
|
||||
abstract fun kotlinOptions(fn: Closure<*>)
|
||||
|
||||
// endregion.
|
||||
|
||||
@@ -225,27 +166,18 @@ abstract class AbstractKotlinNativeCompile : AbstractCompile(), KotlinCompile<Ko
|
||||
@InputFiles
|
||||
var compilerPluginClasspath: FileCollection? = null
|
||||
|
||||
// Used by IDE via reflection.
|
||||
val serializedCompilerArguments: List<String>
|
||||
@Internal get() = buildCommonArgs()
|
||||
|
||||
// Used by IDE via reflection.
|
||||
val defaultSerializedCompilerArguments: List<String>
|
||||
@Internal get() = buildCommonArgs(true)
|
||||
|
||||
private fun buildCommonArgs(defaultsOnly: Boolean = false): List<String> = mutableListOf<String>().apply {
|
||||
|
||||
// Args used by both the compiler and IDEA.
|
||||
protected open fun buildCommonArgs(defaultsOnly: Boolean = false): List<String> = mutableListOf<String>().apply {
|
||||
add("-Xmulti-platform")
|
||||
|
||||
// Language features.
|
||||
addArgIfNotNull("-language-version", languageVersion)
|
||||
addArgIfNotNull("-api-version", apiVersion)
|
||||
addKey("-progressive", progressiveMode)
|
||||
enabledLanguageFeatures.forEach { featureName ->
|
||||
add("-XXLanguage:+$featureName")
|
||||
}
|
||||
experimentalAnnotationsInUse.forEach { annotationName ->
|
||||
add("-Xuse-experimental=$annotationName")
|
||||
}
|
||||
|
||||
// Compiler plugins.
|
||||
compilerPluginClasspath?.let { pluginClasspath ->
|
||||
pluginClasspath.map { it.canonicalPath }.sorted().forEach { path ->
|
||||
@@ -267,7 +199,8 @@ abstract class AbstractKotlinNativeCompile : AbstractCompile(), KotlinCompile<Ko
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun buildArgs(defaultsOnly: Boolean = false): List<String> = mutableListOf<String>().apply {
|
||||
// Args passed to the compiler only (except sources).
|
||||
protected open fun buildCompilerArgs(): List<String> = mutableListOf<String>().apply {
|
||||
addKey("-opt", optimized)
|
||||
addKey("-g", debuggable)
|
||||
addKey("-ea", debuggable)
|
||||
@@ -275,29 +208,21 @@ abstract class AbstractKotlinNativeCompile : AbstractCompile(), KotlinCompile<Ko
|
||||
addArg("-target", target)
|
||||
addArg("-p", outputKind.name.toLowerCase())
|
||||
|
||||
if (!defaultsOnly) {
|
||||
addArg("-o", outputFile.get().absolutePath)
|
||||
addArg("-o", outputFile.get().absolutePath)
|
||||
|
||||
// Libraries.
|
||||
libraries.files.filterExternalKlibs(project).forEach { library ->
|
||||
addArg("-l", library.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
val friends = friendModule?.files
|
||||
if (friends != null && friends.isNotEmpty()) {
|
||||
addArg("-friend-modules", friends.map { it.absolutePath }.joinToString(File.pathSeparator))
|
||||
}
|
||||
|
||||
addAll(buildCommonArgs(defaultsOnly))
|
||||
|
||||
// Sources.
|
||||
addAll(getSource().map { it.absolutePath })
|
||||
if (!commonSources.isEmpty) {
|
||||
add("-Xcommon-sources=${commonSources.map { it.absolutePath }.joinToString(separator = ",")}")
|
||||
// Libraries.
|
||||
libraries.files.filterExternalKlibs(project).forEach { library ->
|
||||
addArg("-l", library.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
// Sources passed to the compiler.
|
||||
// We add sources after all other arguments to make the command line more readable and simplify debugging.
|
||||
protected abstract fun buildSourceArgs(): List<String>
|
||||
|
||||
private fun buildArgs(): List<String> =
|
||||
buildCompilerArgs() + buildCommonArgs() + buildSourceArgs()
|
||||
|
||||
@TaskAction
|
||||
override fun compile() {
|
||||
val output = outputFile.get()
|
||||
@@ -309,7 +234,7 @@ abstract class AbstractKotlinNativeCompile : AbstractCompile(), KotlinCompile<Ko
|
||||
/**
|
||||
* A task producing a klibrary from a compilation.
|
||||
*/
|
||||
open class KotlinNativeCompile : AbstractKotlinNativeCompile() {
|
||||
open class KotlinNativeCompile : AbstractKotlinNativeCompile<KotlinCommonOptions>(), KotlinCompile<KotlinCommonOptions> {
|
||||
@Internal
|
||||
override lateinit var compilation: KotlinNativeCompilation
|
||||
|
||||
@@ -325,12 +250,119 @@ open class KotlinNativeCompile : AbstractKotlinNativeCompile() {
|
||||
@get:Internal
|
||||
override val baseName: String
|
||||
get() = if (compilation.isMainCompilation) project.name else compilation.name
|
||||
|
||||
// Inputs and outputs.
|
||||
// region Sources.
|
||||
@InputFiles
|
||||
@SkipWhenEmpty
|
||||
override fun getSource(): FileTree = project.files(compilation.allSources).asFileTree
|
||||
|
||||
private val commonSources: FileCollection
|
||||
// Already taken into account in getSources method.
|
||||
get() = project.files(compilation.commonSources).asFileTree
|
||||
|
||||
private val friendModule: FileCollection?
|
||||
get() = compilation.friendCompilation?.output?.allOutputs
|
||||
// endregion.
|
||||
|
||||
// region Language settings imported from a SourceSet.
|
||||
val languageSettings: LanguageSettingsBuilder?
|
||||
@Internal get() = project.kotlinExtension.sourceSets.findByName(compilation.defaultSourceSetName)?.languageSettings
|
||||
|
||||
val languageVersion: String?
|
||||
@Optional @Input get() = languageSettings?.languageVersion
|
||||
|
||||
val apiVersion: String?
|
||||
@Optional @Input get() = languageSettings?.apiVersion
|
||||
|
||||
val progressiveMode: Boolean
|
||||
@Input get() = languageSettings?.progressiveMode ?: false
|
||||
|
||||
val enabledLanguageFeatures: Set<String>
|
||||
@Input get() = languageSettings?.enabledLanguageFeatures ?: emptySet()
|
||||
|
||||
val experimentalAnnotationsInUse: Set<String>
|
||||
@Input get() = languageSettings?.experimentalAnnotationsInUse.orEmpty()
|
||||
// endregion.
|
||||
|
||||
// region Kotlin options.
|
||||
private inner class NativeCompileOptions : KotlinCommonOptions {
|
||||
override var apiVersion: String?
|
||||
get() = languageSettings?.apiVersion
|
||||
set(value) { languageSettings!!.apiVersion = value }
|
||||
|
||||
override var languageVersion: String?
|
||||
get() = this@KotlinNativeCompile.languageVersion
|
||||
set(value) { languageSettings!!.languageVersion = value }
|
||||
|
||||
override var allWarningsAsErrors: Boolean = false
|
||||
override var suppressWarnings: Boolean = false
|
||||
override var verbose: Boolean = false
|
||||
|
||||
// TODO: Drop extraOpts in 1.3.70 and create a list here directly
|
||||
// Delegate for compilations's extra options.
|
||||
override var freeCompilerArgs: List<String>
|
||||
get() = compilation.extraOptsNoWarn
|
||||
set(value) {
|
||||
compilation.extraOptsNoWarn = value.toMutableList()
|
||||
}
|
||||
}
|
||||
|
||||
override val kotlinOptions: KotlinCommonOptions = NativeCompileOptions()
|
||||
|
||||
override fun kotlinOptions(fn: KotlinCommonOptions.() -> Unit) {
|
||||
kotlinOptions.fn()
|
||||
}
|
||||
|
||||
override fun kotlinOptions(fn: Closure<*>) {
|
||||
fn.delegate = kotlinOptions
|
||||
fn.call()
|
||||
}
|
||||
// endregion.
|
||||
|
||||
// region Building args.
|
||||
override fun buildCommonArgs(defaultsOnly: Boolean): List<String> = mutableListOf<String>().apply {
|
||||
addAll(super.buildCommonArgs(defaultsOnly))
|
||||
|
||||
// Language features.
|
||||
addArgIfNotNull("-language-version", languageVersion)
|
||||
addArgIfNotNull("-api-version", apiVersion)
|
||||
addKey("-progressive", progressiveMode)
|
||||
enabledLanguageFeatures.forEach { featureName ->
|
||||
add("-XXLanguage:+$featureName")
|
||||
}
|
||||
experimentalAnnotationsInUse.forEach { annotationName ->
|
||||
add("-Xuse-experimental=$annotationName")
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildCompilerArgs(): List<String> = mutableListOf<String>().apply {
|
||||
addAll(super.buildCompilerArgs())
|
||||
|
||||
val friends = friendModule?.files
|
||||
if (friends != null && friends.isNotEmpty()) {
|
||||
addArg("-friend-modules", friends.map { it.absolutePath }.joinToString(File.pathSeparator))
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildSourceArgs(): List<String> = mutableListOf<String>().apply {
|
||||
addAll(getSource().map { it.absolutePath })
|
||||
if (!commonSources.isEmpty) {
|
||||
add("-Xcommon-sources=${commonSources.map { it.absolutePath }.joinToString(separator = ",")}")
|
||||
}
|
||||
}
|
||||
// endregion.
|
||||
}
|
||||
|
||||
/**
|
||||
* A task producing a final binary from a compilation.
|
||||
*/
|
||||
open class KotlinNativeLink : AbstractKotlinNativeCompile() {
|
||||
open class KotlinNativeLink : AbstractKotlinNativeCompile<KotlinCommonToolOptions>() {
|
||||
|
||||
init {
|
||||
dependsOn(project.provider { compilation.compileKotlinTask })
|
||||
}
|
||||
|
||||
@Internal
|
||||
lateinit var binary: NativeBinary
|
||||
|
||||
@@ -338,6 +370,13 @@ open class KotlinNativeLink : AbstractKotlinNativeCompile() {
|
||||
override val compilation: KotlinNativeCompilation
|
||||
get() = binary.compilation
|
||||
|
||||
@InputFile
|
||||
val intermediateLibrary: Provider<File> = project.provider {
|
||||
compilation.compileKotlinTask.outputFile.get()
|
||||
}
|
||||
|
||||
override fun getSource(): FileTree = project.files(intermediateLibrary.get()).asFileTree
|
||||
|
||||
@get:Input
|
||||
override val outputKind: CompilerOutputKind
|
||||
get() = binary.outputKind.compilerOutputKind
|
||||
@@ -354,6 +393,25 @@ open class KotlinNativeLink : AbstractKotlinNativeCompile() {
|
||||
override val baseName: String
|
||||
get() = binary.baseName
|
||||
|
||||
inner class NativeLinkOptions: KotlinCommonToolOptions {
|
||||
override var allWarningsAsErrors: Boolean = false
|
||||
override var suppressWarnings: Boolean = false
|
||||
override var verbose: Boolean = false
|
||||
override var freeCompilerArgs: List<String> = listOf()
|
||||
}
|
||||
|
||||
override val kotlinOptions: KotlinCommonToolOptions = NativeLinkOptions()
|
||||
|
||||
override fun kotlinOptions(fn: KotlinCommonToolOptions.() -> Unit) {
|
||||
kotlinOptions.fn()
|
||||
}
|
||||
|
||||
override fun kotlinOptions(fn: Closure<*>) {
|
||||
fn.delegate = kotlinOptions
|
||||
fn.call()
|
||||
}
|
||||
|
||||
// Binary-specific options.
|
||||
@get:Optional
|
||||
@get:Input
|
||||
val entryPoint: String?
|
||||
@@ -385,32 +443,27 @@ open class KotlinNativeLink : AbstractKotlinNativeCompile() {
|
||||
val embedBitcode: Framework.BitcodeEmbeddingMode
|
||||
get() = (binary as? Framework)?.embedBitcode ?: Framework.BitcodeEmbeddingMode.DISABLE
|
||||
|
||||
@get:Input
|
||||
val freeCompilerArgs: List<String>
|
||||
get() = binary.freeCompilerArgs
|
||||
override fun buildCompilerArgs(): List<String> = mutableListOf<String>().apply {
|
||||
addAll(super.buildCompilerArgs())
|
||||
|
||||
override fun buildArgs(defaultsOnly: Boolean): List<String> {
|
||||
val superArgs = super.buildArgs(defaultsOnly)
|
||||
return mutableListOf<String>().apply {
|
||||
addAll(superArgs)
|
||||
addKey("-tr", processTests)
|
||||
addArgIfNotNull("-entry", entryPoint)
|
||||
when (embedBitcode) {
|
||||
Framework.BitcodeEmbeddingMode.MARKER -> add("-Xembed-bitcode-marker")
|
||||
Framework.BitcodeEmbeddingMode.BITCODE -> add("-Xembed-bitcode")
|
||||
else -> { /* Do nothing. */ }
|
||||
}
|
||||
linkerOpts.forEach {
|
||||
addArg("-linker-option", it)
|
||||
}
|
||||
exportLibraries.files.filterExternalKlibs(project).forEach {
|
||||
add("-Xexport-library=${it.absolutePath}")
|
||||
}
|
||||
addKey("-Xstatic-framework", isStaticFramework)
|
||||
addAll(freeCompilerArgs)
|
||||
addKey("-tr", processTests)
|
||||
addArgIfNotNull("-entry", entryPoint)
|
||||
when (embedBitcode) {
|
||||
Framework.BitcodeEmbeddingMode.MARKER -> add("-Xembed-bitcode-marker")
|
||||
Framework.BitcodeEmbeddingMode.BITCODE -> add("-Xembed-bitcode")
|
||||
else -> { /* Do nothing. */ }
|
||||
}
|
||||
linkerOpts.forEach {
|
||||
addArg("-linker-option", it)
|
||||
}
|
||||
exportLibraries.files.filterExternalKlibs(project).forEach {
|
||||
add("-Xexport-library=${it.absolutePath}")
|
||||
}
|
||||
addKey("-Xstatic-framework", isStaticFramework)
|
||||
}
|
||||
|
||||
override fun buildSourceArgs(): List<String> = listOf("-Xinclude=${intermediateLibrary.get().absolutePath}")
|
||||
|
||||
private fun validatedExportedLibraries() {
|
||||
val exportConfiguration = exportLibraries as? Configuration ?: return
|
||||
val apiFiles = project.configurations.getByName(compilation.apiConfigurationName).files.filterExternalKlibs(project)
|
||||
|
||||
Reference in New Issue
Block a user