2013-08-20 6 views
3

다중 프로젝트 SBT 빌드에서 SBT 어셈블리의 mainClass 속성을 어떻게 명시 적으로 억제해야합니까?SBT 어셈블리에서 메인 클래스를 표시하지 않음

광범위하게 검색했지만 다중 프로젝트 빌드에서 sbt-assembly로 빌드 된 jar에서 메인 클래스가 설정되지 않도록하는 방법을 찾을 수 없습니다. 단일 프로젝트 빌드에서

, 이것은 한 잠재적 명령 행 호출 할 수있는 적어도 두 개의 클래스가로 작동하는 것 같다 그러나

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이하지 않은 것 같습니다 심지어 필요합니다. 사실, 거기에 남겨 지더라도 후보 클래스가 하나만 있으면 메인 클래스가 여전히 매니페스트에 설정됩니다.

다중 프로젝트 빌드에서 추가 클래스를 더미 진입 점으로 포함하여 기본 클래스가 설정되는 것을 방지 할 수 없었습니다.

많은 비웃음을 한 후, 여러 범위에서 독립적으로 mainClassNone으로 설정하여 기본 클래스가 설정되는 것을 방지 할 수 있음을 발견했습니다. 특히, 이것은 트릭을 수행합니다 :

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

이 요구 사항은 설명서에 나와 있지 않으며 필요한 이유를 찾을 수 없습니다. mainClass in (Compile, run) := None 설정이 작동하지 않습니다. 그것들은 실제로 개별적으로 스코프되어야합니다.

수동으로 기본 클래스를 숨기는 적절한 방법입니까, 아니면 누락 된 것입니까? 버그가 아니었다면, 어딘가에 문서화되어야한다고 생각합니다. 특히 단일 및 다중 프로젝트 빌드간에 동작이 일관성이 없다는 점을 고려할 때.

답변

4

Main-Class와 항아리에 다른 모든 속성은 궁극적으로 다음과 같이하여 모든 당신이 그것에서 Package.MainClass을 제거 할 수 있습니다, packageOptions in assembly에 의해 결정됩니다

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을 호출하여 캐시를 지울 필요가 있습니다.