I wonder if is possible to access the Android context application in androidMain sourceSets with the kotlin-multiplatform plugin.
Here is the build.gradle file
apply plugin: 'kotlin-multiplatform'
kotlin {
targets {
final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
? presets.iosArm64 : presets.iosX64
fromPreset(iOSTarget, 'iOS') {
compilations.main.outputKinds('FRAMEWORK')
}
fromPreset(presets.jvm, 'android')
}
sourceSets {
commonMain {
kotlin.srcDir('src')
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
// coroutine
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.1.0"
}
}
androidMain {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
// Timber
implementation "com.jakewharton.timber:timber:$timber_version"
// coroutine
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.0"
}
}
}
}
I have tried add the 'com.android.application' plugin into androidMain source, but the sync fails.
Thanks in advance
Yes, you can.
In your build.gradle file you are not targeting android as such (presets.android) but the jvm (presets.jvm) and calling it android.
As it is now, what your build will generated is a JAR file not an aar file.
If you want to target android you have also to use the android gradle plugin. To be able to use the android framework from the androidMain folder, update your build.gradle file. Below an example:
apply plugin: 'org.jetbrains.kotlin.multiplatform'
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName '1.0'
}
buildTypes {
release {
minifyEnabled false
}
}
// By default the android gradle plugin expects to find the kotlin source files in
// the folder `main` and the test in the folder `test`. This is to be able place
// the source code files inside androidMain and androidTest folders
sourceSets {
main {
manifest.srcFile 'src/androidMain/AndroidManifest.xml'
java.srcDirs = ['src/androidMain/kotlin']
res.srcDirs = ['src/androidMain/res']
}
test {
java.srcDirs = ['src/androidTest/kotlin']
res.srcDirs = ['src/androidTest/res']
}
}
}
dependencies {
implementation "com.jakewharton.timber:timber:$timber_version
}
kotlin {
targets {
final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
? presets.iosArm64 : presets.iosX64
fromPreset(iOSTarget, 'iOS') {
compilations.main.outputKinds('FRAMEWORK')
}
fromPreset(presets.android, 'android')
}
sourceSets {
commonMain {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
// coroutine
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.1.0"
}
}
androidMain {
dependencies {
api "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
}
}
}
task buildiOSFramework(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
inputs.property "mode", mode
dependsOn kotlin.targets.iOS.compilations.main.linkTaskName("FRAMEWORK", mode)
from { kotlin.targets.iOS.compilations.main.getBinary("FRAMEWORK", mode).parentFile }
into frameworkDir
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$#\n"
setExecutable(true)
}
}
}
Related
I am trying to develop a small library to post issues to my company's Jira server, and I thought that a Kotlin MPP w/ KTOR would be just the ticket.
At first, following a few tutorials, I made a shared project, and the imports for iOS were working fine but Android's Ktor implementation would not resolve. Then I realized that I needed to recreate the project and create a library instead of a shared application, as I have existing codebases for each mobile client already, and I need to publish the MPP library to be used by them.
Upon recreating the project as a library, and simply starting to add the dependencies for KTOR 1.3.2, the iOS dependencies are failing to resolve. This is not just KTOR, it is any iOS dependency, so there's obviously something incorrect in my project setup, but I am unable to spot it.
Here is the gradle file:
plugins {
id 'org.jetbrains.kotlin.multiplatform' version '1.3.72'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://kotlin.bintray.com/kotlinx" }
}
group 'com.example.issuereporter'
version '0.0.1'
apply plugin: 'maven-publish'
kotlin {
targets {
final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") ? presets.iosArm64 : presets.iosX64
fromPreset(iOSTarget, 'ios') {
binaries {
framework('IssueReporter')
}
}
fromPreset(presets.jvm, 'android')
}
def ktor_version = "1.3.2"
sourceSets["commonMain"].dependencies {
implementation kotlin('stdlib-common')
implementation "io.ktor:ktor-client-core:$ktor_version"
implementation "io.ktor:ktor-client-json:$ktor_version"
implementation "io.ktor:ktor-client-serialization:$ktor_version"
}
sourceSets["commonTest"].dependencies {
implementation kotlin('test-common')
implementation kotlin('test-annotations-common')
}
sourceSets["androidMain"].dependencies {
implementation kotlin('stdlib')
implementation "io.ktor:ktor-client-core-jvm:$ktor_version"
implementation "io.ktor:ktor-client-json-jvm:$ktor_version"
implementation "io.ktor:ktor-client-serialization-jvm:$ktor_version"
implementation "io.ktor:ktor-client-auth-jvm:$ktor_version"
}
sourceSets["androidTest"].dependencies {
implementation kotlin('test')
implementation kotlin('test-junit')
}
sourceSets["iosMain"].dependencies {
implementation "io.ktor:ktor-client-ios:$ktor_version"
implementation "io.ktor:ktor-client-core-native:$ktor_version"
implementation "io.ktor:ktor-client-json-native:$ktor_version"
implementation "io.ktor:ktor-client-serialization-native:$ktor_version"
}
}
configurations {
compileClasspath
}
task packForXcode(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
final def framework = kotlin.targets.ios.binaries.getFramework("IssueReporter", mode)
inputs.property "mode", mode
dependsOn framework.linkTask
from { framework.outputFile.parentFile }
into frameworkDir
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$#\n"
setExecutable(true)
}
}
}
tasks.build.dependsOn packForXcode
The console output is
Could not resolve io.ktor:ktor-client-ios:1.3.2.
Could not resolve io.ktor:ktor-client-core-native:1.3.2.
Could not resolve io.ktor:ktor-client-json-native:1.3.2.
Could not resolve io.ktor:ktor-client-serialization-native:1.3.2.
Anything obvious that I am missing here?
UPDATE
I scrapped and recreated the project w/ an updated version of IntelliJ (IntelliJ IDEA 2019.3.5 (Community Edition)) & the Kotlin 1.4.0 Plugin installed. This gave me a slightly different creation wizard, and the option to use Kotlin as the Gradle syntax.
Updated build.gradle.kts file:
plugins {
kotlin("multiplatform") version "1.4.0"
kotlin("plugin.serialization") version "1.4.0"
id("com.android.library")
id("kotlin-android-extensions")
}
group = "com.example.issuereporter"
version = "1.0-SNAPSHOT"
repositories {
gradlePluginPortal()
google()
jcenter()
mavenCentral()
maven(url = "https://kotlin.bintray.com/kotlinx")
maven(url = "https://dl.bintray.com/kotlin/ktor")
maven(url = "https://repo1.maven.org/maven2/")
maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
maven(url = "https://plugins.gradle.org/m2/")
}
kotlin {
android()
iosX64("ios") {
binaries {
framework {
baseName = "library"
}
}
}
val ktor_version = "1.3.2"
val serialization_version = "0.20.0"
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.ktor:ktor-client-core:$ktor_version")
implementation("io.ktor:ktor-client-json:$ktor_version")
implementation("io.ktor:ktor-client-serialization:$ktor_version")
implementation("io.ktor:ktor-client-auth:$ktor_version")
implementation("io.ktor:ktor-client-apache:$ktor_version")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting {
dependencies {
implementation("androidx.core:core-ktx:1.2.0")
implementation("io.ktor:ktor-client-android:$ktor_version")
implementation("io.ktor:ktor-client-auth-jvm:$ktor_version")
implementation("io.ktor:ktor-client-json-jvm:$ktor_version")
}
}
val androidTest by getting
val iosMain by getting {
dependencies {
implementation("io.ktor:ktor-client-ios:$ktor_version")
implementation ("io.ktor:ktor-client-core-native:$ktor_version")
implementation("io.ktor:ktor-client-json-native:$ktor_version")
implementation("io.ktor:ktor-client-auth-native:$ktor_version")
}
}
val iosTest by getting
}
}
android {
compileSdkVersion(29)
defaultConfig {
minSdkVersion(24)
targetSdkVersion(29)
versionCode = 1
versionName = "1.0"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
}
The gradle dependencies for iOS successfully sync when I set the ktor_version to 1.3.2 but not for 1.4.0 (assuming the mirrors haven't updated for the native files??)... but the imports don't compile when I attempt to utilize the class at all... see attached image:
I would guess you don't have enableFeaturePreview("GRADLE_METADATA") in settings.gradle.
settings.gradle
Check our starter project KaMPKit for a running example on 1.3.72. We'll probably bump that to 1.4.0 this week, but for now it should be a good reference.
Here are my dependencies (I have separate iOS targets, but it should still help you):
iosEmulatorMain.dependencies {
implementation "io.ktor:ktor-client-ios:$ktorVersion"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutinesVersion"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serializationVersion"
implementation "com.soywiz.korlibs.klock:klock-iosx64:$klockVersion"
implementation "com.github.aakira:napier-iosX64:$napierVersion"
}
iosDeviceMain.dependencies {
implementation "io.ktor:ktor-client-ios:$ktorVersion"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutinesVersion"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serializationVersion"
implementation "com.soywiz.korlibs.klock:klock-iosarm64:$klockVersion"
implementation "com.github.aakira:napier-iosArm64:$napierVersion"
}
Versions:
ktorVersion=1.3.2
Repositories:
maven(url = "https://kotlin.bintray.com/kotlinx")
maven(url = "https://dl.bintray.com/kotlin/ktor")
maven(url = "https://repo1.maven.org/maven2/")
maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
maven(url = "https://plugins.gradle.org/m2/")
To configure client serializer try to write it like this:
install(JsonFeature) {
serializer = KotlinxSerializer(kotlinx.serialization.json.Json {
ignoreUnknownKeys = true
})
}
I have two gradle . One is project level gradle and another is app level gradle . In app gradle when I add this line, "apply from: "../../../buildCommon/common.gradle"" , then manifest file is lost .
The content of app level gradle is given here :
apply plugin: 'com.android.application'
apply from: "../../../buildCommon/applicationCommon.gradle"
apply from: "../../../buildCommon/common.gradle"
android {
compileSdkVersion 19
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "era.safetynet.payment.apps"
minSdkVersion 14
targetSdkVersion 17
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile project(':ftrSDKHelperAndroid')
compile 'com.android.support:support-v4:19.1.0'
}
The content of applicationCommon.gradle is as follows :
// ============================================================================
// Main
// ============================================================================
project.ext.productRootDir = "E://Face Verification Application//Neurotec_Latest"
project.ext.productBinDir = new File(project.productRootDir, "Bin")
project.ext.productBinJavaDir = new File(project.productBinDir, "Java")
project.ext.productBinAndroidDir = new File(project.productBinDir, "Android")
project.ext.productLibAndroidDir = new File(project.productRootDir, "Lib/Android")
// ============================================================================
// Android
// ============================================================================
apply plugin: 'com.android.application'
android {
sourceSets {
main {
jni.srcDirs = [] // This prevents the auto generation of Android.mk
jniLibs.srcDir new File(projectDir, "lib")
}
}
}
The content of common.gradle is as follows :
project.ext.defaultArchitectures = "arm64-v8a,armeabi-v7a,x86"
group = 'com.neurotec.samples'
version = '9.0.0.0'
// ============================================================================
// Android
// ============================================================================
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 15
targetSdkVersion 19
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6
targetCompatibility JavaVersion.VERSION_1_6
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src/main/java']
resources.srcDirs = ['src/main/resources']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
androidTest.setRoot('src/main/tests')
}
packagingOptions {
exclude "META-INF/LE-832C0.RSA"
exclude "META-INF/LE-832C0.SF"
}
lintOptions {
abortOnError false
}
}
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:deprecation"
}
}
// ============================================================================
// Building
// ============================================================================
// Also delete all project related files from product bin directory.
clean {
delete fileTree(dir: project.productBinAndroidDir , include: "${archivesBaseName}*.*")
}
// Copy data files images to project build directory so thay can be packed in apk.
if (project.hasProperty("ndfFiles")) {
task prepareNdfFiles(type: Copy) {
from "${project.productBinDir}/Data"
includes = project.ndfFiles
rename { String fileName ->
fileName.replace('.ndf', '.ndf.jet')
}
into "${android.sourceSets.main.assets.srcDirs[0]}/data";
}
tasks.preBuild.dependsOn(prepareNdfFiles)
}
// Copy native libraries to project directory so thay can be packed in apk.
if (project.hasProperty("nativeLibsInclude") || project.hasProperty("nativeLibsExclude")) {
if (!project.hasProperty("arch")) {
project.ext.arch = project.defaultArchitectures;
}
int counter = 1;
project.arch.split(',').each {
String srcDir = "${project.productLibAndroidDir}/${it}"
String dstDir = "${projectDir}/lib/${it}"
task "prepareNativeLibs$counter"(type: Copy) {
from srcDir
if (project.hasProperty("nativeLibsInclude")) {
for (String lib : project.nativeLibsInclude) {
include lib;
}
}
if (project.hasProperty("nativeLibsExclude")) {
for (String lib : project.nativeLibsExclude) {
exclude lib;
}
}
into dstDir
}
tasks.preBuild.dependsOn("prepareNativeLibs$counter");
counter++;
}
}
// Copy apk to product bin directory.
task copyApk(type: Copy) {
from "${project.buildDir}/outputs/apk"
include "${project.archivesBaseName}-debug.apk"
rename "${project.archivesBaseName}-debug.apk", "${project.archivesBaseName}.apk"
into project.productBinAndroidDir
}
tasks.build.dependsOn(copyApk)
task deleteTemporaryFiles(type: Delete) {
if (project.hasProperty("ndfFiles")) {
for (String file : project.ndfFiles) {
delete "${android.sourceSets.main.assets.srcDirs[0]}/data/${file}.jet";
}
}
delete "${projectDir}/lib"
}
tasks.copyApk.dependsOn(deleteTemporaryFiles)
// ============================================================================
// Dependencies
// ============================================================================
dependencies {
project.ext.modules = [
"android": "com.google.android:android:4.1.1.4",
"acra": "ch.acra:acra:4.5.0",
]
}
repositories {
mavenLocal()
mavenCentral()
flatDir {
dirs "${project.productBinAndroidDir}/"
}
}
Why is the manifest file lost ? Please help me as I am new in android studio .
I am also getting this error .
Error:Cannot read packageName from E:\Android App Source Code\agent banking\SafetyNetPayment\safetyNetPayment\AndroidManifest.xml
I don't think it is manifest file is lost, It's path is not just defined correctly in the common.gradle file. If i'm not mistaken, your manifest file is in your src\main directory, so the manifest.srcFile should be defined as manifest.srcFile 'src\main\AndroidManifest.xml'.
I have an Android NDK based project that uses the experimental gradle plugin. I am trying to add React Native and the React Native Navigation (RNN) module to the project
The example project that comes with RNN builds and runs as expected. However in order to make RNN compatible with my project I had to update its build.gradle file to work with the experimental gradle plugin: https://github.com/adamski/react-native-navigation/commit/0a848f574cedae83bf8961bd1fafe8a42e4257cc
I am hitting the following build error:
Error:(64, 1) error: package com.reactnativenavigation.activities does not exist
I have trawled SO and the web for a solution to this. I can see the project and navigate it in AS:
However on navigating to the main Activity java class, it shows red lines where it cannot find the dependency, even though it offers the option if importing the files to the main project(?).
My settings.gradle:
include ':app'
include ':react-native-navigation'
project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../../node_modules/react-native-navigation/android/app/')
The project build.gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.7.0-rc1'
}
}
allprojects {
repositories {
jcenter()
maven { // All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../../node_modules/react-native/android" // node_modules is two levels up from the AndroidStudio project folder
}
}
}
The app's build.gradle:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "com.company.myapp"
minSdkVersion.apiLevel = 16
targetSdkVersion.apiLevel = 22
}
}
android.ndk {
moduleName = "juce_jni"
toolchain = "clang"
stl = "c++_static"
cppFlags.add("-fsigned-char")
cppFlags.add("-fexceptions")
cppFlags.add("-frtti")
cppFlags.add("-std=c++11")
cppFlags.add("-DJUCE_ENABLE_LIVE_CONSTANT_EDITOR=0")
cppFlags.add("-DJUCER_ANDROIDSTUDIO_4330F05B=1")
cppFlags.add("-DJUCE_APP_VERSION=0.4.0")
cppFlags.add("-DJUCE_APP_VERSION_HEX=0x400")
cppFlags.add("-I${project.rootDir}/../../Fonts".toString())
cppFlags.add("-I${project.rootDir}/../../Source".toString())
cppFlags.add("-I${project.rootDir}/../iOS".toString())
cppFlags.add("-I${project.rootDir}/../../../../juce_modules/adamski/PitchDetector/modules".toString())
cppFlags.add("-I${project.rootDir}/../../Source/LookAndFeel".toString())
cppFlags.add("-I${project.rootDir}/../../Source/Synth".toString())
cppFlags.add("-I${project.rootDir}/../../Source/UI".toString())
ldLibs.add("android")
ldLibs.add("EGL")
ldLibs.add("GLESv2")
ldLibs.add("log")
platformVersion = 15
}
android.sources {
main {
jni {
source {
exclude "**/JuceModules/"
}
}
}
}
android.buildTypes {
debug {
ndk.with {
debuggable = true
cppFlags.add("-g")
cppFlags.add("-DDEBUG=1")
cppFlags.add("-D_DEBUG=1")
cppFlags.add("-O0")
cppFlags.add("-I${project.rootDir}/../../JuceLibraryCode".toString())
cppFlags.add("-I${project.rootDir}/../../../../JUCE/modules".toString())
cppFlags.add("-I${project.rootDir}/../../../../juce_modules/adamski".toString())
cppFlags.add("-DJUCE_ANDROID=1")
cppFlags.add("-DJUCE_ANDROID_API_VERSION=21")
cppFlags.add("-DJUCE_ANDROID_ACTIVITY_CLASSNAME=com_company_myapp_MyApp")
cppFlags.add("-DJUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/company/myapp/MyApp\"")
cppFlags.add("-DJUCE_ENABLE_LIVE_CONSTANT_EDITOR=0")
}
}
release {
signingConfig = $("android.signingConfigs.releaseConfig")
ndk.with {
cppFlags.add("-DNDEBUG=1")
cppFlags.add("-O3")
cppFlags.add("-I${project.rootDir}/../../JuceLibraryCode".toString())
cppFlags.add("-I${project.rootDir}/../../../../JUCE/modules".toString())
cppFlags.add("-I${project.rootDir}/../../../../juce_modules/adamski".toString())
cppFlags.add("-DJUCE_ANDROID=1")
cppFlags.add("-DJUCE_ANDROID_API_VERSION=21")
cppFlags.add("-DJUCE_ANDROID_ACTIVITY_CLASSNAME=com_company_myapp_MyApp")
cppFlags.add("-DJUCE_ANDROID_ACTIVITY_CLASSPATH=\"com/company/myapp/MyApp\"")
cppFlags.add("-DJUCE_ENABLE_LIVE_CONSTANT_EDITOR=0")
}
}
}
android.signingConfigs {
create("releaseConfig") {
storeFile = new File("/Users/adamelemental/.android/debug.keystore")
storePassword = "android"
keyAlias = "androiddebugkey"
keyPassword = "android"
storeType = "jks"
}
}
android.productFlavors {
create("armeabi") {
ndk.abiFilters.add("armeabi")
}
create("armeabi-v7a") {
ndk.abiFilters.add("armeabi-v7a")
}
create("x86") {
ndk.abiFilters.add("x86")
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:support-v4:+'
compile 'com.facebook.react:react-native:+'
// The following do not work with the experimental gradle plugin:
// debugCompile project(path: ':react-native-navigation', configuration: 'libraryDebug')
// releaseCompile project(path: ':react-native-navigation', configuration: 'libraryRelease')
compile project (':react-native-navigation')
}
Deleting the productFlavors part of RNN's build.gradle got past this issue.
I am attempting to follow the Android Studio Experimental Plugin User Guide instructions located at:
http://tools.android.com/tech-docs/new-build-system/gradle-experimental
to modify the Mapbox GL Native library located at:
https://github.com/mapbox/mapbox-gl-native
In specific, I have modified the following Android files:
https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/gradle/wrapper/gradle-wrapper.properties
https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/build.gradle
https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/MapboxGLAndroidSDK/build.gradle
https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
My goal is to modify the library so I can debug it. Ideally I would be able to use Android Studio to build the library and debug the C/C++ code. So far I can build it, but I can't debug it. A programmer working at Mapbox told me they don't how to debug the Android code either, so I suspect this isn't an easy goal to reach.
I have made many different attempts to apply the Android Studio Experimental Plugin User Guide instructions, but I'm not experienced at Gradle and my latest attempt is leaving me with the following error message which I don't understand:
Gradle 'android' project refresh failed
Error:Cause:org.gradle.api.internal.ExtensibleDynamicObject
Does anyone know how to modify these files to have them build a debuggable Android NDK Library? What is causing the above error?
I am using:
> Linux Mint 17.2
> Android Studio 2.1.1
> Build #AI-143.2821654, built on April 28, 2016
> JRE: 1.8.0_65-b17 amd64
> JVM: Java HotSpot(TM) 64-Bit Server VM by Oracle Corporation
Below are the 4 files as I currently have them modified. Since I am new to Gradle, do not assume I have made any modfications correctly. I was merely attempting to apply the Android Studio Experimental Plugin User Guide instructions until I got a successful build.
Thanks
#// mapbox-gl-native/platform/android/gradle/wrapper/gradle-wrapper.properties
#Thu Apr 07 14:21:05 CDT 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#//distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-bin.zip
#//distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-all.zip
distributionSha256Sum=e77064981906cd0476ff1e0de3e6fef747bd18e140960f1915cca8ff6c33ab5c
// mapbox-gl-native/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
maven { url 'https://jitpack.io' }
}
dependencies {
// classpath 'com.android.tools.build:gradle:2.1.0'
//classpath 'com.android.tools.build:gradle-experimental:0.7.0'
classpath 'com.android.tools.build:gradle-experimental:0.8.0-alpha2'
classpath 'com.github.JakeWharton:sdk-manager-plugin:220bf7a88a7072df3ed16dc8466fb144f2817070'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven { url "http://oss.sonatype.org/content/repositories/snapshots/" }
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.12'
}
// mapbox-gl-native/platform/android/MapboxGLAndroidSDK/build.gradle
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.model.library'
apply plugin: 'checkstyle'
apply plugin: 'maven'
apply plugin: 'signing'
allprojects {
group project.GROUP
version project.VERSION_NAME
repositories {
mavenCentral()
}
}
repositories {
mavenCentral()
}
ext {
supportLibVersion = '23.4.0'
}
dependencies {
compile "com.android.support:support-annotations:${supportLibVersion}"
compile "com.android.support:support-v4:${supportLibVersion}"
compile "com.android.support:design:${supportLibVersion}"
compile 'com.squareup.okhttp3:okhttp:3.3.0'
compile 'com.mapzen.android:lost:1.1.0'
}
model {
android {
compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
defaultConfig {
minSdkVersion Integer.parseInt(project.ANDROID_MIN_SDK)
targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
}
sourceSets {
main.res.srcDirs += 'src/main/res-public'
}
repositories {
mavenCentral()
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
lintOptions {
checkAllWarnings true
warningsAsErrors true
}
buildTypes {
debug {
jniDebuggable true
buildConfigField "String", "MAPBOX_EVENTS_USER_AGENT_BASE", new StringBuilder().append("\"").append("MapboxEventsAndroid/").append(project.VERSION_NAME).append("\"").toString()
}
release {
jniDebuggable false
buildConfigField "String", "MAPBOX_EVENTS_USER_AGENT_BASE", new StringBuilder().append("\"").append("MapboxEventsAndroid/").append(project.VERSION_NAME).append("\"").toString()
consumerProguardFiles 'proguard-rules.pro'
}
}
}
}
configurations {
all*.exclude group: 'commons-logging', module: 'commons-logging'
all*.exclude group: 'commons-collections', module: 'commons-collections'
}
model {
android.libraryVariants.all { variant ->
def name = variant.name
task "javadoc$name"(type: Javadoc) {
description = "Generates javadoc for build $name"
failOnError = false
destinationDir = new File(destinationDir, variant.baseName)
source = files(variant.javaCompile.source)
classpath = files(variant.javaCompile.classpath.files) + files(android.bootClasspath)
exclude '**/R.java', '**/BuildConfig.java', 'com/almeros/**'
options.windowTitle("Mapbox Android SDK $VERSION_NAME Reference")
options.docTitle("Mapbox Android SDK $VERSION_NAME")
options.header("Mapbox Android SDK $VERSION_NAME Reference")
options.bottom("© 2015–2016 Mapbox. All rights reserved.")
options.links("http://docs.oracle.com/javase/7/docs/api/")
options.linksOffline("http://d.android.com/reference/", "$System.env.ANDROID_HOME/docs/reference")
options.overview("src/main/java/overview.html")
options.group("Mapbox Android SDK", "com.mapbox.*")
options.group("Third Party Libraries", "com.almeros.*")
// TODO exclude generated R, BuildConfig, com.almeros.*
}
}
}
checkstyle {
configFile project.file('../checks.xml')
showViolations true
}
/*
task cleanJNIBuilds {
def jniLibsDir = new File("MapboxGLAndroidSDK/src/main/jniLibs")
delete jniLibsDir.absolutePath
}
*/
model
{
android.libraryVariants.all { variant ->
def name = variant.buildType.name
def checkstyle = project.tasks.create "checkstyle${name.capitalize()}", Checkstyle
checkstyle.dependsOn variant.javaCompile
checkstyle.source variant.javaCompile.source
checkstyle.classpath = project.fileTree(variant.javaCompile.destinationDir)
checkstyle.exclude('**/BuildConfig.java')
checkstyle.exclude('**/R.java')
checkstyle.exclude('**/com/almeros/android/multitouch/**')
project.tasks.getByName("check").dependsOn checkstyle
}
// From https://raw.github.com/mcxiaoke/gradle-mvn-push/master/jar.gradle
android.libraryVariants.all { variant ->
def jarTask = project.tasks.create(name: "jar${variant.name.capitalize()}", type: Jar) {
from variant.javaCompile.destinationDir
exclude "**/R.class"
exclude "**/BuildConfig.class"
}
jarTask.dependsOn variant.javaCompile
artifacts.add('archives', jarTask);
}
}
// From https://raw.github.com/mcxiaoke/gradle-mvn-push/master/gradle-mvn-push.gradle
def isReleaseBuild() {
return VERSION_NAME.contains("SNAPSHOT") == false
}
def getReleaseRepositoryUrl() {
return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL :
"https://oss.sonatype.org/service/local/staging/deploy/maven2/"
}
def getSnapshotRepositoryUrl() {
return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL :
"https://oss.sonatype.org/content/repositories/snapshots/"
}
def getRepositoryUsername() {
return hasProperty('USERNAME') ? USERNAME :
(hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "")
}
def getRepositoryPassword() {
return hasProperty('PASSWORD') ? PASSWORD :
(hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "")
}
task apklib(type: Zip) {
appendix = extension = 'apklib'
from 'AndroidManifest.xml'
into('res') {
from 'res'
}
into('src') {
from 'src'
}
}
artifacts {
archives apklib
}
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
pom.groupId = GROUP
pom.artifactId = POM_ARTIFACT_ID
pom.version = VERSION_NAME
repository(url: getReleaseRepositoryUrl()) {
authentication(userName: getRepositoryUsername(),
password: getRepositoryPassword())
}
snapshotRepository(url: getSnapshotRepositoryUrl()) {
authentication(userName: getRepositoryUsername(),
password: getRepositoryPassword())
}
/*
// Leaving out as artifact was incorrectly named when found
addFilter('aar') { artifact, file ->
artifact.name == archivesBaseName
}
addFilter('apklib') { artifact, file ->
artifact.name == archivesBaseName + '-apklib'
}
*/
pom.project {
name POM_NAME
packaging POM_PACKAGING
description POM_DESCRIPTION
url POM_URL
scm {
url POM_SCM_URL
connection POM_SCM_CONNECTION
developerConnection POM_SCM_DEV_CONNECTION
}
licenses {
license {
name POM_LICENCE_NAME
url POM_LICENCE_URL
distribution POM_LICENCE_DIST
}
}
developers {
developer {
id POM_DEVELOPER_ID
name POM_DEVELOPER_NAME
}
}
}
}
}
}
signing {
required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
sign configurations.archives
}
model {
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.sourceFiles
classpath = files(android.bootClasspath)
}
}
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
classifier = 'javadoc'
from androidJavadocs.destinationDir
}
model {
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.sourceFiles
}
}
artifacts {
archives androidSourcesJar
archives androidJavadocsJar
}
}
task makeClean(type: Exec) {
workingDir '../../'
commandLine 'make', 'clean'
}
task makeAndroid(type: Exec) {
workingDir '../../'
commandLine 'make', 'android'
}
task makeAndroidAll(type: Exec) {
workingDir '../../'
commandLine 'make', 'apackage'
}
// mapbox-gl-native/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.model.application'
apply plugin: 'checkstyle'
task accessToken {
def tokenFile = new File("MapboxGLAndroidSDKTestApp/src/main/res/values/developer-config.xml")
if (!tokenFile.exists()) {
String tokenFileContents = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<resources>\n" +
" <string name=\"mapbox_access_token\">" + "$System.env.MAPBOX_ACCESS_TOKEN" + "</string>\n" +
"</resources>"
if (tokenFileContents == null) {
throw new InvalidUserDataException("You must set the MAPBOX_ACCESS_TOKEN environment variable.")
}
tokenFile.write(tokenFileContents)
}
}
gradle.projectsEvaluated {
// preBuild.dependsOn('accessToken')
}
ext {
supportLibVersion = '23.4.0'
}
model {
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.mapbox.mapboxsdk.testapp"
minSdkVersion.apiLevel 15
targetSdkVersion.apiLevel 23
versionCode 9
versionName "4.1.0"
// Specify AndroidJUnitRunner as the default test instrumentation runner
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'LICENSE.txt'
}
lintOptions {
checkAllWarnings true
warningsAsErrors true
disable 'IconDensities'
disable 'InvalidPackage'
}
testOptions {
unitTests.returnDefaultValues = true
}
buildTypes {
debug {
// run code coverage reports
testCoverageEnabled = true
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
}
dependencies {
compile(project(':MapboxGLAndroidSDK')) {
transitive = true
}
// Support libraries
compile "com.android.support:support-annotations:${supportLibVersion}"
compile "com.android.support:support-v4:${supportLibVersion}"
compile "com.android.support:appcompat-v7:${supportLibVersion}"
compile "com.android.support:design:${supportLibVersion}"
compile "com.android.support:recyclerview-v7:${supportLibVersion}"
// Leak Canary
//debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta1'
//releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta1'
// Directions SDK
compile('com.mapbox.mapboxsdk:mapbox-android-directions:1.0.0#aar') {
transitive = true
}
// Geocoder SDK
compile('com.mapbox.mapboxsdk:mapbox-android-geocoder:1.0.0#aar') {
transitive = true
}
// Testing dependencies
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile "com.android.support:support-annotations:${supportLibVersion}"
androidTestCompile 'com.android.support.test:runner:0.4.1'
androidTestCompile 'com.android.support.test:rules:0.4.1'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
androidTestCompile 'com.jayway.android.robotium:robotium-solo:5.5.4'
}
checkstyle {
configFile project.file('../checks.xml')
showViolations true
}
model {
android.applicationVariants.all { variant ->
def name = variant.buildType.name
def checkstyle = project.tasks.create "checkstyle${name.capitalize()}", Checkstyle
checkstyle.dependsOn variant.javaCompile
checkstyle.source variant.javaCompile.source
checkstyle.classpath = project.fileTree(variant.javaCompile.destinationDir)
checkstyle.exclude('**/BuildConfig.java')
checkstyle.exclude('**/R.java')
project.tasks.getByName("check").dependsOn checkstyle
}
}
Your gradle approach is essentially rewriting or porting the Android SDK Makefile to gradle. To solve what you are doing on Linux, you will likely need to modify the existing Makefiles.
The reason is that the Mapbox Android SDK build process uses make android to build the target libmapbox-gl.so. The Gradle project you have includes the .so file in with your usual Java code.
make android makes a call into mapbox-gl-native/Makefile
and also generates mapbox-gl-native/build/android-arm-v7/Makefile, which you may have to research how to modify to generate debug information as Chris Stratton mentions in the comments above.
When you do get around to modifying your C++, you will then need to modify the settings.gradle to make use of your modified .so for Android.
include ':MapboxGLAndroidSDK'
project(':MapboxGLAndroidSDK').projectDir = new File(rootProject.projectDir, '<relative-path-to>/../mapbox-gl-native/platform/android/MapboxGLAndroidSDK')
include ':app'
Another thing to consider — Can you build a debuggable version for Linux?
We have successfully debugged C++ for the Mapbox SDK using the Xcode debugger, as we built an iOS app as well. I know this will not fit your exact needs, but I mention it in case anyone else in your lab or organization has access to Xcode on OS X and can start debugging using make iproj.
I have a kotlin-multiplatform project targeting iOS and Android.
Ktor http client is used in common module.
Everything works great with Android app.
But when building project with iOS lib, I receive following exceptions:
> Task :app:compileKotlinIos FAILED
src/commonMain/kotlin/com/ottamotta/mozoli/api/MozoliApiKtor.kt:4:8: error: unresolved reference: io
import io.ktor.client.HttpClient
^
src/commonMain/kotlin/com/ottamotta/mozoli/api/MozoliApiKtor.kt:5:8: error: unresolved reference: io
import io.ktor.client.features.feature
...and other ones, saying none of the ktor dependencies have been resolved.
Here is build.gradle:
plugins {
id 'kotlin-multiplatform' version '1.3.10'
}
repositories {
google()
jcenter()
mavenCentral()
maven { url "https://kotlin.bintray.com/kotlinx" }
}
ext {
support_lib_version = '28.0.0'
ktor_version = '1.0.0'
}
def keystorePropertiesFile = rootProject.file("./app/secret.properties");
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "com.ottamotta.mozoli"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
manifestPlaceholders = [auth0Domain: "#string/com_auth0_domain", auth0Scheme: "https"]
}
buildTypes {
debug {
resValue "string", "com_auth0_client_id", keystoreProperties['com_auth0_client_id']
}
release {
resValue "string", "com_auth0_client_id", keystoreProperties['com_auth0_client_id']
minifyEnabled false
}
}
lintOptions {
abortOnError false
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "com.android.support:recyclerview-v7:${support_lib_version}"
implementation "com.android.support:appcompat-v7:${support_lib_version}"
implementation 'com.squareup.picasso:picasso:2.71828'
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.7"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.1")
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1'
implementation "com.auth0.android:auth0:1.14.1"
androidTestImplementation 'com.android.support.test:runner:1.0.2'
}
kotlin {
targets {
fromPreset(presets.android, 'android')
// This preset is for iPhone emulator
// Switch here to presets.iosArm64 (or iosArm32) to build library for iPhone device
fromPreset(presets.iosX64, 'ios') {
compilations.main.outputKinds('FRAMEWORK')
}
}
sourceSets {
commonMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
implementation "io.ktor:ktor-client:$ktor_version"
implementation "io.ktor:ktor-client-json:$ktor_version"
implementation "io.ktor:ktor-client-jackson:$ktor_version"
}
}
commonTest {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-test-common'
implementation 'org.jetbrains.kotlin:kotlin-test-annotations-common'
}
}
androidMain {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib'
implementation "io.ktor:ktor-client-android:$ktor_version"
}
}
androidTest {
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-test'
implementation 'org.jetbrains.kotlin:kotlin-test-junit'
}
}
iosMain {
dependencies {
implementation("io.ktor:ktor-client-ios:$ktor_version")
}
}
iosTest {
}
}
}
task copyFramework {
def buildType = project.findProperty("kotlin.build.type") ?: "DEBUG"
def target = project.findProperty("kotlin.target") ?: "ios"
dependsOn "link${buildType.toLowerCase().capitalize()}Framework${target.capitalize()}"
doLast {
def srcFile = kotlin.targets."$target".compilations.main.getBinary("FRAMEWORK", buildType)
def targetDir = getProperty("configuration.build.dir")
copy {
from srcFile.parent
into targetDir
include 'app.framework/**'
include 'app.framework.dSYM'
}
}
}
Here is the code of the file from common module which generates errors:
package com.ottamotta.mozoli.api
import com.ottamotta.mozoli.*
import io.ktor.client.HttpClient
import io.ktor.client.features.feature
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.JsonSerializer
import io.ktor.client.features.json.defaultSerializer
import io.ktor.client.request.header
import io.ktor.client.request.request
import io.ktor.client.request.url
import io.ktor.http.HttpMethod
class MozoliApiKtor(
private val serverUrl: String,
private var jsonSerializer: JsonSerializer? = null,
private val tokenProvider: suspend () -> String?
) : MozoliApi {
private val client: HttpClient
private val AUTH_HEADER = "Authorization";
private val TOKEN_PREFIX = "Bearer "
init {
client = HttpClient {
install(JsonFeature) {
serializer = jsonSerializer ?: defaultSerializer()
}
}
jsonSerializer = client.feature(JsonFeature)?.serializer
}
override suspend fun getUserProfile(): User {
return client.request {
url("${serverUrl}/user/")
method = HttpMethod.Get
header(AUTH_HEADER, TOKEN_PREFIX + tokenProvider())
}
}
override suspend infix fun getEventsByCity(cityId: String): List<Event> {
return client.request {
url("${serverUrl}/event/city/${cityId}")
method = HttpMethod.Get
header(AUTH_HEADER, TOKEN_PREFIX + tokenProvider())
}
}
}
I was having the same exact issue as you. Built and works flawlessly for the Android app, but the iOS module cannot find any Ktor, coroutine, or kotlinx serialization class.
Following along https://github.com/adrianbukros/github-multiplatform-example, and trying to copy their set up, I finally got the packForXCode task to work by copying some of their gradle set up namely:
Their common module build.gradle, which should look like this:
apply plugin: 'kotlin-multiplatform'
apply plugin: 'kotlinx-serialization'
kotlin {
targets {
fromPreset(presets.jvm, "android")
fromPreset(presets.iosX64, "ios_x86_64")
fromPreset(presets.iosArm64, "ios_arm64")
configure([ios_x86_64, ios_arm64]) {
compilations.main.outputKinds("FRAMEWORK")
}
}
sourceSets {
commonMain.dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
implementation "io.ktor:ktor-client-core:$ktor_version"
implementation "io.ktor:ktor-client-json:$ktor_version"
}
androidMain.dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
implementation "io.ktor:ktor-client-core-jvm:$ktor_version"
implementation "io.ktor:ktor-client-json-jvm:$ktor_version"
}
iosMain.dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"
implementation "io.ktor:ktor-client-ios:$ktor_version"
implementation "io.ktor:ktor-client-core-ios:$ktor_version"
implementation "io.ktor:ktor-client-json-ios:$ktor_version"
}
configure([ios_x86_64Main, ios_arm64Main]) {
dependsOn iosMain
}
}
}
// workaround for https://youtrack.jetbrains.com/issue/KT-27170
configurations {
compileClasspath
}
task packForXCode(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String configuration = project.findProperty("CONFIGURATION")?.toUpperCase() ?: "DEBUG"
final String arch = project.findProperty("ARCHS") ?: "x86_64"
dependsOn kotlin.targets."ios_${arch}".compilations.main.linkTaskName("FRAMEWORK", configuration)
from { kotlin.targets."ios_${arch}".compilations.main.getBinary("FRAMEWORK", configuration).parentFile }
into frameworkDir
}
tasks.build.dependsOn packForXCode
And their settings.gradle file which should look like this:
enableFeaturePreview("GRADLE_METADATA") // IMPORTANT!
include 'commoncode'
include 'app'
If it's still not working, look at all of their *.gradle and gradle.* files and see how yours are different.
That finally allowed the task to pass for me, and I can use my Kotlin Ktor code in XCode. However, now Android Studio is saying "Kotlin is not configured" for the shared iOS module. I will report back if I figure out why, and if you find something, please share!
EDIT
Changed the common module build.gradle to look like this, seems like everything is working well!
apply plugin: 'kotlin-multiplatform'
apply plugin: 'kotlinx-serialization'
kotlin {
targets {
fromPreset(presets.jvm, 'android')
// Change to `presets.iosArm64` to deploy the app to iPhone
fromPreset(presets.iosX64, 'ios') {
compilations.main.outputKinds('FRAMEWORK')
}
}
sourceSets {
commonMain.dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
implementation "io.ktor:ktor-client-core:$ktor_version"
implementation "io.ktor:ktor-client-json:$ktor_version"
}
androidMain.dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
implementation "io.ktor:ktor-client-core-jvm:$ktor_version"
implementation "io.ktor:ktor-client-json-jvm:$ktor_version"
}
iosMain.dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"
implementation "io.ktor:ktor-client-ios:$ktor_version"
implementation "io.ktor:ktor-client-core-ios:$ktor_version"
implementation "io.ktor:ktor-client-json-ios:$ktor_version"
}
}
}
// workaround for https://youtrack.jetbrains.com/issue/KT-27170
configurations {
compileClasspath
}
task packForXCode(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
inputs.property "mode", mode
dependsOn kotlin.targets.ios.compilations.main.linkTaskName("FRAMEWORK", mode)
from { kotlin.targets.ios.compilations.main.getBinary("FRAMEWORK", mode).parentFile }
into frameworkDir
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$#\n"
setExecutable(true)
}
}
}
tasks.build.dependsOn packForXCode
As of now kotlin multiplatform for iOS does not run on windows. This would explain why only the dependencies in your iosmain code wont resolve.