当前位置: 首页 > 知识库问答 >
问题:

在SBT的多项目构建中,不为带有包的根项目生成工件

乌翔
2023-03-14

我在SBT中有一个多项目构建配置,由两个互不依赖的不同模块组成。它们只是(碰巧)属于同一产品。

项目布局如下:

myLib
  + build.sbt
  + myProject_1
  |    + build.sbt
  |    + src
  |        + ...
  + myProject_2
  |    + build.sbt
  |    + src
  |        + ...
  + project
       + Build.scala

project/Build.scala包含常见设置,如下所示:

import sbt._
import Keys._

object ApplicationBuild extends Build {

  val appVersion = "1.0-SNAPSHOT"

  val defaultScalacOptions = Seq(
    "-unchecked", "-deprecation", "-feature", "-language:reflectiveCalls",
    "-language:implicitConversions", "-language:postfixOps",
    "-language:dynamics", "-language:higherKinds", "-language:existentials",
    "-language:experimental.macros", "-Xmax-classfile-name", "140")

  val defaultResolvers = Seq(
    "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
  )

  val defaultLibraryDependencies = Seq(
    "org.specs2" %% "specs2" % "1.14" % "test",
    "org.slf4j" % "slf4j-nop" % "1.7.5" % "test"
  )

  val defaultSettings = Defaults.defaultSettings ++ Seq(
    scalacOptions ++= defaultScalacOptions,
    resolvers ++= defaultResolvers,
    libraryDependencies ++= defaultLibraryDependencies
  )
}

根构建文件 build.sbt 只需要将它们放在一起 [我也试图删除它...

lazy val myProject_1 = project.in(file("myProject_1"))

lazy val myProject_2 = project.in(file("myProject_2"))

最后是myProject_1/build.sbt[我刚刚省略了myProject_2/build.sbt,因为它非常相似,没有为主题提供任何附加价值]:

name := "myProject_1"

version := ApplicationBuild.appVersion

ApplicationBuild.defaultSettings

libraryDependencies ++= Seq(
  "commons-codec" % "commons-codec" % "1.8"
)

项目编译成功…但是当我发出命令sbt pack时,在root目标目录中生成了一个空jar:

j3d@gonzo:~/myLib/$ ll target/scala-2.10
drwxrwxr-x 2 j3d j3d 4096 Dez 23 17:13 ./
drwxrwxr-x 5 j3d j3d 4096 Dez 23 17:13 ../
-rw-rw-r-- 1 j3d j3d  273 Dez 23 17:13 brix_2.10-0.1-SNAPSHOT.jar

我错过了什么吗?如何防止SBT生成这个空的无用的罐子?

共有3个答案

郎弘壮
2023-03-14

我使用以下内容

lazy val root: Project = Project(
  id        = "root",
  base      = file("."),
  aggregate = Seq(proj1, proj2),
  settings  = Project.defaultSettings ++ Seq(
    publishArtifact in (Compile, packageBin) := false, // there are no binaries
    publishArtifact in (Compile, packageDoc) := false, // there are no javadocs
    publishArtifact in (Compile, packageSrc) := false  // there are no sources
  )
)

这仍然会生成空的打包 jar,但在发布时不会将其导出。

蒋文光
2023-03-14

我提出了一种解决方法,在build.sbt中对package进行以下(重新)定义:

Keys.`package` := {
    (Keys.`package` in (a, Compile)).value
    (Keys.`package` in (b, Compile)).value
}

其中 ab 是(子)模块。

lazy val a = project

lazy val b = project

因为< code>package是Scala中的一个关键字,所以它需要引号才能被解析。

它还需要完全限定,因为<code>包<code>是由<code>键导入的_ sbt_ 导入默认情况下在中。sbt构建文件。

/Users/jacek/sandbox/so/multi-packageBin/build.sbt:5: error: reference to package is ambiguous;
it is imported twice in the same scope by
import Keys._
and import sbt._
`package` := {
^
[error] Type error in expression

另请注意,我使用的是SBT 0.13.2-SNAPSHOT(从源代码构建),因此请谨慎使用(但我怀疑它是否会在任何版本的SBT 0.13中有所作为)。

[multi-packagebin]> */*:sbtVersion
[info] 0.13.2-SNAPSHOT
[multi-packagebin]> projects
[info] In file:/Users/jacek/sandbox/so/multi-packageBin/
[info]     a
[info]     b
[info]   * multi-packagebin
[multi-packagebin]> package
[info] Updating {file:/Users/jacek/sandbox/so/multi-packageBin/}a...
[info] Updating {file:/Users/jacek/sandbox/so/multi-packageBin/}b...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Resolving org.scala-lang#scala-reflect;2.10.3 ...
[info] Packaging /Users/jacek/sandbox/so/multi-packageBin/b/target/scala-2.10/b_2.10-0.1-SNAPSHOT.jar ...
[info] Done packaging.
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Packaging /Users/jacek/sandbox/so/multi-packageBin/a/target/scala-2.10/a_2.10-0.1-SNAPSHOT.jar ...
[info] Done packaging.
[success] Total time: 1 s, completed Feb 23, 2014 10:12:41 AM

濮阳鸿卓
2023-03-14

这是难以实现的。以下一组选项似乎可以实现该目标。这些选项的子集倾向于通过一些执行路径而不是其他路径来抑制根jar,从而烧死您,因此如果您想找到最小的覆盖范围,请确保“sbt包”和“sbt publishLocal”都不会创建jar。我花了很长时间才找到这个集合,我不愿意进一步迭代。

      Keys.`package` :=  file(""),
packageBin in Global :=  file(""),
   packagedArtifacts :=  Map(),

SBT:自2008年以来,让简单的事情变得近乎不可能。

 类似资料:
  • 我正在使用sbt 0.13.12,这是我的项目 在构建中。sbt取决于公共。如果我按sbt project sub1 run运行就可以了。但是,当我将子项目打包为jar文件时,我运行sub1。jar文件中,错误显示sub1无法找到一类公共的。 我的目的是包装sub1。jar和sub2。在每个jar文件中编译带有通用代码的jar。 --更新-- 我尝试作为建议回答。运行时遇到这个问题: 而且,是的!

  • 根settings.gradle.kts如下所示: 在SoaProject的一个build.gradle.kts文件中,例如,我有以下依赖项: 导入/刷新gradle项目在Intellij中工作,并且依赖项被下载。但是当我尝试从子项目执行gradle任务时,我得到一个未解决的引用版本错误。 向西蒙致意

  • sbt子项目是否可以有自己的目录?或者只有根项目可以用。Scala帮助器文件为构建项目的目录?。下面是我目前的建筑结构。无法访问中定义的对象。 更新:sub-project-1/build.sbt中的以下sbt定义 由于以下错误而失败 Common在/my-project/projects/Common.scala中定义,没有问题。但是Localhost是在/my-project/sub-proj

  • 我尝试将基于Scala/sbt的项目切换到Java9。如果我用sbt编译项目,它就可以工作。 如果我尝试使用IntelliJ的build选项构建项目,我会立即得到错误 我尝试添加模块作为依赖项 并添加到IntelliJ的编译器设置中(javac以及scala编译器) 但不幸的是,没有帮助。

  • 为了定义一个多项目构建, 你需要创建一个设置文件 ( settings file). 设置文件放在源代码的根目录, 它指定要包含哪个项目. 它的名字必须叫做 settings.gradle. 在这个例子中, 我们使用一个简单的分层布局. 下面是对应的设置文件: Example 7.11. 多项目构建 - settings.gradle file settings.gradle include "s