[KT-54060] Disable bitcode embedding to frameworks for Xcode >= 14.
This commit is contained in:
committed by
Space Team
parent
ea3713f051
commit
afa8a577cc
+9
-13
@@ -7,29 +7,25 @@
|
||||
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||
|
||||
import org.gradle.api.Named
|
||||
import org.jetbrains.kotlin.konan.target.Architecture.ARM32
|
||||
import org.jetbrains.kotlin.konan.target.Architecture.ARM64
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.konan.target.Family.*
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
enum class NativeBuildType(
|
||||
val optimized: Boolean,
|
||||
val debuggable: Boolean,
|
||||
private val embedBitcodeForAppleDevices: BitcodeEmbeddingMode
|
||||
val debuggable: Boolean
|
||||
) : Named {
|
||||
RELEASE(true, false, BitcodeEmbeddingMode.BITCODE),
|
||||
DEBUG(false, true, BitcodeEmbeddingMode.MARKER);
|
||||
RELEASE(true, false),
|
||||
DEBUG(false, true);
|
||||
|
||||
override fun getName(): String = name.toLowerCase()
|
||||
|
||||
fun embedBitcode(target: KonanTarget) = with(target) {
|
||||
if (family in listOf(IOS, WATCHOS, TVOS) && architecture in listOf(ARM32, ARM64)) {
|
||||
embedBitcodeForAppleDevices
|
||||
} else {
|
||||
BitcodeEmbeddingMode.DISABLE
|
||||
}
|
||||
}
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
@Deprecated(
|
||||
"Default BitcodeEmbeddingMode is BitcodeEmbeddingMode.DISABLE",
|
||||
ReplaceWith("BitcodeEmbeddingMode.DISABLE")
|
||||
)
|
||||
fun embedBitcode(target: KonanTarget) = BitcodeEmbeddingMode.DISABLE
|
||||
|
||||
companion object {
|
||||
val DEFAULT_BUILD_TYPES = setOf(DEBUG, RELEASE)
|
||||
|
||||
+16
-2
@@ -373,15 +373,29 @@ class GeneralNativeIT : BaseGradleIT() {
|
||||
frameworkPaths.forEach { assertFileExists(it) }
|
||||
|
||||
assertTrue(fileInWorkingDir(headerPaths[0]).readText().contains("+ (int32_t)exported"))
|
||||
val xcodeVersionString = runProcess(
|
||||
listOf("/usr/bin/xcrun", "xcodebuild", "-version"),
|
||||
workingDir,
|
||||
System.getenv()
|
||||
).output.lines()[0].removePrefix("Xcode ")
|
||||
val xcodeMajorVersion = xcodeVersionString.split(".")[0].toInt()
|
||||
|
||||
// Check that by default release frameworks have bitcode embedded.
|
||||
withNativeCommandLineArguments(":linkMainReleaseFrameworkIos") { arguments ->
|
||||
assertTrue("-Xembed-bitcode" in arguments)
|
||||
if (xcodeMajorVersion < 14) {
|
||||
assertTrue("-Xembed-bitcode" in arguments)
|
||||
} else {
|
||||
assertFalse("-Xembed-bitcode" in arguments)
|
||||
}
|
||||
assertTrue("-opt" in arguments)
|
||||
}
|
||||
// Check that by default debug frameworks have bitcode marker embedded.
|
||||
withNativeCommandLineArguments(":linkMainDebugFrameworkIos") { arguments ->
|
||||
assertTrue("-Xembed-bitcode-marker" in arguments)
|
||||
if (xcodeMajorVersion < 14) {
|
||||
assertTrue("-Xembed-bitcode-marker" in arguments)
|
||||
} else {
|
||||
assertFalse("-Xembed-bitcode-marker" in arguments)
|
||||
}
|
||||
assertTrue("-g" in arguments)
|
||||
}
|
||||
// Check that bitcode can be disabled by setting custom compiler options
|
||||
|
||||
+3
-1
@@ -19,6 +19,7 @@ import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.AbstractExecTask
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
|
||||
import org.jetbrains.kotlin.gradle.utils.Xcode
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import java.io.File
|
||||
@@ -278,7 +279,8 @@ class Framework(
|
||||
/**
|
||||
* Embed bitcode for the framework or not. See [BitcodeEmbeddingMode].
|
||||
*/
|
||||
var embedBitcode: org.jetbrains.kotlin.gradle.plugin.mpp.BitcodeEmbeddingMode = buildType.embedBitcode(konanTarget)
|
||||
var embedBitcode: org.jetbrains.kotlin.gradle.plugin.mpp.BitcodeEmbeddingMode =
|
||||
Xcode.defaultBitcodeEmbeddingMode(konanTarget, buildType)
|
||||
|
||||
/**
|
||||
* Enable or disable embedding bitcode for the framework. See [BitcodeEmbeddingMode].
|
||||
|
||||
+1
-63
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.gradle.targets.native.cocoapods.MissingCocoapodsMess
|
||||
import org.jetbrains.kotlin.gradle.targets.native.cocoapods.MissingSpecReposMessage
|
||||
import org.jetbrains.kotlin.gradle.tasks.PodspecTask.Companion.retrievePods
|
||||
import org.jetbrains.kotlin.gradle.tasks.PodspecTask.Companion.retrieveSpecRepos
|
||||
import org.jetbrains.kotlin.gradle.utils.runCommand
|
||||
import org.jetbrains.kotlin.konan.target.Family
|
||||
import org.jetbrains.kotlin.konan.target.HostManager
|
||||
import java.io.File
|
||||
@@ -114,69 +115,6 @@ open class PodInstallTask : CocoapodsTask() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun runCommand(
|
||||
command: List<String>,
|
||||
logger: Logger,
|
||||
errorHandler: ((retCode: Int, output: String, process: Process) -> String?)? = null,
|
||||
exceptionHandler: ((ex: IOException) -> Unit)? = null,
|
||||
processConfiguration: ProcessBuilder.() -> Unit = { }
|
||||
): String {
|
||||
var process: Process? = null
|
||||
try {
|
||||
process = ProcessBuilder(command)
|
||||
.apply {
|
||||
this.processConfiguration()
|
||||
}.start()
|
||||
} catch (e: IOException) {
|
||||
if (exceptionHandler != null) exceptionHandler(e) else throw e
|
||||
}
|
||||
|
||||
if (process == null) {
|
||||
throw IllegalStateException("Failed to run command ${command.joinToString(" ")}")
|
||||
}
|
||||
|
||||
var inputText = ""
|
||||
var errorText = ""
|
||||
|
||||
val inputThread = thread {
|
||||
inputText = process.inputStream.use {
|
||||
it.reader().readText()
|
||||
}
|
||||
}
|
||||
|
||||
val errorThread = thread {
|
||||
errorText = process.errorStream.use {
|
||||
it.reader().readText()
|
||||
}
|
||||
}
|
||||
|
||||
inputThread.join()
|
||||
errorThread.join()
|
||||
|
||||
val retCode = process.waitFor()
|
||||
logger.info(
|
||||
"""
|
||||
|Information about "${command.joinToString(" ")}" call:
|
||||
|
|
||||
|${inputText}
|
||||
""".trimMargin()
|
||||
)
|
||||
|
||||
check(retCode == 0) {
|
||||
errorHandler?.invoke(retCode, inputText.ifBlank { errorText }, process)
|
||||
?: """
|
||||
|Executing of '${command.joinToString(" ")}' failed with code $retCode and message:
|
||||
|
|
||||
|$inputText
|
||||
|
|
||||
|$errorText
|
||||
|
|
||||
""".trimMargin()
|
||||
}
|
||||
|
||||
return inputText
|
||||
}
|
||||
|
||||
/**
|
||||
* The task generates a synthetic project with all cocoapods dependencies
|
||||
*/
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.NativeOutputKind
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.enabledOnCurrentHost
|
||||
import org.jetbrains.kotlin.gradle.tasks.dependsOn
|
||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
||||
import org.jetbrains.kotlin.gradle.utils.Xcode
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.konan.target.presetName
|
||||
@@ -122,7 +123,7 @@ internal fun KotlinNativeArtifact.registerLinkFrameworkTask(
|
||||
task.linkerOptions = linkerOptions
|
||||
task.binaryOptions = binaryOptions
|
||||
task.isStaticFramework = isStatic
|
||||
task.embedBitcode = embedBitcode ?: buildType.embedBitcode(target)
|
||||
task.embedBitcode = embedBitcode ?: Xcode.defaultBitcodeEmbeddingMode(target, buildType)
|
||||
task.librariesConfiguration = librariesConfigurationName
|
||||
task.exportLibrariesConfiguration = exportConfigurationName
|
||||
task.kotlinOptions(kotlinOptionsFn)
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.gradle.utils
|
||||
|
||||
import org.gradle.api.logging.Logger
|
||||
import java.io.IOException
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
internal fun runCommand(
|
||||
command: List<String>,
|
||||
logger: Logger? = null,
|
||||
errorHandler: ((retCode: Int, output: String, process: Process) -> String?)? = null,
|
||||
exceptionHandler: ((ex: IOException) -> Unit)? = null,
|
||||
processConfiguration: ProcessBuilder.() -> Unit = { }
|
||||
): String {
|
||||
var process: Process? = null
|
||||
try {
|
||||
process = ProcessBuilder(command)
|
||||
.apply {
|
||||
this.processConfiguration()
|
||||
}.start()
|
||||
} catch (e: IOException) {
|
||||
if (exceptionHandler != null) exceptionHandler(e) else throw e
|
||||
}
|
||||
|
||||
if (process == null) {
|
||||
throw IllegalStateException("Failed to run command ${command.joinToString(" ")}")
|
||||
}
|
||||
|
||||
var inputText = ""
|
||||
var errorText = ""
|
||||
|
||||
val inputThread = thread {
|
||||
inputText = process.inputStream.use {
|
||||
it.reader().readText()
|
||||
}
|
||||
}
|
||||
|
||||
val errorThread = thread {
|
||||
errorText = process.errorStream.use {
|
||||
it.reader().readText()
|
||||
}
|
||||
}
|
||||
|
||||
inputThread.join()
|
||||
errorThread.join()
|
||||
|
||||
val retCode = process.waitFor()
|
||||
logger?.info(
|
||||
"""
|
||||
|Information about "${command.joinToString(" ")}" call:
|
||||
|
|
||||
|${inputText}
|
||||
""".trimMargin()
|
||||
)
|
||||
|
||||
check(retCode == 0) {
|
||||
errorHandler?.invoke(retCode, inputText.ifBlank { errorText }, process)
|
||||
?: """
|
||||
|Executing of '${command.joinToString(" ")}' failed with code $retCode and message:
|
||||
|
|
||||
|$inputText
|
||||
|
|
||||
|$errorText
|
||||
|
|
||||
""".trimMargin()
|
||||
}
|
||||
|
||||
return inputText
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.gradle.utils
|
||||
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.BitcodeEmbeddingMode
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
|
||||
import org.jetbrains.kotlin.konan.target.Architecture.ARM32
|
||||
import org.jetbrains.kotlin.konan.target.Architecture.ARM64
|
||||
import org.jetbrains.kotlin.konan.target.Family.*
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
internal object Xcode {
|
||||
val currentVersion: String by lazy {
|
||||
val out = runCommand(listOf("/usr/bin/xcrun", "xcodebuild", "-version"))
|
||||
out.lines()[0].removePrefix("Xcode ")
|
||||
}
|
||||
|
||||
fun defaultBitcodeEmbeddingMode(target: KonanTarget, buildType: NativeBuildType): BitcodeEmbeddingMode {
|
||||
if (currentVersion.split(".")[0].toInt() < 14) {
|
||||
if (target.family in listOf(IOS, WATCHOS, TVOS) && target.architecture in listOf(ARM32, ARM64)) {
|
||||
when (buildType) {
|
||||
NativeBuildType.RELEASE -> return BitcodeEmbeddingMode.BITCODE
|
||||
NativeBuildType.DEBUG -> return BitcodeEmbeddingMode.MARKER
|
||||
}
|
||||
}
|
||||
}
|
||||
return BitcodeEmbeddingMode.DISABLE
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user