2012-02-16 1 views
8

Представьте Makefile, как следующее:«самонастройки» с Кабал

stage1 : Stage1.hs 
     ghc -o stage1 Stage1.hs 
Stage1.hs : stage0 
     stage0 > Stage1.hs 
stage0 : Stage0.hs 
     ghc -o stage0 Stage0.hs 

Текущий каталог будет содержать Makefile и Stage0.hs в первом, и производить stage1.

Вот вопросы:

  1. Как я могу сделать выше, полностью в Кабал? Должен ли я делать это только с помощью крючков? (например, this или this.) Что делать, если крючок должен зависеть от другой программы в пакете, который будет построен?
  2. Что делать, если Setup.hs становится настолько сложным, что требует собственного управления зависимостями ?
  3. Есть ли кабальный пакет, который делает подобные вещи? Если «Счастливый» включал в себя каббализированную тестовую программу, которая зависела от «Счастливого призыва», это было бы прекрасным примером.
+1

В случае с Happy и Alex Cabal уже знает, как с ними бороться, поэтому вам просто нужно перечислить модули в «Exposed-Modules» или «Other-Modules», а Cabal будет генерировать '.hs' и автоматически их компилировать. – hammar

+0

Это правда. Возможно, я должен упомянуть [препроцессорные инструменты] (http://hackage.haskell.org/package/preprocessor-tools). – mnish

ответ

5

Кабала сложна, когда дело доходит до таких ситуаций.

Как вы сказали, если вы можете втиснуть все в Setup.hs, вы будете держать число головных болей до минимума.

Если у вас есть действительно сложные препроцессор, я бы предложил сделать это:

  1. сделать пакет один междусобойчик для каждого препроцессора, со своими зависимостями и т.д. Таким образом, для stage0, вы бы междусобойчик файл, как это:

    Name: 
        mypackage-stage0 
    Version: 
        0.1 
    -- ... 
    
    Executable mpk-stage0 
        Default-language: 
        Haskell2010 
        Main-is: 
        Stage0.hs 
        -- ... 
    
  2. для stage1, вам необходимо сгенерировать исходный код, так что добавьте preBuild крюк в вашем Setup.hs для mypackage-stage1, который запускает исполняемый mpk-stage0:

    main = 
        defaultMainWithHooks simpleUserHooks 
        { preBuild = 
         -- ... something involving `system "mpk-stage1 Stage1.hs"` 
         -- Note that shell redirection `> bla.hs` doesn't necessarily work 
         -- on all platforms, so make your `mpk-stage1` executable take an 
         -- output file argument 
        } 
    

    Вы бы затем добавить зависимость сборки-инструмента на предыдущем этапе:

    Executable mpk-stage1 
        -- ... 
        Main-is: 
        Stage1.hs 
        Build-tools: 
        mypackage-stage0 
    

    Это должно работать в последних версиях Кабал; в противном случае, возможно, вам придется добавить зависимость Build-depends:.

  3. Вы будет необходимо восстановить каждый пакет в свою очередь, каждый раз, когда вы делаете изменения каскадный (Это необходимо потому, что заговорщики не управлять изменениями зависимостей кросс-проекта), так что вам нужен скрипт, который делает for project in mypackage-stage0 mypackage-stage1; do (cd $project; cabal install); done или что-то аналогичный.

Cabal никогда не был построен для такого рода проектов, поэтому будет быть сложно, если вы хотите сделать что-то вроде этого. Вы должны изучить использование шаблона Haskell вместо этого, если вы хотите сгенерировать код более согласованным образом.

+1

Большое спасибо за ваш быстрый ответ, и я сожалею о том, что опоздал. Этот Кабал никогда не строился для такого проекта, действительно, я подозревал. FYI, моим временным решением было добавить флаг для каждого исполняемого файла и использовать мастер Makefile.am для управления компиляцией. Ваше предложение кажется улучшением, но выскакивает – mnish

+0

другие вопросы. Что делать, если я не хочу устанавливать stage0 в систему пользователя? Возможно ли зарегистрировать временный пакет локально в системе сборки? Поддерживает ли Template Haskell многоэтапное генерирование кода? Наконец, я должен написать здесь в качестве комментариев, если сам найду ответы? Или отправить другой ответ, отвечая на мой собственный вопрос? Благодаря! – mnish

+2

К сожалению, вы не можете создавать временные исполняемые файлы. Шаблон Haskell можно использовать в несколько этапов; вы можете использовать TH для генерации кода TH, который генерирует код Haskell. Если вы считаете, что ваш ответ поможет другим, вы должны отправить свой собственный ответ. – dflemstr

 Смежные вопросы

  • Нет связанных вопросов^_^