如何让 SBT 跳过给定子项目的交叉编译?

Posted

技术标签:

【中文标题】如何让 SBT 跳过给定子项目的交叉编译?【英文标题】:How to have SBT skip cross compile for a given sub-project? 【发布时间】:2014-10-25 03:11:00 【问题描述】:

我遇到了几个与 SBT 相关的案例,这让我很困惑。有没有办法告诉 SBT 在交叉编译时完全跳过某些 scala 版本的子项目?

这里有两个有用的例子。

1) 包含三个项目 A、B 和 C 的构建。A 和 B 都是 scala 项目,并且在其设置中具有 'scalaVersions ++= Seq("2.11.2", "2.10.4")。项目 C 是一个纯 Java 工件,因此我已将 Scala 库从它的依赖项中排除。我希望 A 和 B 依赖于 C,但理想情况下我只想构建 C 一次。如果我使用默认行为并从根聚合器项目中执行“+publish”,我会生成两个 C-1.0.0.jar 副本,并且 SBT 尝试发布它两次,这对于Maven 仓库。

2) 包含多个 Scala 项目的构建,但其中一个项目应该只针对单个 Scala 版本构建。我已经尝试在该项目的设置中定义“scalaVersions”以仅保存一个版本,而其他项目有两个,但来自根聚合器的“+publish”再次似乎忽略了这一点,仍然编译两次,第二次失败,因为它的依赖项不适用于该 Scala 版本。这个项目是依赖图中的一个叶子节点,所以在逻辑上想要做这件事是一件非常好的事情。

对于案例 #2,我曾考虑将“坏”scala 版本的源目录设置为 /dev/null 或类似的东西,但实际上仍会运行构建并产生一个空工件。我知道我可能会进入并找到所有相关的密钥并执行类似的操作

publishArtifact := if(scalaBinaryVersion.value == "2.10") false else publishArtifact.value

然后查找所有其他相关设置/任务(编译、在 Test 中编译、在 Test 中测试、packageBin 等),但这似乎很 hack-ish。某处是否有“跳过”设置?

【问题讨论】:

【参考方案1】:

我写了sbt-doge 来解决子项目之间的任务聚合,尊重它们的crossScalaVersions。对于 Java 项目,您可能需要一个虚拟的 crossScalaVersion 条目。

【讨论】:

这看起来非常有用,但坦率地说,我对在我的构建中添加“如此多的测试”之类的东西持怀疑态度:-/ 我完全错过了 0.1.4 中的“明智”替代方案。对不起,先生!这就像一个魅力! @Tomer 你指的是什么测试和“明智的选择”? @matt 类似于 doge 的语法,以及“政治正确”的替代方案 :-) 我们可以在@TomerGabel 在这里不那么含糊不清吗? :)【参考方案2】:

插件sbt-doge可用于在每个子项目中指定crossScalaVersion设置。

首先,将addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.5") 行添加到您的projects/plugins.sbt

为了避免荒谬的 doge 语法(“这样的编译”,真的吗?)你需要在你的根项目中 enablePlugins(CrossPerProjectPlugin)。有了这个,您可以在您的 sbt 命令之前添加一个加号,它们将遵循交叉构建设置。就像这样:+ compile

【讨论】:

以上是关于如何让 SBT 跳过给定子项目的交叉编译?的主要内容,如果未能解决你的问题,请参考以下文章

跳过不兼容的 libpcap.so - 交叉编译

使用 mono 交叉编译 c 时跳过不兼容的库 (lmono)

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

如何制定android交叉编译工具链

如何在交叉编译armv7的图集时缩短构建时间?

如何安装arm-liunx交叉编译环境?