diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/apple/XcodeDirectIntegrationIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/apple/XcodeDirectIntegrationIT.kt index 7a4508cb20eda..86f4a1d56557d 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/apple/XcodeDirectIntegrationIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/apple/XcodeDirectIntegrationIT.kt @@ -47,7 +47,7 @@ class XcodeDirectIntegrationIT : KGPBaseTest() { override fun provideArguments(context: ExtensionContext): Stream { return super.provideArguments(context).flatMap { arguments -> val gradleVersion = arguments.get().first() - Stream.of(BuildPhase, SchemePreAction, SchemePreActionSpm).flatMap { iosApp -> + Stream.of(SchemePreAction, SchemePreActionSpm).flatMap { iosApp -> Stream.of(true, false).map { isStatic -> Arguments.of(gradleVersion, iosApp, isStatic) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/AppleXcodeTasks.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/AppleXcodeTasks.kt index 1cd85f20cdc4d..4dcfb2133affd 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/AppleXcodeTasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/AppleXcodeTasks.kt @@ -131,6 +131,14 @@ private fun Project.registerSymbolicLinkTask( } } +private fun Project.registerCreateBuildSystemDirectory( + builtProductsDir: Provider, +): TaskProvider<*> { + return locateOrRegisterTask("createBuildSystemDirectory") { + it.buildSystemDirectory.set(builtProductsDir) + } +} + private fun Project.registerDsymArchiveTask( frameworkCopyTaskName: String, dsymPath: Provider?, @@ -221,10 +229,14 @@ internal fun Project.registerEmbedAndSignAppleFrameworkTask(framework: Framework val sandBoxTask = checkSandboxAndWriteProtectionTask(environment, environment.userScriptSandboxingEnabled) val assembleTask = registerAssembleAppleFrameworkTask(framework, environment) ?: return + val builtProductsDir = builtProductsDir(frameworkTaskName, environment) + val createBuildSystemDirectory = registerCreateBuildSystemDirectory(builtProductsDir) + val symbolicLinkTask = registerSymbolicLinkTask( frameworkCopyTaskName = assembleTask.taskProvider.name, - builtProductsDir = builtProductsDir(frameworkTaskName, environment), + builtProductsDir = builtProductsDir ) + symbolicLinkTask.dependsOn(createBuildSystemDirectory) symbolicLinkTask.configure { task -> assembleTask.frameworkPath?.let { task.frameworkPath.set(it) } assembleTask.dsymPath?.let { task.dsymPath.set(it) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/CreateBuildSystemDirectory.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/CreateBuildSystemDirectory.kt new file mode 100644 index 0000000000000..1e4b9ff2624c4 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/apple/CreateBuildSystemDirectory.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2010-2024 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.plugin.mpp.apple + +import org.gradle.api.DefaultTask +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations +import org.gradle.work.DisableCachingByDefault +import org.jetbrains.kotlin.incremental.createDirectory +import java.io.File +import javax.inject.Inject + +/** + * When running Gradle in PreAction scripts we sometimes have to create BUILT_PRODUCTS_DIR if build system didn't create it + */ +@DisableCachingByDefault(because = "This task only copies files") +internal abstract class CreateBuildSystemDirectory @Inject constructor( + private val execOperations: ExecOperations, +) : DefaultTask() { + + @get:Optional + @get:Input + abstract val buildSystemDirectory: Property + + @TaskAction + fun create() { + val buildSystemDirectory = this.buildSystemDirectory.orNull ?: return + if (buildSystemDirectory.exists()) return + + buildSystemDirectory.createDirectory() + + // Mark the directory with this attribute to allow Xcode build system to remove it + execOperations.exec { + it.commandLine( + "/usr/bin/xattr", "-w", "com.apple.xcode.CreatedByBuildSystem", "true", buildSystemDirectory, + ) + }.assertNormalExitValue() + } + +} \ No newline at end of file