【问题标题】:Producing no artifact for root project with package under multi-project build in SBT在 SBT 中的多项目构建下使用包不为根项目生成工件
【发布时间】:2014-01-11 21:26:57
【问题描述】:

我在 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 package时,在根目标目录中生成了一个空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 生成这个空无用的 jar?

【问题讨论】:

    标签: scala sbt


    【解决方案1】:

    我使用以下

    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,但是发布的时候不会导出。

    【讨论】:

    • ...但在那种情况下“publishArtifacts := false”还不够吗?
    • 我也很高兴知道@j3d 的问题的答案
    【解决方案2】:

    我建议一种解决方法,在build.sbt 中使用以下(重新)定义package:

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

    其中a 和b 是(子)模块。

    lazy val a = project
    
    lazy val b = project
    

    由于package 是 Scala 中的关键字,它需要引号才能解析。

    它还需要完全限定,因为 package 由 Keys._ 和 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
    

    【讨论】:

    • Yessss...刚刚尝试使用 SBT 0.13.1 并且它有效 ;-) 非常感谢。
    • 为什么我在遵循您的建议时收到以下警告?警告:纯表达式在语句位置不执行任何操作;您可能会省略必要的括号 (Keys.package in (data, Compile)).value
    • 整个build.sbt 文件是什么?我建议就 SO 提出另一个问题,这样问题和可能的答案就不会被 cmets 所掩盖。
    • 并没有真正阅读整个问题/答案,但这是我能找到的唯一解决我的“对包的引用不明确”问题的地方。谢谢!
    • +1。这也适用于我的 Scala.js 跨项目配置。我只是不明白为什么publishArtifacts := false 不起作用...
    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

      由于我是 SBT 的新手,所以我并不完全确定这一切的含义,但以下似乎可以完成这项工作:

      compile := sbt.inc.Analysis.Empty
      

      在我看来,覆盖打包任务并不合适。所以我使用inspect(加上我一开始不知道要查找什么的源)来查找这些映射的确切来源并找到了这些依赖项:

      compile:package -> compile:packageBin -> compile:packageBin::packageConfiguration -> compile:packageBin::mappings -> compile:packageBin::products (由compile:products提供) -> compile:compile

      我不知道为什么要这么难。我的大部分问题都来自于尝试构建多项目。

      【讨论】:

      • 我刚刚意识到inspect tree compile:package 比手动跟踪依赖项要容易得多。
      • 这实际上是行不通的。如果packageBin 没有重新定义,那么它仍然会调用Defaults.packageTask,而Package.apply 又会调用Package.apply。它会进行一些缓存和最新检查,但可能会调用Package.makeJar,此时您会看到: > [info] Packaging C:\target\my.jar ... > [info] Done Packaging。看起来唯一正确的方法是@Jacek 的解决方法
      【解决方案5】:

      我将以下设置添加到项目根目录:

      Compile / packageBin := { file("") }
      Compile / packageSrc := { file("") }
      Compile / packageDoc := { file("") }
      

      通过更改Compile 范围内的任务,默认的package 任务也会被抑制。

      【讨论】:

        猜你喜欢
        • 2015-02-25
        • 1970-01-01
        • 1970-01-01
        • 2014-04-28
        • 2013-12-20
        • 2021-05-28
        • 2015-03-11
        • 2015-06-11
        • 2014-08-05
        相关资源
        最近更新 更多