2009-10-05 47 views

回答

3

下面是我可以通過偷看到ghc-pkg源代碼想出來的。

getPkgInfos函數返回所有已安裝軟件包(希望包括用戶安裝軟件包)的軟件包定義。有了這個,你可以檢索庫目錄和其他包信息。詳情請參閱the documentation

GHC_PKGCONF變量需要指向不在通常位置的系統的全局程序包配置文件。例如,ghc-pkg通過在Ubuntu中通過包裝腳本接收命令行標誌來解決此問題。

import qualified Config 
import qualified System.Info 
import Data.List 
import Distribution.InstalledPackageInfo 
import GHC.Paths 
import System.Directory 
import System.Environment 
import System.FilePath 
import System.IO.Error 

getPkgInfos :: IO [InstalledPackageInfo] 
getPkgInfos = do 
    global_conf <- 
     catch (getEnv "GHC_PKGCONF") 
       (\err -> if isDoesNotExistError err 
          then do let dir = takeDirectory $ takeDirectory ghc_pkg 
             path1 = dir </> "package.conf" 
             path2 = dir </> ".." </> ".." </> ".." 
                </> "inplace-datadir" 
                </> "package.conf" 
            exists1 <- doesFileExist path1 
            exists2 <- doesFileExist path2 
            if exists1 then return path1 
             else if exists2 then return path2 
             else ioError $ userError "Can't find package.conf" 
          else ioError err) 

    let global_conf_dir = global_conf ++ ".d" 
    global_conf_dir_exists <- doesDirectoryExist global_conf_dir 
    global_confs <- 
     if global_conf_dir_exists 
      then do files <- getDirectoryContents global_conf_dir 
        return [ global_conf_dir ++ '/' : file 
          | file <- files 
          , isSuffixOf ".conf" file] 
      else return [] 

    user_conf <- 
     try (getAppUserDataDirectory "ghc") >>= either 
      (\_ -> return []) 
      (\appdir -> do 
       let subdir = currentArch ++ '-':currentOS ++ '-':ghcVersion 
        user_conf = appdir </> subdir </> "package.conf" 
       user_exists <- doesFileExist user_conf 
       return (if user_exists then [user_conf] else [])) 

    let pkg_dbs = user_conf ++ global_confs ++ [global_conf] 
    return.concat =<< mapM ((>>= return.read).readFile) pkg_dbs 

currentArch = System.Info.arch 
currentOS = System.Info.os 
ghcVersion = Config.cProjectVersion 

我自己寫了這段代碼,但它很大程度上受ghc-pkg的啓發(有些作品逐字複製)。原始代碼是根據BSD樣式許可授權的,我認爲這可以根據cc-wiki許可證分發所有的Stackoverflow內容,但我不確定。無論如何,與其他任何事情一樣,我做了一些初步測試,似乎可行,但使用它需要您自擔風險。

+0

是的,這基本上是我寫的內容的一個更全面的版本 - 而不是隻使用一個硬編碼的'%GHC_ROOT%/ package.conf',我認爲你已經找到所有常用的。 – ephemient 2009-10-11 16:05:06

+0

我試圖找到所有ghc-pkg爲了模仿它的行爲而發現的那些。 – 2009-10-14 01:06:06

0

如果您使用cabal來配置和構建程序/庫,則可以使用自動生成的Paths_ *模塊。

例如,如果你有一個foo.cabal文件,陰謀將產生一個Paths_foo模塊(參見其dist/build/autogen下源),你可以導入。該模塊導出一個函數getLibDir :: IO FilePath,它具有您正在查找的值。

+0

感謝您的回答,但那不是我要找的。我需要檢索其他已安裝軟件包的lib目錄,而不是我自己的。 – 2009-10-05 20:30:30

1

已安裝軟件包數據庫的格式是Distribution.InstalledPackageInfo

import Distribution.InstalledPackageInfo 
import Distribution.Package 
import Distribution.Text 
import GHC.Paths 
import System 
import System.FilePath 
main = do 
    name:_ <- getArgs 
    packages <- fmap read $ readFile $ joinPath [libdir, "package.conf"] 
    let matches = filter ((PackageName name ==) . pkgName . package) packages 
    mapM_ (print . libraryDirs) (matches :: [InstalledPackageInfo_ String]) 

這不符合用戶的包配置,但應該是一個開始。

1

在haskell-cafe @或cabal郵件列表上詢問Duncan Coutts。 (我是認真的,對於Cabal問題,這是一個比堆棧溢出更好的論壇)。

有時你只需要將人員指向不同的論壇。

相關問題