SBT构建,在Compile上运行子项目的主类并运行

时间:2014-08-24 21:59:40

标签: java scala sbt multi-project subproject

我有一个简单的构建工具Multi-Project问题......

我有以下目录结构代表我的java sbt项目:

/project1
/project2
/project3

所以所有项目共享一个共同的直接父文件夹。 在项目1的build.sbt中引用了项目2和3,如下所示:

.dependsOn(project2, project3)
.aggregate(project2, project3)

lazy val project2 = ProjectRef(file("../project2"), "project2")

lazy val project3 = ProjectRef(file("../project3"), "project3")

这样,project1和其他人之间存在依赖关系。

这一切都很好,一切正常。

但是现在我想在执行任何其他操作之前从project2执行main方法。 当我执行"运行"来自父(project1)的任务,我希望project2中的特定类执行其主要方法。我该怎么做呢? sbt文档解释了" 聚合意味着在聚合项目上运行任务也将在聚合项目上运行它。": http://www.scala-sbt.org/0.13.5/docs/Getting-Started/Multi-Project.html#aggregation

我没有看到projet2上的主要课程已被执行。我还将此添加到project2的build.sbt:

mainClass in (Compile, run) := Some("Main")

projet的目标是在Compiletime和运行时生成代码。 Project2的工作是生成Java和Javascript代码。可以在构建其他项目之前生成。

这可能吗?如果没有,我将不得不独立于其他项目运行project2。

=]

2 个答案:

答案 0 :(得分:2)

如果我的结构如下所示:

+ root +--- backend +--- frontend http://www.scala-sbt.org/0.13/docs/Multi-Project.html中指出的类似的build.sbt项目,让我们说:

lazy val commonSettings = Seq(
  version := "0.1.0-SNAPSHOT",
  scalaVersion := "2.12.1",
  resolvers := allResolvers,
  libraryDependencies := AllLibraryDependencies
)

lazy val client = (project in file("client")).
  //  .enablePlugins(PlayScala)
  settings(commonSettings: _*).
  settings(
    name := "client"
  )
  .aggregate(common, frontend, backend)
  .dependsOn(common, frontend, backend)


lazy val common = (project in file("common")).
  settings(commonSettings: _*).
  settings(
    name := "common"
  )

lazy val frontend = (project in file("frontend")).
  settings(commonSettings: _*).
  settings(
    name := "frontend"
  )
  .aggregate(common)
  .dependsOn(common)

lazy val backend = (project in file("backend")).
  settings(commonSettings: _*).
  settings(
    name := "backend"
  )
  .aggregate(common)
  .dependsOn(common)

`

然后执行即前端项目中的一个类,这个命令对我有用:

sbt "frontend/runMain sample.cluster.transformation.frontend.TransformationFrontendApp 2551"

答案 1 :(得分:0)

默认情况下,run / aggregatefalse

sbt:root> inspect run / aggregate
[info] Setting: Boolean = false
[info] Description:
[info]  Configures task aggregation.
[info] Provided by:
[info]  Zero / run / aggregate
[info] Defined at:
[info]  (sbt.Defaults.disableAggregate) Defaults.scala:1920
[info] Delegates:
[info]  run / aggregate
[info]  aggregate
[info]  ThisBuild / run / aggregate
[info]  ThisBuild / aggregate
[info]  Zero / run / aggregate
[info]  Global / aggregate
[info] Related:
[info]  Global / aggregate
[info]  Zero / run / aggregate
[info]  Zero / consoleQuick / aggregate
[info]  dependencyCheckPurge / aggregate
[info]  refinedConsole / dependencyCheckUpdateOnly / aggregate
[info]  refinedConsole / dependencyCheckAggregate / aggregate
[info]  server / dependencyCheckListSettings / aggregate
[info]  Zero / changedInputFiles / aggregate
[info]  refinedConsole / dependencyCheckListSettings / aggregate
[info]  refinedConsole / dependencyCheckPurge / aggregate
[info] ...

因此run任务将不会汇总。

即使将其设置为true,由于聚合任务的顺序未定义,您也不大可能获得所需的内容。

创建任务依赖关系是通过相互评估来完成的(如@akauppi在旧的SBT语法中指出的那样):

lazy val project1 = (project in file("project1")
  .settings(
    Compile / run := (project2 / Compile / run).evaluated
  )

现在,如果您还想在run上调用project1,则会变得有些棘手。

天真的方法是:

lazy val project1 = (project in file("project1")
  .settings(
    Compile / run := {
      (project2 / Compile / run).evaluated
      (project1 / Compile / run).evaluated
    }
  )

但是不能保证它将首先运行project2。

我还没有找到一种方法来使它工作。

我尝试使用:

(project2 / Compile / run).flatMap((project1 / Compile / run).toTask("").taskValue

但是您会收到非法的动态参考错误。

我也尝试过:

Def.sequential((server / Compile / run).toTask(""), (Compile / run).toTask("")).value

但这只会在运行时给出未定义的设置错误。

?‍♂️