diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/FatFrameworkIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/FatFrameworkIT.kt index d68ded66386..e24ffa39a5a 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/FatFrameworkIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/native/FatFrameworkIT.kt @@ -51,13 +51,13 @@ class FatFrameworkIT : BaseGradleIT() { gradleBuildScript().modify { it.checkedReplace("iosArm32()", "watchosArm32()") - .checkedReplace("iosArm64()", "watchosArm64()") + .checkedReplace("iosArm64()", "watchosArm64(); watchosDeviceArm64()") .checkedReplace("iosX64()", "watchosX64()") } build("fat") { checkSmokeBuild( - archs = listOf("x64", "arm64", "arm32"), + archs = listOf("x64", "arm64", "arm32", "deviceArm64"), targetPrefix = "watchos", expectedPlistPlatform = "WatchOS" ) @@ -68,6 +68,7 @@ class FatFrameworkIT : BaseGradleIT() { assertTrue(output.contains("\\(for architecture x86_64\\):\\s+Mach-O 64-bit dynamically linked shared library x86_64".toRegex())) assertTrue(output.contains("\\(for architecture armv7k\\):\\s+Mach-O dynamically linked shared library arm_v7k".toRegex())) assertTrue(output.contains("\\(for architecture arm64_32\\):\\s+Mach-O dynamically linked shared library arm64_32_v8".toRegex())) + assertTrue(output.contains("\\(for architecture arm64\\):\\s+Mach-O 64-bit dynamically linked shared library arm64".toRegex())) } } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/FatFrameworkTask.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/FatFrameworkTask.kt index 4c2c0466f27..77db1d8ff24 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/FatFrameworkTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/tasks/FatFrameworkTask.kt @@ -20,11 +20,9 @@ import org.jetbrains.kotlin.konan.target.HostManager import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget.* import org.jetbrains.kotlin.konan.util.visibleName -import org.jetbrains.kotlin.utils.PathUtil import java.io.ByteArrayOutputStream import java.io.File import java.nio.file.Files -import java.nio.file.Path class FrameworkDsymLayout(val rootDir: File) { init { @@ -117,7 +115,7 @@ open class FatFrameworkTask : DefaultTask() { onlyIf { HostManager.hostIsMac } } - private val archToFramework: MutableMap = mutableMapOf() + private val archToFramework: MutableMap = mutableMapOf() //region DSL properties. /** @@ -166,6 +164,29 @@ open class FatFrameworkTask : DefaultTask() { } } + private enum class AppleArchitecture(val clangMacro: String) { + X64("__x86_64__"), + X86("__i386__"), + ARM32("__arm__"), + // We need to distinguish between variants of aarch64, because there are two WatchOS ARM64 targets that we support + // watchOsArm64 that compiles to arm64_32 architecture + // watchOsDeviceArm64 that compiles to arm64 architecture + // https://github.com/apple/llvm-project/blob/6698c7d5889280d336f4aa8bf665d6e3c0c13ea0/clang/lib/Basic/Targets/AArch64.cpp#L1041 + ARM64_32("__ARM64_ARCH_8_32__"), + ARM64("__ARM64_ARCH_8__"), + } + + private val KonanTarget.appleArchitecture: AppleArchitecture get() = + when (architecture) { + Architecture.X64 -> AppleArchitecture.X64 + Architecture.X86 -> AppleArchitecture.X86 + Architecture.ARM64 -> if (this == WATCHOS_ARM64) AppleArchitecture.ARM64_32 else AppleArchitecture.ARM64 + Architecture.ARM32 -> AppleArchitecture.ARM32 + Architecture.MIPS32, + Architecture.MIPSEL32, + Architecture.WASM32 -> error("Fat frameworks are not supported for target $this") + } + // region DSL methods. /** * Adds the specified frameworks in this fat framework. @@ -185,7 +206,7 @@ open class FatFrameworkTask : DefaultTask() { */ fun fromFrameworkDescriptors(frameworks: Iterable) { frameworks.forEach { framework -> - val arch = framework.target.architecture + val arch = framework.target.appleArchitecture val family = framework.target.family val fatFrameworkFamily = getFatFrameworkFamily() require(fatFrameworkFamily == null || family == fatFrameworkFamily) { @@ -221,15 +242,6 @@ open class FatFrameworkTask : DefaultTask() { return archToFramework.values.firstOrNull()?.target?.family } - private val Architecture.clangMacro: String - get() = when (this) { - Architecture.X86 -> "__i386__" - Architecture.X64 -> "__x86_64__" - Architecture.ARM32 -> "__arm__" - Architecture.ARM64 -> "__aarch64__" - else -> error("Fat frameworks are not supported for architecture `$name`") - } - private val FrameworkDescriptor.plistPlatform: String get() = when (target) { MACOS_X64, MACOS_ARM64 -> "MacOSX"