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
Related
I'd like to Maven publish in my Android app, and I'm using kotlin-dsl for gradle files. This is how I'm trying to publish my code:
subprojects {
plugins.apply("maven-publish")
afterEvaluate {
// Common settings
if (isAndroidLibrary || isAndroidApplication) {
extensions.getByType<com.android.build.gradle.BaseExtension>().apply {
compileSdkVersion(CommonVersions.targetsdk)
buildToolsVersion = CommonVersions.buildTools
defaultConfig {
minSdkVersion(CommonVersions.minsdk)
targetSdkVersion(CommonVersions.targetsdk)
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
buildFeatures.viewBinding = true
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
}
// Set up publishing configuration
val sourceSets: SourceSetContainer by project
print("project name: $name, ")
print("project size: ${sourceSets.size}, ")
print("project size: ${project.the<SourceSetContainer>().size}, ")
print("project size: ${the<SourceSetContainer>().size}, ")
if (!notPublishingModules.contains(name) && sourceSets.size != 0) {
configure<PublishingExtension> {
publications {
create<MavenPublication>("maven") {
groupId = "xx.yyy.zz"
artifactId = "test"
version = "0.0.0"
from(components.findByName("release"))
val sourcesJar by tasks.creating(Jar::class) {
val sourceSets: SourceSetContainer by project
from(sourceSets["main"].allJava)
classifier = "sources"
}
artifact(sourcesJar)
}
}
}
}
}
}
I always get this error: SourceSet with name 'main' not found.
As you can see I was trying to print the sourceset out, to see if it has any information or not. The size of the sourceset is always zero.
What am I doing wrong?
I use groovy with spring applications , I think you missing this in your code
sourceSets {
main {
java { srcDirs = ["src/java"] }
resources { srcDir "src/resources" }
}
}
where you define where is srcDirs are .
I am creating a Jetbrains Compose Multiplatform project. But I will only need Desktop (JVM) and Android, so two JVM targets. I want to factor out the logic which needs grpc, so both Android and Desktop can use it without me having to program it twice.
I can't seem to figure out a way of binding in my grpc/proto into the project, so that I can write the logic once and share it between android and desktop.
This is what my build.gradle.kts of the common project looks like:
plugins {
id("com.android.library")
kotlin("multiplatform")
id("org.jetbrains.compose")
}
kotlin {
android()
jvm("desktop")
sourceSets {
named("commonMain") {
dependencies {
api(compose.runtime)
api(compose.foundation)
api(compose.material)
api(compose.ui)
implementation(compose.preview)
implementation(compose.uiTooling)
}
}
}
}
android {
compileSdk = 31
defaultConfig {
minSdk = 21
targetSdk = 31
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
sourceSets {
named("main") {
manifest.srcFile("src/androidMain/AndroidManifest.xml")
res.srcDirs("src/androidMain/res")
}
}
}
I tried binding my protos into a sourceset but couldn't get it working.
My other approach:
Next I tried creating a second submodule where the protos and the logic would be bound, but I couldn't get that working either:
Here is the build.gradle.kts for shared-logic:
import com.google.protobuf.gradle.*
import org.gradle.kotlin.dsl.proto
plugins {
kotlin("jvm")
idea
id("com.google.protobuf")
}
version = "unspecified"
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib"))
api(project(":kotlin-common")) {
exclude(group = "io.grpc", module = "grpc-protobuf")
exclude(group = "io.grpc", module = "grpc-stub")
}
implementation("io.grpc:grpc-okhttp:${Versions.GRPC}")
api("com.google.protobuf:protobuf-java-util:${Versions.PROTOBUF}")
api("io.grpc:grpc-stub:${Versions.GRPC}")
api("io.grpc:grpc-protobuf-lite:${Versions.GRPC}")
api("io.grpc:grpc-kotlin-stub:${Versions.GRPC_KOTLIN}")
api("com.google.protobuf:protobuf-kotlin-lite:${Versions.PROTOBUF}")
api("io.insert-koin:koin-core:${Versions.KOIN}")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.COROUTINES}")
}
sourceSets {
main {
proto {
srcDirs("../protos/src/main")
}
}
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${Versions.PROTOBUF}"
}
plugins {
id("java") {
artifact = "io.grpc:protoc-gen-grpc-java:${Versions.GRPC}"
}
id("grpc") {
artifact = "io.grpc:protoc-gen-grpc-java:${Versions.GRPC}"
}
id("grpckt") {
artifact = "io.grpc:protoc-gen-grpc-kotlin:${Versions.GRPC_KOTLIN}:jdk7#jar"
}
}
generateProtoTasks {
all().forEach {
it.plugins {
id("grpc") {
option("lite")
}
id("grpckt") {
option("lite")
}
}
it.builtins {
id("kotlin") {
option("lite")
}
}
}
}
}
Here is the build.gradle.kts for kotlin-common:
plugins {
kotlin("jvm")
}
version = "1.0.0"
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib"))
implementation("io.grpc:grpc-stub:${Versions.GRPC}")
}
Here I get resolution error I tried fixing but couldn't figure out what to exclude:
Duplicate class com.google.protobuf.AbstractMessageLite found in modules jetified-protobuf-java-3.19.1 (com.google.protobuf:protobuf-java:3.19.1) and jetified-protobuf-javalite-3.19.1 (com.google.protobuf:protobuf-javalite:3.19.1)
Duplicate class com.google.protobuf.AbstractMessageLite$Builder found in modules jetified-protobuf-java-3.19.1 (com.google.protobuf:protobuf-java:3.19.1) and jetified-protobuf-javalite-3.19.1 (com.google.protobuf:protobuf-javalite:3.19.1)
Duplicate class com.google.protobuf.AbstractMessageLite$Builder$LimitedInputStream found in modules jetified-protobuf-java-3.19.1 (com.google.protobuf:protobuf-java:3.19.1) and jetified-protobuf-javalite-3.19.1 (com.google.protobuf:protobuf-javalite:3.19.1)
...
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 want to convert this file in old build.gradle file, I am doing but there are alot of errors.
have searched too many google links but nothing happened.
I want to convert this file in old build.gradle file, I am doing but there are alot of errors.
have searched too many google links but nothing happened.
import com.android.build.gradle.api.ApplicationVariant
plugins {
id("com.android.application")
kotlin("android")
kotlin("android.extensions")
}
android {
compileSdkVersion(29)
defaultConfig {
minSdkVersion(14)
targetSdkVersion(29)
versionCode = 1
versionName = "0.1.1"
externalNativeBuild {
cmake {
}
}
}
externalNativeBuild {
cmake {
setPath(File("${projectDir}/src/main/cpp/CMakeLists.txt"))
}
}
sourceSets {
getByName("main") {
assets.srcDirs("src/main/assets", "build/ovpnassets")
}
getByName("debug") {
}
getByName("release") {
}
}
lintOptions {
enable("BackButton", "EasterEgg")
warning("ImpliedQuantity", "MissingQuantity")
disable("MissingTranslation", "UnsafeNativeCodeLocation")
}
buildTypes {
getByName("release") {
if (project.hasProperty("icsopenvpnDebugSign")) {
logger.warn("property icsopenvpnDebugSign set, using debug signing for release")
signingConfig = android.signingConfigs.getByName("debug")
} else {
signingConfig = signingConfigs.getByName("release")
}
}
}
flavorDimensions("implementation")
productFlavors {
create("ui") {
setDimension("implementation")
buildConfigField("boolean", "openvpn3", "true")
}
}
splits {
abi {
isEnable = true
reset()
include("x86", "x86_64", "armeabi-v7a", "arm64-v8a")
isUniversalApk = true
}
}
}
var swigcmd = "swig"
if (File("/usr/local/bin/swig").exists())
swigcmd = "/usr/local/bin/swig"
fun registerGenTask(variantName: String, variantDirName: String): File {
val baseDir = File(buildDir, "generated/source/ovpn3swig/${variantDirName}")
val genDir = File(baseDir, "net/openvpn/ovpn3")
tasks.register<Exec>("generateOpenVPN3Swig${variantName}")
{
doFirst {
mkdir(genDir)
}
commandLine(listOf(swigcmd, "-outdir", genDir, "-outcurrentdir", "-c++", "-java", "-package", "net.openvpn.ovpn3",
"-Isrc/main/cpp/openvpn3/client", "-Isrc/main/cpp/openvpn3/",
"-o", "${genDir}/ovpncli_wrap.cxx", "-oh", "${genDir}/ovpncli_wrap.h",
"src/main/cpp/openvpn3/javacli/ovpncli.i"))
}
return baseDir
}
android.applicationVariants.all(object : Action<ApplicationVariant> {
override fun execute(variant: ApplicationVariant) {
val sourceDir = registerGenTask(variant.name, variant.baseName.replace("-", "/"))
val task = tasks.named("generateOpenVPN3Swig${variant.name}").get()
variant.registerJavaGeneratingTask(task, sourceDir)
}
})
dependencies {
val preferenceVersion = "1.1.0"
implementation("androidx.annotation:annotation:1.1.0")
implementation("androidx.core:core:1.1.0")
dependencies.add("uiImplementation", "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.50")
dependencies.add("uiImplementation", "androidx.core:core:$coreVersion")
dependencies.add("uiImplementation", "androidx.core:core-ktx:$coreVersion")
dependencies.add("uiImplementation", "androidx.fragment:fragment-ktx:1.1.0")
dependencies.add("uiImplementation", "androidx.preference:preference:$preferenceVersion")
dependencies.add("uiImplementation", "androidx.preference:preference-ktx:$preferenceVersion")
testImplementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.61")
}
I'm using new beta version of Android Studio 3.4 and kotlin dsl as bulding gradle scripts. I have a lot of modules in the project and that's why I write KotlinBuildScript extension for building projects, but I have error message for all external dependencies like "ERROR: Failed to resolve: com.google.dagger:dagger:2.18", "ERROR: Failed to resolve: androidx.recyclerview:recyclerview:1.0.0". How can I fix it?
Here is my root build.gradle.kts:
buildscript {
repositories {
mavenCentral()
jcenter()
google()
maven(url = uri("https://dl.bintray.com/kotlin/kotlin-eap"))
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.10")
}
}
allprojects {
repositories {
mavenCentral()
jcenter()
google()
maven(url = uri("https://dl.bintray.com/kotlin/kotlin-eap"))
}
}
And my KotlinBuildScript:
object Version {
val kotlin = "1.3.10"
val androidx = "1.0.0"
val constraintlayout = "1.1.3"
val lifecycle = "2.0.0"
val paging = "2.1.0-alpha01"
}
fun KotlinBuildScript.setupApplication(applicationId:String, versionCode:Int, versionName:String) =
setup(applicationId, versionCode, versionName, false)
fun KotlinBuildScript.setupLibrary(applicationId:String) = setup(applicationId, null, null, true)
private fun KotlinBuildScript.setup(
applicationId:String, versionCode:Int?, versionName:String?, library:Boolean
) {
setupPlugins(library)
setupConfiguration(library, applicationId, (versionCode ?: 1) * 2, versionName ?: "1.0")
setupDependencies(library)
}
private fun KotlinBuildScript.setupConfiguration(
library:Boolean, applicationId:String, versionCode:Int, versionName:String
) {
configure<BaseExtension> {
compileSdkVersion(28)
buildToolsVersion("28.0.3")
defaultConfig {
if (!library) {
this.applicationId = applicationId
this.versionCode = versionCode
this.versionName = versionName
}
minSdkVersion(16)
targetSdkVersion(28)
multiDexEnabled = true
vectorDrawables.useSupportLibrary = true
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
}
packagingOptions {
exclude("META-INF/LICENSE.txt")
}
lintOptions {
isCheckReleaseBuilds = false
}
if (library) {
defaultConfig.ndk {
abiFilters("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
}
externalNativeBuild {
cmake {
setPath("CMakeLists.txt")
}
}
} else {
flavorDimensions("architecture")
productFlavors {
create("arm") {
dimension = "architecture"
this.versionCode = versionCode - 1
versionNameSuffix = "-arm"
ndk {
abiFilters("armeabi")
}
}
create("x86") {
dimension = "architecture"
this.versionCode = versionCode
versionNameSuffix = "-x86"
ndk {
abiFilters("x86")
}
}
}
}
}
}
private fun KotlinBuildScript.setupPlugins(library:Boolean) {
apply {
plugin("com.android." + (if (library) "library" else "application"))
plugin("kotlin-android")
plugin("kotlin-android-extensions")
plugin("kotlin-kapt")
}
}
private fun KotlinBuildScript.setupDependencies(library:Boolean) {
dependencies {
add("testImplementation", "junit:junit:4.12")
add("implementation", fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
if (!library) {
add("implementation", project(":Library"))
}
add("kapt", "com.google.dagger:dagger-compiler:2.18")
add("implementation", "com.google.dagger:dagger:2.18")
add("kapt", "androidx.lifecycle:lifecycle-compiler:${Version.lifecycle}")
add("implementation", "androidx.lifecycle:lifecycle-extensions:${Version.lifecycle}")
add("implementation", "androidx.lifecycle:lifecycle-common-java8:${Version.lifecycle}")
add("implementation", "javax.inject:javax.inject:1")
add("implementation", "javax.annotation:javax.annotation-api:1.2")
add("implementation", "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${Version.kotlin}")
add("implementation", "org.jetbrains.kotlin:kotlin-reflect:${Version.kotlin}")
add("implementation", "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0-RC1")
}
}
App module gradle:
import Setup.Version
import Setup.setupLibrary
setupLibrary("com.esminis.server.library")
I've found how to solve the problem. Using kotlin dsl you should always set buildFileName property in the settings.gradle of the project.
rootProject.buildFileName = 'build.gradle.kts'
Also, try to delete .idea and .gradle folder and restart Android Studio.