diff --git a/build.gradle b/build.gradle index d9860294ef5..300bd338b0e 100644 --- a/build.gradle +++ b/build.gradle @@ -40,7 +40,8 @@ ext { kotlinReflectModule="org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}" kotlinScriptRuntimeModule="org.jetbrains.kotlin:kotlin-script-runtime:${kotlinVersion}" - gradlePluginVersion = KonanVersion.CURRENT.gradlePluginVersion + konanVersionFull = KonanVersion.Companion.CURRENT + gradlePluginVersion = konanVersionFull.toString() } allprojects { @@ -345,7 +346,7 @@ task bundle(type: (isWindows()) ? Zip : Tar) { dependsOn('crossDistPlatformLibs') dependsOn('crossDist') def simpleOsName = HostManager.simpleOsName() - baseName = "kotlin-native-$simpleOsName-${KonanVersion.CURRENT}" + baseName = "kotlin-native-$simpleOsName-$konanVersionFull" from("$project.rootDir/dist") { include '**' exclude 'dependencies' @@ -403,7 +404,7 @@ task bundle(type: (isWindows()) ? Zip : Tar) { task uploadBundle { dependsOn ':bundle' doLast { - def kind = (KonanVersion.CURRENT.meta == MetaVersion.DEV) ? "dev" : "releases" + def kind = (konanVersionFull.meta == MetaVersion.DEV) ? "dev" : "releases" def ftpSettings = [ server: project.findProperty("cdnUrl") ?: System.getenv("CDN_URL"), userid: project.findProperty("cdnUser") ?: System.getenv("CDN_USER"), @@ -430,9 +431,9 @@ task performance { task teamcityKonanVersion { doLast { println("##teamcity[setParameter name='kotlin.native.version.base' value='$konanVersion']") - println("##teamcity[setParameter name='kotlin.native.version.full' value='$KonanVersion.CURRENT']") - println("##teamcity[setParameter name='kotlin.native.version.meta' value='${KonanVersion.CURRENT.meta.toString().toLowerCase()}']") - println("##teamcity[buildNumber '${KonanVersion.CURRENT.toString(true, true)}']") + println("##teamcity[setParameter name='kotlin.native.version.full' value='$konanVersionFull']") + println("##teamcity[setParameter name='kotlin.native.version.meta' value='${konanVersionFull.meta.toString().toLowerCase()}']") + println("##teamcity[buildNumber '${konanVersionFull.toString(true, true)}']") } } diff --git a/shared/build.gradle b/shared/build.gradle index 0a2fa3cf8bd..be8c25f7a0e 100644 --- a/shared/build.gradle +++ b/shared/build.gradle @@ -43,7 +43,7 @@ sourceSets { } } -compileKotlin{ +compileKotlin { dependsOn('generateCompilerVersion') } diff --git a/shared/buildSrc/src/main/kotlin/org/jetbrains/kotlin/VersionGenerator.kt b/shared/buildSrc/src/main/kotlin/org/jetbrains/kotlin/VersionGenerator.kt index 0e1e76fdb41..9b295932cf4 100644 --- a/shared/buildSrc/src/main/kotlin/org/jetbrains/kotlin/VersionGenerator.kt +++ b/shared/buildSrc/src/main/kotlin/org/jetbrains/kotlin/VersionGenerator.kt @@ -42,42 +42,57 @@ open class VersionGenerator: DefaultTask() { }?: -1 + """ - |package org.jetbrains.kotlin.konan - |data class KonanVersion(val meta: MetaVersion = MetaVersion.DEV, - | val major: Int, - | val minor: Int, - | val maintenance: Int, - | val build:Int) { - | companion object { - | val CURRENT = KonanVersion($meta, $major, $minor, $maintenance, $build) - | } - | fun toString(showMeta: Boolean, showBuild: Boolean) = buildString { - | append(major) - | append('.') - | append(minor) - | if (maintenance != 0) { - | append('.') - | append(maintenance) - | } - | if (showMeta) { - | append('-') - | append(meta.metaString) - | } - | if (showBuild && build != -1) { - | append('-') - | append(build) - | } - | } - | - | private val isRelease: Boolean - | get() = meta == MetaVersion.RELEASE - | - | private val versionString by lazy { toString(!isRelease, !isRelease) } - | - | override fun toString() = versionString - | - | val gradlePluginVersion by lazy { versionString } - |} + |package org.jetbrains.kotlin.konan + | + |import java.io.Serializable + | + |interface KonanVersion : Serializable { + | val meta: MetaVersion + | val major: Int + | val minor: Int + | val maintenance: Int + | val build: Int + | + | fun toString(showMeta: Boolean, showBuild: Boolean): String + | + | companion object { + | val CURRENT = KonanVersionImpl($meta, $major, $minor, $maintenance, $build) + | } + |} + | + |data class KonanVersionImpl( + | override val meta: MetaVersion = MetaVersion.DEV, + | override val major: Int, + | override val minor: Int, + | override val maintenance: Int, + | override val build: Int + |) : KonanVersion { + | + | override fun toString(showMeta: Boolean, showBuild: Boolean) = buildString { + | append(major) + | append('.') + | append(minor) + | if (maintenance != 0) { + | append('.') + | append(maintenance) + | } + | if (showMeta) { + | append('-') + | append(meta.metaString) + | } + | if (showBuild && build != -1) { + | append('-') + | append(build) + | } + | } + | + | private val isRelease: Boolean + | get() = meta == MetaVersion.RELEASE + | + | private val versionString by lazy { toString(!isRelease, !isRelease) } + | + | override fun toString() = versionString + |} """.trimMargin() } versionFile.printWriter().use { diff --git a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/MetaVersion.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/MetaVersion.kt index 9090daf9b74..2b33e11fca6 100644 --- a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/MetaVersion.kt +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/MetaVersion.kt @@ -19,14 +19,14 @@ package org.jetbrains.kotlin.konan /** * https://en.wikipedia.org/wiki/Software_versioning * scheme major.minor[.build[.revision]]. -*/ + */ -enum class MetaVersion(val metaString:String) { - DEV("dev"), - EAP("eap"), - ALPHA("alpha"), - BETA("beta"), - RC1("rc1"), - RC2("rc2"), - RELEASE("release") -} \ No newline at end of file +enum class MetaVersion(val metaString: String) { + DEV("dev"), + EAP("eap"), + ALPHA("alpha"), + BETA("beta"), + RC1("rc1"), + RC2("rc2"), + RELEASE("release") +} diff --git a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt index efeaa706b09..dcb9fe1b582 100644 --- a/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt +++ b/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/KonanTarget.kt @@ -40,7 +40,7 @@ enum class Architecture(val bitness: Int) { WASM32(32); } -sealed class KonanTarget(override val name: String, val family: Family, val architecture: Architecture) : Named, Serializable { +sealed class KonanTarget(override val name: String, val family: Family, val architecture: Architecture) : Named { object ANDROID_ARM32 : KonanTarget( "android_arm32", Family.ANDROID, Architecture.ARM32) object ANDROID_ARM64 : KonanTarget( "android_arm64", Family.ANDROID, Architecture.ARM64) object IOS_ARM64 : KonanTarget( "ios_arm64", Family.IOS, Architecture.ARM64) diff --git a/tools/kotlin-native-gradle-plugin/build.gradle b/tools/kotlin-native-gradle-plugin/build.gradle index 7dfea0ca4ac..8699951bbee 100644 --- a/tools/kotlin-native-gradle-plugin/build.gradle +++ b/tools/kotlin-native-gradle-plugin/build.gradle @@ -45,7 +45,7 @@ apply plugin: 'com.jfrog.bintray' apply plugin: 'com.github.johnrengelman.shadow' group = 'org.jetbrains.kotlin' -version = KonanVersion.CURRENT.gradlePluginVersion +version = KonanVersion.Companion.CURRENT.toString() repositories { mavenCentral() @@ -76,11 +76,17 @@ dependencies { } } +jar { + appendix = "no-shared" +} + shadowJar { configurations = [project.configurations.bundleDependencies] classifier = null } +assemble.dependsOn shadowJar + test { systemProperty("kotlin.version", buildKotlinVersion) if (project.hasProperty("konan.home")) { diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanLibrariesSpec.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanLibrariesSpec.kt index d55e86dd57a..ce0f425bf4b 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanLibrariesSpec.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanLibrariesSpec.kt @@ -24,6 +24,7 @@ import org.gradle.api.tasks.InputFiles import org.gradle.api.tasks.Internal import org.jetbrains.kotlin.gradle.plugin.tasks.KonanArtifactWithLibrariesTask import org.jetbrains.kotlin.gradle.plugin.tasks.KonanBuildingTask +import org.jetbrains.kotlin.konan.library.SearchPathResolver import org.jetbrains.kotlin.konan.library.defaultResolver import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.KonanTarget @@ -132,14 +133,17 @@ open class KonanLibrariesSpec(val task: KonanArtifactWithLibrariesTask, val proj if (this != another) { evaluationDependsOn(another.path) } } - fun asFiles(): List = mutableListOf().apply { + fun asFiles(): List = asFiles( + defaultResolver( + repos.map { it.absolutePath }, + task.konanTarget, + Distribution(konanHomeOverride = project.konanHome) + ) + ) + + fun asFiles(resolver: SearchPathResolver): List = mutableListOf().apply { files.flatMapTo(this) { it.files } addAll(artifactFiles) - val resolver = defaultResolver( - repos.map { it.absolutePath }, - task.konanTarget, - Distribution(konanHomeOverride = project.konanHome) - ) namedKlibs.mapTo(this) { project.file(resolver.resolve(it).absolutePath) } } } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt index d6549450d92..02d9369dc86 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KonanPlugin.kt @@ -29,7 +29,9 @@ import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.internal.publication.MavenPublicationInternal import org.gradle.language.cpp.internal.NativeVariantIdentity +import org.gradle.tooling.UnsupportedVersionException import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry +import org.gradle.util.GradleVersion import org.jetbrains.kotlin.gradle.plugin.KonanPlugin.Companion.COMPILE_ALL_TASK_NAME import org.jetbrains.kotlin.gradle.plugin.model.KonanToolingModelBuilder import org.jetbrains.kotlin.gradle.plugin.tasks.* @@ -284,21 +286,30 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR internal const val KONAN_DOWNLOAD_TASK_NAME = "checkKonanCompiler" internal const val KONAN_GENERATE_CMAKE_TASK_NAME = "generateCMake" internal const val COMPILE_ALL_TASK_NAME = "compileKonan" - internal const val KONAN_MAIN_VARIANT = "konan_main_variant" internal const val KONAN_EXTENSION_NAME = "konan" + + internal val REQUIRED_GRADLE_VERSION = GradleVersion.version("4.7") } private fun Project.cleanKonan() = project.tasks.withType(KonanBuildingTask::class.java).forEach { project.delete(it.artifact) } + private fun checkGradleVersion() = GradleVersion.current().let { current -> + check(current >= REQUIRED_GRADLE_VERSION) { + "Kotlin/Native Gradle plugin is incompatible with this version of Gradle.\n" + + "The minimal required version is ${REQUIRED_GRADLE_VERSION}\n" + + "Current version is ${current}" + } + } override fun apply(project: ProjectInternal?) { if (project == null) { return } + checkGradleVersion() registry.register(KonanToolingModelBuilder) project.plugins.apply("base") // Create necessary tasks and extensions. diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModel.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModel.kt index afb88fa1228..cc2242797d0 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModel.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModel.kt @@ -16,8 +16,8 @@ package org.jetbrains.kotlin.gradle.plugin.model -import org.jetbrains.kotlin.gradle.plugin.tasks.Produce -import org.jetbrains.kotlin.konan.target.KonanTarget +import org.jetbrains.kotlin.konan.KonanVersion +import org.jetbrains.kotlin.konan.target.CompilerOutputKind import java.io.File import java.io.Serializable @@ -26,8 +26,10 @@ import java.io.Serializable * This model is shared with the client processes such as an IDE. */ interface KonanModel : Serializable { - val konanHome: String - val konanVersion: String + val konanHome: File + val konanVersion: KonanVersion + val languageVersion: String? + val apiVersion: String? val artifacts: List } @@ -37,11 +39,12 @@ interface KonanModel : Serializable { */ interface KonanModelArtifact : Serializable { val name: String - val type: Produce - val targetPlatform: KonanTarget + val type: CompilerOutputKind + val targetPlatform: String val file: File val buildTaskName: String val srcDirs: List val srcFiles: List val libraries: List + val searchPaths: List } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModelImpl.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModelImpl.kt index c4065b4dd2e..cdb89fcaea2 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModelImpl.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/model/KonanModelImpl.kt @@ -5,10 +5,8 @@ import org.gradle.tooling.provider.model.ToolingModelBuilder import org.jetbrains.kotlin.gradle.plugin.konanArtifactsContainer import org.jetbrains.kotlin.gradle.plugin.konanExtension import org.jetbrains.kotlin.gradle.plugin.konanHome -import org.jetbrains.kotlin.gradle.plugin.tasks.KonanBuildingTask -import org.jetbrains.kotlin.gradle.plugin.tasks.KonanCompileTask -import org.jetbrains.kotlin.gradle.plugin.tasks.Produce -import org.jetbrains.kotlin.konan.target.KonanTarget +import org.jetbrains.kotlin.konan.KonanVersion +import org.jetbrains.kotlin.konan.target.CompilerOutputKind import java.io.File @@ -20,26 +18,31 @@ object KonanToolingModelBuilder : ToolingModelBuilder { val artifacts = project.konanArtifactsContainer.flatten().toList().map { it.toModelArtifact() } return KonanModelImpl( artifacts, - project.konanHome, - // TODO: Provide a better support for the default version - project.konanExtension.languageVersion ?: "1.2" + project.file(project.konanHome), + KonanVersion.CURRENT, + // TODO: Provide defaults for these versions. + project.konanExtension.languageVersion, + project.konanExtension.apiVersion ) } } internal data class KonanModelImpl( override val artifacts: List, - override val konanHome: String, - override val konanVersion: String + override val konanHome: File, + override val konanVersion: KonanVersion, + override val languageVersion: String?, + override val apiVersion: String? ) : KonanModel internal data class KonanModelArtifactImpl( override val name: String, override val file: File, - override val type: Produce, - override val targetPlatform: KonanTarget, + override val type: CompilerOutputKind, + override val targetPlatform: String, override val buildTaskName: String, override val srcDirs: List, override val srcFiles: List, - override val libraries: List + override val libraries: List, + override val searchPaths: List ) : KonanModelArtifact diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanCompileTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanCompileTask.kt index c2231bed372..ccafb6e26ed 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanCompileTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanCompileTask.kt @@ -22,17 +22,11 @@ import org.gradle.api.tasks.* import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.model.KonanModelArtifact import org.jetbrains.kotlin.gradle.plugin.model.KonanModelArtifactImpl +import org.jetbrains.kotlin.konan.library.defaultResolver import org.jetbrains.kotlin.konan.target.CompilerOutputKind +import org.jetbrains.kotlin.konan.target.Distribution import java.io.File -enum class Produce(val cliOption: String, val kind: CompilerOutputKind) { - PROGRAM("program", CompilerOutputKind.PROGRAM), - DYNAMIC("dynamic", CompilerOutputKind.DYNAMIC), - FRAMEWORK("framework", CompilerOutputKind.FRAMEWORK), - LIBRARY("library", CompilerOutputKind.LIBRARY), - BITCODE("bitcode", CompilerOutputKind.BITCODE) -} - /** * A task compiling the target executable/library using Kotlin/Native compiler */ @@ -40,16 +34,16 @@ abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec { @Internal override val toolRunner = KonanCompilerRunner(project) - abstract val produce: Produce + abstract val produce: CompilerOutputKind @Internal get // Output artifact -------------------------------------------------------- override val artifactSuffix: String - @Internal get() = produce.kind.suffix(konanTarget) + @Internal get() = produce.suffix(konanTarget) override val artifactPrefix: String - @Internal get() = produce.kind.prefix(konanTarget) + @Internal get() = produce.prefix(konanTarget) // Multiplatform support -------------------------------------------------- @@ -119,7 +113,7 @@ abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec { addArgs("-library", libraries.artifacts.map { it.artifact.canonicalPath }) addFileArgs("-nativelibrary", nativeLibraries) - addArg("-produce", produce.cliOption) + addArg("-produce", produce.name.toLowerCase()) addListArg("-linkerOpts", linkerOpts) @@ -222,41 +216,51 @@ abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec { // endregion // region IDE model - override fun toModelArtifact(): KonanModelArtifact = KonanModelArtifactImpl( - artifactName, - artifact, - produce, - konanTarget, - name, - allSources.filter { it is ConfigurableFileTree }.map { (it as ConfigurableFileTree).dir }, - allSourceFiles, - libraries.asFiles() - ) + override fun toModelArtifact(): KonanModelArtifact { + val repos = libraries.repos + val resolver = defaultResolver( + repos.map { it.absolutePath }, + konanTarget, + Distribution(konanHomeOverride = project.konanHome) + ) + + return KonanModelArtifactImpl( + artifactName, + artifact, + produce, + konanTarget.name, + name, + allSources.filterIsInstance(ConfigurableFileTree::class.java).map { it.dir }, + allSourceFiles, + libraries.asFiles(resolver), + repos.toList() + ) + } // endregion } open class KonanCompileProgramTask: KonanCompileTask() { - override val produce: Produce get() = Produce.PROGRAM + override val produce: CompilerOutputKind get() = CompilerOutputKind.PROGRAM } open class KonanCompileDynamicTask: KonanCompileTask() { - override val produce: Produce get() = Produce.DYNAMIC + override val produce: CompilerOutputKind get() = CompilerOutputKind.DYNAMIC val headerFile: File @OutputFile get() = destinationDir.resolve("$artifactPrefix${artifactName}_api.h") } open class KonanCompileFrameworkTask: KonanCompileTask() { - override val produce: Produce get() = Produce.FRAMEWORK + override val produce: CompilerOutputKind get() = CompilerOutputKind.FRAMEWORK override val artifact @OutputDirectory get() = super.artifact } open class KonanCompileLibraryTask: KonanCompileTask() { - override val produce: Produce get() = Produce.LIBRARY + override val produce: CompilerOutputKind get() = CompilerOutputKind.LIBRARY } open class KonanCompileBitcodeTask: KonanCompileTask() { - override val produce: Produce get() = Produce.BITCODE + override val produce: CompilerOutputKind get() = CompilerOutputKind.BITCODE } diff --git a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt index 6357e192444..f725413af99 100644 --- a/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt +++ b/tools/kotlin-native-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/tasks/KonanInteropTask.kt @@ -25,6 +25,9 @@ import org.jetbrains.kotlin.gradle.plugin.* import org.jetbrains.kotlin.gradle.plugin.KonanInteropSpec.IncludeDirectoriesSpec import org.jetbrains.kotlin.gradle.plugin.model.KonanModelArtifact import org.jetbrains.kotlin.gradle.plugin.model.KonanModelArtifactImpl +import org.jetbrains.kotlin.konan.library.defaultResolver +import org.jetbrains.kotlin.konan.target.CompilerOutputKind +import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.KonanTarget import java.io.File @@ -155,16 +158,26 @@ open class KonanInteropTask: KonanBuildingTask(), KonanInteropSpec { // endregion // region IDE model - override fun toModelArtifact(): KonanModelArtifact = KonanModelArtifactImpl( - artifactName, - artifact, - Produce.LIBRARY, - konanTarget, - name, - listOfNotNull(defFile.parentFile), - listOf(defFile), - libraries.asFiles() - ) + override fun toModelArtifact(): KonanModelArtifact { + val repos = libraries.repos + val resolver = defaultResolver( + repos.map { it.absolutePath }, + konanTarget, + Distribution(konanHomeOverride = project.konanHome) + ) + + return KonanModelArtifactImpl( + artifactName, + artifact, + CompilerOutputKind.LIBRARY, + konanTarget.name, + name, + listOfNotNull(defFile.parentFile), + listOf(defFile), + libraries.asFiles(resolver), + repos.toList() + ) + } // endregion } diff --git a/tools/kotlin-native-gradle-plugin/src/test/kotlin/CompatibilityTests.kt b/tools/kotlin-native-gradle-plugin/src/test/kotlin/CompatibilityTests.kt new file mode 100644 index 00000000000..b8bb102582c --- /dev/null +++ b/tools/kotlin-native-gradle-plugin/src/test/kotlin/CompatibilityTests.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.gradle.plugin.test + +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import java.io.File +import kotlin.test.* + +open class CompatibilityTests { + val tmpFolder = TemporaryFolder() + @Rule get + + val projectDirectory: File + get() = tmpFolder.root + + @Test + fun `Plugin should fail if running with Gradle prior to the required one`() { + val project = KonanProject.createEmpty(projectDirectory) + val result = project + .createRunner() + .withGradleVersion("4.5") + .withArguments("tasks") + .buildAndFail() + println(result.output) + assertTrue("Build doesn't show the warning message") { + result.output.contains("Kotlin/Native Gradle plugin is incompatible with this version of Gradle.") + } + } +} \ No newline at end of file diff --git a/tools/kotlin-native-gradle-plugin/src/test/kotlin/PropertiesAsEnvVariables.kt b/tools/kotlin-native-gradle-plugin/src/test/kotlin/PropertiesAsEnvVariablesTest.kt similarity index 92% rename from tools/kotlin-native-gradle-plugin/src/test/kotlin/PropertiesAsEnvVariables.kt rename to tools/kotlin-native-gradle-plugin/src/test/kotlin/PropertiesAsEnvVariablesTest.kt index 5cef642eb70..62764809dc9 100644 --- a/tools/kotlin-native-gradle-plugin/src/test/kotlin/PropertiesAsEnvVariables.kt +++ b/tools/kotlin-native-gradle-plugin/src/test/kotlin/PropertiesAsEnvVariablesTest.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.jetbrains.kotlin.gradle.plugin.test import org.jetbrains.kotlin.gradle.plugin.test.KonanProject.escapeBackSlashes @@ -11,7 +27,7 @@ import java.io.File import kotlin.test.* @RunWith(Spockito::class) -open class PropertiesAsEnvVariables { +open class PropertiesAsEnvVariablesTest { val tmpFolder = TemporaryFolder() @Rule get diff --git a/tools/kotlin-native-gradle-plugin/src/test/kotlin/ToolingModelTests.kt b/tools/kotlin-native-gradle-plugin/src/test/kotlin/ToolingModelTests.kt new file mode 100644 index 00000000000..4ae8ea4352b --- /dev/null +++ b/tools/kotlin-native-gradle-plugin/src/test/kotlin/ToolingModelTests.kt @@ -0,0 +1,203 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.gradle.plugin.test + +import org.jetbrains.kotlin.konan.KonanVersion +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import java.io.File +import java.nio.file.Paths +import kotlin.test.Test + +open class ToolingModelTests { + val tmpFolder = TemporaryFolder() + @Rule get + + val projectDirectory: File + get() = tmpFolder.root + + @Test + fun `The model should be serialized without exceptions`() { + val project = KonanProject.createEmpty(projectDirectory).apply { + buildFile.appendText(""" + konanArtifacts { + library('foo') { + srcDir 'src/foo/kotlin' + } + interop('bar') + + program('main') { + libraries { + artifact konanArtifacts.foo + artifact konanArtifacts.bar + klib 'posix' + } + } + } + + import org.jetbrains.kotlin.gradle.plugin.model.* + + task testSerialization { + doLast { + def model = KonanToolingModelBuilder.INSTANCE.buildAll("KonanModel", project) + file("model.bin").withObjectOutputStream { + it.writeObject(model) + } + + KonanModelImpl deserializedModel + file("model.bin").withObjectInputStream(model.getClass().getClassLoader()) { stream -> + deserializedModel = (KonanModelImpl) stream.readObject() + } + + if (!deserializedModel.equals(model)) { + throw new AssertionError("The deserialized model doesn't equal to the initial one") + } + } + } + """.trimIndent()) + + generateSrcFile("main.kt") + generateSrcFile(Paths.get("src", "foo", "kotlin"), "foo.kt", "fun foo() = 1") + generateSrcFile(Paths.get("src", "bar", "kotlin"), "bar.kt", "fun bar() = 1") + generateDefFile("baz.def", "") + generateDefFile("qux.def", "") + } + project.createRunner().withArguments("testSerialization").build() + } + + @Test + fun `The model should contain the same data as the Gradle tasks`() { + val project = KonanProject.createEmpty(projectDirectory, listOf("host", "wasm32")).apply { + val konanVersion = KonanVersion.CURRENT.toString() + generateSrcFile(listOf("src", "foo1"), "foo1.kt", "fun foo1() = 0") + generateSrcFile(listOf("src", "foo1"), "foo11.kt", "fun foo11() = 0") + generateSrcFile(listOf("src", "foo2"), "foo2.kt", "fun foo2() = 0") + generateSrcFile(listOf("defs_bar"), "bar.def", "") + generateSrcFile(listOf("src", "baz"), "baz.kt", "fun baz() = 0") + generateSrcFile("main.kt") + createSubDir("custom_repo") + buildFile.appendText(""" + konanArtifacts { + library('foo') { + srcDir 'src/foo1' + srcDir 'src/foo2' + } + interop('bar') { + defFile 'defs_bar/bar.def' + } + library('baz') { + srcDir 'src/baz' + } + + program('main') { + libraries { + artifact konanArtifacts.foo + artifact konanArtifacts.bar + klib 'baz' + + useRepo 'custom_repo' + } + } + } + + konan { + languageVersion = "1.2" + apiVersion = "1.2" + } + + import org.jetbrains.kotlin.gradle.plugin.model.* + import org.jetbrains.kotlin.konan.target.CompilerOutputKind + + public void assertEquals( + T actual, + T expected, + String message = "${'$'}expected expected but ${'$'}actual found") { + if (expected != actual) { + throw new AssertionError(message) + } + } + + public void assertContentEquals( + Collection actual, + Collection expected, + String message = "${'$'}expected\nexpected but\n${'$'}actual\nfound") { + if (actual.size() != expected.size() || !actual.containsAll(expected)) { + throw new AssertionError(message) + } + } + + task testModelData { + dependsOn('compileKonanBaz') + doLast { + def model = KonanToolingModelBuilder.INSTANCE.buildAll("KonanModel", project) + assertEquals(model.konanHome, file(project.getProperty('konan.home'))) + assertEquals(model.konanVersion.toString(), "$konanVersion") + + assertEquals(model.languageVersion, "1.2") + assertEquals(model.apiVersion, "1.2") + + model.artifacts.each { + + def konanArtifact = konanArtifacts[it.name] + def target = it.targetPlatform + def task = konanArtifact.getByTarget(target) + + assertEquals(it.file, task.artifact) + assertEquals(it.buildTaskName, task.name) + + switch(it.name) { + case 'foo': + assertEquals(it.type, CompilerOutputKind.valueOf('LIBRARY')) + assertContentEquals(it.srcDirs, [file('src/foo1'), file('src/foo2')]) + assertContentEquals(it.srcFiles, [ + file('src/foo1/foo1.kt'), + file('src/foo1/foo11.kt'), + file('src/foo2/foo2.kt')]) + assertContentEquals(it.libraries, []) + assertContentEquals(it.searchPaths, [task.artifact.parentFile]) + break + case 'bar': + assertEquals(it.type, CompilerOutputKind.valueOf('LIBRARY')) + assertContentEquals(it.srcDirs, [file('defs_bar')]) + assertContentEquals(it.srcFiles, [file('defs_bar/bar.def')]) + assertContentEquals(it.libraries, []) + assertContentEquals(it.searchPaths, [task.artifact.parentFile]) + break + case 'main': + assertEquals(it.type, CompilerOutputKind.valueOf('PROGRAM')) + assertContentEquals(it.srcDirs, [file('src/main/kotlin')]) + assertContentEquals(it.srcFiles, [file('src/main/kotlin/main.kt')]) + assertContentEquals(it.libraries, [ + konanArtifacts['foo'].getByTarget(target).artifact, + konanArtifacts['bar'].getByTarget(target).artifact, + konanArtifacts['baz'].getByTarget(target).artifact + ]) + assertContentEquals(it.searchPaths, [ + file('custom_repo'), + task.artifact.parentFile, + konanArtifacts.foo.getByTarget(target).artifact.parentFile + ]) + break + } + } + } + } + """.trimIndent()) + } + project.createRunner().withArguments("testModelData").build() + } +}