如何使用 Cabal 将 Haskell 依赖项的版本固定到底层本机依赖项的版本?
How can I pin a version of a Haskell dependency to a version of an underlying native dependency with Cabal?
在我的特殊情况下,我的 Cabal 文件依赖于 Haskell 包 bindings-libzip
。特别是,我可以接受 libzip
的几个不同版本,例如bindings-libzip-0.11
或 bindings-libzip-0.10
。这些又依赖于各自的本机 C libzip
库版本 0.11
和 0.10
.
因此我的 .cabal
文件中有 bindings-libzip >= 0.10 < 0.12
。
Haskell 包 bindings-libzip-x
指定 PkgConfig-Depends
libzip
版本 x
必须存在于客户端计算机上。假设下游用户安装了 libzip
的 0.10
版本。但是,当拉下我的包时,该用户拉下了可能的最新依赖项并传递拉下了 bindings-libzip
的 0.11
版本。这会导致构建过程出错,并显示有关安装的 libzip
版本不正确的消息。
有什么方法可以在我的 .cabal 文件中指定当且仅当 pkg-config
检测到 libzip
的 0.11
版本并使用 bindings-libzip-0.10
当且仅当 pkg-config
检测到 libzip
的版本 0.10
?
我认为执行此操作的方法是使用自定义 Setup.hs
文件(在 .cabal 文件中指定 build-type: Custom
。)
您可以使用 main
覆盖构建过程的特定阶段,如下所示:
main = defaultMainWithHooks $ simpleUserHooks { preConf = myPreConf }
myPreConf :: Args -> ConfigFlags -> IO HookedBuildInfo
myPreConf args configFlags = ...
覆盖 confHook
也可能是您想要的。
一些链接:
- 所有 cabal 挂钩:
data UserHooks
- 标准挂钩组:(link)
自定义 Setup.hs 文件覆盖 confHook
的示例:
abcBridge
arb-fft
cabalmdvrpm
darkplaces-text
GLFW
happybara-webkit-server
haskeline
HDBC-postgresql
helics
hlbfgsb
hlibsass
hpqtypes
hruby
hsqml
hubris
illuminate
intel-aes
keera-posture
KiCS-debugger
libpq
llvm-general
morfeusz
postgresql-libpq
tamarin-prover
tamarin-prover-term
tamarin-prover-theory
tamarin-prover-utils
voyeur
wxc
wxcore
特别是 hruby Setup.hs 看起来它正在做您想要做的事情。
我正在提交另一个答案,因为这使用了另一个想法...
使用带有 defaultMainWithHooksArgs
的自定义 Setup.hs 允许您检查和修改 cabal configure
命令的参数。
这是一个 Setup.hs 没有修改:
import Distribution.Simple
import Distribution.Simple.Configure
import System.Environment
main = do
args <- getArgs
defaultMainWithHooksArgs simpleUserHooks args
如果您的 .cabal 文件定义了标志,例如:
Flag Foo
Default: False
然后在参数中您将看到 "--flags=-foo"
。所以思路是:
- 在 .cabal 文件中定义两个标志 -
use10
和 use11
到 select 要使用哪个版本的 bindings-libzip
。
- 在您的自定义中Setup.hs确定要使用的版本。
- 找到
"--flags=..."
arg 并在将其传递给 defaultMainWithHooksArgs
之前对其进行适当修改。
在我的特殊情况下,我的 Cabal 文件依赖于 Haskell 包 bindings-libzip
。特别是,我可以接受 libzip
的几个不同版本,例如bindings-libzip-0.11
或 bindings-libzip-0.10
。这些又依赖于各自的本机 C libzip
库版本 0.11
和 0.10
.
因此我的 .cabal
文件中有 bindings-libzip >= 0.10 < 0.12
。
Haskell 包 bindings-libzip-x
指定 PkgConfig-Depends
libzip
版本 x
必须存在于客户端计算机上。假设下游用户安装了 libzip
的 0.10
版本。但是,当拉下我的包时,该用户拉下了可能的最新依赖项并传递拉下了 bindings-libzip
的 0.11
版本。这会导致构建过程出错,并显示有关安装的 libzip
版本不正确的消息。
有什么方法可以在我的 .cabal 文件中指定当且仅当 pkg-config
检测到 libzip
的 0.11
版本并使用 bindings-libzip-0.10
当且仅当 pkg-config
检测到 libzip
的版本 0.10
?
我认为执行此操作的方法是使用自定义 Setup.hs
文件(在 .cabal 文件中指定 build-type: Custom
。)
您可以使用 main
覆盖构建过程的特定阶段,如下所示:
main = defaultMainWithHooks $ simpleUserHooks { preConf = myPreConf }
myPreConf :: Args -> ConfigFlags -> IO HookedBuildInfo
myPreConf args configFlags = ...
覆盖 confHook
也可能是您想要的。
一些链接:
- 所有 cabal 挂钩:
data UserHooks
- 标准挂钩组:(link)
自定义 Setup.hs 文件覆盖 confHook
的示例:
abcBridge arb-fft cabalmdvrpm darkplaces-text GLFW happybara-webkit-server haskeline HDBC-postgresql helics hlbfgsb hlibsass hpqtypes hruby hsqml hubris illuminate intel-aes keera-posture KiCS-debugger libpq llvm-general morfeusz postgresql-libpq tamarin-prover tamarin-prover-term tamarin-prover-theory tamarin-prover-utils voyeur wxc wxcore
特别是 hruby Setup.hs 看起来它正在做您想要做的事情。
我正在提交另一个答案,因为这使用了另一个想法...
使用带有 defaultMainWithHooksArgs
的自定义 Setup.hs 允许您检查和修改 cabal configure
命令的参数。
这是一个 Setup.hs 没有修改:
import Distribution.Simple
import Distribution.Simple.Configure
import System.Environment
main = do
args <- getArgs
defaultMainWithHooksArgs simpleUserHooks args
如果您的 .cabal 文件定义了标志,例如:
Flag Foo
Default: False
然后在参数中您将看到 "--flags=-foo"
。所以思路是:
- 在 .cabal 文件中定义两个标志 -
use10
和use11
到 select 要使用哪个版本的bindings-libzip
。 - 在您的自定义中Setup.hs确定要使用的版本。
- 找到
"--flags=..."
arg 并在将其传递给defaultMainWithHooksArgs
之前对其进行适当修改。