为啥交叉构建约定将 scala 版本附加到 artifactId?

Posted

技术标签:

【中文标题】为啥交叉构建约定将 scala 版本附加到 artifactId?【英文标题】:Why does the cross-building convention append the scala version to the artifactId?为什么交叉构建约定将 scala 版本附加到 artifactId? 【发布时间】:2014-06-01 01:48:37 【问题描述】:

用于指示编译库的 Scala 版本的底层机制是将 _ 附加到库的名称中。这种相当简单的方法允许与 Maven、Ant 和其他构建工具的用户进行互操作。 -- sbt Documentation: Cross-Build Publishing Conventions

虽然这是一种简单的方法,但与 Maven 和其他构建工具的互操作性仍有待改进。因为artifactId 不同(例如scalatest_2.9.0scalatest_2.10.0),Maven 将它们视为不同的工件。 Maven 的依赖解析机制因此受到损害,同一工件的多个版本(针对不同的 scala 版本构建)可能会出现在类路径上。

为什么不把 scala 版本放在分类器中呢?这似乎是分类器的主要预期用例之一:

分类器允许 [Maven] 区分从同一个 POM 构建但内容不同的工件。作为这个元素的动机,考虑一个项目,它提供了一个针对 JRE 1.5 的工件,但同时也提供了一个仍然支持 JRE 1.4 的工件。第一个工件可以配备分类器 jdk15,第二个工件配备 jdk14,以便客户端可以选择使用哪一个。 -- Maven Documentation: POM Reference

【问题讨论】:

我记得这个决定是几年前做出的,我几乎可以肯定使用分类器被讨论过并被拒绝,所有人都同意这不是一个可行的解决方案。我不记得是为什么! @SethTisue 感谢您的提示。 【参考方案1】:

将版本附加到名称是很久以前做出的历史决定,因此它可能不会改变,因为许多库已经按照约定发布。

话虽如此,正如 Seth 所指出的,几年前 sbt 0.12 将“_2.10.0”后缀缩短为“_2.10”以利用 Scala 库的二进制兼容性版本。这是来自[0.12] plan 的马克:

所谓跨版本,我的意思是在模块 ID 中包含 Scala 版本的某些部分,以区分通过针对不同 Scala 版本编译相同源代码生成的工件。我并不是说能够使用 +task 构建多个 Scala 版本,这将保持不变;我只是指跨版本约定。

[剪辑]

以不灵活的 pom.xml 格式对其进行编码一直是一种 hack,我认为对于针对 Scala 2.10 及更高版本构建的项目,最好不要使用这种格式。但是,也许这比任何可能取代它的临时解决方案要好。我没有看到其他构建工具的用户这样做,所以我希望没有什么可以取代它。

在线程的某个地方 Josh suggested:

(1) Scala 分类器。这些可以是自定义字符串 并且 可以使用依赖项指定。至少,IIRC 这应该可以工作。

这是马克的response:

“可以指定依赖项”是什么意思?所有分类器只有一个 pom,对吧?如何为每个分类器声明不同的依赖关系?

这里有一些来自Geoff Reedy的关于分类器的更有趣的评论

我也认为分类器是处理 这个问题尤其是鉴于 Maven 文档中的建议 分类器java-1.4java-1.5 用于区分罐子 适合各自的平台。致命的缺陷似乎是 传递依赖管理。也就是说,没有办法选择 基于分类器的传递依赖集 模块。当您使用此模块时,我们需要能够说 使用scala-2.10 分类器,它使用 scala-2.10 分类器,当与 2.9 分类器一起使用时,会引入 使用 scala-2.9 分类器的自己的部门。

我认为使用 jvm 版本可以使这项工作成为可能,因为 jvm 版本控制在配置文件激活中具有特殊支持,可以 可以控制依赖关系。

【讨论】:

以上是关于为啥交叉构建约定将 scala 版本附加到 artifactId?的主要内容,如果未能解决你的问题,请参考以下文章

如何交叉编译支持不同核心库API的Scala版本?

为啥在尝试将 UIPopover 附加到不同类中的 UIButton 时出现此构建错误?

如何为 appJS/appJVM 交叉构建项目运行 scala sbt-native-packager

directory/.pm 曾经是一个约定吗?它为啥存在?

如何将 SBT 类附加到 Intellij Idea?

Scala:将元素附加到数组的最佳方法是啥?