2013年7月6日 星期六

cabal, cabal-dev 疑難雜症處理

最近為了要設置隔離的開發環境,使用了cabal-dev。相對於把 haskell 套件安裝到系統區內,cabal-dev 會把套件安裝到另外的地方。這樣做的好處是:

  • 可以確認自己的程式可以在乾淨的環境中被建置起來
  • 有比較大的機會避開套件地獄。
    所謂套件地獄,是指兩個套件依賴了名稱相同,但版本互相衝突的套件的現象。之所以叫做地獄,是因為使用者將因為不知如何是好而狂抓頭皮(或臉頰),並且眼中浮現地獄的景色,故得其名(?)
這裡紀錄了一些遇到的問題以及我使用的解法。

cannot satisfy package ....

使用 cabal-dev 時,如果使用下面的指令:

cabal-dev install fay --enable-shared
則會出現類似下面的錯誤訊息
: cannot satisfy -package-id ansi-terminal-0.6-648cf1698c4a4e76a8187461c4376a8d
    (use -v for more information)
然而仔細檢驗可以發現該 package 確實的註冊在 ./cabal-dev/packages-x.y.z.conf/ 中。

這可能是因為 cabal 的版本太老所導致(在 1.14 版的 cabal 可以看到此錯誤)。升級到 1.16 版應該就可以解決此問題。

如果因為某些因素無法升級 cabal (例如說,這是公司的機器),那麼可以利用下面三種方法來跳過此問題:

cabal-dev install fay --enable-shared --ghc-option=-package-conf=`pwd`/cabal-dev/packages-7.4.2.conf
#(/usr/lib64/ghc-7.4.2/package.conf.d/)是 global package database 的位置,可以用 ghc-pkg list 來查看
GHC_PACKAGE_PATH=/usr/lib64/ghc-7.4.2/package.conf.d/:`pwd`/cabal-dev/packages-7.4.2.conf cabal-dev install fay --enable-shared
或是放棄建立 shared library(會失去建置 dynamic-linked executable 的能力,但有得用總比沒得用好。)

This is not a standard build!

使用 cabal-dev, 或 cabal 時,使用下面的指令來安裝執行檔:

cabal-dev install fay --enable-executable-dynamic
而且該執行檔使用了 Template Haskell 技術的話,有相當高的機會得到類似下面的錯誤訊息:
src/Test/CommandLine.hs:18:9:
    Dynamic linking required, but this is a non-standard build (eg. prof).
    You need to build the program twice: once the normal way, and then
    in the desired way using -osuf to set the object file suffix.
此錯誤訊息導因於 cabal (1.16) 在建置執行檔時沒辦法對 ghc 下達正確的建置指令序列所導致。這個錯誤似乎和 profiling 無關。利用 Template Haskell 技術的程式庫似乎不會被這個問題影響。

要解決這個問題,可以

  • 安裝尚未發行的 cabal。可以到 Cabal 的程式碼倉儲下載最新的原始碼,自行編譯。
  • 暫時放棄建置使用動態連結執行檔。反正 cabal 1.17 應該會跟著下一版的 Haskell platform 一起出來。(當然,這時候就必須忍受大到不像話的執行檔...超級大的...)

沒有留言:

張貼留言