2013-12-23 51 views
8

我在SBT中有一個多項目構建配置,它由兩個不同的模塊組成,不需要彼此依賴。他們只是(碰巧)屬於同一產品。在多項目構建中爲包根項目生成沒有工件的項目SBT

項目佈局如下:

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

項目/ 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,然後在根目標目錄中生成一個空罐子:

[email protected]:~/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產生這個空的無用的罐子?

回答

6

我提出一種變通方法以下的(重新)的packagebuild.sbt定義:

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

其中ab是(子)模塊。

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-快照(從源代碼構建的),所以請小心使用(但我懷疑它會在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 
+0

Yessss ...剛試過SBT 0.13.1,它的工作原理;-)非常感謝。 – j3d

+0

爲什麼我在遵循你的建議時有下列警告?警告:一個純粹的表達式在聲明中不做任何事情;你可能省略了必要的括號 (keys.'package' in(data,Compile))。value – Dzanvu

+0

什麼是整個'build.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 
) 
) 

這仍然產生空包裝罐,但發佈時,它不會將其導出。

+2

...但在這種情況下,不會「publishArtifacts:=假」就夠了嗎? – j3d

+0

我也很高興知道@ j3d的問題的答案 – arya

10

這是很荒謬的難以實現的。以下一組選項似乎實現了目標。這些選項的子集傾向於通過一些執行路徑而不是其他路徑來壓制root jar,所以如果你想找到最小覆蓋範圍,確保'sbt package'和'sbt publishLocal'都不創建jar。我花了很多時間才找到這個集合,而且我不想進一步迭代。

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

SBT:製作簡單的事情,因爲2008年

+1

爲標記行增加了投票。 –

1

交界不可能我不是這一切的意義完全肯定,因爲我是新來SBT但以下似乎做的工作:

compile := sbt.inc.Analysis.Empty 

覆蓋包裝任務似乎不適合我。所以我用inspect(加,因爲我不知道要查找在第一來源是什麼)來找到確切位置這些映射是從未來和發現這些依賴關係:

編譯:包 - >編譯:packageBin - >編譯:packageBin :: packageConfiguration - >編譯:packageBin ::映射 - >編譯:packageBin ::產品(由編譯提供:產品) - >編譯:編譯

我不知道爲什麼它有這是困難的。我的大部分問題都來自嘗試建立多個項目。

+0

我剛剛意識到'inspect tree compile:package'會比手動執行依賴關係容易得多。 – Steiny

+0

這實際上不起作用。如果'packageBin'沒有被重新定義,那麼它仍然會調用'Defaults.packageTask',然後調用'Package.apply'。它會執行一些緩存和最新的檢查,但可能會調用'Package.makeJar',當您看到: > [info]打包C:\ target \ my.jar ... > [info]完成打包。 它看起來像唯一正確的方法是來自@Jacek的解決方法 – Steiny

0

我添加了以下設置項目根:

root.settings(
    packageBin := { new File("") }, 
    packageSrc := { new File("") })