[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
|
package org.jetbrains.kotlin.gradle.plugin.mpp
|
||||||
|
|
||||||
import org.gradle.api.Named
|
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.CompilerOutputKind
|
||||||
import org.jetbrains.kotlin.konan.target.Family.*
|
import org.jetbrains.kotlin.konan.target.Family.*
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
|
|
||||||
enum class NativeBuildType(
|
enum class NativeBuildType(
|
||||||
val optimized: Boolean,
|
val optimized: Boolean,
|
||||||
val debuggable: Boolean,
|
val debuggable: Boolean
|
||||||
private val embedBitcodeForAppleDevices: BitcodeEmbeddingMode
|
|
||||||
) : Named {
|
) : Named {
|
||||||
RELEASE(true, false, BitcodeEmbeddingMode.BITCODE),
|
RELEASE(true, false),
|
||||||
DEBUG(false, true, BitcodeEmbeddingMode.MARKER);
|
DEBUG(false, true);
|
||||||
|
|
||||||
override fun getName(): String = name.toLowerCase()
|
override fun getName(): String = name.toLowerCase()
|
||||||
|
|
||||||
fun embedBitcode(target: KonanTarget) = with(target) {
|
@Suppress("UNUSED_PARAMETER")
|
||||||
if (family in listOf(IOS, WATCHOS, TVOS) && architecture in listOf(ARM32, ARM64)) {
|
@Deprecated(
|
||||||
embedBitcodeForAppleDevices
|
"Default BitcodeEmbeddingMode is BitcodeEmbeddingMode.DISABLE",
|
||||||
} else {
|
ReplaceWith("BitcodeEmbeddingMode.DISABLE")
|
||||||
BitcodeEmbeddingMode.DISABLE
|
)
|
||||||
}
|
fun embedBitcode(target: KonanTarget) = BitcodeEmbeddingMode.DISABLE
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val DEFAULT_BUILD_TYPES = setOf(DEBUG, RELEASE)
|
val DEFAULT_BUILD_TYPES = setOf(DEBUG, RELEASE)
|
||||||
|
|||||||
+16
-2
@@ -373,15 +373,29 @@ class GeneralNativeIT : BaseGradleIT() {
|
|||||||
frameworkPaths.forEach { assertFileExists(it) }
|
frameworkPaths.forEach { assertFileExists(it) }
|
||||||
|
|
||||||
assertTrue(fileInWorkingDir(headerPaths[0]).readText().contains("+ (int32_t)exported"))
|
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.
|
// Check that by default release frameworks have bitcode embedded.
|
||||||
withNativeCommandLineArguments(":linkMainReleaseFrameworkIos") { arguments ->
|
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)
|
assertTrue("-opt" in arguments)
|
||||||
}
|
}
|
||||||
// Check that by default debug frameworks have bitcode marker embedded.
|
// Check that by default debug frameworks have bitcode marker embedded.
|
||||||
withNativeCommandLineArguments(":linkMainDebugFrameworkIos") { arguments ->
|
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)
|
assertTrue("-g" in arguments)
|
||||||
}
|
}
|
||||||
// Check that bitcode can be disabled by setting custom compiler options
|
// 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.AbstractExecTask
|
||||||
import org.gradle.api.tasks.TaskProvider
|
import org.gradle.api.tasks.TaskProvider
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
|
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.gradle.utils.lowerCamelCaseName
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -278,7 +279,8 @@ class Framework(
|
|||||||
/**
|
/**
|
||||||
* Embed bitcode for the framework or not. See [BitcodeEmbeddingMode].
|
* 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].
|
* 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.targets.native.cocoapods.MissingSpecReposMessage
|
||||||
import org.jetbrains.kotlin.gradle.tasks.PodspecTask.Companion.retrievePods
|
import org.jetbrains.kotlin.gradle.tasks.PodspecTask.Companion.retrievePods
|
||||||
import org.jetbrains.kotlin.gradle.tasks.PodspecTask.Companion.retrieveSpecRepos
|
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.Family
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import java.io.File
|
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
|
* 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.plugin.mpp.enabledOnCurrentHost
|
||||||
import org.jetbrains.kotlin.gradle.tasks.dependsOn
|
import org.jetbrains.kotlin.gradle.tasks.dependsOn
|
||||||
import org.jetbrains.kotlin.gradle.tasks.registerTask
|
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.gradle.utils.lowerCamelCaseName
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||||
import org.jetbrains.kotlin.konan.target.presetName
|
import org.jetbrains.kotlin.konan.target.presetName
|
||||||
@@ -122,7 +123,7 @@ internal fun KotlinNativeArtifact.registerLinkFrameworkTask(
|
|||||||
task.linkerOptions = linkerOptions
|
task.linkerOptions = linkerOptions
|
||||||
task.binaryOptions = binaryOptions
|
task.binaryOptions = binaryOptions
|
||||||
task.isStaticFramework = isStatic
|
task.isStaticFramework = isStatic
|
||||||
task.embedBitcode = embedBitcode ?: buildType.embedBitcode(target)
|
task.embedBitcode = embedBitcode ?: Xcode.defaultBitcodeEmbeddingMode(target, buildType)
|
||||||
task.librariesConfiguration = librariesConfigurationName
|
task.librariesConfiguration = librariesConfigurationName
|
||||||
task.exportLibrariesConfiguration = exportConfigurationName
|
task.exportLibrariesConfiguration = exportConfigurationName
|
||||||
task.kotlinOptions(kotlinOptionsFn)
|
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