In a Kotlin Multiplatform module, what artifact does the androidTarget() produce versus the iosArm64()/iosSimulatorArm64() targets, and how does each get consumed?
answer
- androidTarget() -> AAR over Android SDK
- iosArm64 = device, iosSimulatorArm64 = Apple-silicon simulator
- iOS targets are Kotlin/Native -> .framework
- commonMain shared, androidMain/iosMain actuals
- android() renamed androidTarget() in 1.9
basics
~10 sandroidTarget() builds an Android library (an AAR) that Android apps use. The iOS targets build a native framework that an Xcode/Swift app imports. Same Kotlin code, two different output packages.
solid answer
~30 sIn the kotlin { } block, androidTarget() configures compilation against the Android SDK and produces an Android Archive (AAR) consumed via Gradle by an Android app module. iosArm64() (real devices) and iosSimulatorArm64() (Apple-silicon simulator) are Kotlin/Native targets that compile to a .framework (or XCFramework) which Xcode/Swift imports. The shared module declares these targets; commonMain holds shared code, androidMain and iosMain hold platform-specific actual implementations of expect declarations. Android consumes the AAR like any Gradle dependency; iOS links the framework. The same source set feeds both, so business logic is written once and packaged twice for the two platforms.
code
kotlin · 11 lineskotlin {
androidTarget() // -> AAR consumed by Android app
iosArm64() // -> device framework
iosSimulatorArm64() // -> Apple-silicon simulator framework
sourceSets {
commonMain.dependencies { /* shared deps */ }
androidMain.dependencies { /* Android deps */ }
iosMain.dependencies { /* iOS deps */ }
}
}go deeper
Knows androidTarget() makes an AAR and iOS targets make a framework, and that code is shared via commonMain.
Distinguishes device vs simulator targets and explains expect/actual feeding both artifacts.
Explains JVM-backend vs Kotlin/Native-backend differences and consumption paths (Gradle dependency vs Xcode linking).
Frames target selection as a packaging/distribution decision and can reason about XCFramework vs single framework trade-offs.
## What a KMP target is A **target** in Kotlin Multiplatform (KMP) is a single platform you compile your shared code for. You declare targets inside the `kotlin { }` DSL of a Gradle build file. Each target pulls in a platform-specific compiler backend and produces a platform-native artifact. ## androidTarget() - `androidTarget()` compiles your Kotlin against the **Android SDK** using the JVM backend (Android runs Kotlin/JVM bytecode, later turned into DEX by the Android toolchain). - It requires the **Android Gradle Plugin (AGP)** to be applied (`com.android.library`). - The output is an **AAR (Android Archive)** - a zip containing compiled classes plus Android resources/manifest - which an Android app module consumes as a normal Gradle dependency. - Renamed from the old `android()` to `androidTarget()` in Kotlin 1.9 to free up `android` for a future Android-specific DSL. ## iosArm64() and iosSimulatorArm64() These are **Kotlin/Native** targets - they compile straight to machine code via LLVM, no JVM involved. - `iosArm64()` -> ARM64 binary for **real iPhones/iPads**. - `iosSimulatorArm64()` -> ARM64 binary for the **iOS Simulator running on Apple-silicon Macs**. - (`iosX64()` exists for Intel-Mac simulators.) - Output is an Apple **`.framework`** (or several combined into an **XCFramework**) that an Xcode project imports and Swift/Objective-C code calls. ## Source sets tie them together ```kotlin kotlin { androidTarget() iosArm64() iosSimulatorArm64() sourceSets { commonMain.dependencies { /* shared */ } androidMain.dependencies { /* Android-only */ } iosMain.dependencies { /* iOS-only */ } } } ``` `commonMain` is the shared code. `expect` declarations there get platform `actual` implementations in `androidMain` / `iosMain`. The compiler produces the AAR and the framework from the same common source plus the platform source set. ## How each is consumed - **Android:** add the shared module as a Gradle dependency; Gradle resolves the AAR. - **iOS:** link the framework into the Xcode app (manually, or via CocoaPods/SwiftPM packaging).
- Why was android() renamed to androidTarget()?To reserve the cleaner android name for a future Android-specific DSL; androidTarget() is the current spelling since Kotlin 1.9.
- Do iOS targets use the JVM?No. They are Kotlin/Native targets compiled to native machine code via LLVM; there is no JVM or JVM-style runtime.
One recipe (commonMain), two kitchens: the Android kitchen plates an AAR, the iOS kitchen plates a framework.
saying these in an interview costs you the question
- Says iOS targets produce a JAR or run on a JVM
- Thinks androidTarget() outputs an APK rather than an AAR library
- Confuses iosArm64 (device) with the simulator target
- Believes you must duplicate business logic per platform