更具体地说,给定一个任意的包名称,我需要检索相同的包名称 library-dirs 可以通过以下方式获得的字段 ghc-pkg describe 来自正在运行的 Haskell 程序内部的命令。

有帮助吗?

解决方案

这是我能想出的窥视到ghc-pkg源代码。

getPkgInfos函数返回所有安装的软件包(希望包括用户已安装的包)的包定义。有了这个在你的手中,你可以检索库目录和其他包的信息。请参见的文档的的信息。

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许可证的所有内容#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])

这不遵循用户的包配置,但应该是一个开始。

向邓肯库茨上Haskell的咖啡厅或@小集团邮件列表。 (我是认真的,这是惊天动地的问题比栈溢出更好论坛)。

有时候,你必须在不同的论坛,以点人。

如果您正在使用阴谋配置和构建你的程序/库,你可以使用自动生成的Paths_ *模块。

例如,如果有一个文件foo.cabal,小集团将生成Paths_foo模块(参见其下dist/build/autogen源),其可以导入。该模块导出的函数getLibDir :: IO FilePath其中有您正在寻找的价值。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top