3

マルチプロジェクト SBT ビルドでは、SBT アセンブリで mainClass 属性を明示的に抑制するにはどうすればよいですか?

私は広範囲に検索しましたが、マルチプロジェクトビルドで sbt-assembly によってビルドされた jar にメインクラスが設定されないようにする方法を見つけることができないようです。

単一プロジェクトのビルドでは、コマンド ラインによって呼び出される可能性のあるクラスが少なくとも 2 つある限り、これは機能するようです。

import sbt._
import Keys._

import sbtassembly.Plugin._
import sbtassembly.AssemblyUtils._
import AssemblyKeys._

object TestBuild extends Build {
  lazy val buildSettings = Defaults.defaultSettings ++ assemblySettings ++ Seq(
    version := "0.1-SNAPSHOT",
    organization := "com.organization",
    scalaVersion := "2.10.2",
    mergeStrategy in assembly := mergeFirst
  )

  lazy val root = Project(id = "test-assembly",
    base = file("."),
    settings = buildSettings) settings(
    mainClass in assembly := None
  )
  lazy val mergeFirst: String => MergeStrategy = { 
    case "reference.conf" | "rootdoc.txt" => MergeStrategy.concat
    case PathList("META-INF", xs @ _*) =>
    (xs map {_.toLowerCase}) match {
      case ("manifest.mf" :: Nil) | ("index.list" :: Nil) | ("dependencies" :: Nil) =>
      MergeStrategy.discard
      case ps @ (x :: xs) if ps.last.endsWith(".sf") || ps.last.endsWith(".dsa") =>
      MergeStrategy.discard
      case "plexus" :: xs =>
      MergeStrategy.discard
      case "services" :: xs =>
      MergeStrategy.filterDistinctLines
      case ("spring.schemas" :: Nil) | ("spring.handlers" :: Nil) =>
      MergeStrategy.filterDistinctLines
      case _ => MergeStrategy.first
    }
    case _ => MergeStrategy.first
  }
}

ただし、mainClass := None必要さえないようです。実際、そこに残っていても、候補クラスが 1 つしかない場合は、マニフェストにメイン クラスが設定されます。

残念ながら、マルチプロジェクト ビルドでは、追加のクラスをダミーのエントリ ポイントとして含めても、メイン クラスが設定されるのを防ぐことはできませんでした。

いろいろいじった後、いくつかのスコープを個別に設定mainClassすることで、メインクラスが設定されないようにすることができることがわかりました。None特に、これはトリックを行います:

mainClass in assembly := None
mainClass in packageBin := None
nainClass in Compile := None
mainClass in run := None

ドキュメントに記載されているこの要件を見つけることができず、なぜこれが必要なのかわかりません。設定がうまくいきmainClass in (Compile, run) := Noneません。それらは実際には個別にスコープする必要があります。

これは、メイン クラスを手動で抑制する適切な方法ですか、それとも何か不足していますか? バグでない場合、これはどこかに文書化する必要があると思います。特に、シングル プロジェクト ビルドとマルチ プロジェクト ビルドの間で動作が一貫していないことを考えると。

4

1 に答える 1

4

Main-Classjar 内の他のすべての属性は最終的に によって決定されるため、次のようにpackageOptions in assembly削除できます。Package.MainClass

lazy val root = Project(id = "test-assembly",
  base = file("."),
  settings = buildSettings) settings(
  packageOptions in assembly ~= { os => os filterNot {_.isInstanceOf[Package.MainClass]} }
)

これは、マルチプロジェクト ビルドでも機能するはずです。

注: sbt-assembly は、ソース入力のメタデータに基づいて出力 jar をキャッシュするため、設定をテストするにassemblyは、 を呼び出してキャッシュをクリアする必要がありますclean

于 2013-08-20T07:31:15.430 に答える