2012-02-16 25 views
8

Hãy tưởng tượng một Makefile như sau:"Bootstrapping" với Cabal

stage1 : Stage1.hs 
     ghc -o stage1 Stage1.hs 
Stage1.hs : stage0 
     stage0 > Stage1.hs 
stage0 : Stage0.hs 
     ghc -o stage0 Stage0.hs 

Thư mục hiện tại sẽ chứa Makefile và Stage0.hs lúc đầu, và sản xuất stage1.

Dưới đây là những câu hỏi:

  1. Làm thế nào tôi có thể làm các việc trên hoàn toàn trong Cabal? Tôi có nên làm điều này chỉ với móc? (như this hoặc this.) Điều gì xảy ra nếu móc phải phụ thuộc vào chương trình khác trong gói sẽ được xây dựng?
  2. Điều gì xảy ra nếu Setup.hs trở nên phức tạp đến mức cần phải có quản lý phụ thuộc của riêng mình?
  3. Có gói cabalized thực hiện những việc tương tự không? Nếu Happy bao gồm một chương trình thử nghiệm cabalized phụ thuộc vào lời kêu gọi hạnh phúc, đó sẽ là một ví dụ hoàn hảo.
+1

Trong trường hợp của Happy và Alex, Cabal đã biết cách xử lý chúng, vì vậy bạn chỉ cần liệt kê các mô-đun trong 'Exposed-Modules' hoặc' Other-Modules' và Cabal sẽ tạo ra '.hs' tập tin và biên dịch chúng tự động. – hammar

+0

Đúng vậy. Tôi có lẽ nên đề cập đến [preprocessor-tools] (http://hackage.haskell.org/package/preprocessor-tools) để thay thế. – mnish

Trả lời

5

Cabal là khó khăn khi nói đến các tình huống như thế này.

Như bạn đã nói, nếu bạn có thể ép mọi thứ vào Setup.hs, bạn sẽ giữ số lượng cơn đau đầu bạn sẽ đạt đến mức tối thiểu.

Nếu bạn có thực sự preprocessors phức tạp, tôi sẽ đề nghị làm điều này:

  1. Hãy gói một cabal cho mỗi tiền xử lý, với sự phụ thuộc của riêng mình, vv Vì vậy, đối với stage0, bạn sẽ có một cabal nộp như thế này:

    Name: 
        mypackage-stage0 
    Version: 
        0.1 
    -- ... 
    
    Executable mpk-stage0 
        Default-language: 
        Haskell2010 
        Main-is: 
        Stage0.hs 
        -- ... 
    
  2. Đối stage1, bạn cần phải tạo ra các mã nguồn, vì vậy thêm một cái móc preBuild trongcủa bạncho mypackage-stage1 chạy các mpk-stage0 thực thi:

    main = 
        defaultMainWithHooks simpleUserHooks 
        { preBuild = 
         -- ... something involving `system "mpk-stage1 Stage1.hs"` 
         -- Note that shell redirection `> bla.hs` doesn't necessarily work 
         -- on all platforms, so make your `mpk-stage1` executable take an 
         -- output file argument 
        } 
    

    Sau đó bạn có muốn thêm một sự phụ thuộc xây dựng công cụ trên sân khấu theo thời gian:

    Executable mpk-stage1 
        -- ... 
        Main-is: 
        Stage1.hs 
        Build-tools: 
        mypackage-stage0 
    

    này nên làm việc trong các phiên bản cabal gần đây; nếu không, bạn có thể phải thêm một phụ thuộc Build-depends: để thay thế.

  3. Bạn sẽ cần phải xây dựng lại từng gói lần lượt mỗi khi bạn làm một sự thay đổi tầng (Điều này là cần thiết vì cabal không quản lý những thay đổi phụ thuộc chéo dự án), vì vậy bạn cần một kịch bản mà không for project in mypackage-stage0 mypackage-stage1; do (cd $project; cabal install); done hoặc một cái gì đó giống.

Cabal không bao giờ được xây dựng cho các loại hình dự án, vì vậy nó sẽ được khôn lanh nếu bạn muốn làm một cái gì đó như thế này. Bạn nên xem xét sử dụng mẫu Haskell thay vào đó nếu bạn muốn tạo mã theo cách mạch lạc hơn.

+1

Cảm ơn bạn rất nhiều vì đã trả lời nhanh và tôi xin lỗi vì đã đến trễ. Cabal đó không bao giờ được xây dựng cho loại dự án này thực sự là những gì tôi nghi ngờ. FYI, giải pháp tạm thời của tôi là thêm cờ vào mỗi tệp thi hành được và sử dụng Makefile.am chính để thúc đẩy quá trình biên dịch. Đề xuất của bạn có vẻ như cải thiện, nhưng bật lên – mnish

+0

các câu hỏi khác. Điều gì sẽ xảy ra nếu tôi không muốn cài đặt stage0 trong hệ thống của người dùng? Có thể đăng ký gói tạm thời cục bộ trong hệ thống xây dựng không? Mẫu Haskell có hỗ trợ tạo mã nhiều giai đoạn không? Cuối cùng, tôi có nên viết ở đây là bình luận nếu tôi tìm thấy câu trả lời cho bản thân mình không? Hoặc đăng câu trả lời khác trả lời câu hỏi của riêng tôi? Cảm ơn! – mnish

+2

Đáng buồn thay, bạn không thể thực thi tạm thời. Mẫu Haskell có thể được sử dụng trong nhiều giai đoạn; bạn có thể sử dụng TH để tạo mã TH tạo mã Haskell. Nếu bạn nghĩ rằng câu trả lời của bạn sẽ giúp người khác, bạn nên đăng câu trả lời của riêng bạn. – dflemstr

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