Compiler l’app iOS d’un projet Kotlin Multiplatform sans Mac
Avec Kotlin Multiplatform, la plus grande partie de votre app est du code Kotlin partagé. Vous pouvez l’écrire sous Windows ou Linux. Le framework iOS et l’app Xcode demandent quand même macOS. Nous avons testé cela le 19 octobre 2026 avec le template KMP officiel de JetBrains. Voici ce qui a marché, et un piège.
Ce qui marche sous Windows et Linux
La documentation de Kotlin dit que vous pouvez travailler sur le code partagé et sur toutes les plateformes sauf iOS depuis n’importe quel système. Nous l’avons vérifié avec KMP-App-Template, le template officiel de l’équipe Kotlin sur GitHub. C’est une app Compose Multiplatform pour Android, iOS, desktop et web. Sur des runners Windows et Ubuntu, ceci a réussi :
./gradlew :shared:compileKotlinJvm :androidApp:assembleDebug
Le code partagé a compilé pour la JVM, et l’app Android a été construite. Vous pouvez lancer les tests Android, desktop et JVM de la même façon. Écrivez-y votre logique métier et votre UI Compose, et vérifiez-les sur Android.
Le piège : un build vert sans framework iOS
Ensuite, nous avons demandé le framework iOS aux runners Windows et Ubuntu. Gradle a compilé le Kotlin pour iOS, puis a sauté l’étape de link. Il a quand même annoncé un succès :
> Task :shared:compileKotlinIosSimulatorArm64 > Task :shared:linkDebugFrameworkIosSimulatorArm64 SKIPPED BUILD SUCCESSFUL in 27s
Aucun framework n’est sorti. La page de Kotlin sur les cibles prises en charge explique pourquoi. Linux et Windows peuvent produire des bibliothèques Kotlin pour les cibles Apple. Les binaires finaux pour les cibles Apple ne peuvent pas y être construits. L’étape de configuration a aussi prévenu que les tests sur simulateur iOS demandent macOS.
Ce qui demande macOS
- Le link du framework. L’app iOS importe votre code partagé sous forme de framework, et seul un Mac peut le linker.
- Le projet iosApp. C’est un projet Xcode normal. Sa phase de build appelle Gradle pour intégrer le framework.
- Les tests iOS et le simulateur. Les deux demandent Xcode.
- CocoaPods et les autres cinterop. La documentation de Kotlin dit qu’ils demandent un hôte macOS, même pour des bibliothèques.
Les commandes sur le Mac
Un Mac MacRun est livré avec Xcode 27.1 et Xcode 26.6. Il n’a pas de JDK, donc installez-en un d’abord. Nous avons utilisé Zulu JDK 21. Le guide de démarrage de Kotlin dit d’ouvrir Xcode une fois avant votre premier build, pour qu’il termine sa configuration. Ensuite, clonez votre dépôt et linkez le framework pour le simulateur :
./gradlew :shared:linkDebugFrameworkIosSimulatorArm64
Puis compilez le projet iosApp pour le simulateur. Ces options sont celles du fichier CI du template lui-même. CODE_SIGNING_ALLOWED=NO saute la signature, dont un build pour le simulateur n’a pas besoin.
cd iosApp xcodebuild -project iosApp.xcodeproj -scheme iosApp \ -configuration Debug -sdk iphonesimulator -arch arm64 \ -derivedDataPath build CODE_SIGNING_ALLOWED=NO build
Gardez -arch arm64. Notre premier essai utilisait à la place une destination de simulateur générique. Xcode a alors demandé à Gradle une tranche pour simulateur Intel en plus, et le build a échoué :
Xcode requested target architectures that are not configured in your Gradle build: ios_x64.
Le template ne définit que iosArm64 et iosSimulatorArm64. Passer à la fois -destination et -arch a aussi échoué. Xcode a répondu que la destination implique déjà l’architecture.
Pour ouvrir l’app, démarrez un simulateur et installez le build. Utilisez votre propre bundle ID. Sur MacRun, le runtime iOS 27.1 apporte l’appareil iPhone Duo.
xcrun simctl list devices available xcrun simctl boot "iPhone Duo" xcrun simctl install booted "build/Build/Products/Debug-iphonesimulator/KMP App.app" xcrun simctl launch booted com.jetbrains.kmpapp.KMP-App-Template
Vous pouvez aussi ouvrir iosApp.xcodeproj dans Xcode en partage d’écran. Réglez votre équipe, puis appuyez sur Run. Depuis Windows, voyez Xcode depuis Windows pour l’écran à distance.
Le workflow lancé sur GitHub Actions
Voici le job macOS de notre test. Il fixe le template sur un commit précis, donc vous pouvez le lancer tel quel. Dans votre propre dépôt, faites plutôt le checkout de votre code.
name: kmp-ios
on: workflow_dispatch
env:
TEMPLATE_SHA: 6b6d09e4f3f5e845116422d59b658791ed6149c6
jobs:
macos:
runs-on: macos-26
steps:
- uses: actions/checkout@v4
with:
repository: Kotlin/KMP-App-Template
ref: ${{ env.TEMPLATE_SHA }}
- uses: actions/setup-java@v4
with:
distribution: zulu
java-version: 21
- run: xcodebuild -version && sw_vers && java -version
- name: Link the iOS simulator framework
run: time ./gradlew :shared:linkDebugFrameworkIosSimulatorArm64
- name: Build the iosApp for the Simulator
run: |
time xcodebuild -project iosApp.xcodeproj -scheme iosApp \
-configuration Debug -sdk iphonesimulator -arch arm64 \
-derivedDataPath build CODE_SIGNING_ALLOWED=NO build
working-directory: iosApp
- name: Install and launch in the Simulator
run: |
APP=$(ls -d build/Build/Products/Debug-iphonesimulator/*.app | head -1)
UDID=$(xcrun simctl list devices available -j | python3 -c "import json,sys; d=json.load(sys.stdin)['devices']; print(next(x['udid'] for k,v in d.items() if 'iOS' in k for x in v if x['name'].startswith('iPhone')))")
xcrun simctl boot "$UDID"
xcrun simctl bootstatus "$UDID"
xcrun simctl install booted "$APP"
xcrun simctl launch booted com.jetbrains.kmpapp.KMP-App-Template
sleep 10
xcrun simctl io booted screenshot shot.png && ls -la shot.png
working-directory: iosAppLe job a pris 6 minutes 35 secondes. Le link Gradle a pris 4 minutes 7 secondes sur un runner à froid, surtout pour télécharger la chaîne d’outils Kotlin/Native. L’étape xcodebuild a pris 26 secondes. Ces lignes viennent du journal :
Xcode 26.6 Build version 17F113 openjdk version "21.0.12" 2026-07-21 LTS BUILD SUCCESSFUL in 4m 4s 263M shared/build/bin/iosSimulatorArm64/debugFramework/Shared.framework ** BUILD SUCCEEDED ** 59M build/Build/Products/Debug-iphonesimulator/KMP App.app com.jetbrains.kmpapp.KMP-App-Template: 26325
La dernière ligne montre l’app qui tourne dans le simulateur. Notre run utilisait Xcode 26.6, car l’image de GitHub n’a pas Xcode 27. Sur un Mac MacRun, vous pouvez faire pareil avec sudo xcode-select -s /Applications/Xcode.app, qui est Xcode 26.6 sur ces Mac.
Publier sur TestFlight
Le build de release se fait dans le projet iosApp, comme pour n’importe quelle app iOS. Réglez votre équipe dans Xcode, archivez et envoyez vers App Store Connect. Notre guide de publication couvre la signature, les clés API et la review. Nous n’avons pas testé ces étapes, car notre runner n’avait pas de compte Apple. Pour un vrai iPhone, installez depuis TestFlight. Un Mac distant ne voit pas un téléphone branché sur votre PC.
Qui ne devrait pas louer un Mac pour ça
Si vous voulez seulement un build qui prouve qu’iOS compile encore, utilisez la CI. Le workflow ci-dessus tourne sur un runner macOS GitHub Actions, facturé à la minute. Les comptes personnels Codemagic incluent 500 minutes de build macOS gratuites par mois. Si vous travaillez sur iOS tous les jours, votre propre Mac peut revenir moins cher sur un an.
Louez un Mac quand vous devez voir l’app iOS. Cela veut dire l’UI Compose sur un vrai écran iOS, un crash dans Xcode, ou un problème de signature. Un pass journée MacRun coûte $15 pour un Mac mini M6 dédié, et une semaine coûte $59. Vous payez une seule fois et rien ne se renouvelle. Le Mac est effacé à la fin, donc poussez votre travail sur git avant.
Questions fréquentes
Puis-je compiler l’app iOS d’un projet Kotlin Multiplatform sous Windows ?
+
Non. La documentation de Kotlin dit que les binaires finaux pour les cibles Apple ne peuvent pas être construits sous Linux ou Windows. Le code partagé et les cibles Android et JVM s’y compilent sans problème. Le framework iOS et l’app Xcode demandent un Mac.
Pourquoi Gradle affiche-t-il BUILD SUCCESSFUL pour iOS sous Windows ?
+
Sous Linux et Windows, Gradle saute les tâches de link Apple au lieu d’échouer. Dans notre test, linkDebugFrameworkIosSimulatorArm64 a affiché SKIPPED, et Gradle a quand même annoncé un succès. Aucun framework n’a été produit.
Puis-je écrire une UI Compose Multiplatform sous Windows ?
+
Oui. Dans notre test, le code partagé du template a compilé pour la JVM et son app Android a été construite sous Windows. Il ne vous faut un Mac que pour compiler et lancer l’UI sur iOS.
Comment corriger "Xcode Requested Architecture Not Configured in Gradle" ?
+
Compilez pour une seule architecture. Nous avons passé -sdk iphonesimulator -arch arm64 à xcodebuild, comme le fait la CI du template KMP. Une destination de simulateur générique demandait aussi x86_64, que le template ne définit pas.
Combien de temps prend un build iOS Kotlin Multiplatform ?
+
Sur le runner macos-26 de GitHub, le link du framework pour simulateur du template a pris environ 4 minutes sur un runner à froid. Le build Xcode de iosApp a ensuite pris 26 secondes.
Un JDK est-il installé sur un Mac MacRun ?
+
Non. Xcode 27.1, Xcode 26.6 et le simulateur iOS 27.1 sont installés. Vous avez les droits administrateur et Homebrew, donc vous installez le JDK et tout ce dont vous avez besoin.