使用 SBT 进行跨平台构建 [英] Cross platform build with SBT

查看:34
本文介绍了使用 SBT 进行跨平台构建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在测试 SBT Native Packager,我想要的结果是为每个受支持的平台提供一个本地安装程序.显然,要做到这一点,平台特定的 SBT 任务需要在该平台上运行.

I'm currently testing out SBT Native Packager and my desired result is to have a native installer for each supported platform. Obviously to do this the platform specific SBT tasks will need to run on that platform.

将使用 Atlassian 的 Bamboo 或 JetBrains 的 Team City 进行构建.

The build will either be done with Atlassian's Bamboo or JetBrains' Team City.

理想情况下,我只进行一次编译和测试,并为打包任务重用相同的工件.

Ideally I would only do the compilation and tests once and reuse the same artifacts for the packaging tasks.

用 SBT 解决这个问题的好方法是什么?

What is a good way to approach this with SBT?

我能想到的一种方法是在任何平台上进行编译和测试,然后将它们发布到本地存储库.然后包会以某种方式使用这些.但是,这也需要更改包装,使其不依赖于编译任务等.

One way I can think of is to do the compile and test on any platform and then publish these to a local repository. Then the package would use these somehow. However this would also require changing the packaging so that it doesn't depend on the compile task etc.

推荐答案

TL;DR 版本:使用单独的 sbt 项目.

TL;DR version: use separate sbt projects.

您可能已经注意到,JDKPackager 插件在各种平台上创建本地包.构建和测试主要工件一次的技巧是将它们发布到工件服务器,然后有一个单独的项目来创建安装程序.

As you probably noted, the JDKPackager plugin creates native packages on the various platforms. The trick to building and testing the primary artifacts once is to publish them to an artifact server, and then have a separate project for creating the installer.

如果您的项目每个平台只需要一个安装程序,那么您只需添加依赖项,设置 mainClass 键,然后添加 enablePlugins(JDKPackagerPlugin):

If you your project only needs one installer per platform, then all you should need to do is add the dependency, set the mainClass key, and add enablePlugins(JDKPackagerPlugin):

enablePlugins(JDKPackagerPlugin)

name := "JDKPackagerPlugin Example"

version := "0.1.0"

organization := "com.foo.bar"

libraryDependencies += "com.foo.bar" %% "myProject" % "0.1.0"

mainClass in Compile := Some("com.foo.bar.ExampleApp")

// Optional: provide application file associations
jdkPackagerAssociations := Seq(
    FileAssociation("foobar", "application/foobar", "Foobar file type"),
    FileAssociation("barbaz", "application/barbaz", "Barbaz file type", jdkAppIcon.value)
)

如果您有每个平台需要多个安装程序的场景(例如,命令行工具与 GUI),我通常会构建一个项目,使其具有一个名为packaging"的子目录,其中包含一个独立的 build.xml 文件,聚合定义每个安装程序配置的单独子项目:

If you have a scenario where you need multiple installers per platform (e.g. command-line tools vs. GUI), I typically structure a project to have a subdirectory called "packaging" with a stand-alone build.xml file, aggregating separate sub-projects defining each installer configuration:

// Settings common across subprojects. Could also do this with a 
// project-specific `AutoPlugin`
val baseSettings = Seq(
    libraryDependencies += "com.foo.bar" %% "myProject" % "0.1.0"
)

// The packaging aggregation project
lazy val packaging = project
   .in(file("."))
   .aggregate(a, b)

// Project with CLI configuration
lazy val a = Project(id = "my-project-cli", base = file("my-project-cli"))
  .settings(baseSettings: _*)

// Project with GUI configuration    
lazy val b = Project(id = "my-project-gui", base = file("my-project-gui"))
  .settings(baseSettings: _*)

// Create a task for invoking the sub-projects as needed
val packageSubs = taskKey[Seq[File]]("Build packages in subprojects")
(packageSubs in packaging) := {
  Seq(
    (packageBin.in(a, Universal)).value,
    (packageBin.in(b, JDKPackager)).value
  ) 
}

我发现像这样分解安装程序配置有助于保持依赖关系以及特定自定义的效果.

I find breaking up the installer configurations like this helps keep straight the dependencies, and effects of specific customizations.

这篇关于使用 SBT 进行跨平台构建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