有没有简单的方法,但它是可能的。
假设您使用的是Distribution.Simple,您基本上需要将一个用户挂钩添加到构建阶段。
以下更改都需要出现在Setup.hs:
变化主要使用构建挂钩,是这样的:
main :: IO()
main = defaultMainWithHooks simpleUserHooks { buildHook = myBuildHook }
接下来你需要构建钩。它可能会看起来像以下:
myBuildHook pkg_descr local_bld_info user_hooks bld_flags =
do
let lib = fromJust (library pkg_descr)
lib_bi = libBuildInfo lib
custom_bi = customFieldsBI lib_bi
cpp_name = fromJust (lookup "x-cc-name" custom_bi)
c_srcs = cSources lib_bi
cc_opts = ccOptions lib_bi
inc_dirs = includeDirs lib_bi
lib_dirs = extraLibDirs lib_bi
bld_dir = buildDir local_bld_info
-- Compile C/C++ sources
putStrLn "invoking my compile phase"
objs <- mapM (compileCxx cpp_name cc_opts inc_dirs bld_dir) c_srcs
-- Remove C/C++ source code from the hooked build (don't change libs)
let lib_bi' = lib_bi { cSources = [] }
lib' = lib { libBuildInfo = lib_bi' }
pkg_descr' = pkg_descr { library = Just lib' }
-- The following line invokes the standard build behaviour
putStrLn "Invoke default build hook"
bh <- buildHook simpleUserHooks pkg_descr' local_bld_info user_hooks bld_flags
return bh
上面大概需要拆包位的代码。 let子句基本上是从传递给构建钩子的结构中解压所需的数据字段。请注意,您可以在foo.cabal中创建自定义节。我已经提供了代码来支持类似这样的节:
x-cc-name: icc
作为一种手段来指定您的编译器。在提取所有源文件后,可以使用函数来映射它们以编译单个文件(注意:在某些情况下,这是次优的,例如那些可以高效编译多个源文件以产生单个对象输出和利益的编译器从大规模的优化,但我们会暂时搁置)。
所有的最后,因为我们现在已经编制了C/C++代码,你到默认的编译钩通过之前的一切从构建结构中删除。
对不起,这是一个多罐装回答了“HOWTO”,但它应该帮助你走了。
我应该提到代码是未经测试的。我已经从我在wxHaskell构建系统上做的一些工作中适应了它,所以我知道这个想法工作正常。Cabal API实际上有很好的文档记录 - 主要受这些区域的某些不稳定性影响。
是的。有一个[github上的#1325问题](https://github.com/haskell/cabal/issues/1325):) – ony 2015-01-09 12:00:43