multiplatform-swiftpackage icon indicating copy to clipboard operation
multiplatform-swiftpackage copied to clipboard

M1 support

Open jizoquval opened this issue 2 years ago • 37 comments

Attention

This repo is not maintained anymore. Please use @luca992 fork.

Changed

  • new arm simulator targets: macosArm64, iosSimulatorArm64, watchosSimulatorArm64, tvosSimulatorArm64
  • kotlin version to 1.6.20
  • gradle 7.4.2

Fixed

  • desktop (arm64, x64, and x86) binaries need to be packed in a fat framworks building XCFramworks (Thanks to @luca992)

jizoquval avatar Sep 02 '21 13:09 jizoquval

@ge-org can we please have this merged and released? it would unblock a bunch of us who want to start either building KMP for arm64, or simply want debug symbols when debugging an iOS app on a device (instead of of the simulator). I suppose it'd also unblock people who want to debug on the simulator on an M1 mac.

netroy avatar Oct 19 '21 19:10 netroy

Hello @jizoquval, thank you for you work. I'm testing your change but it doesn't seem to work with my project.

I have following configuration:

multiplatformSwiftPackage {
    packageName("MyProject")
    swiftToolsVersion("5.3")
    buildConfiguration { release() }
    targetPlatforms {
        iOS { v("13") }
    }
    outputDirectory(File(projectDir, "build/xcframework"))
}

And then run:

./gradlew :MyProject:createXCFramework

But created XCFramework doesn't have arm64-simulator architecture.

ls MyProject/build/xcframework/MyProject.xcframework
Info.plist           ios-arm64            ios-x86_64-simulator

I'm using Kotlin 1.5.30 and Gradle 7.2.

dstranz avatar Oct 21 '21 13:10 dstranz

Hi @dstranz, I think you need to add iosSimulatorArm64() target in your build.gradle like here. But also the dependencies used in the project should have support for arm64 (for example, currently ktor doesnt have).

batuypn avatar Oct 22 '21 09:10 batuypn

Hello, @ge-org ! Any luck on this? My team needs M1 support, so we're deciding if we should just add it ourselves and fork the repo here.

mqln avatar Nov 09 '21 08:11 mqln

Hello, @dstranz! Any luck on this? My team needs M1 support, so we're deciding if we should just add it ourselves and fork the repo here.

Hello 👋🏻

I'm also waiting for merging M1 support to released version of this Gradle plugin.

Maybe you should ask project owner about future plans for this task?

dstranz avatar Nov 09 '21 08:11 dstranz

I managed to get this working by uploading a built jar to our internal maven repo. But the createXCFramework task now fails with

Both 'ios-arm64-simulator' and 'ios-x86_64-simulator' represent two equivalent library definitions.

I see that this is coming from xcodebuild, and not this plugin. But, does anyone with more xcode experience know if I'm doing anything wrong?

netroy avatar Nov 12 '21 13:11 netroy

I also noticed that iosArm64 and iosX64 builds in the build folder contain both a debugFramework as well as a releaseFramework. But, iosSimulatorArm64 only has a releaseFramework.

this is how I've enabled ios builds in my gradle file:

kotlin {
  ....
  listOf(
    iosX64(),
    iosArm64(),
    iosSimulatorArm64()
  ).forEach {
    it.binaries.framework {
      ....
    }
  }
  ....
}

How can I get the debugFramework for iosSimulatorArm64? I assume I need that to be able to see compile and debug any app using this xcframework.

netroy avatar Nov 12 '21 13:11 netroy

I've just see that there is a new JetBrains plugin for creating XCFramework. That maybe a good replacement for this plugin. It Gradle configuration looks like that in new created project:

import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework

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

kotlin {
    android()
    
    val xcf = XCFramework()
    listOf(
        iosX64(),
        iosArm64(),
        //iosSimulatorArm64() sure all ios dependencies support this target
    ).forEach {
        it.binaries.framework {
            baseName = "MyLibrary"
            xcf.add(this)
        }
    }

    sourceSets {
        val commonMain by getting
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }
        val androidMain by getting
        val androidTest by getting {
            dependencies {
                implementation(kotlin("test-junit"))
                implementation("junit:junit:4.13.2")
            }
        }
        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)
        }
        val iosX64Test by getting
        val iosArm64Test by getting
        //val iosSimulatorArm64Test by getting
        val iosTest by creating {
            dependsOn(commonTest)
            iosX64Test.dependsOn(this)
            iosArm64Test.dependsOn(this)
            //iosSimulatorArm64Test.dependsOn(this)
        }
    }
}

android {
    compileSdk = 31
    sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
    defaultConfig {
        minSdk = 21
        targetSdk = 31
    }
}

dstranz avatar Nov 22 '21 09:11 dstranz

Thanks @dstranz. With this new plugin, where is the generated framework after running a ./gradlew build? I see frameworks in bin and fat-framework but no idea which to use.

adamwaite avatar Dec 02 '21 20:12 adamwaite

@adamwaite Under the build folder you will have fat-framework and XCFrameworks. XCFrameworks/release is exactly what you need.

