[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)