Как использовать стек для установки модулей Haskell, созданных локально, для глобального использования?

У меня есть локальный проект Haskell, который производит оба:

  1. двоичный исполняемый файл и
  2. несколько новых модулей Haskell, которые я хотел бы сделать доступными для других моих исполняемых файлов на основе Haskell.

После:

stack build
stack install

Я нахожу, что:

  1. двоичный исполняемый файл (№ 1 выше) прекрасно работает из любого каталога.
  2. Но новые модули Haskell (№ 2 выше) обнаруживаются только тогда, когда я запускаю их из каталога моего проекта! (То есть для любого исполняемого файла, кроме № 1 выше.)

Мне нужно иметь возможность найти новые модули из любого места. Как я могу этого добиться?


person dbanas    schedule 27.12.2017    source источник
comment
Похоже на этот вопрос всего пару часов назад, и, как и в этом случае, я бы посоветовал вам использовать Cabal-install вместо стека, тогда вам никогда не придется беспокоиться о том, чтобы сделать установку модулей глобальной.   -  person leftaroundabout    schedule 27.12.2017
comment
Спасибо за ваш комментарий. Да, установка Кабала решила мою проблему. Однако теперь у меня есть две отдельные, параллельные и в значительной степени избыточные установки Haskell, занимающие место на жестком диске, и это кажется ужасно расточительным и ненужным. Это особенно бесит, потому что двоичный исполняемый файл, который я создаю, может нормально работать из любого каталога, а это значит, что он знает, как найти мои новые модули Haskell из любой точки моей системы (поскольку он их импортирует). Итак, почему я не могу сделать эти новые модули доступными и для других исполняемых файлов Haskell?!   -  person dbanas    schedule 28.12.2017
comment
Это совершенно не нужно, поэтому я использую только Cabal-install на своем ноутбуке, а Stack только на Travis. — Обратите внимание, что способ, которым ваш исполняемый файл находит импортированные модули, сильно отличается от того, как компилятор находит их для исходного файла. На самом деле, если вы связываете статически, то нет ничего внешнего, что нужно найти, так как все уже включено в двоичный файл. Если вы выполняете динамическую компоновку, он ищет жестко запрограммированный путь к конкретному хешированному файлу динамической библиотеки, но это работает только потому, что преобразователь версий и компоновщик выполнили свою работу заранее.   -  person leftaroundabout    schedule 28.12.2017
comment
О, я понял (я думаю, возможно, вы могли бы подтвердить?): мой недавно скомпилированный исполняемый файл имел преимущество, зная, где эти пользовательские модули Haskell были расположены в моей системе во время его компиляции/компоновки. Эти другие исполняемые файлы Haskell, в которые я хотел бы иметь возможность импортировать те же самые пользовательские модули, не имели такой же роскоши, когда они были скомпилированы/слинкованы. Это оно?   -  person dbanas    schedule 30.12.2017
comment
Да все верно. Но с кабалой (не изолированной программной средой) есть один глобальный реестр пакетов, к которому имеют доступ все проекты, поэтому обычно дублирования не больше, чем необходимо.   -  person leftaroundabout    schedule 30.12.2017


Ответы (1)


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

Обратите внимание, что вы можете указать относительный путь в списке пакетов и указать на этот пакет. Он будет построен снова, но таким образом его можно будет напрямую использовать в другом проекте. Зачем дополнительное здание? У стека другая модель проектов, чем у cabal-install - она ​​не позволяет мутациям в базе данных пакетов влиять на то, как строятся ваши другие проекты.

Одним из вариантов совместного использования такого пакета является размещение его в репозитории git и использование https://docs.haskellstack.org/en/stable/custom_snapshot/ , но этот материал все еще немного новый.

person mgsloan    schedule 27.12.2017
comment
Спасибо за ответ. Итак, если я понимаю, о чем вы говорите, похоже, что модули, созданные для использования с исполняемыми файлами Haskell, которые используют динамический стиль настройки плагинов, просто не являются хорошим кандидатом для сборки/установки со стеком. Вместо этого они должны быть построены/установлены кликой. Это справедливое резюме? - person dbanas; 28.12.2017
comment
О, я не знал, что вы пытаетесь динамически загружать модули. Если вы выполняете сборку стека pkg-x в проекте, то модули будут доступны в пакетных базах данных, указанных в GHC_PACKAGE_PATH, заданном stack exec. Похоже, вам нужен более глобальный обмен, но учтите, что для работы динамических плагинов версии зависимостей должны выстраиваться в линию, поэтому это должно быть сделано в рамках одного проекта стека... Нет, вам, вероятно, не следует использовать для этого кабалу. Почти уверен, что новая сборка на самом деле сделает это немного более неудобным, потому что вам нужно будет указать конкретный идентификатор пакета. - person mgsloan; 30.12.2017
comment
Спасибо! Я хотел бы убедиться, что я понимаю: так что мне действительно нужно сделать, это перестроить этот сторонний исполняемый файл после добавления моих новых пользовательских плагинов в его описание проекта стека. Это правильно? Другими словами, попытка собрать исполняемый файл, используя один проект стека, а плагины, используя другой проект стека, по своей сути является ошибочным подходом. Если это так, то это кажется ужасно хрупким и ограничивающим для потенциальных разработчиков плагинов. Я думал, что это то, что хорошо спроектированный / документированный API (для исполняемого файла) должен был предотвратить. Я должен упустить что-то фундаментальное, здесь. - person dbanas; 30.12.2017
comment
Плагины должны быть бинарно-совместимыми, так что да, версии должны точно совпадать. Простой совместимости API недостаточно. Один из способов обойти это — загрузить плагины из исходных файлов. Если вы говорите об инструменте разработчика, который использует плагины, то должно быть возможно запустить его в одной среде стека, но использовать в другой. Вам просто нужно установить переменные среды, такие как PATH и GHC_PACKAGE_PATH, в нужные места. - person mgsloan; 03.01.2018