This is my setup

    val xcf = XCFramework("YourLibName")
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { target ->
        target.binaries.framework {
            baseName = "YourLibName"
            xcf.add(this)
        }
    }

    sourceSets {
        val commonMain by getting
        val androidMain by getting
        val androidTest by getting 
        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)
        }
    }

And you can build it using next gradle command: ./gradlew shared:assembleYourLibNameXCFramework

jizoquval avatar Dec 06 '21 11:12 jizoquval

@ge-org What's stopping from merging this?

JohNan avatar Jan 20 '22 10:01 JohNan

Has anyone published the fork of this PR, are they are not maintaining this anymore?

luca992 avatar Apr 26 '22 22:04 luca992

Forked this pr and published it here 👍 settings.gradle:

pluginManagement {
    repositories {
        maven ("https://s01.oss.sonatype.org/content/repositories/releases/")
    }
}
id("io.github.luca992.multiplatform-swiftpackage") version "2.0.3-arm64"

luca992 avatar Apr 27 '22 18:04 luca992

So turns out there's a few issues with this pr. I'm running into this issue: https://developer.apple.com/forums/thread/666335

Before making an XCFramwork: macos (including simulators) arm64, x64, and x86 binaries need to be packed in a fat framework 🙃

I'm gonna make a pr for your fork to include the fixes @jizoquval

luca992 avatar Apr 28 '22 01:04 luca992

Working build:

pluginManagement {
    repositories {
        maven ("https://s01.oss.sonatype.org/content/repositories/releases/")
    }
}
id("io.github.luca992.multiplatform-swiftpackage") version "2.0.4-arm64"

luca992 avatar Apr 29 '22 00:04 luca992

@jizoquval https://github.com/jizoquval/multiplatform-swiftpackage/pull/2 made a PR for your PR 😅

luca992 avatar Apr 29 '22 04:04 luca992

@luca992 Thanks, I will look at it tomorrow!

jizoquval avatar Apr 29 '22 19:04 jizoquval

Works great here!:

image

markst avatar May 05 '22 12:05 markst

+1 on this issue

jacao avatar May 24 '22 14:05 jacao

how can i use this fork since the original one is abandoned?

lazar-otasevic-cif avatar Jun 29 '22 14:06 lazar-otasevic-cif

Created a new release with the latest changes for this pr:

pluginManagement {
    repositories {
        maven ("https://s01.oss.sonatype.org/content/repositories/releases/")
    }
}
id("io.github.luca992.multiplatform-swiftpackage") version "2.0.5-arm64"

luca992 avatar Jun 29 '22 14:06 luca992

thanks @luca992 . can't seem to use it yet:

  • Plugin Repositories (could not resolve plugin artifact 'io.github.luca992.multiplatform-swiftpackage:io.github.luca992.multiplatform-swiftpackage.gradle.plugin:2.0.5-arm64')

markst avatar Jun 29 '22 16:06 markst

@markst If you tried immediately it probably wasn't indexed yet. Should be up now I think: https://repo1.maven.org/maven2/io/github/luca992/multiplatform-swiftpackage/io.github.luca992.multiplatform-swiftpackage.gradle.plugin/

luca992 avatar Jun 29 '22 16:06 luca992

Yeah. Gradle resolved it for me. Just tried

luca992 avatar Jun 29 '22 16:06 luca992

its working! thanks

lazar-otasevic-cif avatar Jun 30 '22 08:06 lazar-otasevic-cif

Hi there, any news on this PR?

I do experiment this issue and the fix @luca992 provided is working fine on my side, but it is still a little bit hacky to use a fork for this fix instead of an approved release.

Nebneb avatar Aug 31 '22 12:08 Nebneb

Hi there, any news on this PR?

I do experiment this issue and the fix @luca992 provided is working fine on my side, but it is still a little bit hacky to use a fork for this fix instead of an approved release.

Idk not up to me 🤷‍♂️.

Ps. The macos fat framework workaround can now be removed on kotlin 1.8 dev builds and be ported over to how the fat frameworks are being generated for the other targets. https://youtrack.jetbrains.com/issue/KT-47355/Support-macos-target-for-FatFramework-task

luca992 avatar Aug 31 '22 14:08 luca992

@luca992 changes are working also fine on my side. So what is still the issue with integrating the changes? Does someone need to make the Travis CI job happy?

muellnes avatar Oct 01 '22 08:10 muellnes

Kotlin 1.8.0-beta is out. That macOs fat framework workaround now could probably be removed now to match all the other targets.

luca992 avatar Nov 16 '22 19:11 luca992

They clearly aren't maintaining this. I updated my fork with a new release using kotlin 1.8.0 that removes my hacky macOs fat framework workaround. I don't see the point in submitting more pr updates here until someone responds, and I will just maintain my own fork 🙃.

// build.gradle.kts
plugins {
  // projects targting kotlin >=1.8.0
  id("io.github.luca992.multiplatform-swiftpackage") version "2.1.4"
  // projects targting kotlin <1.8.0
  id("io.github.luca992.multiplatform-swiftpackage") version "2.0.5-arm64"
}

luca992 avatar Jan 09 '23 18:01 luca992