sbt 提供标准挂钩,用于添加源文件和资源生成任务。
源文件生成任务应该在 sourceManaged
的子目录中生成源文件,并返回生成的源文件列表。源文件生成函数(成为任务的基础)的签名通常如下所示
def makeSomeSources(base: File): Seq[File]
要添加任务的键称为 sourceGenerators
。由于我们要添加任务,而不是执行后获得的值,因此我们使用 taskValue
代替通常的 value
。sourceGenerators
应该根据生成的文件是主文件(Compile
)还是测试(Test
)源文件进行范围限定。这种基本结构如下所示
Compile / sourceGenerators += <task of type Seq[File]>.taskValue
例如,假设一个方法 def makeSomeSources(base: File): Seq[File]
,
Compile / sourceGenerators += Def.task {
makeSomeSources((Compile / sourceManaged).value / "demo")
}.taskValue
作为一个具体的示例,以下源文件生成器生成 Test.scala
应用程序对象,该对象一旦执行,就会在控制台中打印 "Hi"
Compile / sourceGenerators += Def.task {
val file = (Compile / sourceManaged).value / "demo" / "Test.scala"
IO.write(file, """object Test extends App { println("Hi") }""")
Seq(file)
}.taskValue
执行 run
将打印 "Hi"
。
> run
[info] Running Test
Hi
将 Compile
更改为 Test
以使其成为测试源文件。
注意: 为了提高构建效率,sourceGenerators
应该避免在每次调用时重新生成源文件。相反,输出应该基于输入值进行缓存,可以使用 文件跟踪系统 或使用 sbt.Tracked.{ inputChanged, outputChanged }
等手动跟踪输入值。
默认情况下,生成的源文件不会包含在打包的源文件工件中。要做到这一点,请像添加其他映射一样添加它们。请参阅 向包中添加文件。源文件生成器可以返回 Java 和 Scala 源文件的混合,它们在同一个序列中。它们将在稍后根据其扩展名进行区分。
资源生成任务应该在 resourceManaged
的子目录中生成资源,并返回生成的资源列表。与源文件生成函数类似,资源生成函数(成为任务的基础)的签名通常如下所示
def makeSomeResources(base: File): Seq[File]
要添加任务的键称为 resourceGenerators
。由于我们要添加任务,而不是执行后获得的值,因此我们使用 taskValue
代替通常的 value
。它应该根据生成的文件是主文件(Compile
)还是测试(Test
)资源进行范围限定。这种基本结构如下所示
Compile / resourceGenerators += <task of type Seq[File]>.taskValue
例如,假设一个方法 def makeSomeResources(base: File): Seq[File]
,
Compile / resourceGenerators += Def.task {
makeSomeResources((Compile / resourceManaged).value / "demo")
}.taskValue
执行 run
(或 package
,而不是 compile
)将在 resourceManaged
中添加一个名为 demo
的文件,resourceManaged
是 target/scala-*/resource_managed"
。默认情况下,生成的资源不会包含在打包的源文件工件中。要做到这一点,请像添加其他映射一样添加它们。请参阅 向包中添加文件.
作为一个具体的示例,以下代码会生成一个名为 myapp.properties
的属性文件,其中包含应用程序名称和版本
Compile / resourceGenerators += Def.task {
val file = (Compile / resourceManaged).value / "demo" / "myapp.properties"
val contents = "name=%s\nversion=%s".format(name.value,version.value)
IO.write(file, contents)
Seq(file)
}.taskValue
将 Compile
更改为 Test
以使其成为测试资源。
注意: 为了提高构建效率,resourceGenerators
应该避免在每次调用时重新生成资源文件,而是使用 sbt.Tracked.{ inputChanged, outputChanged }
等对输入值进行缓存。