我即将编写一个(大部分)SWIG的C ++库包装的构建配置,可以从Scala中调用。由于Scala方面存在第三方依赖,以及大量的社区支持,我想使用sbt自动化构建。
但是,我对使swig和c ++编译步骤自动化感到有点不知所措。有没有人有过sbt驱动的混合语言构建配置的经验,可以就此提供建议吗?
到目前为止,我已经找到了sbt-sh插件,但如果可能的话,我宁愿避免直接炮轰。我还考虑过使用cmake作为驱动程序(因为cmake确实有一个swig-driver插件),并且在完成swig和c ++构建步骤之后,有一个java / scala-only构建步骤触发了cmake。
答案 0 :(得分:1)
SBT有自己的语法来执行外部进程。您可以利用此+路径查找+源代码生成。
一个粗略的例子:
lazy val invokeSwig = taskKey[Seq[File]]("invoke swig")
invokeSwig := {
s"swig -java example.i -outdir ${target.value}" !
val pathFinder = target.value ** "*.java"
pathFinder.get
}
target in invokeSwig := target.value / "swig"
sourceGenerators in Compile <+= invokeSwig
注意:我使用的是sbt v0.13.9,但这也适用于其他版本。
您必须为本机组件执行一些额外的工作。这包括编译它们以及确保它们在运行期间可用。
答案 1 :(得分:0)
不幸的是,我不认为你可以绕过一些shell脚本,因为swig是一个命令行工具。 (我还没有找到任何java包装器。)
SBT具有源生成器的概念。源生成器只不过是一个函数/任务编写(并返回)一些文件。如果你这样做,那么SBT将首先执行所有源生成器,然后再开始编译(其余的)代码。
只需确保swig将其文件输出到sourceManaged in Compile
,然后在编译期间生成的源文件在类路径中可用。
def runSwig: Seq[File] = {
import sys.process._
Seq("swig" , "param1", "param2", "..." ).!
// Somehow determine which files have been written by swig.
// I would make swig output its files to a temp directory and copy them to the source managed directory manually.
}
sourceGenerators in Compile += Def.task {
runSwig
}
我不确定C ++代码。在我自己的项目中,我使用docker交叉编译到各种平台。如果您的本机代码不经常更改,我建议不要在每次SBT编译java / scala代码时重新编译本机代码。