CocoaPods Gradle plugin: Support incremental task execution when switching between Xcode and terminal

#KT-37511
This commit is contained in:
Viacheslav Kormushkin
2021-07-23 12:42:10 +03:00
committed by Space
parent 91ecaa32e3
commit fa2e787f76
4 changed files with 75 additions and 67 deletions
@@ -885,6 +885,24 @@ class CocoaPodsIT : BaseGradleIT() {
fun testPodDependencyInUnitTests() =
getProjectByName(cocoapodsTestsProjectName).testWithWrapper(":iosX64Test")
@Test
fun testCinteropUpToDate() {
project.gradleBuildScript().addPod(defaultPodName, produceGitBlock(defaultPodRepo))
project.testImport()
hooks.addHook {
assertTasksUpToDate(
defaultCinteropTaskName
)
}
project.test(
"syncFramework",
"-Pkotlin.native.cocoapods.platform=iphonesimulator",
"-Pkotlin.native.cocoapods.archs=x86_64",
"-Pkotlin.native.cocoapods.configuration=Debug",
"-Pkotlin.native.cocoapods.generate.wrapper=true"
)
}
// paths
private fun CompiledProject.url() = externalSources().resolve("url")
@@ -251,26 +251,27 @@ open class CocoapodsExtension(private val project: Project) {
}
internal fun configureLinkingOptions(binary: NativeBinary, setRPath: Boolean = false) {
project.findProperty(KotlinCocoapodsPlugin.FRAMEWORK_PATHS_PROPERTY)?.toString()?.let { args ->
binary.linkerOpts.addAll(args.splitQuotedArgs().map { "-F$it" })
}
pods.all { pod ->
binary.linkerOpts("-framework", pod.moduleName)
if (project.shouldUseSyntheticProjectSettings &&
KotlinCocoapodsPlugin.isAvailableToProduceSynthetic
) {
binary.linkTaskProvider.configure { task ->
val podBuildTaskProvider = project.getPodBuildTaskProvider(binary.target, pod)
task.inputs.file(podBuildTaskProvider.map { it.buildSettingsFile })
task.dependsOn(podBuildTaskProvider)
check(KotlinCocoapodsPlugin.isAvailableToProduceSynthetic) {
"""
Dependency on pods requires cocoapods-generate plugin to be installed.
Please install it by executing 'gem install cocoapods-generate' in terminal.
""".trimMargin()
}
task.doFirst { _ ->
val podBuildSettings = project.getPodBuildSettingsProperties(binary.target, pod)
binary.linkerOpts.addAll(podBuildSettings.frameworkSearchPaths.map { "-F$it" })
if (setRPath) {
binary.linkerOpts.addAll(podBuildSettings.frameworkSearchPaths.flatMap { listOf("-rpath", it) })
}
binary.linkTaskProvider.configure { task ->
val podBuildTaskProvider = project.getPodBuildTaskProvider(binary.target, pod)
task.inputs.file(podBuildTaskProvider.map { it.buildSettingsFile })
task.dependsOn(podBuildTaskProvider)
task.doFirst { _ ->
val podBuildSettings = project.getPodBuildSettingsProperties(binary.target, pod)
binary.linkerOpts.addAll(podBuildSettings.frameworkSearchPaths.map { "-F$it" })
if (setRPath) {
binary.linkerOpts.addAll(podBuildSettings.frameworkSearchPaths.flatMap { listOf("-rpath", it) })
}
}
}
@@ -18,9 +18,6 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.plugin.addExtension
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.CocoapodsDependency
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.CocoapodsDependency.PodLocation.*
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.ARCHS_PROPERTY
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.CONFIGURATION_PROPERTY
import org.jetbrains.kotlin.gradle.plugin.cocoapods.KotlinCocoapodsPlugin.Companion.PLATFORM_PROPERTY
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import org.jetbrains.kotlin.gradle.plugin.mpp.TestExecutable
@@ -92,11 +89,6 @@ private val CocoapodsDependency.toPodDownloadTaskName: String
name.asValidTaskName()
)
internal val Project.shouldUseSyntheticProjectSettings: Boolean
get() = (project.findProperty(PLATFORM_PROPERTY) == null &&
project.findProperty(ARCHS_PROPERTY) == null &&
project.findProperty(CONFIGURATION_PROPERTY) == null)
private val KotlinNativeTarget.toValidSDK: String
get() = when (konanTarget) {
IOS_X64, IOS_SIMULATOR_ARM64 -> "iphonesimulator"
@@ -231,6 +223,21 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
val platforms = project.findProperty(PLATFORM_PROPERTY)?.toString()?.split(",", " ")?.filter { it.isNotBlank() }
val archs = project.findProperty(ARCHS_PROPERTY)?.toString()?.split(",", " ")?.filter { it.isNotBlank() }
if (
project.findProperty(CFLAGS_PROPERTY) != null ||
project.findProperty(FRAMEWORK_PATHS_PROPERTY) != null ||
project.findProperty(HEADER_PATHS_PROPERTY) != null
) {
logger.warn(
"""
Properties
kotlin.native.cocoapods.cflags
kotlin.native.cocoapods.paths.frameworks
kotlin.native.cocoapods.paths.headers
are not supported and will be ignored since Cocoapods plugin generates all required properties automatically.
""".trimIndent())
}
if (platforms == null || archs == null) {
check(project.findProperty(TARGET_PROPERTY) == null) {
"""
@@ -292,6 +299,13 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
// to avoid showing it in the `tasks` output.
}
check(isAvailableToProduceSynthetic) {
"""
Dependency on pods requires cocoapods-generate plugin to be installed.
Please install it by executing 'gem install cocoapods-generate' in terminal.
""".trimMargin()
}
kotlinExtension.supportedTargets().all { target ->
target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME).cinterops.create(pod.moduleName) { interop ->
@@ -305,46 +319,27 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
_extraOptsProp.addAll(project.provider { pod.extraOpts })
}
if (project.shouldUseSyntheticProjectSettings &&
isAvailableToProduceSynthetic
) {
val podBuildTaskProvider = project.getPodBuildTaskProvider(target, pod)
interopTask.inputs.file(podBuildTaskProvider.map {it.buildSettingsFile })
interopTask.dependsOn(podBuildTaskProvider)
}
project.findProperty(CFLAGS_PROPERTY)?.toString()?.let { args ->
// Xcode quotes around paths with spaces.
// Here and below we need to split such paths taking this into account.
interop.compilerOpts.addAll(args.splitQuotedArgs())
}
project.findProperty(HEADER_PATHS_PROPERTY)?.toString()?.let { args ->
interop.compilerOpts.addAll(args.splitQuotedArgs().map { "-I$it" })
}
project.findProperty(FRAMEWORK_PATHS_PROPERTY)?.toString()?.let { args ->
interop.compilerOpts.addAll(args.splitQuotedArgs().map { "-F$it" })
}
val podBuildTaskProvider = project.getPodBuildTaskProvider(target, pod)
interopTask.inputs.file(podBuildTaskProvider.map {it.buildSettingsFile })
interopTask.dependsOn(podBuildTaskProvider)
interopTask.doFirst { _ ->
// Since we cannot expand the configuration phase of interop tasks
// receiving the required environment variables happens on execution phase.
// TODO This needs to be fixed to improve UP-TO-DATE checks.
if (project.shouldUseSyntheticProjectSettings &&
isAvailableToProduceSynthetic
) {
val podBuildSettings = project.getPodBuildSettingsProperties(target, pod)
val podBuildSettings = project.getPodBuildSettingsProperties(target, pod)
podBuildSettings.cflags?.let { args ->
// Xcode quotes around paths with spaces.
// Here and below we need to split such paths taking this into account.
interop.compilerOpts.addAll(args.splitQuotedArgs())
}
podBuildSettings.headerPaths?.let { args ->
interop.compilerOpts.addAll(args.splitQuotedArgs().map { "-I$it" })
}
interop.compilerOpts.addAll(podBuildSettings.frameworkSearchPaths.map { "-F$it" })
podBuildSettings.cflags?.let { args ->
// Xcode quotes around paths with spaces.
// Here and below we need to split such paths taking this into account.
interop.compilerOpts.addAll(args.splitQuotedArgs())
}
podBuildSettings.headerPaths?.let { args ->
interop.compilerOpts.addAll(args.splitQuotedArgs().map { "-I$it" })
}
interop.compilerOpts.addAll(podBuildSettings.frameworkSearchPaths.map { "-F$it" })
}
}
}
@@ -589,12 +584,9 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
if (HostManager.hostIsMac && !isAvailableToProduceSynthetic) {
logger.quiet(
"""
To take advantage of the new functionality for Cocoapods Integration like synchronizing with the Xcode project
and supporting dependencies on pods, please install the `cocoapods-generate` plugin for CocoaPods
by calling `gem install cocoapods-generate` in terminal.
More details are available by https://github.com/square/cocoapods-generate
""".trimIndent()
Dependency on pods requires cocoapods-generate plugin to be installed.
If you plan to add dependencies on third party pods, don't forget to install it by executing 'gem install cocoapods-generate' in terminal.
""".trimIndent()
)
}
createInterops(project, kotlinExtension, cocoapodsExtension)
@@ -149,10 +149,7 @@ open class PodspecTask : DefaultTask() {
| "$gradleCommand" -p "${'$'}REPO_ROOT" ${'$'}KOTLIN_PROJECT_PATH:$SYNC_TASK_NAME \
| -P${KotlinCocoapodsPlugin.PLATFORM_PROPERTY}=${'$'}PLATFORM_NAME \
| -P${KotlinCocoapodsPlugin.ARCHS_PROPERTY}="${'$'}ARCHS" \
| -P${KotlinCocoapodsPlugin.CONFIGURATION_PROPERTY}=${'$'}CONFIGURATION \
| -P${KotlinCocoapodsPlugin.CFLAGS_PROPERTY}="${'$'}OTHER_CFLAGS" \
| -P${KotlinCocoapodsPlugin.HEADER_PATHS_PROPERTY}="${'$'}HEADER_SEARCH_PATHS" \
| -P${KotlinCocoapodsPlugin.FRAMEWORK_PATHS_PROPERTY}="${'$'}FRAMEWORK_SEARCH_PATHS"
| -P${KotlinCocoapodsPlugin.CONFIGURATION_PROPERTY}=${'$'}CONFIGURATION
| SCRIPT
| }
| ]