How can I pin a version of a Haskell dependency to a version of an underlying native dependency with Cabal?

若如初见. 提交于 2019-12-22 10:31:25

问题


In my particuar case, I have a dependency in my Cabal file on the Haskell package bindings-libzip. In particular, I could accept several different versions of libzip, e.g. bindings-libzip-0.11 or bindings-libzip-0.10. These in turn have a dependency on the respective native C libzip libraries versions 0.11 and 0.10.

Therefore I have bindings-libzip >= 0.10 < 0.12 in my .cabal file.

The Haskell package bindings-libzip-x specifies with PkgConfig-Depends that libzip version x must be present on a client machine. Let's say a downstream user has version 0.10 of libzip installed. However, when pulling down my package, this user pulls down the latest dependencies possible and transitively pulls down version 0.11 of bindings-libzip. This causes the build process to error out with a message about an incorrect version of libzip installed.

Is there any way I can specify in my .cabal file to use bindings-libzip-0.11 if and only if pkg-config detects version 0.11 of libzip and to use bindings-libzip-0.10 if and only if pkg-config detects version 0.10 of libzip?


回答1:


I'm submitting another answer because this uses another idea...

Using a custom Setup.hs with defaultMainWithHooksArgs allows you to inspect and modify the args to the cabal configure command.

This is a Setup.hs which does no modification:

import Distribution.Simple
import Distribution.Simple.Configure
import System.Environment

main = do
  args <- getArgs
  defaultMainWithHooksArgs simpleUserHooks args

If your .cabal file has a flag defined, e.g.:

Flag Foo
  Default:  False

then in the args you will see "--flags=-foo". So the idea is:

  1. Define two flags in the .cabal file - use10 and use11 to select which version of bindings-libzip to use.
  2. In your custom Setup.hs determine which version to use.
  3. Find the "--flags=..." arg and modify it appropriately before passing it along to defaultMainWithHooksArgs.



回答2:


I think the way to do this is with a custom Setup.hs file (specify build-type: Custom in the .cabal file.)

You can override specific stages of the build process by using a main like this:

main = defaultMainWithHooks $ simpleUserHooks { preConf = myPreConf }

myPreConf :: Args -> ConfigFlags -> IO HookedBuildInfo
myPreConf args configFlags = ...

It is also likely that overriding the confHook is what you want.

Some links:

  • all cabal hooks: data UserHooks
  • standard sets of hooks: (link)

Examples of custom Setup.hs files overriding 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

In particular, the hruby Setup.hs looks like it is doing something like what you want to do.



来源:https://stackoverflow.com/questions/32676638/how-can-i-pin-a-version-of-a-haskell-dependency-to-a-version-of-an-underlying-na

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!