必要なすべてのライブラリ (scala-library.jar) をメイン パッケージにパッケージ化するように sbt に指示して、スタンドアロンにする方法はありますか? (静的?)
5 に答える
編集 2011:
それ以来、retronym ( 2010 年にこのページに回答を投稿した) は、このsbt-plugin "sbt-onejar"を作成し、現在はGitHub の新しいアドレスにあり、ドキュメントは SBT 0.12 用に更新されています。
One-JAR™を使用してプロジェクトをパッケージ化</a>
onejar-sbtすべてのコードと依存関係をネストされた JAR として含む単一の実行可能 JAR をビルドするための simple-build-tool プラグインです。
現在、One-JAR バージョン 0.9.7 が使用されています。これはプラグインに含まれており、個別にダウンロードする必要はありません。
元の答え:
直接的には、これは sbt ( 「パッケージ」 sbt アクションのモデルの後のカスタム アクション) を拡張しないと不可能です。
GitHub は、桟橋の展開用にカスタム作成されたアセンブリ タスクについて言及しています。ただし、必要に応じて調整できます。
コードはかなり一般的です(この投稿とユーザー Rio から):
project / build / AssemblyProject.scala
import sbt._
trait AssemblyProject extends BasicScalaProject
{
def assemblyExclude(base: PathFinder) = base / "META-INF" ** "*"
def assemblyOutputPath = outputPath / assemblyJarName
def assemblyJarName = artifactID + "-assembly-" + version + ".jar"
def assemblyTemporaryPath = outputPath / "assembly-libs"
def assemblyClasspath = runClasspath
def assemblyExtraJars = mainDependencies.scalaJars
def assemblyPaths(tempDir: Path, classpath: PathFinder, extraJars: PathFinder, exclude: PathFinder => PathFinder) =
{
val (libs, directories) = classpath.get.toList.partition(ClasspathUtilities.isArchive)
for(jar <- extraJars.get ++ libs) FileUtilities.unzip(jar, tempDir, log).left.foreach(error)
val base = (Path.lazyPathFinder(tempDir :: directories) ##)
(descendents(base, "*") --- exclude(base)).get
}
lazy val assembly = assemblyTask(assemblyTemporaryPath, assemblyClasspath, assemblyExtraJars, assemblyExclude) dependsOn(compile)
def assemblyTask(tempDir: Path, classpath: PathFinder, extraJars: PathFinder, exclude: PathFinder => PathFinder) =
packageTask(Path.lazyPathFinder(assemblyPaths(tempDir, classpath, extraJars, exclude)), assemblyOutputPath, packageOptions)
}
少し手間がかかりますが、 SBT 内からProguardを使用してスタンドアロン JAR を作成することもできます。
私は最近、Scalala の SBT ビルドでこれを行いました。
最も簡単な方法は、コマンド ラインから jar を作成することです。これを行う方法がわからない場合は、そうすることを強くお勧めします。自動化は便利ですが、自動化が何をしているのかを知っていれば、はるかに優れています。
実行可能な jar の作成を自動化する最も簡単な方法は、Windows で bash スクリプトまたはバッチ スクリプトを使用することです。
sbt で最も簡単な方法は、必要な Scala ライブラリをリソース ディレクトリに追加することです。
unmanagedResourceDirectories in Compile := Seq(file("/sdat/bins/ScalaCurrent/lib/scalaClasses"))
したがって、私の環境では ScalaCurrent は現在の Scala ライブラリへのリンクです。執筆時点では 2.11.4。重要な点は、Scala ライブラリーを抽出して、ScalaClassses ディレクトリー内に配置することです。抽出された各ライブラリは、その最上位ディレクトリに移動する必要があります。
上で @retronym が提供したものに基づいて、Proguard と sbt を使用して、Scala ライブラリ (つまり scala-library.jar) を含むスタンドアロンの jar をビルドする簡単な例を作成しました。ありがとう、レトロニム。
sbt-assemblyを使用した最も単純な例
ファイル assembly.sbt を含むディレクトリ プロジェクトをホーム プロジェクト dir に作成します。
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
ファイルbuild.sbtで
import AssemblyKeys._ // これをファイルの先頭に置きます
アセンブリ設定
jarName += "Mmyjarnameall.jar"
libraryDependencies ++= Seq( "exmpleofmydependency % "mydep" % "0.1" )
アセンブリ内の mergeStrategy <<= (アセンブリ内の mergeStrategy) { (古い) =>
{
case s if s.endsWith(".class") => MergeStrategy.last
case s if s.endsWith("pom.xml") => MergeStrategy.last
case s if s.endsWith("pom.properties") => MergeStrategy.last
ケース x => 古い (x)
}
}