From fd5c061c0b4b90deaae9f9d64136f963a0f382ec Mon Sep 17 00:00:00 2001 From: Anton Lakotka Date: Wed, 5 Oct 2022 06:59:45 +0200 Subject: [PATCH] [Gradle] Use more granular arm64 clang macro's for fat frameworks After introducing watchOsDeviceArm64 target it conflicted with existing watchOsArm64 target. Because both having the same Konan Architecture as Arm64. This is not entirely correct and actual architectures are different. So it requires more precise macros for fat framework. * __ARM64_ARCH_8_32__ for `watchOsArm64` which is based on `arm64_32` * __ARM64_ARCH_8__ for other arm64 devices including `watchOsDeviceArm64` ^KT-53107 --- .../kotlin/gradle/native/FatFrameworkIT.kt | 5 ++- .../targets/native/tasks/FatFrameworkTask.kt | 38 ++++++++++++------- 2 files changed, 28 insertions(+), 15 deletions(-) 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"