I have created a very simple KMP project, with the following structure:
-Root
--app
--gradle
--SharedCode
--src\commonMain\kotlin\actual.kt
--src\iosMain\kotlin\actual.kt
--scr\androidMain\kotlin\actual.kt
--build.gradle.kts
--native
--KotlinIOS
--iOS project (xcodeproj, etc)
Everything works, and the basic project work on both Android and iOS platforms.
But when I try to use an android-specific import statement in my androidMain directory, the import statement won't resolve:
import android.os.build // Android Studio can't find this
actual fun platformName(): String {
return "Android"
}
It is weird, since the iOS package is using iOS-specific imports successfully:
import platform.UIKit.UIDevice // This import works
actual fun platformName(): String {
return UIDevice.currentDevice.systemName() +
" " + UIDevice.currentDevice.systemVersion
}
Any suggestions about what I may need to configure to get my Android import to work?
This is my build.gradle.kts file for completeness:
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins {
kotlin("multiplatform")
}
kotlin {
//select iOS target platform depending on the Xcode environment variables
val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
::iosArm64
else
::iosX64
iOSTarget("ios") {
binaries {
framework {
baseName = "SharedCode"
}
}
}
jvm("android")
sourceSets["commonMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
}
sourceSets["androidMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib")
}
}
val packForXcode by tasks.creating(Sync::class) {
val targetDir = File(buildDir, "xcode-frameworks")
/// selecting the right configuration for the iOS
/// framework depending on the environment
/// variables set by Xcode build
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val framework = kotlin.targets
.getByName<KotlinNativeTarget>("ios")
.binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
from({ framework.outputDirectory })
into(targetDir)
/// generate a helpful ./gradlew wrapper with embedded Java path
doLast {
val gradlew = File(targetDir, "gradlew")
gradlew.writeText("#!/bin/bash\n"
+ "export 'JAVA_HOME=${System.getProperty("java.home")}'\n"
+ "cd '${rootProject.rootDir}'\n"
+ "./gradlew \$#\n")
gradlew.setExecutable(true)
}
}
tasks.getByName("build").dependsOn(packForXcode)
You do not have the android required definitions in your gradle build script. Here's a basic gradle script that works for me:
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.tasks.FatFrameworkTask
buildscript {
repositories {
mavenLocal()
maven("https://kotlin.bintray.com/kotlinx")
maven("https://dl.bintray.com/jetbrains/kotlin-native-dependencies")
maven("https://dl.bintray.com/kotlin/kotlin-eap")
maven("https://plugins.gradle.org/m2/")
google()
jcenter()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50")
classpath("com.android.tools.build:gradle:3.5.0")
classpath("co.touchlab:kotlinxcodesync:0.1.5")
}
}
plugins {
id ("com.android.library") version "1.3.50"
id ("org.jetbrains.kotlin.multiplatform") version "1.3.50"
}
allprojects {
repositories {
mavenLocal()
google()
jcenter()
mavenCentral()
maven("https://dl.bintray.com/kotlin/kotlin-eap")
maven("https://kotlin.bintray.com/ktor")
maven("https://kotlin.bintray.com/kotlinx")
}
}
group = "com.example.mykmp"
version = "0.0.1"
apply(plugin = "maven-publish")
apply(plugin = "com.android.library")
apply(plugin = "kotlin-android-extensions")
android {
compileSdkVersion(29)
defaultConfig {
minSdkVersion(21)
targetSdkVersion(29)
}
}
kotlin {
android()
val frameworkName = "mykmp"
val ios = iosX64("ios") {
binaries.framework {
baseName = frameworkName
}
}
sourceSets {
commonMain {
dependencies {
implementation(kotlin("stdlib-common"))
}
}
commonTest {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting {
dependencies {
implementation(kotlin("stdlib-jdk8"))
}
}
val androidTest by getting {
dependencies {
implementation(kotlin("test"))
implementation(kotlin("test-junit"))
}
}
val iosMain by getting {
dependencies {
implementation(kotlin("stdlib"))
}
}
val iosTest by getting {
dependencies {
implementation(kotlin("stdlib"))
}
}
}
tasks.create("framework", FatFrameworkTask::class) {
baseName = frameworkName
from(
ios.binaries.getFramework("DEBUG")
)
destinationDir = buildDir.resolve("xcode-frameworks")
group = "iOS frameworks"
description = "Builds a simulator only framework to build from xcode directly"
doLast {
val file = File(destinationDir, "gradlew")
file.writeText(text = "#!/bin/bash\nexport JAVA_HOME=${System.getProperty("java.home")}\ncd ${rootProject.rootDir}\n./gradlew \$#\n")
file.setExecutable(true)
}
}
}
tasks.getByName("build").dependsOn(packForXcode)
Also, in the settings.gradle.kts, I have this:
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.id == "kotlin-multiplatform") {
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
}
if (requested.id.id == "com.android.library") {
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
}
if (requested.id.id == "kotlinx-serialization") {
useModule("org.jetbrains.kotlin:kotlin-serialization:${requested.version}")
}
}
}
}
Otherwise, it might complain that com.android.library could not be found.
I would also recommend Invalidate Cache/Restart on Android Studio or IntelliJ after that.
Hope that helps.
Related
I am creating KMM library. I want to create a cocoapods framework, but when I tried to build my project, the framework is not generating. I tried clean project and build again. My cocoapods is not generating the at all in build folder. I didn't get why this is not working. I am adding my build file.
build.gradle.kts
plugins {
kotlin("multiplatform") version "1.6.21"
kotlin("native.cocoapods") version "1.6.21"
id("com.android.library")
id("org.jetbrains.dokka") version "1.6.10"
id("org.jetbrains.kotlin.plugin.serialization") version "1.6.21"
id("maven-publish")
}
val libraryVersion = "0.0.1"
var libraryGroup = "com.vivek"
var libraryArtifactId = "kmm-module"
var libraryUri = uri("https://maven.pkg.github.com/vivek/KotlinMultiplatformMobile")
repositories {
google()
mavenCentral()
}
kotlin {
android {
publishLibraryVariants("release", "debug")
}
cocoapods {
version = libraryVersion
summary = "Some description for a Kotlin/Native module"
homepage = ""
ios.deploymentTarget = "13.0"
name = "VivekKmmPod"
framework {
baseName = "VivekFramework"
isStatic = false
}
}
iosX64()
iosArm64()
iosSimulatorArm64()
sourceSets {
val ktorVersion = "2.0.0"
val commonMain by getting {
dependencies {
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-logging:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
implementation("io.ktor:ktor-client-auth:$ktorVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.3.2")
implementation("io.insert-koin:koin-core:3.2.0")
}
}
val androidMain by getting {
dependencies {
implementation("io.ktor:ktor-client-okhttp:$ktorVersion")
implementation("io.ktor:ktor-client-logging-jvm:$ktorVersion")
}
}
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
dependencies {
implementation("io.ktor:ktor-client-darwin:$ktorVersion")
}
}
}
}
android {
compileSdk = 21
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdk = 21
targetSdk = 31
}
}
tasks {
create<Jar>("javadocJar") {
val dokkaHtml by getting(org.jetbrains.dokka.gradle.DokkaTask::class)
dependsOn(dokkaHtml)
archiveClassifier.set("javadoc")
from(dokkaHtml.outputDirectory)
}
}
publishing {
publications {
group = libraryGroup
publications.withType<MavenPublication> {
artifactId.toLowerCase()
groupId = libraryGroup
artifactId = libraryArtifactId
version = libraryVersion
artifact(tasks["javadocJar"])
}
repositories {
maven {
url = libraryUri
credentials {
username = (System.getenv("GITHUB_USER") ?: project.properties["GITHUB_USER"]).toString()
password = (System.getenv("GITHUB_PERSONAL_ACCESS_TOKEN") ?: project.properties["GITHUB_PERSONAL_ACCESS_TOKEN"]).toString()
}
}
}
}
}
As you can see no framework generated in build folder.
just sync the project ... the framework file will be created .. or try ./gradlew build
I am trying to include the documentation into maven publication. The publication itself works fine. I can also publish with the setup bellow sources and javadoc to gitlab packages. I can download and open the javadoc.jar and sources.jar which contains those comments/documentation of classes. However when I include that library as a dependency to my android app as a gradle dependency, I can not see the comments on my interfaces/classes with F1 or when I open that class.
Any help would be appreciated.
Using kotlin DSL
id("maven-publish")
id("org.jetbrains.dokka")
tasks {
dokka {
outputFormat = "javadoc"
outputDirectory = "$buildDir/javadoc"
moduleName = rootProject.name
}
}
val dokkaJar by tasks.creating(Jar::class) {
group = JavaBasePlugin.DOCUMENTATION_GROUP
description = "Assembles Kotlin docs with Dokka"
archiveClassifier.set("javadoc")
from(tasks.dokka)
dependsOn(tasks.dokka)
}
val sourcesJar by tasks.registering(Jar::class) {
archiveClassifier.set("sources")
from(android.sourceSets.getByName("main").java.srcDirs)
}
artifacts {
archives(sourcesJar)
archives(dokkaJar)
}
afterEvaluate {
publishing {
publications {
create<MavenPublication>("snapshot_aar") {
groupId = libGroupId
artifactId = libArticactId
version = getVersionNameForSnapshot()
artifact(tasks.getByName("bundleDebugAar"))
artifact(dokkaJar)
artifact(sourcesJar)
pom.withXml {
fun groovy.util.Node.addDependency(dependency: Dependency) {
appendNode("dependency").apply {
appendNode("groupId", dependency.group)
appendNode("artifactId", dependency.name)
appendNode("version", dependency.version)
}
}
asNode().appendNode("dependencies").let { dependencies ->
configurations.api.get().allDependencies.forEach {
dependencies.addDependency(it)
}
configurations.implementation.get().allDependencies.forEach {
dependencies.addDependency(it)
}
}
}
}
...
I created a new project in Android Studio using KMM wizard. I was following handson tutorial and I noticed that I don't have an option of creating a package inside of some directories. Specifically, inside of "shared" module only kotlin directory of androidMain folder is always marked as "sources root".
I manually marked kotlin directories in other folders (commonMain, iosMain) as "sources root". I also marked sqldelight directory inside of commonMain as "sources root".
But Android Studio keeps reverting that state back periodically. I don't know what is causing this issue. It also shows that kotlin directory of androidMain folder is set as "sources root" and also is not. Which is weird, directory can't be set and unset as "sources root" at the same time.
Is it a bug of Android Studio, KMM Plugin or some kind of setting in preferences?
Android Studio version: 4.1.1
KMM plugin version: 0.1.3-release-54-Studio4.1
EDIT:
build.gradle.kts for shared module:
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins {
kotlin("multiplatform")
kotlin("plugin.serialization")
id("com.android.library")
id("kotlin-android-extensions")
id("com.squareup.sqldelight")
}
group = "com.example.kmmapplication"
version = "1.0-SNAPSHOT"
repositories {
gradlePluginPortal()
google()
jcenter()
mavenCentral()
}
kotlin {
android()
ios {
binaries {
framework {
baseName = "shared"
}
}
}
// Block from https://github.com/cashapp/sqldelight/issues/2044#issuecomment-721299517.
val onPhone = System.getenv("SDK_NAME")?.startsWith("iphoneos") ?: false
if (onPhone) {
iosArm64("ios")
} else {
iosX64("ios")
}
val coroutinesVersion = "1.3.9-native-mt"
val serializationVersion = "1.0.1"
val ktorVersion = "1.4.2"
val sqlDelightVersion: String by project
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-serialization:$ktorVersion")
implementation("com.squareup.sqldelight:runtime:$sqlDelightVersion")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting {
dependencies {
implementation("io.ktor:ktor-client-android:$ktorVersion")
implementation("com.squareup.sqldelight:android-driver:$sqlDelightVersion")
}
}
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:4.13.1")
}
}
val iosMain by getting {
dependencies {
implementation("io.ktor:ktor-client-ios:$ktorVersion")
implementation("com.squareup.sqldelight:native-driver:$sqlDelightVersion")
}
}
val iosTest by getting
}
}
android {
compileSdkVersion(29)
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdkVersion(24)
targetSdkVersion(29)
versionCode = 1
versionName = "1.0"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
}
sqldelight {
database("AppDatabase") {
packageName = "com.example.kmmapplication.shared.cache"
}
}
val packForXcode by tasks.creating(Sync::class) {
group = "build"
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
val framework =
kotlin.targets.getByName<KotlinNativeTarget>(targetName).binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
val targetDir = File(buildDir, "xcode-frameworks")
from({ framework.outputDirectory })
into(targetDir)
}
tasks.getByName("build").dependsOn(packForXcode)
settings.gradle.kts:
pluginManagement {
repositories {
gradlePluginPortal()
google()
jcenter()
mavenCentral()
}
resolutionStrategy {
eachPlugin {
if (requested.id.namespace == "com.android" || requested.id.name == "kotlin-android-extensions") {
useModule("com.android.tools.build:gradle:4.0.1")
}
}
}
}
rootProject.name = "KMMApplication"
include(":androidApp")
include(":shared")
gradle-wrapper.properties:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
These ios target definitions conflict:
ios { //Target 1
binaries {
framework {
baseName = "shared"
}
}
}
// Block from https://github.com/cashapp/sqldelight/issues/2044#issuecomment-721299517.
val onPhone = System.getenv("SDK_NAME")?.startsWith("iphoneos") ?: false
if (onPhone) {
iosArm64("ios") //Target 2
} else {
iosX64("ios") //Target 3
}
You have ios, which is a combined target for arm and x64, then the individual targets iosArm64 and iosX64`. I don't know if that's what's causing the IDE issue, but it's certainly confusing.
The 2nd two don't define frameworks as they were taken from a context that would use cocoapods. If you look at the sqldelight issue comment, it came from me, and ultimately came from KaMPKit: https://github.com/touchlab/KaMPKit/blob/master/shared/build.gradle.kts#L28.
To get the IDE working, I'd suggest removing the first ios target. However, again, the sample from the sqldelight issue assumes you have cocoapods configured. You'll either need to add cocoapods or update both the target config and packForXcode.
The targets would look something like the following.
val onPhone = System.getenv("SDK_NAME")?.startsWith("iphoneos") ?: false
if (onPhone) {
iosArm64("ios") {
binaries {
framework {
baseName = "shared"
}
}
}
} else {
iosX64("ios") {
binaries {
framework {
baseName = "shared"
}
}
}
}
As an alternative, I'd suggest just using KaMPKit as a base for your project until you're more familiar with the KMM plugin samples and config options. They don't quite work out of the box yet.
Im trying to publish an Android library (debug/release) with the new Kotlin MultiPlatform set up. Im successfully able to publish iOS frameworks, but not android libraries. This is the error I end up getting:
A problem occurred configuring project ':shared'.
Failed to notify project evaluation listener.
Kotlin target 'android' tried to set up publishing for Android build variants that are not library variants or do not exist:
* release
* debug
Check the 'publishLibraryVariants' property, it should point to existing Android library variants. Publishing of application and test variants is not supported.
However, I can clearly see the variants in my Android Studio. Im also able to run the Android/IOS app from Android Studio using the library dependecy as a project dependency
implementation(project(":shared"))
Only facing problems when trying to publish it.
This is my build.gradle.kts:
plugins {
kotlin("multiplatform")
kotlin("plugin.serialization")
id("com.android.library")
id("kotlin-android-extensions")
id("com.squareup.sqldelight")
id("dev.icerock.mobile.multiplatform-resources")
`maven-publish`
}
group = "com.sekhar.testkmp"
version = "0.1"
val coroutinesVersion = "1.3.9-native-mt"
val serializationVersion = "1.0.0-RC"
val ktorVersion = "1.4.0"
val sqlDelightVersion: String by project
repositories {
gradlePluginPortal()
google()
jcenter()
mavenCentral()
}
kotlin {
android {
publishLibraryVariants("release", "debug")
}
ios {
binaries {
framework {
baseName = "shared"
}
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$serializationVersion")
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-serialization:$ktorVersion")
implementation("com.squareup.sqldelight:runtime:$sqlDelightVersion")
implementation("dev.icerock.moko:resources:0.13.1")
implementation("dev.icerock.moko:parcelize:0.4.0")
implementation("dev.icerock.moko:graphics:0.4.0")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting {
dependencies {
implementation("com.google.android.material:material:1.2.1")
implementation("io.ktor:ktor-client-android:$ktorVersion")
implementation("com.squareup.sqldelight:android-driver:$sqlDelightVersion")
}
}
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:4.12")
}
}
val iosMain by getting {
dependencies {
implementation("io.ktor:ktor-client-ios:$ktorVersion")
implementation("com.squareup.sqldelight:native-driver:$sqlDelightVersion")
}
}
val iosTest by getting
}
}
dependencies {
commonMainApi("dev.icerock.moko:resources:0.13.1")
}
multiplatformResources {
multiplatformResourcesPackage = "com.sekhar.testkmp" // required
}
android {
compileSdkVersion(29)
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdkVersion(24)
targetSdkVersion(29)
versionCode = 1
versionName = "1.0"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
getByName("debug") {
isMinifyEnabled = false
}
}
lintOptions {
isAbortOnError = false
}
}
val packForXcode by tasks.creating(Sync::class) {
group = "build"
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
val framework = kotlin.targets.getByName<KotlinNativeTarget>(targetName).binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
val targetDir = File(buildDir, "xcode-frameworks")
from({ framework.outputDirectory })
into(targetDir)
}
tasks.getByName("build").dependsOn(packForXcode)```
The most common solution to this is to apply the android plugin: id("com.android.library") before the kotlin multiplatform plugin: kotlin("multiplatform").
plugins {
id("com.android.library")
kotlin("multiplatform")
kotlin("plugin.serialization")
id("kotlin-android-extensions")
id("com.squareup.sqldelight")
id("dev.icerock.mobile.multiplatform-resources")
`maven-publish`
}
I am creating a Kotlin Multiplatform library with Android support.
When I try to build with gradle I get an error (./gradlew build --warning-mode all).
Either this:
Could not determine the dependencies of task ':lib:compileDebugAidl'.
> Failed to find target with hash string '29' in: /home/user/Android/Sdk
Or that:
Could not determine the dependencies of task ':lib:verifyReleaseResources'.
> Failed to find target with hash string '29' in: /home/user/Android/Sdk
The first right after indexing and the second when I do ./gradlew clean
However, there is this dependency in any case since I have already created Android apps based on that.
I have also tried Target 28 and an RC version of 30 (since 30 has not yet been officially released, but I have still created apps)
My structure of the gradle files is like this:
root
|-build.gradle.kts
|-settings.gradle.kts
|-gradlew
|-gradlew.bat
|-gradle
|-wrapper
|-gradle-wrapper.jar
|-gradle-wrapper.properties
|-lib
|-build.gradle.kts
settings.gradle.kts:
rootProject.name = "Library"
include(":lib")
root build.gradle.kts:
buildscript {
repositories {
addRepos()
maven(uri("https://dl.bintray.com/kotlin/kotlin-eap")) {
metadataSources {
gradleMetadata()
mavenPom()
}
}
}
dependencies {
classpath("com.android.tools.build:gradle:4.1.0-beta04")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.72")
}
}
allprojects {
repositories {
addRepos()
maven(uri("https://dl.bintray.com/kotlin/kotlin-eap")) {
metadataSources {
gradleMetadata()
mavenPom()
}
}
}
}
lib build.gradle.kts:
plugins {
id("com.android.library")
kotlin("multiplatform")
id("maven-publish")
}
group = "de.datlag"
version = "1.0"
android {
compileSdkVersion = 29.toString()
buildToolsVersion = "29.0.3"
defaultConfig {
targetSdkVersion(29)
versionCode = 1
versionName = "1.0"
}
buildTypes {
val debug by getting {
isMinifyEnabled = false
isDebuggable = true
isShrinkResources = false
}
val release by getting {
isMinifyEnabled = false
isDebuggable = false
isShrinkResources = false
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
repositories {
addRepos()
}
kotlin {
jvm {
compilations.all {
kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
js {
browser()
nodejs()
}
android {
publishAllLibraryVariants()
}
val hostOs = System.getProperty("os.name")
val isMingwX64 = hostOs.startsWith("Windows")
val nativeTarget = when {
hostOs == "Mac OS X" -> macosX64("native")
hostOs == "Linux" -> linuxX64("native")
isMingwX64 -> mingwX64("native")
else -> throw GradleException("Host OS is not supported in Kotlin/Native.")
}
sourceSets {
val commonMain by getting {
dependencies {
implementation(kotlin("stdlib-common"))
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val jvmMain by getting {
dependencies {
implementation(kotlin("stdlib-jdk8"))
}
}
val jvmTest by getting {
dependencies {
implementation(kotlin("test"))
implementation(kotlin("test-junit"))
}
}
val androidMain by getting {
dependsOn(jvmMain)
}
val androidTest by getting {
dependsOn(jvmTest)
}
val jsMain by getting {
dependencies {
implementation(kotlin("stdlib-js"))
}
}
val jsTest by getting {
dependencies {
implementation(kotlin("test-js"))
}
}
val nativeMain by getting { }
val nativeTest by getting { }
}
}
addRepos method:
fun RepositoryHandler.addRepos() {
mavenLocal {
metadataSources {
gradleMetadata()
mavenPom()
}
}
mavenCentral {
metadataSources {
gradleMetadata()
mavenPom()
}
}
jcenter {
metadataSources {
gradleMetadata()
mavenPom()
}
}
google {
metadataSources {
gradleMetadata()
mavenPom()
}
}
gradlePluginPortal()
}
In lib.build.gradle.kts you should use the compileSdkVersion(29) syntax rather than setting a string. You can see in the source for these extensions that the behavior is different if you call the string version.
/** #see #getCompileSdkVersion() */
public void compileSdkVersion(String version) {
checkWritability();
this.target = version;
}
/** #see #getCompileSdkVersion() */
public void compileSdkVersion(int apiLevel) {
compileSdkVersion("android-" + apiLevel);
}
The when passing an int it will append "android-" for you. So you could do compileSdkVersion = "android-29" if you wanted, but just passing the int is easier