Gradle 如何正确导入Kotlin多平台项目(仅在构建时运行必要的任务)

Gradle 如何正确导入Kotlin多平台项目(仅在构建时运行必要的任务),gradle,android-gradle-plugin,gradle-kotlin-dsl,kotlin-multiplatform,kotlin-multiplatform-mobile,Gradle,Android Gradle Plugin,Gradle Kotlin Dsl,Kotlin Multiplatform,Kotlin Multiplatform Mobile,当我开发导入kotlin多平台项目的android应用程序时,是否可能不运行所有的iOS(kotlin/Native)任务(cinterop+Cocoapod) 我们目前的KMP项目(共享图书馆)结构是: SharedLibrary - build.gradle.kts - settings.gradle.kts - ... - shared - build.gradle.kts - commonMain - androidMain (android libra

当我开发导入kotlin多平台项目的android应用程序时,是否可能不运行所有的iOS(kotlin/Native)任务(cinterop+Cocoapod)

我们目前的KMP项目(共享图书馆)结构是:

SharedLibrary
 - build.gradle.kts
 - settings.gradle.kts
 - ...
 - shared
   - build.gradle.kts
     - commonMain
     - androidMain (android library target)
     - ...  
我们有一个单独的Android项目(SomeApp),具有以下设置以导入我们的共享库

// settings.gradle.kts
include ":shared"
project(":shared").projectDir = file("../SharedLibrary/shared")
问题是。。。这是一个相当烦人的开发模式,尤其是因为每次有变化时iOS工件(cinterop+cocoapods等)都会被重建,即使我只关心android库工件

我尝试过的事情:

  • 我尝试切换到复合构建,但我得到了与gradle无法找到多平台插件相关的错误
  • 我正在考虑转向推动当地的maven,但这肯定会减慢开发过程,所以我拒绝

这是我们设置的问题吗?或者任务只是相互依赖,没有办法解决吗?

您可以像这样将iOS目标从构建中排除:

kotlin {
    android()
    // kotlin.native.cocoapods.target property passed by cocoapods build from Xcode 
    val shouldBuildIos = project.findProperty("kotlin.native.cocoapods.target") != null
    if (shouldBuildIos) {
        ios()
        cocoapods {
            // ...
        }
    }
    sourceSets {
        // ...
        if (shouldBuildIos) {
            val iosMain by getting {
                libDependencies(
                    "ktor.client.engine.ios",
                )
            }
        }
    }
}
featureProvider = FeatureProvider(
    context: .init(
        rootController: rootViewController,
        application: application,
        launchOptions: launchOptions
    ),
    providerGenerator: { socialNetwork, context -> CredentialProvider in
        switch socialNetwork {
        case .facebook:
            return FacebookProvider(context: context)
            
        case .google:
            return GoogleProvider(context: context)
            
        default: fatalError()
        }
    }
)
但是在这种情况下,IDE中不会有任何代码建议。还要小心,因为在这种情况下,您的podspec将被删除

如果您只使用android部件,而其他开发人员使用的是iOS one,那么您可以在local.properties中创建自己的属性,并确保不会强制删除podspec文件(或者忽略它)

但是如果你是一个开发人员,这不是一个好的选择。我也面临着很长的CoCoapod构建时间,并决定将其从多平台模块中移出

每次我需要它时,我都在公共代码中创建一个接口,并从iOS部分传递一个实现它的实例或一个“生成器”函数(如果您不想创建对象,除非需要)

在iOS部分,它看起来像这样:

kotlin {
    android()
    // kotlin.native.cocoapods.target property passed by cocoapods build from Xcode 
    val shouldBuildIos = project.findProperty("kotlin.native.cocoapods.target") != null
    if (shouldBuildIos) {
        ios()
        cocoapods {
            // ...
        }
    }
    sourceSets {
        // ...
        if (shouldBuildIos) {
            val iosMain by getting {
                libDependencies(
                    "ktor.client.engine.ios",
                )
            }
        }
    }
}
featureProvider = FeatureProvider(
    context: .init(
        rootController: rootViewController,
        application: application,
        launchOptions: launchOptions
    ),
    providerGenerator: { socialNetwork, context -> CredentialProvider in
        switch socialNetwork {
        case .facebook:
            return FacebookProvider(context: context)
            
        case .google:
            return GoogleProvider(context: context)
            
        default: fatalError()
        }
    }
)

您可以从生成中排除iOS目标,如下所示:

kotlin {
    android()
    // kotlin.native.cocoapods.target property passed by cocoapods build from Xcode 
    val shouldBuildIos = project.findProperty("kotlin.native.cocoapods.target") != null
    if (shouldBuildIos) {
        ios()
        cocoapods {
            // ...
        }
    }
    sourceSets {
        // ...
        if (shouldBuildIos) {
            val iosMain by getting {
                libDependencies(
                    "ktor.client.engine.ios",
                )
            }
        }
    }
}
featureProvider = FeatureProvider(
    context: .init(
        rootController: rootViewController,
        application: application,
        launchOptions: launchOptions
    ),
    providerGenerator: { socialNetwork, context -> CredentialProvider in
        switch socialNetwork {
        case .facebook:
            return FacebookProvider(context: context)
            
        case .google:
            return GoogleProvider(context: context)
            
        default: fatalError()
        }
    }
)
但是在这种情况下,IDE中不会有任何代码建议。还要小心,因为在这种情况下,您的podspec将被删除

如果您只使用android部件,而其他开发人员使用的是iOS one,那么您可以在local.properties中创建自己的属性,并确保不会强制删除podspec文件(或者忽略它)

但是如果你是一个开发人员,这不是一个好的选择。我也面临着很长的CoCoapod构建时间,并决定将其从多平台模块中移出

每次我需要它时,我都在公共代码中创建一个接口,并从iOS部分传递一个实现它的实例或一个“生成器”函数(如果您不想创建对象,除非需要)

在iOS部分,它看起来像这样:

kotlin {
    android()
    // kotlin.native.cocoapods.target property passed by cocoapods build from Xcode 
    val shouldBuildIos = project.findProperty("kotlin.native.cocoapods.target") != null
    if (shouldBuildIos) {
        ios()
        cocoapods {
            // ...
        }
    }
    sourceSets {
        // ...
        if (shouldBuildIos) {
            val iosMain by getting {
                libDependencies(
                    "ktor.client.engine.ios",
                )
            }
        }
    }
}
featureProvider = FeatureProvider(
    context: .init(
        rootController: rootViewController,
        application: application,
        launchOptions: launchOptions
    ),
    providerGenerator: { socialNetwork, context -> CredentialProvider in
        switch socialNetwork {
        case .facebook:
            return FacebookProvider(context: context)
            
        case .google:
            return GoogleProvider(context: context)
            
        default: fatalError()
        }
    }
)

我想从支持者的角度谈谈这个问题。我发现这个YouTrack问题似乎与此相关:。请检查这是否正确描述了您的问题,如果没有,请在此处进行评论。另外,这是获取问题状态更新的最佳地点。

我只想从支持者的角度说一句关于问题的话。我发现这个YouTrack问题似乎相关:。请检查这是否正确描述了您的问题,如果没有,请在此处进行评论。此外,这是获取问题状态最新信息的最佳地点。

谢谢,我相信这个问题是相关的+您过去在youtrack上帮助过我,并想在此处表示感谢:)谢谢,我相信这个问题是相关的+您过去在youtrack上帮助过我,并想在此处表示感谢:)谢谢!我没有想到在那里加一个条件。我今天会试一试,然后回来汇报。我们已经为不同的本地AS插件版本等使用本地构建文件,因此将尝试利用您提到的方法。编辑:将shell类与传入的实例一起使用听起来像是一个很好的解决方案,但我完全明白这一点,并且可能是我们最后的选择:/谢谢!我没有想到在那里加一个条件。我今天会试一试,然后回来汇报。我们已经为不同的本地AS插件版本等使用本地构建文件,因此将尝试利用您提到的方法。编辑:使用带有传入实例的shell类听起来很像是一种变通解决方案,但我完全明白这一点,这可能也是我们最后的选择:/