70

I would like my cabalised program to have a --version switch.

I would like it to report the same version as is present in the .cabal file.

If I have to update the version number separately in my Haskell source code as well as in the .cabal file, I will eventually get them out of sync.

So, how can my program, while being compiled under cabal, get its version number from the .cabal file?

Don Stewart
  • 137,316
  • 36
  • 365
  • 468
dave4420
  • 46,404
  • 6
  • 118
  • 152

1 Answers1

97

This is well supported with Cabal. As follows (from xmonad):

Import Paths_$myprogram - a file Cabal creates with lots of metadata from the .cabal file, along with a the module for handling version numbers:

import Paths_xmonad (version)
import Data.Version (showVersion)

Add a print statement to print the 'version' field provided by Paths_$myprogram:

case args of
     ["--version"] -> putStrLn ("xmonad " ++ showVersion version)

In general, Cabal's generated Paths file contains the following values, in dist/build/autogen/

version,
getBinDir, getLibDir, getDataDir, getLibexecDir,
getDataFileName
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
Don Stewart
  • 137,316
  • 36
  • 365
  • 468
  • 9
    5 years after this answer, it's worth mentioning that this works just as well under the new Stack build tool. The only difference is that the Paths file is in a location like `.stack-work/dist/x86_64-osx/Cabal-1.22.4.0/build/autogen/` (the `x86_64-osx` part changes according to your architecture). – Luis Casillas Jan 01 '16 at 00:04
  • 3
    Remember to put `Paths_$myprogram` into the "other-modules" in your .cabal to avoid "ld returned 1 exit status" – Sophie Sep 27 '16 at 19:20
  • 1
    Reading @LuisCasillas's comment above, it seems like to make this work, one needs to have a statically linked module available in the import paths. But that means that this path needs to change based on where the program is being built, right? If so, this is barely feasible in cases where your program is built across several architectures, or built remotely. – Ashesh Dec 09 '18 at 14:41
  • 3
    Note that any `-`s in your package name must be replaced with `_` in `Paths_$myprogram`. – orome Dec 09 '18 at 19:56