Как настроить build-зависимости в haskell + cabal? - PullRequest
3 голосов
/ 17 сентября 2011

Мне нужно создать приложение, которое зависит от ОС. Например, я ищу по каталогу, и если я вижу, что какой-то элемент является символической ссылкой (в Linux), я просто пропускаю их и перехожу. Чтобы проверить это, я использую функцию System.Posix.Files.isSymbolicLink, которая поставляется в пакете "unix". Проблема заключается в том, что этот пакет не будет собираться в Windows, и я должен как-то обойти это ограничение, когда приложение собирается в Windows. Я попробовал этот трюк:
1) Создан дополнительный файл: ./System/Posix/Files.hs, где выставлена ​​функция isSymbolicLink , которая всегда возвращает False .
2) Обновлен файл .cabal:

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

Но, несмотря на мою конфигурацию, cabal build всегда собирает мой /System/Posix/Files.hs, так как у меня import System.Posix.Files в моем main.hs:

Предварительная обработка исполняемых файлов для 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 из 2] Компиляция Main (main.hs, dist / build / test / test-tmp / Main.o)
Связывание dist / build / test / test ...

Таким образом, даже если я собираюсь использовать Linux, приложение получает мою пустую функцию isSymbolicLink вместо функций, предоставляемых пакетом "unix". Как я могу сказать, чтобы cabal не включал этот файл и использовал модуль из пакета "unix" при сборке на linux? А может, есть какой-то другой подход к решению таких проблем?

1 Ответ

4 голосов
/ 17 сентября 2011

Эту проблему можно решить с помощью препроцессора 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: .
...