2011-11-02 28 views
31

Tôi mới sử dụng sbt. Tôi muốn nó để đặt tất cả các phụ thuộc jar bay cũng như tập tin jar của tôi vào một nơi. SBT sẽ chạy ứng dụng, nhưng tôi đã có nhiều phụ thuộc khác nhau nằm rải rác xung quanh và một thư mục .ivy chứa đầy những thứ mà tệp jar của tôi phụ thuộc gián tiếp. Vì vậy, có một lệnh đơn giản để sao chép tất cả vào một nơi duy nhất để tôi có thể phân phối nó cho một máy khác?làm cách nào để nhận được sbt thu thập tất cả các tệp jar mà mã của tôi phụ thuộc vào một địa điểm?

+3

Có, đây là nỗi đau thực sự. Có lẽ tôi đã bỏ lỡ điều gì đó nhưng tôi thực sự không hiểu tại sao đây không phải là một phần của _Simple_ Build Tool –

+0

@AlexPovar: Tôi đoán có rất nhiều cách để thực hiện việc này và chọn tiêu chuẩn hóa nó có thể gây hại (nhưng thuận tiện tôi đồng ý) . –

Trả lời

10

Tạo một nhiệm vụ trong xây dựng tập tin của bạn như thế này:

lazy val copyDependencies = TaskKey[Unit]("pack") 

def copyDepTask = copyDependencies <<= (update, crossTarget, scalaVersion) map { 
    (updateReport, out, scalaVer) => 
    updateReport.allFiles foreach { 
     srcPath => 
     val destPath = out/"lib"/srcPath.getName 
     IO.copyFile(srcPath, destPath, preserveLastModified = true) 
    } 
} 

Thêm Task để một dự án như thế này:

lazy val HubSensors = 
    Project("HubSensors", file("HubSensors"), settings = shared ++ Seq(
    copyDepTask, 
    resolvers ++= Seq(novusRels), 
    libraryDependencies ++= Seq(
     jodatime 
    ) 
)) dependsOn(HubCameraVision, JamServiceProxy, HubDAL) 

Trong giao diện điều khiển loại SBT:

project [Project Name] 
pack 
+1

Tôi thấy hai khó khăn trong cách tiếp cận này, đặc biệt với các dự án lớn: 1. Chạy _update_ trên nhiều dự án với phụ thuộc lẫn nhau sẽ sao chép cùng một .jar nhiều lần; 2. Bạn có thể có cùng sự phụ thuộc nhưng với các phiên bản riêng biệt được sao chép. Điều này xảy ra nói chung với các thư viện phổ biến, như log4j và apache-commons, bởi vì cùng một tạo phẩm được tham chiếu quá mức bởi nhiều phụ thuộc. Xem tác vụ 'đã bị đuổi' để biết thêm thông tin. Bạn có thể làm điều gì đó như (mã giả) "allFiles - bị đuổi ra khỏi", nhưng nó không quan trọng. Bạn sẽ phải đi sâu vào API SBT. –

+0

Nhưng, đối với các dự án nhỏ, cách tiếp cận của bạn sẽ hoàn toàn ổn. –

8

Thử plugin sbt-pack https://github.com/xerial/sbt-pack, thu thập tất cả các lọ phụ thuộc vào thư mục đích/gói và cũng tạo tập lệnh khởi chạy.

+3

Tôi vừa chuyển từ sbt-onejar sang sbt-pack và tôi phải nói nó rất hay: nhanh, dễ sử dụng và đáng tin cậy. –

4

Bạn cũng có thể thử SBT Native Packager: https://github.com/sbt/sbt-native-packager (SBT 0.7+)

này vẫn là một WIP nhưng sẽ được sử dụng trong Google Play Khung 2.2 trong vài tuần tới. Với điều này, bạn có thể tạo các tệp ZIP độc lập, gói Debian (DEB), các gói cài đặt Windows (MSI), DMG, RPM, v.v.

+0

Để giúp thêm một chút, với sbt-native-packager được cài đặt, người ta sẽ thực hiện 'sbt stage' để lấy các tệp trong' target/universal/stage' – akauppi

10

Thêm dòng sau vào tập tin build.sbt của bạn.

retrieveManaged := true 

này sẽ tập hợp các phụ thuộc tại địa phương

+1

Cảm ơn gợi ý. Làm thế nào bạn biết về điều này - là có một liên kết để sbt tài liệu 0.13.13 (tôi đã không tìm thấy). Nó hoạt động - 'sbt compile' tập hợp các phụ thuộc trong' lib_unmanaged/'. – akauppi

+1

Được đề cập trong http://www.scala-sbt.org/0.13/docs/Faq.html#Where+has+0.7%E2%80%99s++gone%3F – akauppi

+0

Cảm ơn rất nhiều, tôi thích cách tiếp cận này, don không muốn cấu hình cho plugin khác biệt. Tuy nhiên, nó trông giống như retrieveManaged sẽ không nhận được phụ thuộc vào thư viện java được quản lý bởi maven, nếu có giải pháp về điều đó? – carfield

Các vấn đề liên quan