1

I am trying to build an Android Library and I have the following:

  • Github Repo for the library
    • Library 1: Kotlin native/multiplatform code that can compile to Android and iOS
    • Library 2: Kotlin/JVM code dependent on Library 1
    • Example App: App using Library 2 and Library 1
  • Personal Android Project
    • Dependent on the Github Library above

On my personal project I only have:

implementation 'com.github.username:myrepo:0.5'

Issues

  1. The private Android project is loading android library (Library 2) but the multiplatform kotlin models and functions (Library 1) are not accessible.

    Note that the example app of the library is working fine. I suspect that the jitpack.io is not publishing the artifacts correctly. Any idea on how to troubleshoot this? Is there anything that should be done to the gradle files to solve the problem?

  2. I would like to have the multiplatform library published alone. I tried to access it from a multiplatform Kotlin module but I am getting "Unable to resolve dependencies". This is what I was trying:

    implementation 'com.github.username.myrepo:library1_moduleName:0.1'


Gradle for Library 1 multiplatform:

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 = "library1"
                freeCompilerArgs.add("-Xobjc-generics")

            }
        }
    }

    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)

Gradle for library 2

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {

    repositories {
        google()
        jcenter()
        maven { url 'https://jitpack.io' }
    }

    compileSdkVersion 29
    buildToolsVersion "29.0.0"


    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 29

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles 'consumer-rules.pro'
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    api project(":library1")
}

2 Answers 2

2

I suggest you change your build.gradle configuration for targeting android/ Change it to

plugins {
    kotlin("multiplatform")
    id("com.android.library")
    id("maven-publish")
}

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.0"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 29
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

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 = "library1"
                freeCompilerArgs.add("-Xobjc-generics")

            }
        }
    }

    // jvm("android")
    android {
        publishLibraryVariants("release")
    }

    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)

create an AndroidManifest.xml file for library1 under src/main/AndroidManifest.xml

<manifest package="library1"/>

you can now push your projet to github, create a tag and wait for jitpack to do its magic

When you want to use it in library2, under the dependencies section, just add

implementation 'com.github.username.myrepo:library1-android:0.1' //for android
Sign up to request clarification or add additional context in comments.

Comments

1

Think you may need to enable meta-data for the multi-platform library; in settings.gradle:

enableFeaturePreview('GRADLE_METADATA')

As well as configuring the library for Maven (it is unclear how you publish it to GitHub, as the build.gradle does not feature any of that as automation). Even when publishing it to GitHub instead of mavenLocal(), it likely needs to provide some kind of meta-data... as "Unable to resolve dependencies" might hint for, assuming that it exists under the referenced package name.

apply plugin: 'maven-publish'
group 'com.github.username'
version '1.0.0'

Configuration api is merely good for dependencies, which are being referenced by multiple modules; everything else (any single occurance) should be implementation. I mean, I find the library 2 build.gradle confusing, because on top it reads maven { url 'https://jitpack.io' } (without actually referencing a remote dependency) and then later it reads api project(":library1") (which defintely is a local dependency).

3 Comments

I am using jitpack.io, it relies on the GitHub release version to build the artifacts. But it's only building one of the submodules. After I applied the changes you suggested (except the version since it's taken from GitHub) it is now building the kotin multi-platform (Library 1) and nothing related to Library 2. For the last point, I have other dependencies that I removed to simplify the question. I should have removed repositories. Thanks
@ELKA Packaging multi-platform libraries with jitpack.io may not yet be possible: github.com/jitpack/jitpack.io/issues/3853
Thanks, I switched to maven.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.