Add tests for new binaries DSL
This commit is contained in:
+169
-4
@@ -6,13 +6,11 @@ package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.ProjectLocalConfigurations
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.UnusedSourceSetsChecker
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.METADATA_CONFIGURATION_NAME_SUFFIX
|
||||
import org.jetbrains.kotlin.gradle.plugin.sources.SourceSetConsistencyChecks
|
||||
import org.jetbrains.kotlin.gradle.util.checkBytecodeContains
|
||||
import org.jetbrains.kotlin.gradle.util.isWindows
|
||||
import org.jetbrains.kotlin.gradle.util.modify
|
||||
import org.jetbrains.kotlin.gradle.util.testResolveAllConfigurations
|
||||
import org.jetbrains.kotlin.gradle.util.*
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import org.junit.Assert
|
||||
@@ -152,6 +150,15 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
val nativeExeName = if (isWindows) "main.exe" else "main.kexe"
|
||||
assertFileExists("build/bin/$nativeHostTargetName/mainReleaseExecutable/$nativeExeName")
|
||||
assertFileExists("build/bin/$nativeHostTargetName/mainDebugExecutable/$nativeExeName")
|
||||
|
||||
// Check that linker options was correctly passed to the K/N compiler.
|
||||
output.lineSequence().filter {
|
||||
it.contains("Run tool: konanc") && it.contains("-p program")
|
||||
}.toList().also {
|
||||
assertTrue(it.isNotEmpty())
|
||||
}.forEach {
|
||||
assertTrue(it.contains("-linker-options -L."))
|
||||
}
|
||||
}
|
||||
|
||||
build("assemble", "resolveRuntimeDependencies") {
|
||||
@@ -171,6 +178,12 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
build("clean", "assemble", "--rerun-tasks") {
|
||||
checkAppBuild()
|
||||
}
|
||||
|
||||
// Check that binary getters initially introduced in 1.3 work.
|
||||
build("checkBinaryGetters") {
|
||||
assertTrue(output.contains("Wasm binary file: main.wasm"))
|
||||
assertTrue(output.contains("Wasm link task: linkMainReleaseExecutableWasm32"))
|
||||
}
|
||||
}
|
||||
|
||||
with(oldStyleAppProject) {
|
||||
@@ -835,6 +848,158 @@ class NewMultiplatformIT : BaseGradleIT() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNativeBinaryKotlinDSL() = doTestNativeBinaryDSL("kotlin-dsl")
|
||||
|
||||
@Test
|
||||
fun testNativeBinaryGroovyDSL() = doTestNativeBinaryDSL("groovy-dsl")
|
||||
|
||||
private fun doTestNativeBinaryDSL(
|
||||
projectName: String,
|
||||
gradleVersionRequired: GradleVersionRequired = gradleVersion
|
||||
) = with(transformProjectWithPluginsDsl(projectName, gradleVersionRequired, "new-mpp-native-binaries")) {
|
||||
val hostSuffix = nativeHostTargetName.capitalize()
|
||||
val binaries = mutableListOf(
|
||||
"debugExecutable" to "native-binary",
|
||||
"releaseExecutable" to "native-binary",
|
||||
"fooDebugExecutable" to "foo",
|
||||
"fooReleaseExecutable" to "foo",
|
||||
"barReleaseExecutable" to "bar",
|
||||
"bazReleaseExecutable" to "my-baz",
|
||||
"testDebugExecutable" to "test",
|
||||
"test2ReleaseExecutable" to "test2",
|
||||
"releaseStatic" to "native_binary",
|
||||
"releaseShared" to "native_binary"
|
||||
)
|
||||
|
||||
val linkTasks = binaries.map { (name, _) -> "link${name.capitalize()}$hostSuffix" }
|
||||
val outputFiles = binaries.map { (name, fileBaseName) ->
|
||||
val outputKind = NativeOutputKind.values().single { name.endsWith(it.taskNameClassifier, true) }.compilerOutputKind
|
||||
val prefix = outputKind.prefix(HostManager.host)
|
||||
val suffix = outputKind.suffix(HostManager.host)
|
||||
val fileName = "$prefix$fileBaseName$suffix"
|
||||
"build/bin/$nativeHostTargetName/$name/$fileName"
|
||||
}
|
||||
|
||||
val runTasks = listOf(
|
||||
"runDebugExecutable",
|
||||
"runReleaseExecutable",
|
||||
"runFooDebugExecutable",
|
||||
"runFooReleaseExecutable",
|
||||
"runBarReleaseExecutable",
|
||||
"runBazReleaseExecutable",
|
||||
"runTest2ReleaseExecutable"
|
||||
).map { "$it$hostSuffix" }.toMutableList()
|
||||
|
||||
val binariesTasks = arrayOf("${nativeHostTargetName}MainBinaries", "${nativeHostTargetName}TestBinaries")
|
||||
|
||||
// Check that all link and run tasks are generated.
|
||||
build(*binariesTasks) {
|
||||
assertSuccessful()
|
||||
assertTasksExecuted(linkTasks.map { ":$it" })
|
||||
outputFiles.forEach {
|
||||
assertFileExists(it)
|
||||
}
|
||||
// Check that getters work fine.
|
||||
assertTrue(output.contains("Check link task: linkReleaseShared$hostSuffix"))
|
||||
assertTrue(output.contains("Check run task: runFooReleaseExecutable$hostSuffix"))
|
||||
}
|
||||
|
||||
build("tasks") {
|
||||
assertSuccessful()
|
||||
runTasks.forEach {
|
||||
assertTrue(output.contains(it), "The 'tasks' output doesn't contain a task ${it}")
|
||||
}
|
||||
}
|
||||
|
||||
// Clean the build to check that run tasks build corresponding binaries.
|
||||
build("clean") {
|
||||
assertSuccessful()
|
||||
}
|
||||
|
||||
// Check that run tasks work find and an entry point can be specified.
|
||||
build("runDebugExecutable$hostSuffix") {
|
||||
assertSuccessful()
|
||||
assertTrue(output.contains("<root>.main"))
|
||||
}
|
||||
|
||||
build("runBazReleaseExecutable$hostSuffix") {
|
||||
assertSuccessful()
|
||||
assertTrue(output.contains("foo.main"))
|
||||
}
|
||||
|
||||
build("runTest2ReleaseExecutable$hostSuffix") {
|
||||
assertSuccessful()
|
||||
assertTrue(output.contains("tests.foo"))
|
||||
}
|
||||
|
||||
// Check that we still have a default test task and it can be executed properly.
|
||||
build("${nativeHostTargetName}Test") {
|
||||
assertSuccessful()
|
||||
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.
|
||||
// For release builds
|
||||
build("linkReleaseFrameworkIos") {
|
||||
assertSuccessful()
|
||||
assertFileExists("build/bin/ios/releaseFramework/native_binary.framework")
|
||||
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 {
|
||||
assertTrue(it.contains("-Xembed-bitcode"))
|
||||
assertTrue(it.contains("-opt"))
|
||||
}
|
||||
}
|
||||
|
||||
// For debug builds
|
||||
build("linkDebugFrameworkIos") {
|
||||
assertSuccessful()
|
||||
assertFileExists("build/bin/ios/debugFramework/native_binary.framework")
|
||||
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 {
|
||||
assertTrue(it.contains("-Xembed-bitcode-marker"))
|
||||
assertTrue(it.contains("-g"))
|
||||
}
|
||||
}
|
||||
|
||||
// Check manual disabling bitcode embedding and custom command line args.
|
||||
build("linkCustomReleaseFrameworkIos") {
|
||||
assertSuccessful()
|
||||
checkFrameworkCompilationCommandLine {
|
||||
assertTrue(it.contains("-linker-options -L."))
|
||||
assertTrue(it.contains("-Xtime"))
|
||||
assertFalse(it.contains("-Xembed-bitcode-marker"))
|
||||
assertFalse(it.contains("-Xembed-bitcode"))
|
||||
}
|
||||
}
|
||||
|
||||
// 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\"))", "")
|
||||
}
|
||||
build("linkReleaseFrameworkIos") {
|
||||
assertFailed()
|
||||
val failureMsg = "Following dependencies exported in the releaseFramework binary " +
|
||||
"are not specified as API-dependencies of a corresponding source set"
|
||||
assertTrue(output.contains(failureMsg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSourceJars() = with(Project("sample-lib", gradleVersion, "new-mpp-lib-and-app")) {
|
||||
setupWorkingDir()
|
||||
|
||||
+10
-3
@@ -1,5 +1,3 @@
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind.EXECUTABLE
|
||||
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.multiplatform").version("<pluginMarkerVersion>")
|
||||
id("maven-publish")
|
||||
@@ -29,6 +27,8 @@ kotlin {
|
||||
compilations.getByName("main") {
|
||||
outputKinds.add(EXECUTABLE)
|
||||
entryPoint = "com.example.app.native.main"
|
||||
// Check that linker options are correctly passed to the compiler.
|
||||
linkerOpts = mutableListOf("-L.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,13 @@ kotlin {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.create("checkBinaryGetters") {
|
||||
doLast {
|
||||
println("Wasm binary file: ${wasm32.compilations.getByName("main").getBinary("EXECUTABLE", "RELEASE").name}")
|
||||
println("Wasm link task: ${wasm32.compilations.getByName("main").getLinkTask("EXECUTABLE", "RELEASE").name}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.create("resolveRuntimeDependencies", DefaultTask::class.java) {
|
||||
@@ -67,4 +74,4 @@ tasks.create("resolveRuntimeDependencies", DefaultTask::class.java) {
|
||||
val configName = kotlin.jvm("jvm6").compilations["main"].runtimeDependencyConfigurationName
|
||||
configurations[configName].resolve()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -66,6 +66,8 @@ kotlin {
|
||||
configure([wasm32, linux64, mingw64, macos64]) {
|
||||
compilations.main.outputKinds += org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind.EXECUTABLE
|
||||
compilations.main.entryPoint = "com.example.app.native.main"
|
||||
// Check that linker options are correctly passed to the compiler.
|
||||
compilations.main.linkerOpts = ['-L.']
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,4 +78,11 @@ task resolveRuntimeDependencies(type: DefaultTask) {
|
||||
def configName = kotlin.targets.jvm6.compilations.main.runtimeDependencyConfigurationName
|
||||
configurations[configName].resolve()
|
||||
}
|
||||
}
|
||||
|
||||
task checkBinaryGetters {
|
||||
doLast {
|
||||
println("Wasm binary file: ${kotlin.targets.wasm32.compilations.main.getBinary("EXECUTABLE", "RELEASE").name}")
|
||||
println("Wasm link task: ${kotlin.targets.wasm32.compilations.main.getLinkTask("EXECUTABLE", "RELEASE").name}")
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'kotlin-multiplatform'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api "org.jetbrains.kotlin:kotlin-stdlib-common"
|
||||
}
|
||||
}
|
||||
|
||||
iosMain {
|
||||
dependencies {
|
||||
api(project(":exported"))
|
||||
}
|
||||
}
|
||||
|
||||
commonTest {
|
||||
dependencies {
|
||||
api "org.jetbrains.kotlin:kotlin-test-annotations-common"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
targets {
|
||||
macosX64("macos64")
|
||||
linuxX64("linux64")
|
||||
mingwX64("windows64")
|
||||
|
||||
configure([macos64, linux64, windows64]) {
|
||||
binaries {
|
||||
|
||||
executable() // Executable with default name.
|
||||
executable("foo") // Custom binary name.
|
||||
executable("bar", [RELEASE]) // Custom build types.
|
||||
|
||||
// Configure a binary.
|
||||
executable("baz", [RELEASE]) {
|
||||
// Rename an output binary: baz.kexe -> my-baz.kexe.
|
||||
baseName = "my-baz"
|
||||
// Use a custom entry point.
|
||||
entryPoint = "foo.main"
|
||||
}
|
||||
|
||||
executable("test2", [RELEASE]) {
|
||||
compilation = compilations["test"]
|
||||
}
|
||||
|
||||
sharedLib([RELEASE])
|
||||
staticLib([RELEASE])
|
||||
}
|
||||
// Check that we can access binaries/tasks:
|
||||
// Just by name:
|
||||
println("Check link task: ${binaries.releaseShared.linkTask.name}")
|
||||
// Using a typed getter:
|
||||
println("Check run task: ${binaries.getExecutable("foo", RELEASE).runTask.name}")
|
||||
}
|
||||
iosArm64("ios") {
|
||||
binaries {
|
||||
framework {
|
||||
export project(':exported')
|
||||
}
|
||||
framework('custom', [RELEASE]) {
|
||||
embedBitcode = 'DISABLE'
|
||||
linkerOpts = ['-L.']
|
||||
freeCompilerArgs = ["-Xtime"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.multiplatform")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven { setUrl("http://dl.bintray.com/kotlin/kotlinx.html/") }
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets.commonMain {
|
||||
dependencies {
|
||||
api("org.jetbrains.kotlin:kotlin-stdlib-common")
|
||||
}
|
||||
}
|
||||
|
||||
iosArm64("ios")
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun exported() = 42
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
enableFeaturePreview('GRADLE_METADATA')
|
||||
|
||||
rootProject.name = "native-binary"
|
||||
|
||||
include ':exported'
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package foo
|
||||
|
||||
fun main() {
|
||||
println("foo.main")
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
println("<root>.main")
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun foo() {
|
||||
println("tests.foo")
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.multiplatform").version("<pluginMarkerVersion>")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven { setUrl("http://dl.bintray.com/kotlin/kotlinx.html/") }
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets["commonMain"].apply {
|
||||
dependencies {
|
||||
api("org.jetbrains.kotlin:kotlin-stdlib-common")
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets.create("iosMain").apply {
|
||||
dependencies {
|
||||
api(project(":exported"))
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets["commonTest"].apply {
|
||||
dependencies {
|
||||
api("org.jetbrains.kotlin:kotlin-test-annotations-common")
|
||||
}
|
||||
}
|
||||
|
||||
val macos = macosX64("macos64")
|
||||
val linux = linuxX64("linux64")
|
||||
val windows = mingwX64("windows64")
|
||||
|
||||
configure(listOf(macos, linux, windows)) {
|
||||
|
||||
binaries {
|
||||
|
||||
executable() // Executable with default name.
|
||||
executable("foo") // Custom binary name.
|
||||
executable("bar", listOf(RELEASE)) // Custom build types.
|
||||
|
||||
// Configure a binary.
|
||||
executable("baz") {
|
||||
// Rename an output binary: baz.kexe -> my-baz.kexe.
|
||||
baseName = "my-baz"
|
||||
// Use a custom entry point.
|
||||
entryPoint = "foo.main"
|
||||
}
|
||||
|
||||
executable("test2") {
|
||||
compilation = compilations["test"]
|
||||
}
|
||||
|
||||
sharedLib(listOf(RELEASE))
|
||||
staticLib(listOf(RELEASE))
|
||||
}
|
||||
// Check that we can access binaries/tasks:
|
||||
// Just by name:
|
||||
println("Check link task: ${binaries["releaseShared"].linkTask.name}")
|
||||
// Using a typed getter:
|
||||
println("Check run task: ${binaries.getExecutable("foo", RELEASE).runTask?.name}")
|
||||
}
|
||||
|
||||
iosArm64("ios") {
|
||||
binaries {
|
||||
framework {
|
||||
export(project(":exported"))
|
||||
}
|
||||
framework("custom", listOf(RELEASE)) {
|
||||
embedBitcode("disable")
|
||||
linkerOpts = mutableListOf("-L.")
|
||||
freeCompilerArgs = mutableListOf("-Xtime")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.multiplatform")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven { setUrl("http://dl.bintray.com/kotlin/kotlinx.html/") }
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets["commonMain"].apply {
|
||||
dependencies {
|
||||
api("org.jetbrains.kotlin:kotlin-stdlib-common")
|
||||
}
|
||||
}
|
||||
|
||||
iosArm64("ios")
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun exported() = 42
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
enableFeaturePreview('GRADLE_METADATA')
|
||||
|
||||
rootProject.name = "native-binary"
|
||||
|
||||
include ':exported'
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package foo
|
||||
|
||||
fun main() {
|
||||
println("foo.main")
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun main() {
|
||||
println("<root>.main")
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import kotlin.test.*
|
||||
|
||||
@Test
|
||||
fun foo() {
|
||||
println("tests.foo")
|
||||
}
|
||||
+5
-3
@@ -199,11 +199,13 @@ class Framework(
|
||||
|
||||
/**
|
||||
* Enable or disable embedding bitcode for the framework.
|
||||
* The parameter [mode] is one of the following string constants:
|
||||
*
|
||||
* @param mode - one of the following string constants:
|
||||
* disable - Don't embed LLVM IR bitcode.
|
||||
* bitcode - Embed LLVM IR bitcode as data. Has the same effect as the -Xembed-bitcode command line option.
|
||||
* marker - Embed placeholder LLVM IR data as a marker. Has the same effect as the -Xembed-bitcode-marker command line option.
|
||||
* bitcode - Embed LLVM IR bitcode as data.
|
||||
* Has the same effect as the -Xembed-bitcode command line option.
|
||||
* marker - Embed placeholder LLVM IR data as a marker.
|
||||
* Has the same effect as the -Xembed-bitcode-marker command line option.
|
||||
*/
|
||||
fun embedBitcode(mode: String) = embedBitcode(BitcodeEmbeddingMode.valueOf(mode.toUpperCase()))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user