Gradle多项目与KMM框架:子项目API依赖问题咨询
KMM依赖机制与问题解决方案
一、api(project(":models"))在KMM中的工作机制
在KMM多平台项目中,api(project(":models"))是传递性依赖声明,核心逻辑适配多平台特性:
- 依赖传递:依赖
client的模块(如iOS/Android应用)能自动使用models的代码,无需重复声明。 - 平台自动匹配:Gradle会根据当前构建目标(iOS、Android、JVM等),自动拉取
models对应平台源码集的编译产物:- Android端(JVM目标):使用
models的jvmMain输出 - iOS端(Native目标):使用
models的iosMain输出
- Android端(JVM目标):使用
- 死代码消除(DCE):Kotlin/Native默认开启DCE,仅保留依赖链中被直接/间接引用的代码,未被
client或上层应用使用的方法、类型会被编译时剔除,这是你看不到未使用代码的核心原因。
二、iOS端看不到models未使用代码及iOS特定代码的解决方案
1. 调整死代码消除规则
在models的build.gradle.kts中,针对iOS目标配置禁用DCE:
kotlin { ios { binaries { framework { // 禁用DCE,保留所有代码 freeCompilerArgs += "-Xdisable-dead-code-elimination" } } } }
如果不想完全禁用DCE,可通过显式引用强制保留代码:在models的iosMain中添加公开空对象,让client的iosMain引用它:
// models/iosMain/kotlin/com/example/IOSExports.kt object IOSExports
// client/iosMain/kotlin/com/example/ClientInit.kt import com.example.IOSExports fun initModels() { // 显式引用触发DCE保留iosMain所有代码 IOSExports }
2. 确保源码集依赖配置正确
检查models的源码集关联,确保iosMain依赖commonMain:
kotlin { sourceSets { val commonMain by getting val iosMain by getting { dependsOn(commonMain) } } }
同时确认client的iOS目标正确依赖models的iOS产物,避免仅拉取commonMain代码。
三、ModelsUser与第三方User类不关联的解决方案
1. 封装类型转换逻辑
在models中添加扩展函数,实现两个类的双向转换,把转换逻辑封装在models内部:
// models/iosMain/kotlin/com/example/ModelConversions.kt import com.awesome.framework.User fun ModelsUser.toAwesomeUser(): User { return User(id = this.id, name = this.displayName) } fun User.toModelsUser(): ModelsUser { return ModelsUser(id = this.userId, displayName = this.userName) }
2. 抽象通用接口解耦依赖
在models的commonMain中定义通用User接口,让ModelsUser实现它,同时为第三方User添加适配扩展:
// models/commonMain/kotlin/com/example/UserInterface.kt interface User { val id: String val name: String } // models/commonMain/kotlin/com/example/ModelsUser.kt data class ModelsUser(override val id: String, override val name: String) : User
// models/iosMain/kotlin/com/example/AwesomeUserAdapter.kt import com.awesome.framework.User as AwesomeUser fun AwesomeUser.asUser(): User { return ModelsUser(id = this.userId, name = this.userName) }
这样client只需依赖models的User接口,无需直接接触第三方框架的User类。
3. 调整依赖层级
让models单独依赖AwesomeFramework,client仅依赖models,避免client同时引入AwesomeFramework和AwesomeModels,通过models做中间层封装,隔离第三方依赖。
四、相关学习资源
- Kotlin官方文档:KMM多平台依赖配置、iOS框架编译选项
- Kotlin/Native死代码消除规则说明
- KMM源码集组织与平台特定代码编写指南
内容的提问来源于stack exchange,提问作者edelaney05
相关产品推荐
相关产品推荐

