Cabal не может найти локально поставленные (но правильно установленные) пакеты - PullRequest
3 голосов
/ 12 марта 2020

Я недавно обновился до Cabal 3.2 (и GH C 8.10), и я столкнулся с некоторыми серьезными проблемами, из-за которых некоторые из моих проектов больше не могут быть собраны ...

Подробное описание проблемы

Вот минимальная (не) рабочая конфигурация, которая каждый раз дает сбой:

  1. Я начинаю с чистой конфигурации Cabal (удаляя ~/.cabal); причина этого появится позже в посте. Я запускаю cabal update, чтобы воссоздать каталог .cabal и убедиться, что Cabal работает.

  2. Я создаю проект (назовем его test1), используя cabal init. Это библиотечный проект с одним открытым модулем (условно названным Test1), который экспортирует некоторую фиктивную функцию foo. Я бегу cabal build, затем cabal install --lib; все работает нормально, пока все хорошо.

  3. Просто чтобы быть уверенным, я покидаю каталог проекта и запускаю GHCi. Я набираю :m Test1, чтобы загрузить модуль, который я создал ранее, и он работает! Я могу набрать foo ... и посмотреть, как выполняется моя функция. Кроме того, я перечисляю содержимое ~/.cabal/store/ghc-8.10.xxx и вижу, что там находится каталог test1-xxx.

  4. Затем я создаю новый проект, test2, все еще используя cabal init. На этот раз я настраиваю его как исполняемый файл и добавляю test1 в качестве зависимости (используя поле build-depends). Но на этот раз, когда я запускаю cabal build, я сталкиваюсь с некоторой проблемой:

~/projects/haskell/test2> cabal build
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: test2-0.1.0.0 (user goal)
[__1] unknown package: test1 (dependency of test2)
[__1] fail (backjumping, conflict set: test1, test2)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: test2, test1

Мне кажется, что пакет test1 не может быть найден, однако я могу получить к нему доступ из GHCi (и GH C в этом отношении), и он присутствует в ~/.cabal/store ...

Но, к сожалению, есть и другие.

Я создаю третий проект, test3. Это библиотека, и она зависит только от base (поэтому, в частности, не зависит от test1). Библиотека предоставляет один модуль, Test3, с одной экспортированной функцией, bar. Я бегу cabal build, здесь нет проблем. Но когда я хочу установить test3 с cabal install --lib, я сталкиваюсь с некоторыми ошибками:
~/projects/haskell/test3> cabal install --lib
Wrote tarball sdist to
/home/<user>/projects/haskell/test3/dist-newstyle/sdist/test3-0.1.0.0.tar.gz
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] unknown package: test1 (user goal)
[__0] fail (backjumping, conflict set: test1)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: test1

Кажется, что он не может найти test1, хотя он был установлен правильно; может быть, это остаток неудачной сборки test2, хотя ...

Просто чтобы быть уверенным, я запускаю GHCi и набираю :m Test3, но GHCi говорит мне, что не может найти модуль Test3 (и даже предполагает, что это опечатка, и я имел в виду Test1) , показывая, что test3 действительно не был установлен, хотя он был успешно собран ...

Хорошо, есть еще одна особенность всей этой ситуации: я снова создаю новый проект с cabal init, называемым test4, который является исполняемым файлом, который (опять же) зависит только от base. Я сохраняю значение по умолчанию Main.hs (которое просто печатает «Hello, Haskell!»). Я бегу cabal build: нет проблем. Затем я запускаю cabal install и ... Нет проблем? Я запускаю test4 в случайном месте, и он запускает исполняемый файл, выводя «Hello, Haskell!» в терминале ...

И еще одна вещь: я go в случайном месте и запускаю cabal install xxx --lib, где xxx - это пакет библиотеки, доступный в Hackage (например, xml) и:

~> cabal install xml --lib
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] unknown package: test1 (user goal)
[__0] fail (backjumping, conflict set: test1)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: test1

Это причина, почему мне нужно регулярно обстреливать .cabal ... Прямо сейчас я, кажется, в какой-то устаревшее состояние, в котором я больше не могу устанавливать библиотеки.

Техническая конфигурация и примечания

Я использую Cabal 3.2.0.0 и GH C 8.10.0.20200123. Я установил их с hvr / gh c PPA и убедился, что на моем компьютере нет других версий этих инструментов.

Как примечание, я использую Ubuntu 18.04.4 LTS ( с XFCE так XUbuntu, если быть точным). Все остальное (кажется, похоже) обновлено.

