Cross platform build with SBT

我的未来我决定 提交于 2020-01-10 04:21:07

问题


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.

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.

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.


回答1:


TL;DR version: use separate sbt projects.

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.

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)
)

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.



来源:https://stackoverflow.com/questions/33071612/cross-platform-build-with-sbt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!