A new DSL for framework configuration within cocoapods block
#KT-46479 #KT-35723
This commit is contained in:
committed by
Space
parent
5a3f84c8fa
commit
3c0709cf4f
+32
-11
@@ -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"
|
||||||
|
|||||||
+64
-2
@@ -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,
|
||||||
|
|||||||
+68
-55
@@ -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"
|
||||||
|
|||||||
+11
-3
@@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
// Autogenerated placeholder header. Do not edit manually.
|
||||||
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
+6
@@ -0,0 +1,6 @@
|
|||||||
|
framework module dummy {
|
||||||
|
umbrella header "placeholder.h"
|
||||||
|
|
||||||
|
export *
|
||||||
|
module * { export * }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user