Последнее, что касается файлов *.cabal, которые я использую для сборки, они в значительной степени сгенерированы cabal init, за исключением того, что я переключаю executable xxx для library в случае библиотек, и я просто добавляю поле exposed-modules для отображения модулей для библиотек (поэтому Test1 для test1 и Test3 для test3 соответственно). Я также использую build-depends в test2, чтобы проект зависел от test1. Кроме того, они в значительной степени остались нетронутыми.

Заметки и мысли

Я должен признаться, что я новичок в Кабале 3; до прошлой недели я использовал Cabal 1 (потому что никогда не обновлял его; да, я знаю, что это плохо). С Cabal 1 у меня не было никаких проблем, и я прекрасно смог установить пакет из локальных источников и зависеть от него в других проектах ...

Я чувствую, что делаю что-то не так; возможно я не использую правильные команды Кабала? Я где-то видел что-то про cabal new-build и cabal new-install, но, похоже, он не делает ничего, кроме cabal build и cabal install, по крайней мере, в моем случае. Я также хотел исследовать песочницы, но, похоже, он исчез со второй версии Cabal.

Существует также небольшая вероятность того, что это ошибка Cabal, но я не вижу какой-либо соответствующей проблемы в трекере ошибок, которая может быть связано с моей проблемой ...

Что вы думаете об этом? Что я делаю неправильно? Видите ли вы какие-либо альтернативы или возможные исправления?

Большое спасибо!

1 Ответ

3 голосов
/ 12 марта 2020

GH C файлы среды

Установка GH C поставляется с определенным количеством пакетов из коробки . base является одним из них, но есть и другие, например text . Если вы устанавливаете GH C в одиночку (без каббалы или стека) и открываете ghci, это должно позволить вам import Data.Text без проблем.

Что если вы хотите, чтобы GH C или ghci знали о других скомпилированных пакеты в вашей файловой системе? Вы можете указать GH C на дополнительные базы данных пакетов , используя флаги командной строки , но также существует концепция файлов среды пакета .

Среды - это простые текстовые файлы, которые содержат список связанных с пакетом флагов GH C. В ~/.ghc/$ARCH-$OS-$GHCVER/environments/default может существовать глобальная среда, а также могут существовать локальные среды, которые влияют только на команды GH C и ghci, вызываемые внутри одной и той же папки. точные правила поиска описаны в Руководстве пользователя GH C.

Что на самом деле делает cabal install --lib ?

По умолчанию он изменяет файл среды global , так что GH C и ghci теперь могут найти эту библиотеку. Вот почему пункт 3) работал. Фактически скомпилированные двоичные файлы библиотеки все еще находятся в хранилище cabal.

Мы также можем создавать локальные файлы среды. Например, cabal install sop-core --lib --package-env . создаст файл среды .ghc.environment.xxx в текущей папке, и библиотека будет доступна для gh c и ghci, когда они там будут вызваны.

Почему test1 недоступен для test2?

Современная кабальная система делает различие между локальными пакетами и внешними пакетами .

  • локальными пакетами - это набор пакетов, которыми вы являетесь развивается вместе в проекте, редактируется, перекомпилируется и неоднократно изменяется. Они построены «на месте» и не видны за пределами проекта. Они могут зависеть друг от друга.
  • внешние пакеты - это зависимости от build-depends:, исходный код которых загружен из репозитория пакетов и которые после компиляции помещаются в хранилище cabal, чтобы другие проекты Cabal могут использовать их без перекомпиляции.

Список локальных пакетов и другие подробности конфигурации уровня проекта указаны в файле cabal.project . Но он вам не нужен, если вы работаете с одним изолированным пакетом; по умолчанию список пакетов просто ./*.cabal.

. cabal хочет полностью контролировать среду сборки локальных пакетов и игнорирует файл глобальной среды. В вашем случае вам придется создавать локальные пакеты test1 и test2 в одном проекте (вероятно, лучший вариант) или publi sh test1 и обрабатывать его как внешний пакет.

Обратите внимание, что "cabal project" «Это понятие актуально только при разработке. Пакеты публикуются независимо, в Hackage или других репозиториях нет «проектов», только пакеты.

Что если я хочу рассматривать test1 как внешний, не публикуя его в Hackage?

У вас будет установить локальный репозиторий пакетов , в основном не публиковать c Hackage.

Вы можете сообщить Cabal о дополнительных репозиториях пакетов в файле конфигурации Cabal, то есть файл, который настраивает сам себя. Его местоположение указано в последней строке cabal --help.

Но как настроить хранилище? hackage-repo-tool может помочь с этим.

Почему test3 провалился? Почему дальнейшая установка библиотеки не удалась?

Это странно, я понятия не имею, почему это происходит. Вы случайно удалили папку ~/.cabal между шагами 3) и 5) ? Что произойдет, если вы удалите файл глобальной среды GH C и повторите попытку?

...