
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
Получился вот такой проект:

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

Я ожидал увидеть 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
Теперь всё скомпиллировалось и можно переходить к планированию архитектуры и тестам.
Библиография
ссылка на оригинал статьи https://habr.com/ru/post/664434/
Добавить комментарий