Android 如何在iOS项目上添加两个或多个kotlin本机模块 TL;博士
如何在一个iOS项目上添加两个或多个kotlin本机模块,而不获取重复符号 详细问题 下面我们假设一个多模块KMP项目,其中存在一个用于Android的本机应用程序和一个用于iOS的本机应用程序,以及两个用于保存共享kotlin代码的通用模块Android 如何在iOS项目上添加两个或多个kotlin本机模块 TL;博士,android,ios,kotlin,gradle,kotlin-multiplatform,Android,Ios,Kotlin,Gradle,Kotlin Multiplatform,如何在一个iOS项目上添加两个或多个kotlin本机模块,而不获取重复符号 详细问题 下面我们假设一个多模块KMP项目,其中存在一个用于Android的本机应用程序和一个用于iOS的本机应用程序,以及两个用于保存共享kotlin代码的通用模块 。 ├── 安卓 │ └── 应用程序 ├── 常见的 │ ├── 模 │ └── 模B ├── 网间网操作系统 │ └── 应用程序 模块A包含一个数据类HelloWorld,并且没有模块依赖项: 包hello.world.module
。
├── 安卓
│ └── 应用程序
├── 常见的
│ ├── 模
│ └── 模B
├── 网间网操作系统
│ └── 应用程序
模块A包含一个数据类HelloWorld,并且没有模块依赖项:
包hello.world.modulea
数据类HelloWorld(
val消息:字符串
)
模块B包含HelloWorld类的扩展函数,因此它依赖于模块A:
包hello.world.moduleb
导入hello.world.modulea.HelloWorld
fun HelloWorld.egassem()=message.reversed()
模块的build.gradle配置为:
- 模块A
- 模块B
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72"
implementation project(":common:moduleA")
implementation project(":common:moduleB")
}
但是,这似乎不是在iOS上组织多个模块的正确方法,因为运行/gradlew podspec
我可以获得构建成功
,正如预期的那样,使用以下pod:
pod'moduleA',:path=>'…/HelloWorld/common/moduleA'
pod'moduleB',:path=>'…/HelloWorld/common/moduleB'
即使运行pod安装
我也能成功地完成pod安装!Podfile中有2个依赖项,总共安装了2个POD。
Xcode在pods部分显示模块A和模块B后,什么看起来正确
但是,如果我尝试构建iOS项目,会出现以下错误:
Ld…/Hello\u World-…/Build/Products/Debug iphonesimulator/Hello\World.app/Hello\World normal x86\u 64(在项目“Hello World”的目标“Hello World”中)
cd…/HelloWorld/ios/app
…
在以下位置重复符号“\u ktypew:kotlin.Any”:
…/HelloWorld/common/moduleA/build/cocoapods/framework/moduleA.framework/moduleA(result.o)
…/HelloWorld/common/moduleB/build/cocoapods/framework/moduleB.framework/moduleB(result.o)
…大量重复符号更多…
重复符号“\u kfun:kotlin.throwon失败$stdlib@kotlin.Result.()在:
…/HelloWorld/common/moduleA/build/cocoapods/framework/moduleA.framework/moduleA(result.o)
…/HelloWorld/common/moduleB/build/cocoapods/framework/moduleB.framework/moduleB(result.o)
ld:9928体系结构x86_64的重复符号
叮当声:错误:链接器命令失败,退出代码为1(使用-v查看调用)
我对iOS的了解不多,所以在我未经训练的眼中,似乎每个模块都在添加自己版本的东西,而不是使用一些分辨率策略来共享
如果我只使用模块A,代码可以正常工作和运行,因此我知道代码本身是正确的,问题是如何管理多个模块,因此问题是,如何在iOS上同时添加(模块A和模块B)并使其正常工作
附笔
我确实尽可能地减少了代码,试图只保留我认为是问题根源的部分,但是,如果您想检查代码片段中缺少的任何内容,或者如果您想运行并尝试解决问题,则可以使用完整的代码…多个Kotlin框架可能很棘手,但是应该在1.3.70开始工作,我看到你有 问题似乎是这两个框架都是静态的,这在1.3.70中是一个问题,所以它不起作用。(应在1.40之前进行更新)。默认情况下,cocoapods插件会将框架设置为静态的,这是不起作用的。我不知道有什么方法可以将cocoapods设置为动态的,但是我已经测试过不使用cocoapods的构建,并在gradle任务中使用
isStatic
变量,并且已经得到了一个iOS项目来编译。比如:
binaries {
framework("moduleA"){
isStatic = false
}
}
现在,您可以通过使用上面的代码并创建一个任务来构建框架()来使用此方法解决这个问题
另一件值得注意的事情是,在iOS端,HelloWorld类将显示为两个独立的类,尽管它们都来自moduleA。对于多个Kotlin框架,这是另一种奇怪的情况,但我认为扩展在这种情况下仍然可以工作,因为您返回了一个字符串
实际上,我刚刚写了一篇关于多个Kotlin框架的博文,如果您想看一看的话,这可能有助于解决一些其他问题
EDIT:看起来cocoapodsext
也有一个isStatic
变量,因此将其设置为isStatic=false
tl:dr在同一个iOS项目中,当前不能有多个静态Kotlin框架。使用isStatic=false
将它们设置为非静态
但是,如果我尝试构建iOS项目,会出现以下错误:
此特定错误是已知的问题。多个调试静态框架与编译器缓存不兼容
因此,要解决这个问题,您可以通过在gradle.properties
中插入以下行来禁用编译器缓存:
kotlin.native.cacheKind=none
或者,通过向Gradle构建脚本中添加以下代码片段,使框架成为动态的:
kotlin{
目标.withType{
binaries.withType{
isStatic=false
}
}
}
有关更多详细信息,请参阅
我猜当前多框架的行为对于最初的主题初学者来说没有多大意义,我只是在这里为可能遇到相同问题的任何人提供答案
我对iOS的了解不多,所以在我未经训练的眼中,似乎每个模块都在添加自己版本的东西,而不是使用一些分辨率策略来共享
这正是它在这个mo中的工作方式
binaries {
framework("moduleA"){
isStatic = false
}
}
kotlin.native.cacheKind=none