2017-12-27 197 views
1

我有一個本地創作Haskell的項目,這既產生:如何使用堆棧來安裝本地創作的Haskell模塊以實現全局使用?

  1. 二進制可執行文件,
  2. 幾個新的哈斯克爾模塊,我想發到我的其他訪問,哈斯克爾基礎,可執行文件。

後:

stack build 
stack install 

我發現:

  1. 二進制可執行文件(#1,以上)運行在任何目錄下就好了。
  2. 但是,新的Haskell模塊(上面#2)只有在我從我的項目目錄中運行時才能找到! (也就是說,對於除#1以外的任何可執行文件)。

我需要能夠從任何地方找到新模塊。 我該如何做到這一點?

+0

聽起來和[這個問題只有幾個小時前]類似(https://stackoverflow.com/questions/47989939/is-there-a-declarative-way-to-specify-packages-to-be-installed- into-global-proje),在那裏我建議你使用Cabal-install而不是stack,那麼你永遠不需要擔心模塊安裝是全局的。 – leftaroundabout

+0

感謝您的評論。是的,「cabal install」確實解決了我的問題。然而,現在我已經有了兩個單獨的,並行的,大部分冗餘的Haskell設備來啃硬盤空間,這看起來非常浪費和不必要。這尤其令人憤慨,因爲我生產的二進制可執行文件可以在任何目錄下運行,這意味着它知道如何從我的系統的任何地方(因爲它導入它們)找到我的新Haskell模塊。那麼,爲什麼我不能讓這些新模塊可用於其他Haskell可執行文件呢? – dbanas

+0

這絕對是不必要的,這就是爲什麼我在我的筆記本電腦上只使用_only_ Cabal-install,而僅使用Travis的Stack。 - 請注意,您的可執行文件找到導入模塊的方式與編譯器爲源文件找到它們的方式有很大不同。事實上,如果你靜態鏈接,那麼就不需要找到任何外部的東西,因爲一切都已經包含在二進制文件中了。如果您動態鏈接,它會查找特定散列動態庫文件的硬編碼路徑,但這隻適用於版本解析程序和鏈接程序在完成之前完成其工作。 – leftaroundabout

回答

1

每個堆棧項目位於其自己的沙箱中,因此編譯的模塊只能在該項目中使用。編譯的依賴項(來自堆棧快照)有時會在項目之間共享。

請注意,您可以在軟件包列表中列出相對路徑,並指向該軟件包。它會重新構建,但可以通過這種方式直接在另一個項目中使用。爲什麼多餘的建築? Stack與Cabal-install有不同的項目模型 - 它不允許包DB的變化影響其他項目的構建。

共享這樣一個包的一個選擇是讓它在git倉庫中使用https://docs.haskellstack.org/en/stable/custom_snapshot/,但這些東西還是有點新的。

+0

感謝您的迴應。所以,如果我理解你在說什麼,那聽起來像爲Haskell可執行文件構建的模塊,使用動態插件的自定義風格,並不適合用堆棧構建/安裝。相反,它們應該用cabal製造/安裝。這是一個公平的總結嗎? – dbanas

+0

哦,我沒有意識到你正在嘗試動態加載模塊。如果您在項目中執行「堆棧生成pkg-x」,那麼這些模塊將在由'stack exec'設置的GHC_PACKAGE_PATH指定的包DB中可用。這聽起來像你想要更多的全球共享,但考慮到動態插件的工作,依賴版本需要排隊,所以它應該在一個堆棧項目內完成...... 不,你可能不應該使用cabal for這個。很確定新構建的東西實際上會讓這個更笨拙,因爲你需要指定一個特定的軟件包編號 – mgsloan

+0

謝謝!我想確保我明白了:所以,我真正需要做的是在將新的自定義插件添加到其堆棧項目描述之後,重新生成此「外部」可執行文件。是對的嗎?換句話說,嘗試構建可執行文件,使用一個堆棧項目和插件,使用不同的堆棧項目,這是一種固有的缺陷。如果這是正確的,那麼潛在的插件開發人員似乎非常脆弱和限制。我認爲這是一個設計良好的/有記錄的API(可執行文件)旨在防止的。我必須在這裏錯過一些基本的東西。 – dbanas