[Native] Support x86-64 arch for catalyst
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt
index 65df739..7992bc1 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt
@@ -27,6 +27,7 @@
import org.jetbrains.kotlin.config.nativeBinaryOptions.CoreSymbolicationImageListType
import org.jetbrains.kotlin.config.nativeBinaryOptions.GC
import org.jetbrains.kotlin.config.nativeBinaryOptions.GCSchedulerType
+import org.jetbrains.kotlin.config.nativeBinaryOptions.MacAbi
import org.jetbrains.kotlin.config.nativeBinaryOptions.ObjCExportSuspendFunctionLaunchThreadRestriction
import org.jetbrains.kotlin.config.nativeBinaryOptions.RuntimeAssertsMode
import org.jetbrains.kotlin.config.nativeBinaryOptions.RuntimeLinkageStrategy
@@ -51,23 +52,26 @@
* Determine if we compile for iOS target with Mac ABI (Catalyst).
* Avoid using this property if possible. Instead, use [TargetTriple.isMacabi] as it is more direct.
*/
- val macabi: Boolean = run {
- val macabi = configuration.getBoolean(BinaryOptions.macabi)
+ val macabi: MacAbi? = run {
+ val macabi = configuration.get(BinaryOptions.macabi)
// We can't access `target` property due to circular dependency.
- if (macabi && configuration.get(KonanConfigKeys.TARGET) != "ios_arm64") {
+ if (macabi != null && configuration.get(KonanConfigKeys.TARGET) != "ios_arm64") {
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "macabi is only supported for iosArm64 target")
- false
- }
- else macabi
+ null
+ } else macabi
}
internal val distribution = run {
val overridenProperties = mutableMapOf<String, String>().apply {
- if (macabi) {
+ if (macabi != null) {
+ val arch = when (macabi) {
+ MacAbi.X64 -> "x86_64"
+ MacAbi.ARM64 -> "arm64"
+ }
// Overriding target-triple via properties is a bit better alternative than
// Tracking all usages of `configurables.targeTriple` and making adjustments on call-site.
// Still ugly, of course.
- put("targetTriple.ios_arm64", "arm64-apple-ios-macabi")
+ put("targetTriple.ios_arm64", "$arch-apple-ios-macabi")
// macabi implies usage of macOS sysroot.
put("targetSysRoot.ios_arm64", "\$targetSysRoot.macos_arm64")
}
@@ -520,7 +524,11 @@
append("-check_state_at_external_calls")
if (stackProtectorMode != StackProtectorMode.NO)
append("-stack_protector${stackProtectorMode.name}")
- if (macabi) append("-macabi")
+ when (macabi) {
+ MacAbi.X64 -> append("-macabi-x64")
+ MacAbi.ARM64 -> append("-macabi-arm64")
+ null -> {}
+ }
}
private val systemCacheFlavorString = buildString {
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/SetupConfiguration.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/SetupConfiguration.kt
index f02eb44..5705e0c 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/SetupConfiguration.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/SetupConfiguration.kt
@@ -362,7 +362,7 @@
put(CommonConfigurationKeys.PARALLEL_BACKEND_THREADS, konanConfig.threadsCount)
putIfNotNull(KONAN_DATA_DIR, konanConfig.distribution.localKonanDir.absolutePath)
putIfNotNull(BinaryOptions.minidumpLocation, konanConfig.minidumpLocation)
- put(BinaryOptions.macabi, konanConfig.macabi)
+ putIfNotNull(BinaryOptions.macabi, konanConfig.macabi)
}
private fun Array<String>?.toNonNullList() = this?.asList().orEmpty()
diff --git a/native/binary-options/src/main/kotlin/org/jetbrains/kotlin/config/nativeBinaryOptions/BinaryOptions.kt b/native/binary-options/src/main/kotlin/org/jetbrains/kotlin/config/nativeBinaryOptions/BinaryOptions.kt
index bebba84..05d64c7 100644
--- a/native/binary-options/src/main/kotlin/org/jetbrains/kotlin/config/nativeBinaryOptions/BinaryOptions.kt
+++ b/native/binary-options/src/main/kotlin/org/jetbrains/kotlin/config/nativeBinaryOptions/BinaryOptions.kt
@@ -112,9 +112,9 @@
val minidumpLocation by stringOption()
/**
- * Generate a macOS Catalyst binary.
+ * Generate a macOS Catalyst binary for the given architecture
*/
- val macabi by booleanOption()
+ val macabi by option<MacAbi>()
}
open class BinaryOption<T : Any>(
diff --git a/native/binary-options/src/main/kotlin/org/jetbrains/kotlin/config/nativeBinaryOptions/MacAbi.kt b/native/binary-options/src/main/kotlin/org/jetbrains/kotlin/config/nativeBinaryOptions/MacAbi.kt
new file mode 100644
index 0000000..2811e3f
--- /dev/null
+++ b/native/binary-options/src/main/kotlin/org/jetbrains/kotlin/config/nativeBinaryOptions/MacAbi.kt
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2010-2025 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.config.nativeBinaryOptions
+
+/**
+ * An architecture of macOS Catalyst.
+ *
+ * Overall, this class highlights the limits of [org.jetbrains.kotlin.konan.target.KonanTarget] class.
+ * We would not need this binary option at all if we could directly pass target triple to the compiler.
+ *
+ * Could be replaced by [org.jetbrains.kotlin.konan.target.Architecture],
+ * but it requires adding a dependency on another module.
+ */
+enum class MacAbi {
+ X64,
+ ARM64,
+}
\ No newline at end of file
diff --git a/native/native.tests/testFixtures/org/jetbrains/kotlin/konan/test/blackbox/support/compilation/TestCompilation.kt b/native/native.tests/testFixtures/org/jetbrains/kotlin/konan/test/blackbox/support/compilation/TestCompilation.kt
index 1760fc4..6ca068b 100644
--- a/native/native.tests/testFixtures/org/jetbrains/kotlin/konan/test/blackbox/support/compilation/TestCompilation.kt
+++ b/native/native.tests/testFixtures/org/jetbrains/kotlin/konan/test/blackbox/support/compilation/TestCompilation.kt
@@ -13,6 +13,7 @@
import org.jetbrains.kotlin.konan.target.AppleConfigurables
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.KonanTarget
+import org.jetbrains.kotlin.konan.target.isMacabi
import org.jetbrains.kotlin.konan.target.withOSVersion
import org.jetbrains.kotlin.konan.test.blackbox.support.*
import org.jetbrains.kotlin.konan.test.blackbox.support.TestCase.*
@@ -589,12 +590,29 @@
val optimizationModeFlags = swiftcOptimizationModeFlags(testRunSettings.get<OptimizationMode>())
- val args = swiftExtraOpts + optimizationModeFlags + sources.map { it.absolutePath } + listOf(
- "-sdk", configs.absoluteTargetSysRoot, "-target", swiftTarget,
- "-o", outputFile(expectedArtifact).absolutePath,
- "-g", // Xcode seems to pass -g even for optimized builds by default.
- "-Xcc", "-Werror", // To fail compilation on warnings in framework header.
- )
+ val args = buildList {
+ addAll(
+ listOf(
+ "-sdk", configs.absoluteTargetSysRoot,
+ "-target", swiftTarget,
+ "-o", outputFile(expectedArtifact).absolutePath,
+ "-g", // Xcode seems to pass -g even for optimized builds by default.
+ "-Xcc", "-Werror", // To fail compilation on warnings in framework header.
+ )
+ )
+ if (configs.targetTriple.isMacabi) {
+ addAll(
+ // Since the sysroot is for macOS, we should point the compiler to the directory with iOS system frameworks.
+ listOf(
+ "-Fsystem", "${configs.absoluteTargetSysRoot}/System/iOSSupport/System/Library/Frameworks",
+ "-Xcc", "-isystem", "-Xcc", "${configs.absoluteTargetSysRoot}/System/iOSSupport/usr/include",
+ )
+ )
+ }
+ addAll(sources.map { it.absolutePath })
+ addAll(optimizationModeFlags)
+ addAll(swiftExtraOpts)
+ }
val loggedSwiftCParameters = LoggedData.SwiftCParameters(args, sources)
val (loggedCall: LoggedData, immediateResult: TestCompilationResult.ImmediateResult<out T>) = try {
diff --git a/native/native.tests/testFixtures/org/jetbrains/kotlin/konan/test/blackbox/support/settings/SettingsContainers.kt b/native/native.tests/testFixtures/org/jetbrains/kotlin/konan/test/blackbox/support/settings/SettingsContainers.kt
index 8d97600..47a114e 100644
--- a/native/native.tests/testFixtures/org/jetbrains/kotlin/konan/test/blackbox/support/settings/SettingsContainers.kt
+++ b/native/native.tests/testFixtures/org/jetbrains/kotlin/konan/test/blackbox/support/settings/SettingsContainers.kt
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.konan.test.blackbox.support.settings
import org.jetbrains.kotlin.config.nativeBinaryOptions.BinaryOptions
+import org.jetbrains.kotlin.config.nativeBinaryOptions.MacAbi
import org.jetbrains.kotlin.konan.target.Configurables
import org.jetbrains.kotlin.konan.target.Distribution
import org.jetbrains.kotlin.konan.target.HostManager
@@ -70,9 +71,15 @@
val propertyOverrides = buildMap {
// Development variant of LLVM is used to have utilities like FileCheck
put("llvmHome.${HostManager.hostName}", "\$llvm.${HostManager.hostName}.dev")
- if (get<ExplicitBinaryOptions>().getOrNull(BinaryOptions.macabi) == true) {
+
+ val macabi = get<ExplicitBinaryOptions>().getOrNull(BinaryOptions.macabi)
+ if (macabi != null) {
// The same as in KonanConfig. See the motivation there.
- put("targetTriple.ios_arm64", "arm64-apple-ios-macabi")
+ val arch = when (macabi) {
+ MacAbi.X64 -> "x86_64"
+ MacAbi.ARM64 -> "arm64"
+ }
+ put("targetTriple.ios_arm64", "$arch-apple-ios-macabi")
put("targetSysRoot.ios_arm64", "\$targetSysRoot.macos_arm64")
}
}
diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/test/blackbox/FrameworkTest.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/test/blackbox/FrameworkTest.kt
index f9574fb..86ad918 100644
--- a/native/native.tests/tests/org/jetbrains/kotlin/konan/test/blackbox/FrameworkTest.kt
+++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/test/blackbox/FrameworkTest.kt
@@ -6,9 +6,11 @@
package org.jetbrains.kotlin.konan.test.blackbox
import com.intellij.testFramework.TestDataPath
+import org.jetbrains.kotlin.config.nativeBinaryOptions.BinaryOptions
import org.jetbrains.kotlin.config.nativeBinaryOptions.GC
import org.jetbrains.kotlin.config.nativeBinaryOptions.GCSchedulerType
import org.jetbrains.kotlin.konan.target.Family
+import org.jetbrains.kotlin.konan.target.isMacabi
import org.jetbrains.kotlin.konan.test.blackbox.support.*
import org.jetbrains.kotlin.konan.test.blackbox.support.compilation.*
import org.jetbrains.kotlin.konan.test.blackbox.support.compilation.TestCompilationResult.Companion.assertSuccess
@@ -236,6 +238,8 @@
fun testStacktrace() {
val testName = "stacktrace"
Assumptions.assumeFalse(testRunSettings.get<OptimizationMode>() == OptimizationMode.OPT)
+ // TODO: create ticket.
+ Assumptions.assumeFalse(testRunSettings.configurables.targetTriple.isMacabi)
val testCase = generateObjCFramework(testName, listOf("-g"))
compileAndRunSwift(testName, testCase)