gpt4 book ai didi

java - 当您不是 Kotlin Multiplatform 项目时,是否有一种干净的方法可以在 Gradle 中声明多平台依赖项?

转载 作者:行者123 更新时间:2023-12-05 04:27:36 25 4
gpt4 key购买 nike

因此,我们在这个构建中使用了一些库,无论出于何种原因,这些库都作为不同的 jar 文件分发给不同的 native 操作系统。

当然,那些库已经安排好了,如果我们同时包含所有这些库,事情就会爆炸。

很好,我们只是确保包含正确的内容,如下所示:

if (isWindows()) {
runtimeOnly(libraries.nd4j.windows)
runtimeOnly(libraries.openblas.windows)
} else if (isMacOS()) {
runtimeOnly(libraries.nd4j.macos)
runtimeOnly(libraries.openblas.macos)
} else if (isLinux()) {
runtimeOnly(libraries.nd4j.linux)
runtimeOnly(libraries.openblas.linux)
}

现在,我当然可以编写一些高尔夫代码了。在函数调用中插入条件,然后将条件移动到 libraries 中,这样就不会有人看到它,诸如此类。不过,这不是问题所在。

问题是,当我发布这个项目时,根据我在运行构建时所使用的操作系统,发布的项目的 POM 会说它取决于这些 jar 的 Windows 变体。然后其他人尝试在 macOS 上针对我的项目进行构建,但它不起作用。

如果 Gradle 认识到配置文件的存在并支持它,这些项目可能会声明它们有多个配置文件,具体取决于您运行构建的平台。然后我们的构建可以做同样的事情并将其放入我们的 POM 中。下游项目会看到这一点,一切都会好起来的。

但是,Gradle 支持用于读取或写入 POM 的 Maven 配置文件,因此拆分它的唯一方法似乎是将我的项目分为四个子项目 - 一个公共(public)部分,一个窗口部分,一个 macos 部分和一个 linux 部分,这样每个部分都可以有不同的依赖关系。然后,我所有的代码都位于公共(public)目录中,大多数依赖项声明位于公共(public)子项目中,然后每个特定于平台的子项目将依赖于两个讨厌的依赖项的公共(public)版本和相应的特定于平台的版本。

现在 是问题的制造者,因为任何想使用我的 库的人都会遇到同样的问题,并提示它。等等。

有没有更好的方法来解决这个问题?

我知道 Kotlin/Multiplatform 是一回事并且已经看到了这些构建的结构,但是这个项目根本没有使用 Kotlin(这是一个 Java 项目,尽管构建脚本正在重写为 Kotlin DSL),所以它不会从中受益,除非我能以某种方式扭曲它以适用于我们不完全相同的用例。

最佳答案

允许以不同方式解析单个依赖模块的 Gradle 功能是 variant-aware dependency resolution .

有了它,一个模块可以提供其工件的多个变体,以及多组传递依赖项,并且消费者可以从其依赖项中请求满足某些属性的内容,这应该会产生匹配的依赖项变体。

但是,您的依赖项是已经存在的第三方库,它们当然不会提供您可以通过请求属性来选择的变体。

在您这边,您可以通过执行以下操作之一来解决此问题:

  • 指定组件元数据规则,插入构建的依赖项解析并修改特定第三方依赖项的组件元数据,adding the Native JAR variants to them .

  • 构建并发布您自己的“伞式”库,这些库将具有依赖于第三方库的平台特定部分的变体。然后使用“umbrella”模块作为依赖,请求匹配当前平台的属性。

    为此,您需要配置一个没有自己代码的库的构建,但它仍应公开具有不同属性的多个变体。在这些变体中,您可以指定不同的依赖项,例如依赖于 Windows 变体中的 nd4j.windows 和面向 Linux 的变体中的 nd4j.linux

    • 或者使您分发的库成为“多平台”,这样就没有单独的“伞形”库,而是您的库具有针对不同平台的多个变体。如果您想简化发布和分发管道,这可能更可取,即使是以主库构建的复杂性为代价。

然后,在您的构建中,您需要请求与当前主机对应的属性。

Gradle API 中您可以重用以区分操作系统和架构的常见属性是 OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTEMachineArchitecture.ARCHITECTURE_ATTRIBUTE

根据您的选择,发布的库将具有原始依赖项或对“伞形”库的依赖项,但无论主机平台如何,它都将是相同的依赖项。

另一方面,这两种方法都将责任强加给您的出版物的消费者以调整他们的构建,或者通过在他们这一边指定正确的操作系统属性,并可能添加相同的组件元数据规则。这些都可以通过您可以分发的 Gradle 插件或手动完成。


既然您提到了 Kotlin/Multiplatform,您可能会对以上内容大致了解 Kotlin 如何支持指定对多平台库的单一依赖项感兴趣。您可以在已发布的 Kotlin 库中找到特定于平台的变体,例如,在 Gradle *.module metadata file of kotlinx.coroutines 中:

"variants": [
...
{
"name": "iosArm32MetadataElements-published",
"attributes": {
"org.gradle.category": "library",
"org.gradle.usage": "kotlin-metadata",
"org.jetbrains.kotlin.native.target": "ios_arm32",
"org.jetbrains.kotlin.platform.type": "native"
},
"available-at": { ... }
},
{
"name": "iosArm64ApiElements-published",
"attributes": {
"org.gradle.category": "library",
"org.gradle.usage": "kotlin-api",
"org.jetbrains.kotlin.native.target": "ios_arm64",
"org.jetbrains.kotlin.platform.type": "native"
},
"available-at": { ... }
},
...
]

就 Kotlin/Multiplatform 而言,是 Kotlin Gradle 插件根据消费者的目标平台在消费者端设置正确的属性。

关于java - 当您不是 Kotlin Multiplatform 项目时,是否有一种干净的方法可以在 Gradle 中声明多平台依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72781741/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com