stack — это утилита для сборки проекта на языке haskell.

Чтобы разобраться с haskell, я решил переписать свой транслитератор клавиатурного ввода erswitcher на этом языке.

Вначале всё шло отлично. Я установил stask и компиллятор ghc:

# pacman -S stack ghc

И указал stack-y использовать системный ghc:

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 9.0.2

$ stack setup --system-ghc --resolver ltc-9.0.2

Создал проект:

$ stack new erswitcher
$ mv erswitcher erswitcher-2

Получился вот такой проект:

Рис.1. Структура проекта созданного по дефолтному шаблону.
Рис.1. Структура проекта созданного по дефолтному шаблону.

Пробежавшись по файлам я выяснил, что package.yaml используется для указания опций компилятора для сборки исполняемых файлов и юнит-тестов. Так же там прописан автор, лицензия и прочая информация для создания и публикации проекта на hackage.haskell.org. При каждом запуске stack на его основе генерирует файл <проект>.cabal.

Ошибка "Не найден модуль Prelude"

Однако при компилляции выскочила ошибка:

Рис.2. Ошибка во время сборки проекта.
Рис.2. Ошибка во время сборки проекта.

Я ожидал увидеть import Distribution.Simple в app/Main.hs или src/Lib.hs, но поиск по проекту указал на Setup.hs. Я удалил содержимое Setup.hs и... осталась та же ошибка. При этом пакет distributive с библиотекой Distribution.Simple был установлен:

$ ghc-pkg list | grep dist
    distributive-0.6.2.1

$ stack install distribution так же ругнулся, что версии зависимостей у distribution не подходят.

Оказалось, что нужно просто установить ghc-static, так как собирать бинарники с динамической линковкой stack не позволяет, даже если прописать опцию -dynamic в package.yaml:

# pacman -S ghc-static

Модуль Main в app/Main.hs нельзя переименовать

Дальше я перетиеновал модуль app/Main.hs на app/Erswitcher.hs. Соответственно и в файле изменил название модуля:

module Erswitcher where

import Lib

main :: IO ()
main = someFunc

В package.yaml заменил название модуля соответственно:

executables:
  erswitcher-exe:
    main:                Erswitcher.hs
    source-dirs:         app
    ghc-options:
    - -dynamic
    - -threaded
    - -rtsopts
    - -with-rtsopts=-N
    dependencies:
    - erswitcher

Это привело к ошибке:

<no location info>: error:
    output was redirected with -o, but no output will be generated
because there is no Main module.

Оказывается, исходный файл бинарника может называться как угодно, а пакет в нём нужно называть всегда Main:

module Main where

import Lib

main :: IO ()
main = someFunc

Теперь всё скомпиллировалось и можно переходить к планированию архитектуры и тестам.

Библиография

  1. Установка и настройка haskell в Arhlinux.

  2. R2AUK „Сборка проектов на Haskell при помощи Stack”.

  3. Darviarush „Транслитератор текста и переключатель клавиатуры на haskell”.

  4. Darviarush „Транслитератор текста и переключатель клавиатуры”.

Комментарии (1)


  1. includedlibrary
    07.05.2022 10:32
    +1

    В чём смысл статьи? Официальная документация раскрывает вопросы конфигурации и использования stack куда лучше. В статье же я смог найти только установку stack на arch, которая тоже крайне хорошо расписана на archwiki.

    Оказалось, что нужно просто установить ghc-static, так как собирать бинарники с динамической линковкой stack не позволяет

    Таки позволяет

    Есть ещё самый простой способ установки на арч - использовать официальный бинарник отсюда и позволить ему самому установить нужную версию ghc для вашего проекта. На этот случай есть скрипт, который сам качает stack и делает пакет для арча.