Cas Van Luijtelaar
11/14/2023, 4:18 PMplugins {
`kmm-base-config`
`kmm-artifact-publish`
kotlin("native.cocoapods")
}
val iosDeploymentTarget: String by project
kotlin {
sourceSets {
val androidMain by getting {
dependencies {
implementation(libs.jmustache)
}
}
}
cocoapods {
ios.deploymentTarget = iosDeploymentTarget
pod("GRMustache", "~> 7.3.2")
}
}
umbrella module:
...
plugins {
`kmm-base-config`
`kmm-artifact-publish`
kotlin("native.cocoapods")
}
kotlin {
cocoapods {
summary = "Cocoapod for $libBaseName."
homepage = libSiteUrl
ios.deploymentTarget = iosDeploymentTarget
authors = libDeveloperOrg
version = libBaseVersion
license = "Unlicensed"
name = libBaseName
source = "{ :git => '$libGitUrl', :tag => '$libBaseVersion' }"
extraSpecAttributes["vendored_frameworks"] = "'$libBaseName.xcframework'"
xcodeConfigurationToNativeBuildType["CUSTOM_RELEASE"] =
org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType.RELEASE
framework {
isStatic = false
baseName = libBaseName
exportedProjects.forEach { export(project(":sub-module")) }
}
specRepos {
url("<https://github.com/Kotlin/kotlin-cocoapods-spec.git>")
}
}
sourceSets {
val commonMain by getting {
dependencies {
api(project(":sub-module"))
}
}
}
}
...
when building this it results in a:
ld: framework not found GRMustache
a-dd
11/14/2023, 4:32 PMpod("GRMustache", version = "~> 7.3.2", linkOnly = true)
to umbrella doesn’t help, right? That’s strange
Could you share a build log with --info
?Cas Van Luijtelaar
11/14/2023, 4:51 PMa-dd
11/14/2023, 5:11 PMlinkDebugFrameworkIosArm64
task and the task that builds the framework connected to cocoapods plugin would be called link**Pod**DebugFrameworkIosArm64
with this configuration. And the problem is that cocoapods plugin links dependencies only to its own framework.Cas Van Luijtelaar
11/15/2023, 9:34 AM./gradlew clean podspec podPublishReleaseXCFramework
./gradlew kSwiftMultiplatformLibraryPodspec
it seems the kswift step is the one failing, so I’ll have to look into what it is doingframework.linktask
target.binaries
.withType<Framework>()
.configureEach { applyToAppleFramework(it, processor, kSwiftExtension) }
private fun applyToAppleFramework(
framework: Framework,
processor: KLibProcessor,
kSwiftExtension: KSwiftExtension
) {
val linkTask: KotlinNativeLink = framework.linkTask
linkTask.doLast(PostProcessLinkTask(framework, processor, kSwiftExtension))
registerPodspecTask(linkTask, kSwiftExtension)
}
...
and looking at the logs it seems this linktask is the linkDebugFrameworkIosArm64
I don’t quite understand how this relates to our setup and if/how we can change this to the linkDebugFrameworkIosArm64
a-dd
11/15/2023, 12:14 PMumbrella
?Cas Van Luijtelaar
11/15/2023, 12:16 PMkotlin {
val xcf = XCFramework()
android {
mavenPublication {
artifactId = project.name
}
}
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = libBaseName
xcf.add(this)
}
}
targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget> {
compilations.get("main").kotlinOptions.freeCompilerArgs += "-Xexport-kdoc"
}
}
a-dd
11/15/2023, 12:18 PMit.binaries.framework
declares the framework which can’t be built because it requires linking with the pod binaryCas Van Luijtelaar
11/15/2023, 12:18 PMa-dd
11/15/2023, 12:22 PMCas Van Luijtelaar
11/15/2023, 12:38 PMXCFramework
and framework
or what to define wherea-dd
11/15/2023, 1:00 PMsometarget.binaries.framework {}
In Kotlin world frameworks are needed only for integration to iOS world (when you build a final artifact/binary). XCFrameworks need to be declared only when you publish them directly (not through CocoaPods).
CocoaPods plugin declares its own frameworks for each iOS target implicitly (it’s probably a design flaw, but it’s the way it works now). And when it builds binaries from Pod-dependencies it links then only to these frameworks and ignores any other.
In practice, it means that:
1) If you’re using CocoaPods plugin, you shouldn’t declare any other frameworks. There’ll probably be an error or a warning for that soon.
2) One should declare frameworks or XCFrameworks only when it’s required.
3) And therefore declaring frameworks in a convention plugin is not a good idea, because most likely only one (maybe a few) module will need them.Cas Van Luijtelaar
11/15/2023, 1:18 PMframework {
isStatic = false
baseName = libBaseName
exportedProjects.forEach { export(project(":$it")) }
iosX64()
iosArm64()
iosSimulatorArm64()
}
running into some other kswift issues now so I cannot confirm it resolved it. mainly that kSwiftMultiplatformLibraryPodspec
no longer existsa-dd
11/15/2023, 1:29 PMframework
block doesn’t make much sense — it works but it’s basically the same as
kotlin {
iosX64()
iosArm64()
iosSimulatorArm64()
cocoapods { framework { .... } }
}
Cas Van Luijtelaar
11/24/2023, 12:24 PM