7

我遇到了这个命令序列的问题:

wget http://hackage.haskell.org/package/github-0.7.1/github-0.7.1.tar.gz
tar zxf github-0.7.1.tar.gz
cd github-0.7.1
ghci samples/Users/ShowUser.hs

我得到的错误是:

Github/Private.hs:142:0:
     error: missing binary operator before token "("

Github/Private.hs:148:0:
     error: missing binary operator before token "("
phase `C pre-processor' failed (exitcode = 1)

那是因为模块 Github/Private.hscpp在两个地方使用了指令:

#if MIN_VERSION_http_conduit(1, 9, 0)
    successOrMissing s@(Status sci _) hs cookiejar
#else
    successOrMissing s@(Status sci _) hs
#endif
      | (200 <= sci && sci < 300) || sci == 404 = Nothing
#if MIN_VERSION_http_conduit(1, 9, 0)
      | otherwise = Just $ E.toException $ StatusCodeException s hs cookiejar
#else
      | otherwise = Just $ E.toException $ StatusCodeException s hs
#endif

这些 CPP 指令似乎ghci令人窒息。但是,cabal install成功编译并安装了该软件包。使用ghci -XCPP没有帮助。

我的问题是:如何使用该包目录中的库代码运行示例程序(即samples目录中的示例程序) ?ghciGithub

我想尝试调整示例程序和库代码,所以我想在ghci.

有效的一件事是:

cabal install
cd samples
ghci Users/ShowUser.hs

但是,再一次,我宁愿不必为了测试它而安装库代码。

4

2 回答 2

11

以下命令有效:

ghci -optP-include -optPdist/build/autogen/cabal_macros.h samples/Users/ShowUser.hs

它告诉 C 预处理器读取文件dist/build/autogen/cabal_macros.h。此文件由 生成cabal build,但您可以在以下preprocessing步骤后中止它:

Resolving dependencies...
Configuring github-0.7.1...
Building github-0.7.1...
Preprocessing library github-0.7.1...
[ 1 of 24] Compiling Github.Data.Definitions ( Github/Data/Definitions.hs,    dist/build/Github/Data/Definitions.o )
^C

如果您希望在该目录中启动 ghci 时自动设置这些选项,请创建一个.ghci包含以下内容的文件:

:set -optP-include -optPdist/build/autogen/cabal_macros.h
于 2013-10-27T22:02:34.580 回答
6

问题不在于 C 预处理器本身,而是MIN_VERSION_*由 cabal 在构建时生成的宏,因此您无法在 GHCi 中获取它们。如果您只是想在不安装库的情况下使用它,阻力最小的路径是注释掉宏以及与http-conduit您当前拥有的版本不匹配的 CPP 条件分支(如果有疑问,请检查与ghc-pkg list)。


稍微更有原则的黑客将使用 CPP 来检查您是否正在使用 cabal 进行安装。假设http_conduit >= 1.9.0它可能看起来像这样:

#ifdef CABAL
#  if MIN_VERSION_http_conduit(1, 9, 0)
    successOrMissing s@(Status sci _) hs cookiejar
#  else
    successOrMissing s@(Status sci _) hs
#  endif
      | (200 <= sci && sci < 300) || sci == 404 = Nothing
#  if MIN_VERSION_http_conduit(1, 9, 0)
      | otherwise = Just $ E.toException $ StatusCodeException s hs cookiejar
#  else
      | otherwise = Just $ E.toException $ StatusCodeException s hs
#  endif
#else
    successOrMissing s@(Status sci _) hs cookiejar
      | (200 <= sci && sci < 300) || sci == 404 = Nothing
      | otherwise = Just $ E.toException $ StatusCodeException s hs cookiejar
#endif

但是,鉴于您的用例,我认为额外的步骤不值得麻烦。


为了完整起见:这个答案解释了如何在 GHCi 中使用 cabal 宏。但是,这样做需要cabal build至少运行一次。

于 2013-10-27T21:08:57.093 回答