在Haskell包中使用外部版本号(Cabal)

时间:2017-08-31 07:50:12

标签: haskell cabal

我正在开发一个选择CMake作为其构建工具的项目。该项目由几个可执行文件组成,几个月前,其中一些是用Haskell编写的。我们强烈希望所有可执行文件在被称为foo --version时显示相同的版本号。理想情况下,该版本应该记录在一个地方,理想情况下该地点应该是顶级CMakeLists.txt(这是所有其他可执行文件的来源,通过使用CMake的configure_file函数获取它)。

有没有很好的方法来实现这个目标?

可能有用的一些额外信息:

  • 每个可执行文件的源代码都位于自己的目录中,并带有自己的 Cabal 文件。
  • 我们使用stack构建,并且有一个stack.yaml文件指向所有带有Haskell代码的目录。

1 个答案:

答案 0 :(得分:1)

我以为我会记录我已经落实的解决方案。

来源更改

我添加了 CPP 语言扩展,并使用宏(VERSION)在作为CPP宏提供的版本和Cabal提供的版本之间进行选择:

{-# LANGUAGE CPP #-}
module Main where

import           Data.Version
import           Text.ParserCombinators.ReadP
.... -- other imports

#ifdef VERSION
#define xstr(s) str(s)
#define str(s) #s
version = fst $ last $ readP_to_S parseVersion xstr(VERSION)
#else
import Paths_<Cabal project name> (version)
#endif

the answer to another question中解释了对双扩展( xstr str )的需求。

建筑

遗憾的是,上面的代码不会使用简单的stack build命令构建。这显然与 ghc 使用的默认CPP(/usr/bin/gcc)及其传递给它的标志有关(据我所知,罪魁祸首是-traditional)。解决方案是告诉 ghc 使用GNU CPP:

stack build --ghc-options "-pgmP=/usr/bin/cpp -DVERSION=1.2.3"

或者我把它放在我的CMakeLists.txt中(我使用ExternalProject堆栈集成到基于CMake的版本中):

ExternalProject_Add(haskell-bits
...
BUILD_COMMAND cd <SOURCE_DIR>
  && ${HaskellStack_EXE} --local-bin-path <BINARY_DIR> --install-ghc
         install --ghc-options "-pgmP=/usr/bin/cpp -DVERSION=${<CMake proj name>_VERSION}"
...
)