Add ios_arm64e Kotlin/Native compilation target#6306
Draft
Oskar Wirga (oskarwirga) wants to merge 1 commit into
Draft
Add ios_arm64e Kotlin/Native compilation target#6306Oskar Wirga (oskarwirga) wants to merge 1 commit into
Oskar Wirga (oskarwirga) wants to merge 1 commit into
Conversation
Wires the iOS arm64e target (Pointer Authentication Code, FEAT_PAuth)
end-to-end through target registration, toolchain configuration, gradle
DSL, source-set hierarchy, test infrastructure, and platform libraries.
Produces Mach-O arm64e framework binaries with __auth_got / auth-bind
chained fixups, ARM64_RELOC_AUTHENTICATED_POINTER relocations, and full
ptrauth-* LLVM function attributes from the bundled kotlin/llvm-19-apple
toolchain.
Layer breakdown
---------------
- Target registration: KonanTarget.IOS_ARM64E plus predefinedTargets,
HostManager.appleTargets, supportsIosCrashLog.
- Toolchain config (konan.properties): arm64e-apple-ios triple,
apple-a12 CPU, +pauth/+v8.3a features, linker flags, SDK paths.
- Compiler build tooling (runtime/build.gradle.kts): TARGET_OS_*
defines extended to cover IOS_ARM64E in the same branch as IOS_ARM64.
The fixBrokenMacroExpansionInXcode15_3 logic was previously in
ExecClang.kt and is now in the runtime build script.
- ObjC export (InfoPListBuilder.kt): UIRequiredDeviceCapabilities
emitted for arm64e frameworks.
- Apple SDK / framework (AppleSdk.kt, XCFrameworkTask.kt,
FatFrameworkTask.kt): arm64e Xcode arch mapped to IOS_ARM64E;
appleArchitecture distinguishes arm64 from arm64e via a new
AppleArchitecture.ARM64E enum value; IPHONE_DEVICE and
FatFrameworkTask.supportedTargets extended.
- Gradle DSL (KotlinTargetContainerWithPresetFunctions.kt,
KotlinHierarchyBuilder.kt + Impl): iosArm64e() factory overloads (5)
and withIosArm64e() hierarchy filter.
- Commonizer (PlatformWidthIndex.kt): IOS_ARM64E mapped to LONG (same
width class as IOS_ARM64).
- Test infrastructure (SettingsExecutor, TestProcessSettings,
AbstractNativeCInteropTest, kotlin-test-native-xctest,
XCTestExecutor, FirebaseCloudXCTestExecutor): SDK mapping to
iphoneos, cinterop golden-file mapping, XCTest framework copy task
wired with iosArm64e().
Behavioral change
-----------------
AppleSdk.kt previously mapped the Xcode-requested arch "arm64e" to
KonanTarget.IOS_ARM64 - an Xcode pipeline requesting arm64e silently
produced an arm64 binary. The mapping now splits:
"arm64" -> KonanTarget.IOS_ARM64
"arm64e" -> KonanTarget.IOS_ARM64E
Callers that depended on the silent downgrade must now explicitly
request arm64 in Xcode. The prior behavior was an unintended footgun.
Carried workaround: libunwind.h in darwin.def
---------------------------------------------
kotlin-native/platformLibs/src/platform/ios/darwin.def temporarily
drops libunwind.h from its headers = ... list. Apple's <libunwind.h>
declares fields such as unw_word_t reg[34] using __ptrauth qualifiers
(specifically ptrauth_restricted_intptr_qualifier, which Apple's
downstream clang accepts on plain integer types). Kotlin's bundled
LLVM 19 (kotlin/llvm-19-apple) does not yet recognise that qualifier,
so cinterop fails to parse the header on every ios target - not just
arm64e. Removal condition: cherry-pick the qualifier from Apple-LLVM
26.4+ into kotlin/llvm-19-apple, then revert this hunk.
Dependency: kotlin/llvm-19-apple FunctionSpecialization fix
-----------------------------------------------------------
This commit deliberately does NOT include the
StripDirectCallPtrauthBundlesPass workaround that was carried during
local bring-up. The workaround masked an LLVM 19 IR-verifier failure:
FunctionSpecializationPass devirtualized an indirect call whose body
carried a ptrauth operand bundle, producing a direct call that still
carried the bundle - which LLVM rejects as "Direct call cannot have a
ptrauth bundle". Concrete reproducer: K/N's CallInitGlobalPossiblyLock
runtime helper, cloned as @CallInitGlobalPossiblyLock.specialized.1.
The proper fix is in upstream LLVM (FunctionSpecialization.cpp strips
ptrauth bundles from devirtualized calls before IPSCCP propagates the
constant). That fix MUST be cherry-picked into kotlin/llvm-19-apple
and the K/N LLVM dependency rolled forward before this commit will
produce a working ios_arm64e build - without it, compiling any arm64e
Kotlin program will abort at the verifier when the runtime gets
linked.
Bootstrap integration note
--------------------------
The KonanTarget.IOS_ARM64E references in runtime/build.gradle.kts and
native/kotlin-test-native-xctest/build.gradle.kts compile against the
bootstrap kotlin-native-utils classpath, not the in-tree
:native:kotlin-native-utils source. Until bootstrap is bumped to a
kotlin-native-utils that exports KonanTarget.IOS_ARM64E, those compiles
fail with "Unresolved reference: IOS_ARM64E". The standard workflow is
to publish an interim bootstrap first.
Verification baseline
---------------------
Verified during the original bring-up against JetBrains/kotlin
f95cb2f with the StripDirectCallPtrauthBundlesPass workaround in
place. Outcomes were:
- :kotlin-native:ios_arm64eCrossDist - PASS (2m54s)
- :kotlin-native:platformLibs:ios_arm64eInstall - PASS (1m33s)
- konanc hello.kt -target ios_arm64e -produce framework - PASS;
Mach-O 64-bit arm64e, 344 ARM64_RELOC_AUTHENTICATED_POINTER
relocations, 85 PAC instructions (blraaz, braaz, paci, autia, ...),
__DATA_CONST __auth_got auth-bind rows for every imported symbol.
This rebased version (against current master, without the
StripDirectCallPtrauthBundlesPass workaround) has not been re-verified
end-to-end because verification requires kotlin/llvm-19-apple to ship
the FunctionSpecialization fix first. The Kotlin-side change set is
unchanged in intent; only the target file for the Xcode15.3 macro-
expansion workaround shifted from ExecClang.kt to
runtime/build.gradle.kts to track the upstream code move.
Code Owners
|
Contributor
|
Link to the kotlinlang slack thread. Also from there: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wires the iOS arm64e target (Pointer Authentication Code, FEAT_PAuth) end-to-end through target registration, toolchain configuration, gradle DSL, source-set hierarchy, test infrastructure, and platform libraries.
Produces Mach-O arm64e framework binaries with __auth_got / auth-bind chained fixups, ARM64_RELOC_AUTHENTICATED_POINTER relocations, and full ptrauth-* LLVM function attributes from the bundled kotlin/llvm-19-apple toolchain.
Layer breakdown
Behavioral change
AppleSdk.kt previously mapped the Xcode-requested arch "arm64e" to KonanTarget.IOS_ARM64 - an Xcode pipeline requesting arm64e silently produced an arm64 binary. The mapping now splits:
"arm64" -> KonanTarget.IOS_ARM64
"arm64e" -> KonanTarget.IOS_ARM64E
Callers that depended on the silent downgrade must now explicitly request arm64 in Xcode. The prior behavior was an unintended footgun.
Carried workaround: libunwind.h in darwin.def
kotlin-native/platformLibs/src/platform/ios/darwin.def temporarily drops libunwind.h from its headers = ... list. Apple's <libunwind.h> declares fields such as unw_word_t reg[34] using __ptrauth qualifiers (specifically ptrauth_restricted_intptr_qualifier, which Apple's downstream clang accepts on plain integer types). Kotlin's bundled LLVM 19 (kotlin/llvm-19-apple) does not yet recognise that qualifier, so cinterop fails to parse the header on every ios target - not just arm64e. Removal condition: cherry-pick the qualifier from Apple-LLVM 26.4+ into kotlin/llvm-19-apple, then revert this hunk.
Dependency: kotlin/llvm-19-apple FunctionSpecialization fix ----------------------------------------------------------- This commit deliberately does NOT include the
StripDirectCallPtrauthBundlesPass workaround that was carried during local bring-up. The workaround masked an LLVM 19 IR-verifier failure: FunctionSpecializationPass devirtualized an indirect call whose body carried a ptrauth operand bundle, producing a direct call that still carried the bundle - which LLVM rejects as "Direct call cannot have a ptrauth bundle". Concrete reproducer: K/N's CallInitGlobalPossiblyLock runtime helper, cloned as @CallInitGlobalPossiblyLock.specialized.1.
The proper fix is in upstream LLVM (FunctionSpecialization.cpp strips ptrauth bundles from devirtualized calls before IPSCCP propagates the constant). That fix MUST be cherry-picked into kotlin/llvm-19-apple and the K/N LLVM dependency rolled forward before this commit will produce a working ios_arm64e build - without it, compiling any arm64e Kotlin program will abort at the verifier when the runtime gets linked.
Bootstrap integration note
The KonanTarget.IOS_ARM64E references in runtime/build.gradle.kts and native/kotlin-test-native-xctest/build.gradle.kts compile against the bootstrap kotlin-native-utils classpath, not the in-tree :native:kotlin-native-utils source. Until bootstrap is bumped to a kotlin-native-utils that exports KonanTarget.IOS_ARM64E, those compiles fail with "Unresolved reference: IOS_ARM64E". The standard workflow is to publish an interim bootstrap first.
Verification baseline
Verified during the original bring-up against JetBrains/kotlin f95cb2f with the StripDirectCallPtrauthBundlesPass workaround in place. Outcomes were:
This rebased version (against current master, without the StripDirectCallPtrauthBundlesPass workaround) has not been re-verified end-to-end because verification requires kotlin/llvm-19-apple to ship the FunctionSpecialization fix first. The Kotlin-side change set is unchanged in intent; only the target file for the Xcode15.3 macro- expansion workaround shifted from ExecClang.kt to
runtime/build.gradle.kts to track the upstream code move.