Scala 如何在多模块项目中使用自定义插件?

Scala 如何在多模块项目中使用自定义插件?,scala,sbt,Scala,Sbt,在多模块项目中,当一个模块使用自定义TaskKey实现自定义SBT插件时,如何为另一个子模块的项目设置导入该插件 如果使用插件的子模块在submodule1/build.sbt中定义,则不会加载submodule1/project/plugins.sbt 如果插件注册在project/plugins.sbt中,加载top/aggregate项目时将失败,因为插件不一定已经生成 有没有其他方法来定义需要自定义依赖项的自定义任务,以便子模块可以使用它 以下是我最终如何让它工作的: import sb

在多模块项目中,当一个模块使用自定义TaskKey实现自定义SBT插件时,如何为另一个子模块的项目设置导入该插件

如果使用插件的子模块在
submodule1/build.sbt
中定义,则不会加载
submodule1/project/plugins.sbt

如果插件注册在
project/plugins.sbt
中,加载top/aggregate项目时将失败,因为插件不一定已经生成


有没有其他方法来定义需要自定义依赖项的自定义任务,以便子模块可以使用它

以下是我最终如何让它工作的:

import sbt._
import Keys._

object MyBuild extends Build {
  private lazy val myGenerator = 
    // Private project with generator code and its specific dependencies
    // (e.g. Javassist)
    Project(id = "my-generator", 
      base = file("project") / "my-generator").settings(
      name := "my-generator",
      javacOptions in Test ++= Seq("-Xlint:unchecked", "-Xlint:deprecation"),
      autoScalaLibrary := false,
      scalacOptions += "-feature",
      resolvers += 
        "Typesafe Snapshots" at "http://repo.typesafe.com/typesafe/releases/",
      libraryDependencies ++= Seq( // Dependencies required to generate classes
        "org.javassist" % "javassist" % "3.18.2-GA")
    )

  // Some custom setting & task
  lazy val generatedClassDirectory = settingKey[File](
    "Directory where classes get generated")

  lazy val generatedClasses = taskKey[Seq[(File, String)]]("Generated classes")

  lazy val myProject =
    Project(id = "my-project", base = file("my-project")).settings(
      name := "my-project",
      javacOptions in Test ++= Seq("-Xlint:unchecked", "-Xlint:deprecation"),
      autoScalaLibrary := false,
      scalacOptions += "-feature",
      libraryDependencies ++= Seq(/* ... */),
      generatedClassDirectory := { 
        // Defines setting for path to generated classes
        val dir = target.value / "generated_classes"
        if (!dir.exists) dir.mkdirs()
        dir
      },
      generatedClasses <<= Def.task { // Define task generating .class files
        // first get classloader including generator and its dependencies
        val cp = (fullClasspath in (myGenerator, Compile)).value
        val cl = classpath.ClasspathUtilities.toLoader(cp.files)

        // then loaded generator class, and instantiate with structural type
        val genClass = cl loadClass "my.custom.GeneratorClass"
        val generator = genClass.newInstance.
          asInstanceOf[{def writeTo(out: File): File}]

        // finally we can call the
        val outdir = generatedClassDirectory.value
        val generated = generator writeTo outdir
        val path = generated.getAbsolutePath

        // Mappings describing generated classes
        Seq[(File, String)](generated -> path.
          drop(outdir.getAbsolutePath.length+1))

      } dependsOn(compile in (myGenerator, Compile))/* awkward? */,
      managedClasspath in Compile := {
        // Add generated classes to compilation classpath, 
        // so it can be used in my-project sources
        val cp = (managedClasspath in Compile).value
        cp :+ Attributed.blank(generatedClassDirectory.value)
      },
      // Make sure custom class generation is done before compile
      compile in Compile <<= (compile in Compile) dependsOn generatedClasses,
      mappings in (Compile, packageBin) := {
        val ms = mappings.in(Compile, packageBin).value
        ms ++ generatedClasses.value // add generated classes to package
      }
    ).dependsOn(myGenerator/* required even if there dependsOn(compile in (myGenerator, Compile)) */)
}
导入sbt_
导入密钥_
对象MyBuild扩展了Build{
专用延迟val myGenerator=
//具有生成器代码及其特定依赖项的专用项目
//(例如Javassist)
项目(id=“我的生成器”,
base=文件(“项目”)/“我的生成器”)。设置(
名称:=“我的生成器”,
Test++=Seq中的javacopions(“-Xlint:unchecked”,“-Xlint:deprecation”),
AutoScalarLibrary:=false,
ScalaOptions+=“-功能”,
解析程序+=
“类型安全快照”位于http://repo.typesafe.com/typesafe/releases/",
libraryDependencies++=Seq(//生成类所需的依赖项
“org.javassist”%“javassist”%“3.18.2-GA”)
)
//一些自定义设置和任务
lazy val generatedClassDirectory=settingKey[文件](
“生成类的目录”)
lazy val generatedClasses=taskKey[Seq[(文件,字符串)]](“生成的类”)
懒惰的val myProject=
项目(id=“我的项目”,base=文件(“我的项目”)。设置(
名称:=“我的项目”,
Test++=Seq中的javacopions(“-Xlint:unchecked”,“-Xlint:deprecation”),
AutoScalarLibrary:=false,
ScalaOptions+=“-功能”,
libraryDependencies++=Seq(/*…*/),
generatedClassDirectory:={
//定义生成类的路径设置
val dir=target.value/“生成的类”
如果(!dir.exists)dir.mkdirs()
迪尔
},
生成类