Register "embedAndSignAppleFrameworkForXcode" anytime but throw error without Xcode environment.

#KT-49971
This commit is contained in:
konstantin.tskhovrebov
2021-11-29 18:39:33 +01:00
committed by Space
parent ab6c8a4abe
commit 14ee13c72e
2 changed files with 73 additions and 47 deletions
@@ -34,7 +34,9 @@ class AppleFrameworkIT : BaseGradleIT() {
customEnvironmentVariables = mapOf(
"CONFIGURATION" to "debug",
"SDK_NAME" to "iphoneos123",
"ARCHS" to "arm64"
"ARCHS" to "arm64",
"TARGET_BUILD_DIR" to "no use",
"FRAMEWORKS_FOLDER_PATH" to "no use"
)
)
build("assembleDebugAppleFrameworkForXcodeIosArm64", options = options) {
@@ -60,7 +62,9 @@ class AppleFrameworkIT : BaseGradleIT() {
customEnvironmentVariables = mapOf(
"CONFIGURATION" to "Release",
"SDK_NAME" to "iphonesimulator",
"ARCHS" to "arm64 x86_64"
"ARCHS" to "arm64 x86_64",
"TARGET_BUILD_DIR" to "no use",
"FRAMEWORKS_FOLDER_PATH" to "no use"
)
)
build("assembleReleaseAppleFrameworkForXcode", options = options) {
@@ -75,14 +79,11 @@ class AppleFrameworkIT : BaseGradleIT() {
}
@Test
fun `check there aren't Xcode tasks without Xcode environment`() {
fun `check embedAndSignAppleFrameworkForXcode fail`() {
with(Project("sharedAppleFramework")) {
build("tasks") {
assertSuccessful()
assertTasksNotRegistered(
":shared:assembleDebugAppleFrameworkForXcodeIosArm64",
":shared:embedAndSignAppleFrameworkForXcode"
)
build(":shared:embedAndSignAppleFrameworkForXcode") {
assertTasksFailed(":shared:embedAndSignAppleFrameworkForXcode")
assertContains("Please run the embedAndSignAppleFrameworkForXcode task from Xcode")
}
}
}
@@ -106,9 +107,7 @@ class AppleFrameworkIT : BaseGradleIT() {
":shared:assembleDebugAppleFrameworkForXcodeIosArm64",
":shared:embedAndSignAppleFrameworkForXcode",
":shared:assembleCustomDebugAppleFrameworkForXcodeIosArm64",
":shared:embedAndSignCustomAppleFrameworkForXcode"
)
assertTasksNotRegistered(
":shared:embedAndSignCustomAppleFrameworkForXcode",
":shared:assembleDebugAppleFrameworkForXcodeIosX64",
":shared:assembleReleaseAppleFrameworkForXcodeIosX64",
":shared:assembleReleaseAppleFrameworkForXcodeIosArm64",
@@ -121,7 +120,7 @@ class AppleFrameworkIT : BaseGradleIT() {
}
@Test
fun `check there isn't embedAndSignAppleFrameworkForXcode task without required Xcode environments`() {
fun `check embedAndSignAppleFrameworkForXcode was registered without required Xcode environments`() {
with(Project("sharedAppleFramework")) {
val options: BuildOptions = defaultBuildOptions().copy(
customEnvironmentVariables = mapOf(
@@ -133,16 +132,24 @@ class AppleFrameworkIT : BaseGradleIT() {
build("tasks", options = options) {
assertSuccessful()
assertTasksRegistered(
":shared:assembleDebugAppleFrameworkForXcodeIosArm64",
":shared:assembleCustomDebugAppleFrameworkForXcodeIosArm64"
":shared:embedAndSignAppleFrameworkForXcode",
":shared:embedAndSignCustomAppleFrameworkForXcode"
)
assertTasksNotRegistered(
":shared:embedAndSignAppleFrameworkForXcode",
":shared:assembleReleaseAppleFrameworkForXcodeIosX64",
":shared:assembleDebugAppleFrameworkForXcodeIosX64",
":shared:embedAndSignCustomAppleFrameworkForXcode",
":shared:assembleCustomDebugAppleFrameworkForXcodeIosX64"
":shared:assembleReleaseAppleFrameworkForXcodeIosArm64",
":shared:assembleDebugAppleFrameworkForXcodeIosArm64",
":shared:assembleCustomDebugAppleFrameworkForXcodeIosX64",
":shared:assembleCustomReleaseAppleFrameworkForXcodeIosX64",
":shared:assembleCustomDebugAppleFrameworkForXcodeIosArm64",
":shared:assembleCustomReleaseAppleFrameworkForXcodeIosArm64"
)
}
build(":shared:embedAndSignCustomAppleFrameworkForXcode", options = options) {
assertTasksFailed(":shared:embedAndSignCustomAppleFrameworkForXcode")
assertContains("Please run the embedAndSignCustomAppleFrameworkForXcode task from Xcode")
}
}
}
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.gradle.plugin.mpp.apple
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.plugins.BasePlugin
@@ -20,7 +21,6 @@ import org.jetbrains.kotlin.gradle.tasks.locateTask
import org.jetbrains.kotlin.gradle.tasks.registerTask
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
import java.io.File
private object XcodeEnvironment {
@@ -61,6 +61,15 @@ private object XcodeEnvironment {
}
val sign: String? get() = System.getenv("EXPANDED_CODE_SIGN_IDENTITY")
override fun toString() = """
XcodeEnvironment:
buildType=$buildType
targets=$targets
frameworkSearchDir=$frameworkSearchDir
embeddedFrameworksDir=$embeddedFrameworksDir
sign=$sign
""".trimIndent()
}
private fun Project.registerAssembleAppleFrameworkTask(framework: Framework): TaskProvider<out Task>? {
@@ -90,29 +99,27 @@ private fun Project.registerAssembleAppleFrameworkTask(framework: Framework): Ta
"Specify 'KOTLIN_FRAMEWORK_BUILD_TYPE' to 'debug' or 'release'"
)
} else {
logger.debug(
"Not registering $frameworkTaskName, since not called from Xcode " +
"('SDK_NAME', 'ARCHS' and 'CONFIGURATION' not provided)"
)
logger.debug("Not registering $frameworkTaskName, since not called from Xcode")
}
return null
}
if (frameworkBuildType != envBuildType || !envTargets.contains(frameworkTarget.konanTarget)) return null
return if (needFatFramework) {
locateOrRegisterTask<FatFrameworkTask>(frameworkTaskName) { task ->
task.group = BasePlugin.BUILD_GROUP
return when {
!envTargets.contains(frameworkTarget.konanTarget) -> locateOrRegisterTask<DefaultTask>(frameworkTaskName) { task ->
task.description = "Packs $frameworkBuildType ${frameworkTarget.name} framework for Xcode"
task.isEnabled = false
}
needFatFramework -> locateOrRegisterTask<FatFrameworkTask>(frameworkTaskName) { task ->
task.description = "Packs $frameworkBuildType fat framework for Xcode"
task.baseName = framework.baseName
task.destinationDir = appleFrameworkDir(envFrameworkSearchDir)
task.isEnabled = frameworkBuildType == envBuildType
}.also {
it.configure { task -> task.from(framework) }
}
} else {
registerTask<Copy>(frameworkTaskName) { task ->
task.group = BasePlugin.BUILD_GROUP
else -> registerTask<Copy>(frameworkTaskName) { task ->
task.description = "Packs $frameworkBuildType ${frameworkTarget.name} framework for Xcode"
task.isEnabled = frameworkBuildType == envBuildType
task.dependsOn(framework.linkTaskName)
task.from(framework.outputDirectory)
task.into(appleFrameworkDir(envFrameworkSearchDir))
@@ -121,8 +128,6 @@ private fun Project.registerAssembleAppleFrameworkTask(framework: Framework): Ta
}
internal fun Project.registerEmbedAndSignAppleFrameworkTask(framework: Framework) {
val assembleTask = registerAssembleAppleFrameworkTask(framework) ?: return
val envBuildType = XcodeEnvironment.buildType
val envTargets = XcodeEnvironment.targets
val envEmbeddedFrameworksDir = XcodeEnvironment.embeddedFrameworksDir
@@ -132,32 +137,46 @@ internal fun Project.registerEmbedAndSignAppleFrameworkTask(framework: Framework
val frameworkTaskName = lowerCamelCaseName("embedAndSign", framework.namePrefix, "AppleFrameworkForXcode")
if (envBuildType == null || envTargets.isEmpty() || envEmbeddedFrameworksDir == null || envFrameworkSearchDir == null) {
logger.debug(
"Not registering $frameworkTaskName, since not called from Xcode " +
"('SDK_NAME', 'CONFIGURATION', 'TARGET_BUILD_DIR', 'ARCHS' and 'FRAMEWORKS_FOLDER_PATH' not provided)"
)
locateOrRegisterTask<DefaultTask>(frameworkTaskName) { task ->
task.group = BasePlugin.BUILD_GROUP
task.description = "Embed and sign ${framework.namePrefix} framework as requested by Xcode's environment variables"
task.doFirst {
val envConfiguration = System.getenv("CONFIGURATION")
if (envConfiguration != null && envBuildType == null) {
throw IllegalStateException(
"Unable to detect Kotlin framework build type for CONFIGURATION=$envConfiguration automatically. " +
"Specify 'KOTLIN_FRAMEWORK_BUILD_TYPE' to 'debug' or 'release'" +
"\n$XcodeEnvironment"
)
} else {
throw IllegalStateException(
"Please run the $frameworkTaskName task from Xcode " +
"('SDK_NAME', 'CONFIGURATION', 'TARGET_BUILD_DIR', 'ARCHS' and 'FRAMEWORKS_FOLDER_PATH' not provided)" +
"\n$XcodeEnvironment"
)
}
}
}
return
}
if (framework.buildType != envBuildType || !envTargets.contains(framework.konanTarget)) return
if (locateTask<Copy>(frameworkTaskName) != null) return
registerTask<Copy>(frameworkTaskName) { task ->
task.group = "build"
val embedAndSignTask = locateOrRegisterTask<Copy>(frameworkTaskName) { task ->
task.group = BasePlugin.BUILD_GROUP
task.description = "Embed and sign ${framework.namePrefix} framework as requested by Xcode's environment variables"
task.dependsOn(assembleTask)
task.inputs.apply {
property("type", envBuildType)
property("targets", envTargets)
property("embeddedFrameworksDir", envEmbeddedFrameworksDir)
property("sign", envSign)
}
}
task.from(appleFrameworkDir(envFrameworkSearchDir)) { spec ->
spec.include(framework.outputFile.name + "/**")
}
val assembleTask = registerAssembleAppleFrameworkTask(framework) ?: return
if (framework.buildType != envBuildType || !envTargets.contains(framework.konanTarget)) return
embedAndSignTask.configure { task ->
task.dependsOn(assembleTask)
task.from(appleFrameworkDir(envFrameworkSearchDir)) { it.include(framework.outputFile.name + "/**") }
task.into(envEmbeddedFrameworksDir)
if (envSign != null) {