1

より具体的には、任意のパッケージ名を指定すると、実行中のHaskellプログラム内からコマンドlibrary-dirsで取得できるのと同じフィールドを取得する必要があります。ghc-pkg describe

4

4 に答える 4

3

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 スタイルのライセンスの下でライセンスされていました。これは、すべての Stackoverflow コンテンツが下にある cc-wiki ライセンスの下で配布できると思いますが、よくわかりません。とにかく、私はいくつかの初期テストを行い、動作しているように見えますが、自己責任で使用してください.

于 2009-10-08T19:15:29.390 に答える
1

haskell-cafe@またはcabalメーリングリストでDuncanCouttsに質問してください。(私は真剣です。それはスタックオーバーフローよりもCabalの質問のためのより良いフォーラムです)。

時々あなたはただ人々を別のフォーラムに向けなければならない。

于 2009-10-06T03:32:15.523 に答える
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])

これはユーザーのパッケージ構成には従いませんが、開始する必要があります。

于 2009-10-05T21:21:06.020 に答える
0

プログラム/ライブラリの構成とビルドに cabal を使用している場合は、自動生成された Paths_* モジュールを使用できます。

たとえば、foo.cabalファイルがある場合、cabal はインポート可能なPaths_fooモジュール ( のソースを参照) を生成します。このモジュールは、探している値を持つdist/build/autogen関数をエクスポートします。getLibDir :: IO FilePath

于 2009-10-05T20:23:10.863 に答える