A new DSL for framework configuration within cocoapods block

#KT-46479
#KT-35723
This commit is contained in:
Viacheslav Kormushkin
2021-06-11 11:10:49 +00:00
committed by Space
parent 5a3f84c8fa
commit 3c0709cf4f
12 changed files with 182 additions and 71 deletions
@@ -793,6 +793,35 @@ class CocoaPodsIT : BaseGradleIT() {
} }
} }
@Test
fun testUseDynamicFramework() {
with(project) {
gradleBuildScript().addPod(defaultPodName, produceGitBlock(defaultPodRepo))
gradleBuildScript().appendToFrameworkBlock("isStatic=false")
hooks.addHook {
// Check that an output framework is a dynamic framework
val framework = fileInWorkingDir("build/cocoapods/framework/cocoapods.framework/cocoapods")
with(runProcess(listOf("file", framework.absolutePath), projectDir)) {
assertTrue(isSuccessful)
assertTrue(output.contains("dynamically linked shared library"))
}
}
test(
"linkPodDebugFrameworkIOS",
"-Pkotlin.native.cocoapods.generate.wrapper=true"
)
}
}
@Test
fun testCocoapodsWithRegularFrameworkDefinition() {
with(project) {
gradleBuildScript().appendToKotlinBlock("iosX64(\"iOS\") {binaries.framework{}}")
testImport()
}
}
// paths // paths
private fun CompiledProject.url() = externalSources().resolve("url") private fun CompiledProject.url() = externalSources().resolve("url")
@@ -980,6 +1009,8 @@ class CocoaPodsIT : BaseGradleIT() {
private fun File.appendToCocoapodsBlock(str: String) = appendToKotlinBlock(str.wrap("cocoapods")) private fun File.appendToCocoapodsBlock(str: String) = appendToKotlinBlock(str.wrap("cocoapods"))
private fun File.appendToFrameworkBlock(str: String) = appendToCocoapodsBlock(str.wrap("framework"))
private fun String.wrap(s: String): String = """ private fun String.wrap(s: String): String = """
|$s { |$s {
| $this | $this
@@ -1122,15 +1153,7 @@ class CocoaPodsIT : BaseGradleIT() {
private fun Project.useCustomFrameworkName(subproject: String, frameworkName: String, iosAppLocation: String? = null) { private fun Project.useCustomFrameworkName(subproject: String, frameworkName: String, iosAppLocation: String? = null) {
// Change the name at the Gradle side. // Change the name at the Gradle side.
gradleBuildScript(subproject).appendText( gradleBuildScript(subproject).appendToFrameworkBlock("baseName = \"$frameworkName\"")
"""
|kotlin {
| cocoapods {
| frameworkName = "$frameworkName"
| }
|}
""".trimMargin()
)
// Change swift sources import if needed. // Change swift sources import if needed.
if (iosAppLocation != null) { if (iosAppLocation != null) {
@@ -1289,7 +1312,6 @@ class CocoaPodsIT : BaseGradleIT() {
spec.authors = '' spec.authors = ''
spec.license = '' spec.license = ''
spec.summary = 'CocoaPods test library' spec.summary = 'CocoaPods test library'
spec.static_framework = true
spec.vendored_frameworks = "build/cocoapods/framework/${frameworkName ?: "kotlin_library"}.framework" spec.vendored_frameworks = "build/cocoapods/framework/${frameworkName ?: "kotlin_library"}.framework"
spec.libraries = "c++" spec.libraries = "c++"
spec.module_name = "#{spec.name}_umbrella" spec.module_name = "#{spec.name}_umbrella"
@@ -1333,7 +1355,6 @@ class CocoaPodsIT : BaseGradleIT() {
spec.authors = '' spec.authors = ''
spec.license = '' spec.license = ''
spec.summary = 'CocoaPods test library' spec.summary = 'CocoaPods test library'
spec.static_framework = true
spec.vendored_frameworks = "build/cocoapods/framework/${frameworkName ?: "second_library"}.framework" spec.vendored_frameworks = "build/cocoapods/framework/${frameworkName ?: "second_library"}.framework"
spec.libraries = "c++" spec.libraries = "c++"
spec.module_name = "#{spec.name}_umbrella" spec.module_name = "#{spec.name}_umbrella"
@@ -7,13 +7,16 @@
package org.jetbrains.kotlin.gradle.plugin.cocoapods package org.jetbrains.kotlin.gradle.plugin.cocoapods
import groovy.lang.Closure import groovy.lang.Closure
import org.gradle.api.Action
import org.gradle.api.Named import org.gradle.api.Named
import org.gradle.api.NamedDomainObjectSet import org.gradle.api.NamedDomainObjectSet
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.tasks.* import org.gradle.api.tasks.*
import org.gradle.util.ConfigureUtil import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.dsl.multiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.CocoapodsDependency.PodLocation.* import org.jetbrains.kotlin.gradle.plugin.cocoapods.CocoapodsExtension.CocoapodsDependency.PodLocation.*
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
import org.jetbrains.kotlin.gradle.plugin.mpp.Framework
import java.io.File import java.io.File
import java.net.URI import java.net.URI
@@ -85,6 +88,18 @@ open class CocoapodsExtension(private val project: Project) {
@Input @Input
var homepage: String? = null var homepage: String? = null
/**
* Configure framework of the pod built from this project.
*/
fun framework(configure: Framework.() -> Unit) = configureRegisteredFrameworks(configure)
/**
* Configure framework of the pod built from this project.
*/
fun framework(configure: Action<Framework>) = framework {
configure.execute(this)
}
@Nested @Nested
val ios: PodspecPlatformSettings = PodspecPlatformSettings("ios") val ios: PodspecPlatformSettings = PodspecPlatformSettings("ios")
@@ -100,8 +115,18 @@ open class CocoapodsExtension(private val project: Project) {
/** /**
* Configure framework name of the pod built from this project. * Configure framework name of the pod built from this project.
*/ */
@Input @Deprecated("Use 'baseName' property within framework{} block to configure framework name")
var frameworkName: String = project.name.asValidFrameworkName() var frameworkName: String
get() = frameworkNameInternal
set(value) {
configureRegisteredFrameworks {
baseName = value
}
}
internal var frameworkNameInternal: String = project.name.asValidFrameworkName()
internal var useDynamicFramework: Boolean = false
/** /**
* Configure custom Xcode Configurations to Native Build Types mapping * Configure custom Xcode Configurations to Native Build Types mapping
@@ -210,6 +235,43 @@ open class CocoapodsExtension(private val project: Project) {
ConfigureUtil.configure(configure, this) ConfigureUtil.configure(configure, this)
} }
private fun configureRegisteredFrameworks(configure: Framework.() -> Unit) {
project.multiplatformExtension.supportedTargets().all { target ->
target.binaries.withType(Framework::class.java) { framework ->
framework.configure()
frameworkNameInternal = framework.baseName
useDynamicFramework = framework.isStatic.not()
if (useDynamicFramework) {
configureDynamicFrameworkLinking(framework)
}
}
}
}
private fun configureDynamicFrameworkLinking(framework: Framework) {
project.findProperty(KotlinCocoapodsPlugin.FRAMEWORK_PATHS_PROPERTY)?.toString()?.let { args ->
framework.linkerOpts.addAll(args.splitQuotedArgs().map { "-F$it" })
}
pods.all { pod ->
framework.linkerOpts("-framework", pod.moduleName)
if (project.shouldUseSyntheticProjectSettings &&
KotlinCocoapodsPlugin.isAvailableToProduceSynthetic
) {
framework.linkTaskProvider.configure { task ->
val podBuildTaskProvider = project.getPodBuildTaskProvider(framework.target, pod)
task.inputs.file(podBuildTaskProvider.map { it.buildSettingsFile })
task.dependsOn(podBuildTaskProvider)
task.doFirst { _ ->
val podBuildSettings = project.getPodBuildSettingsProperties(framework.target, pod)
framework.linkerOpts.addAll(podBuildSettings.frameworkSearchPaths.map { "-F$it" })
}
}
}
}
}
data class CocoapodsDependency( data class CocoapodsDependency(
private val name: String, private val name: String,
@get:Input var moduleName: String, @get:Input var moduleName: String,
@@ -75,9 +75,6 @@ private fun String.toSetupBuildTaskName(pod: CocoapodsDependency): String = lowe
this this
) )
fun KotlinNativeTarget.toSetupBuildTaskName(pod: CocoapodsDependency) =
this.toValidSDK.toSetupBuildTaskName(pod)
private fun String.toBuildDependenciesTaskName(pod: CocoapodsDependency): String = lowerCamelCaseName( private fun String.toBuildDependenciesTaskName(pod: CocoapodsDependency): String = lowerCamelCaseName(
KotlinCocoapodsPlugin.POD_BUILD_TASK_NAME, KotlinCocoapodsPlugin.POD_BUILD_TASK_NAME,
pod.name.asValidTaskName(), pod.name.asValidTaskName(),
@@ -90,41 +87,72 @@ private val CocoapodsDependency.toPodDownloadTaskName: String
name.asValidTaskName() name.asValidTaskName()
) )
internal val Project.shouldUseSyntheticProjectSettings: Boolean
get() = (findProperty(KotlinCocoapodsPlugin.TARGET_PROPERTY) == null &&
findProperty(KotlinCocoapodsPlugin.CONFIGURATION_PROPERTY) == null)
private val KotlinNativeTarget.toValidSDK: String private val KotlinNativeTarget.toValidSDK: String
get() = when (konanTarget) { get() = when (konanTarget) {
IOS_X64 -> "iphonesimulator" IOS_X64, IOS_SIMULATOR_ARM64 -> "iphonesimulator"
IOS_ARM32, IOS_ARM64 -> "iphoneos" IOS_ARM32, IOS_ARM64 -> "iphoneos"
WATCHOS_X86, WATCHOS_X64 -> "watchsimulator" WATCHOS_X86, WATCHOS_X64, WATCHOS_SIMULATOR_ARM64 -> "watchsimulator"
WATCHOS_ARM32, WATCHOS_ARM64 -> "watchos" WATCHOS_ARM32, WATCHOS_ARM64 -> "watchos"
TVOS_X64 -> "appletvsimulator" TVOS_X64, TVOS_SIMULATOR_ARM64 -> "appletvsimulator"
TVOS_ARM64 -> "appletvos" TVOS_ARM64 -> "appletvos"
MACOS_X64 -> "macosx" MACOS_X64, MACOS_ARM64 -> "macosx"
else -> throw IllegalArgumentException("Bad target ${konanTarget.name}.") else -> throw IllegalArgumentException("Bad target ${konanTarget.name}.")
} }
open class KotlinCocoapodsPlugin : Plugin<Project> { internal fun Project.getPodBuildTaskProvider(
fun KotlinMultiplatformExtension.supportedTargets() = targets target: KotlinNativeTarget,
.withType(KotlinNativeTarget::class.java) pod: CocoapodsDependency
.matching { it.konanTarget.family.isAppleFamily } ): TaskProvider<PodBuildTask> {
return tasks.named(target.toValidSDK.toBuildDependenciesTaskName(pod), PodBuildTask::class.java)
}
/** internal fun Project.getPodBuildSettingsProperties(
* Splits a string using a whitespace characters as delimiters. target: KotlinNativeTarget,
* Ignores whitespaces in quotes and drops quotes, e.g. a string pod: CocoapodsDependency
* `foo "bar baz" qux="quux"` will be split into ["foo", "bar baz", "qux=quux"]. ): PodBuildSettingsProperties {
*/ return getPodBuildTaskProvider(target, pod).get().buildSettingsFile.get()
private fun String.splitQuotedArgs(): List<String> = .reader()
Regex("""(?:[^\s"]|(?:"[^"]*"))+""").findAll(this).map { .use {
it.value.replace("\"", "") PodBuildSettingsProperties.readSettingsFromReader(it)
}.toList() }
}
internal val PodBuildSettingsProperties.frameworkSearchPaths: List<String>
get() {
val frameworkPathsSelfIncluding = mutableListOf<String>()
frameworkPathsSelfIncluding += configurationBuildDir.trimQuotes()
frameworkPaths?.let { frameworkPathsSelfIncluding.addAll(it.splitQuotedArgs()) }
return frameworkPathsSelfIncluding
}
/**
* Splits a string using a whitespace characters as delimiters.
* Ignores whitespaces in quotes and drops quotes, e.g. a string
* `foo "bar baz" qux="quux"` will be split into ["foo", "bar baz", "qux=quux"].
*/
internal fun String.splitQuotedArgs(): List<String> =
Regex("""(?:[^\s"]|(?:"[^"]*"))+""").findAll(this).map {
it.value.replace("\"", "")
}.toList()
internal fun KotlinMultiplatformExtension.supportedTargets() = targets
.withType(KotlinNativeTarget::class.java)
.matching { it.konanTarget.family.isAppleFamily }
open class KotlinCocoapodsPlugin : Plugin<Project> {
private fun KotlinMultiplatformExtension.targetsForPlatform(requestedPlatform: KonanTarget) = private fun KotlinMultiplatformExtension.targetsForPlatform(requestedPlatform: KonanTarget) =
supportedTargets().matching { it.konanTarget == requestedPlatform } supportedTargets().matching { it.konanTarget == requestedPlatform }
private fun createDefaultFrameworks(kotlinExtension: KotlinMultiplatformExtension, cocoapodsExtension: CocoapodsExtension) { private fun createDefaultFrameworks(kotlinExtension: KotlinMultiplatformExtension, cocoapodsExtension: CocoapodsExtension) {
kotlinExtension.supportedTargets().all { target -> kotlinExtension.supportedTargets().all { target ->
target.binaries.framework { target.binaries.framework(POD_FRAMEWORK_PREFIX) {
baseNameProvider = project.provider { cocoapodsExtension.frameworkName } baseName = cocoapodsExtension.frameworkNameInternal
isStatic = true isStatic = true
} }
} }
@@ -165,7 +193,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
fatTargets.forEach { _, targets -> fatTargets.forEach { _, targets ->
targets.singleOrNull()?.let { targets.singleOrNull()?.let {
task.from(it.binaries.getFramework(requestedBuildType)) task.from(it.binaries.getFramework(POD_FRAMEWORK_PREFIX, requestedBuildType))
} }
} }
} }
@@ -184,7 +212,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
check(targets.isNotEmpty()) { "The project doesn't contain a target for the requested platform: `${requestedPlatform.visibleName}`" } check(targets.isNotEmpty()) { "The project doesn't contain a target for the requested platform: `${requestedPlatform.visibleName}`" }
check(targets.size == 1) { "The project has more than one target for the requested platform: `${requestedPlatform.visibleName}`" } check(targets.size == 1) { "The project has more than one target for the requested platform: `${requestedPlatform.visibleName}`" }
val frameworkLinkTask = targets.single().binaries.getFramework(requestedBuildType).linkTaskProvider val frameworkLinkTask = targets.single().binaries.getFramework(POD_FRAMEWORK_PREFIX, requestedBuildType).linkTaskProvider
project.createSyncFrameworkTask(frameworkLinkTask.map { it.destinationDir }, frameworkLinkTask) project.createSyncFrameworkTask(frameworkLinkTask.map { it.destinationDir }, frameworkLinkTask)
} }
@@ -200,7 +228,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
check(requestedBuildType != null) { check(requestedBuildType != null) {
""" """
Could not identify build type for Kotlin framework '${cocoapodsExtension.frameworkName}' built via cocoapods plugin with CONFIGURATION=$xcodeConfiguration. Could not identify build type for Kotlin framework '${cocoapodsExtension.frameworkNameInternal}' built via cocoapods plugin with CONFIGURATION=$xcodeConfiguration.
Add xcodeConfigurationToNativeBuildType["$xcodeConfiguration"]=NativeBuildType.DEBUG or xcodeConfigurationToNativeBuildType["$xcodeConfiguration"]=NativeBuildType.RELEASE to cocoapods plugin configuration Add xcodeConfigurationToNativeBuildType["$xcodeConfiguration"]=NativeBuildType.DEBUG or xcodeConfigurationToNativeBuildType["$xcodeConfiguration"]=NativeBuildType.RELEASE to cocoapods plugin configuration
""".trimIndent() """.trimIndent()
} }
@@ -259,14 +287,11 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
_extraOptsProp.addAll(project.provider { pod.extraOpts }) _extraOptsProp.addAll(project.provider { pod.extraOpts })
} }
if ( if (project.shouldUseSyntheticProjectSettings &&
isAvailableToProduceSynthetic isAvailableToProduceSynthetic
&& project.findProperty(TARGET_PROPERTY) == null
&& project.findProperty(CONFIGURATION_PROPERTY) == null
) { ) {
val podBuildTaskProvider = val podBuildTaskProvider = project.getPodBuildTaskProvider(target, pod)
project.tasks.named(target.toValidSDK.toBuildDependenciesTaskName(pod), PodBuildTask::class.java) interopTask.inputs.file(podBuildTaskProvider.map {it.buildSettingsFile })
interopTask.inputs.file(podBuildTaskProvider.get().buildSettingsFile)
interopTask.dependsOn(podBuildTaskProvider) interopTask.dependsOn(podBuildTaskProvider)
} }
@@ -286,36 +311,21 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
// Since we cannot expand the configuration phase of interop tasks // Since we cannot expand the configuration phase of interop tasks
// receiving the required environment variables happens on execution phase. // receiving the required environment variables happens on execution phase.
// TODO This needs to be fixed to improve UP-TO-DATE checks. // TODO This needs to be fixed to improve UP-TO-DATE checks.
if ( if (project.shouldUseSyntheticProjectSettings &&
isAvailableToProduceSynthetic isAvailableToProduceSynthetic
&& project.findProperty(TARGET_PROPERTY) == null
&& project.findProperty(CONFIGURATION_PROPERTY) == null
) { ) {
val podBuildTaskProvider = val podBuildSettings = project.getPodBuildSettingsProperties(target, pod)
project.tasks.named(target.toValidSDK.toBuildDependenciesTaskName(pod), PodBuildTask::class.java)
val buildSettings =
podBuildTaskProvider.get().buildSettingsFile.get()
.reader()
.use {
PodBuildSettingsProperties.readSettingsFromReader(it)
}
buildSettings.cflags?.let { args -> podBuildSettings.cflags?.let { args ->
// Xcode quotes around paths with spaces. // Xcode quotes around paths with spaces.
// Here and below we need to split such paths taking this into account. // Here and below we need to split such paths taking this into account.
interop.compilerOpts.addAll(args.splitQuotedArgs()) interop.compilerOpts.addAll(args.splitQuotedArgs())
} }
buildSettings.headerPaths?.let { args -> podBuildSettings.headerPaths?.let { args ->
interop.compilerOpts.addAll(args.splitQuotedArgs().map { "-I$it" }) interop.compilerOpts.addAll(args.splitQuotedArgs().map { "-I$it" })
} }
val frameworkPaths = buildSettings.frameworkPaths interop.compilerOpts.addAll(podBuildSettings.frameworkSearchPaths.map { "-F$it" })
val configurationBuildDir = buildSettings.configurationBuildDir
val frameworkPathsSelfIncluding = mutableListOf<String>()
frameworkPathsSelfIncluding += configurationBuildDir.trimQuotes()
frameworkPaths?.let { frameworkPathsSelfIncluding.addAll(it.splitQuotedArgs()) }
interop.compilerOpts.addAll(frameworkPathsSelfIncluding.map { "-F$it" })
} }
} }
} }
@@ -328,7 +338,8 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
cocoapodsExtension: CocoapodsExtension cocoapodsExtension: CocoapodsExtension
) { ) {
project.tasks.register(DUMMY_FRAMEWORK_TASK_NAME, DummyFrameworkTask::class.java) { project.tasks.register(DUMMY_FRAMEWORK_TASK_NAME, DummyFrameworkTask::class.java) {
it.frameworkName = project.provider { cocoapodsExtension.frameworkName } it.frameworkName = project.provider { cocoapodsExtension.frameworkNameInternal }
it.useDynamicFramework = project.provider { cocoapodsExtension.useDynamicFramework }
} }
} }
@@ -348,7 +359,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
it.license.set(cocoapodsExtension.license) it.license.set(cocoapodsExtension.license)
it.authors.set(cocoapodsExtension.authors) it.authors.set(cocoapodsExtension.authors)
it.summary.set(cocoapodsExtension.summary) it.summary.set(cocoapodsExtension.summary)
it.frameworkName = project.provider { cocoapodsExtension.frameworkName } it.frameworkName = project.provider { cocoapodsExtension.frameworkNameInternal }
it.ios = project.provider { cocoapodsExtension.ios } it.ios = project.provider { cocoapodsExtension.ios }
it.osx = project.provider { cocoapodsExtension.osx } it.osx = project.provider { cocoapodsExtension.osx }
it.tvos = project.provider { cocoapodsExtension.tvos } it.tvos = project.provider { cocoapodsExtension.tvos }
@@ -370,7 +381,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
it.group = TASK_GROUP it.group = TASK_GROUP
it.description = "Invokes `pod install` call within Podfile location directory" it.description = "Invokes `pod install` call within Podfile location directory"
it.podfile.set(cocoapodsExtension.podfile) it.podfile.set(cocoapodsExtension.podfile)
it.frameworkName = project.provider { cocoapodsExtension.frameworkName } it.frameworkName = project.provider { cocoapodsExtension.frameworkNameInternal }
it.onlyIf { isAvailableToProduceSynthetic } it.onlyIf { isAvailableToProduceSynthetic }
it.dependsOn(podspecTaskProvider) it.dependsOn(podspecTaskProvider)
} }
@@ -461,7 +472,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
it.pod = project.provider { pod } it.pod = project.provider { pod }
it.sdk = project.provider { sdk } it.sdk = project.provider { sdk }
it.podsXcodeProjDir = podGenTaskProvider.map { podGen -> podGen.podsXcodeProjDir.get() } it.podsXcodeProjDir = podGenTaskProvider.map { podGen -> podGen.podsXcodeProjDir.get() }
it.frameworkName = project.provider { cocoapodsExtension.frameworkName } it.frameworkName = project.provider { cocoapodsExtension.frameworkNameInternal }
it.dependsOn(podGenTaskProvider) it.dependsOn(podGenTaskProvider)
it.onlyIf { isAvailableToProduceSynthetic } it.onlyIf { isAvailableToProduceSynthetic }
} }
@@ -531,6 +542,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
} }
override fun apply(project: Project): Unit = with(project) { override fun apply(project: Project): Unit = with(project) {
pluginManager.withPlugin("kotlin-multiplatform") { pluginManager.withPlugin("kotlin-multiplatform") {
val kotlinExtension = project.multiplatformExtension val kotlinExtension = project.multiplatformExtension
val cocoapodsExtension = CocoapodsExtension(this) val cocoapodsExtension = CocoapodsExtension(this)
@@ -565,6 +577,7 @@ open class KotlinCocoapodsPlugin : Plugin<Project> {
companion object { companion object {
const val COCOAPODS_EXTENSION_NAME = "cocoapods" const val COCOAPODS_EXTENSION_NAME = "cocoapods"
const val TASK_GROUP = "CocoaPods" const val TASK_GROUP = "CocoaPods"
const val POD_FRAMEWORK_PREFIX = "pod"
const val SYNC_TASK_NAME = "syncFramework" const val SYNC_TASK_NAME = "syncFramework"
const val POD_SPEC_TASK_NAME = "podspec" const val POD_SPEC_TASK_NAME = "podspec"
const val DUMMY_FRAMEWORK_TASK_NAME = "generateDummyFramework" const val DUMMY_FRAMEWORK_TASK_NAME = "generateDummyFramework"
@@ -124,7 +124,6 @@ open class PodspecTask : DefaultTask() {
| spec.license = '${license.getOrEmpty()}' | spec.license = '${license.getOrEmpty()}'
| spec.summary = '${summary.getOrEmpty()}' | spec.summary = '${summary.getOrEmpty()}'
| |
| spec.static_framework = true
| spec.vendored_frameworks = "$frameworkDir/${frameworkName.get()}.framework" | spec.vendored_frameworks = "$frameworkDir/${frameworkName.get()}.framework"
| spec.libraries = "c++" | spec.libraries = "c++"
| spec.module_name = "#{spec.name}_umbrella" | spec.module_name = "#{spec.name}_umbrella"
@@ -215,9 +214,18 @@ open class DummyFrameworkTask : DefaultTask() {
@Input @Input
lateinit var frameworkName: Provider<String> lateinit var frameworkName: Provider<String>
@Input
lateinit var useDynamicFramework: Provider<Boolean>
private val frameworkDir: File private val frameworkDir: File
get() = destinationDir.resolve("${frameworkName.get()}.framework") get() = destinationDir.resolve("${frameworkName.get()}.framework")
private val dummyFrameworkPath: String
get() {
val staticOrDynamic = if (useDynamicFramework.get()) "dynamic" else "static"
return "/cocoapods/$staticOrDynamic/dummy.framework/"
}
private fun copyResource(from: String, to: File) { private fun copyResource(from: String, to: File) {
to.parentFile.mkdirs() to.parentFile.mkdirs()
to.outputStream().use { file -> to.outputStream().use { file ->
@@ -240,7 +248,7 @@ open class DummyFrameworkTask : DefaultTask() {
private fun copyFrameworkFile(relativeFrom: String, relativeTo: String = relativeFrom) = private fun copyFrameworkFile(relativeFrom: String, relativeTo: String = relativeFrom) =
copyResource( copyResource(
"/cocoapods/dummy.framework/$relativeFrom", "$dummyFrameworkPath$relativeFrom",
frameworkDir.resolve(relativeTo) frameworkDir.resolve(relativeTo)
) )
@@ -249,7 +257,7 @@ open class DummyFrameworkTask : DefaultTask() {
relativeTo: String = relativeFrom, relativeTo: String = relativeFrom,
transform: (String) -> String = { it } transform: (String) -> String = { it }
) = copyTextResource( ) = copyTextResource(
"/cocoapods/dummy.framework/$relativeFrom", "$dummyFrameworkPath$relativeFrom",
frameworkDir.resolve(relativeTo), frameworkDir.resolve(relativeTo),
transform transform
) )
@@ -0,0 +1 @@
// Autogenerated placeholder header. Do not edit manually.
@@ -0,0 +1,6 @@
framework module dummy {
umbrella header "placeholder.h"
export *
module * { export * }
}