2011-11-30 97 views
12

假設我公司的一個人有一個名爲commons的sbt項目,這個項目非常通用。這個項目是以傳統的方式定義的:在project/Build.scala文件中具有構建定義的主文件夾中。如何指定構建項目另一個項目B必須先構建?

現在一些其他人正在開發一個名爲databinding的項目,該項目取決於commons。我們想用project/Build.scala來定義這個項目。

我們有以下的目錄佈局:

dev/ 
    commons/ 
    src/ 
     *.scala files here... 
    project/ 
     Build.scala 
    databinding/ 
    src/ 
     *.scala files here... 
    project/ 
     Build.scala 

我怎麼可以指定databinding需要commons興建第一和使用輸出類文件?

我讀Multi-project builds,並與中databinding構建定義如下上來:

object MyBuild extends Build { 

    lazy val root = Project(id = "databinding", base = file(".")) settings (
    // ... omitted 
) dependsOn (commons) 

    lazy val common = Project(id = "commons", 
    base = file("../commons") 
) 

} 

除非它不工作:SBT不喜歡..並拋出一個AssertionError。顯然,commons應該是databinding內的文件夾。但是這兩個項目保存在單獨的git倉庫中,我們不能嵌套。

如何正確指定這種依賴關係?

回答

12

您需要在根項目中定義多項目(或任何名稱,但這個很合適),這些項目將在dev/project/Build.scala中定義。

object RootBuild extends Build { 
    lazy val root = Project(id = "root", base = file(".")) 
    .settings(...) 
    .aggregate(commons, databinding) 

    lazy val commons = Project(id = "commons", base = file("commons")) 
    .settings(...) 

    lazy val databinding = Project(id = "databinding", base = file("databinding")) 
    .settings(...) 
    .dependsOn(commons) 
} 

還有一件事,SBT在子項目中不支持*.scala配置文件。這意味着您必須將您在commons/project/Build.scaladatabinding/project/Build.scala上所做的配置分別遷移到commons/build.sbtdatabinding/build.sbt

如果某些配置不適用於.sbt定義文件,則必須將它們添加到根project/Build.scala。很顯然,在根文件文件中提供了在根Build.scala中定義的設置。

+0

非常感謝您的解釋,大衛樣品。這看起來很奇怪,是不是因爲其他項目使用我的項目'commons',它不能在'.scala'文件中有完整的定義? –

+0

而且,是否有其他選擇 - 例如,添加一個解析器來查找它依賴的項目生成的jar文件? –

+0

關於你的第一個問題,這是一個阻止你使用'*的SBT限制。scala'文件來定義子項目。我認爲這是SBT合併項目定義文件的一個限制。幸運的是,'* .sbt'文件將能夠從您的根項目'Build.scala'中訪問vals,settings ...。你也可以考慮如你在第二個評論中提到的那樣,例如在本地發佈你的'common'(發佈 - 本地),解析器應該檢索它。如果您想使用SNAPSHOT系統,請注意將isChanging()添加到依賴關係定義中。希望這會有所幫助。 – David

1

您可以有兩個獨立的項目,並且只是在本地發佈其中一個項目,將其作爲正常的庫依賴項添加到其他項目中。

10

您應該使用RootProject(在引用另一個項目的根項目的情況下)或ProjectRef(在引用另一個項目的子項目的情況下)。

下面是使用RootProject樣本:

 lazy val commons = RootProject(file("../commons")) 
     lazy val root = Project(id = "databinding", base = file(".")) settings (...) dependsOn (commons) 

這裏是使用ProjectRef

 lazy val commons = ProjectRef(file("../commons"), "sub-project") 
     lazy val root = Project(id = "databinding", base = file(".")) settings (...) dependsOn (commons) 
+0

這個'RootProject'是新的嗎?這個新的API是否會使David推薦的解決方案失效? –

+0

似乎是這樣。不,但我會說這有點簡單 –

+1

我無法理解批准的答案如何在不影響兩個獨立項目目的的情況下爲OP提供幫助。由於根項目,他們不會在遷移之後。 –