如何在haskell + cabal中配置构建依赖项?

时间:2011-09-17 18:38:59

标签: haskell cabal

我必须构建一些依赖于操作系统的应用程序。例如,我正在搜索目录,如果我看到一些项目是符号链接(在linux中),我只是跳过它们然后继续。为了检查这个,我使用“unix”包附带的函数System.Posix.Files.isSymbolicLink。问题是这个软件包不能在Windows上构建,当我在Windows上构建应用程序时,我必须以某种方式绕过这个限制。我试过这个伎俩:
1)创建了附加文件:./ System /Posix / File.hs,其中公开函数 isSymbolicLink ,它总是返回 False
2)更新了.cabal文件,包括以下内容:

if os(windows)
    other-modules: System.Posix.Files
else
    build-depends: unix

但是,尽管我的配置, cabal build 总是构建我的/System/Posix/Files.hs,因为我在main.hs中导入System.Posix.Files

  

预处理test-1.1.1的可执行文件...
  建筑测试-1.1.1 ...
  [1/2]编译System.Posix.Files(System / Posix / Files.hs,dist / build / test / test-tmp / System / Posix / Files.o)
  [2 of 2]编译Main(main.hs,dist / build / test / test-tmp / Main.o)
  链接dist / build / test / test ...

所以即使我在linux上构建,应用程序也会获得我的空白 isSymbolicLink 函数,而不是“unix”包提供的函数。我如何告诉cabal不包含这个文件,并在我构建linux时使用“unix”包提供的模块?或者也许有另一种方法可以解决这些问题?

1 个答案:

答案 0 :(得分:4)

这可以使用CPP预处理器来解决。

.cabal文件中,添加

if os(windows)
  Cpp-options: -DWINDOWS
else
  Build-depends: unix

然后添加一个模块,该模块将有条件地从isSymbolicLink包中导出unix,或者为Windows添加虚拟模块。

{-# LANGUAGE CPP #-}
module Compatibility (isSymbolicLink) where

#ifndef WINDOWS
import System.Posix.Files
#else
isSymbolicLink _ = return False
#endif

现在只要你需要使用这个功能就可以导入这个模块,你应该好好去。


另一种选择是坚持使用您的初始方法,但将System/Posix/Files.hs移到您有条件添加到Hs-Source-Dirs的子目录中。

if os(windows)
  Other-modules: System.Posix.Files
  -- Assuming you moved it to windows/System/Posix/Files.hs
  Hs-source-dirs: .,windows    
else
  Build-depends: unix
  Hs-Source-Dirs: .