2009-10-05 56 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问题,这是一个比堆栈溢出更好的论坛)。

有时你只需要将人员指向不同的论坛。

相关问题