nix-shell как #! переводчик для runghc

Я пытаюсь использовать nix-shell как #! оболочка для runghc, как это предлагается на странице руководства. Но не может найти библиотеки. В следующем примере вырезано из справочной страницы

#! /usr/bin/env nix-shell
#! nix-shell -i runghc -p haskellPackages.HTTP

import Network.HTTP

main = return ()

Получаю такой результат:

[~:0]$ ./nixshelltest 

nixshelltest:4:1: error:
    Failed to load interface for ‘Network.HTTP’
    Use -v to see a list of the files searched for.
[~:1]$ 

на мой взгляд, именно этого следует избегать при использовании nix-shell -p.

Я что-то делаю не так, упускаю суть или есть ошибка? Это как на хосте nixOS 17.03, так и на хосте с nix 17.09 поверх Ubuntu.

Спасибо,


person user3416536    schedule 10.07.2017    source источник


Ответы (1)


В среде, которую вы используете для запуска сценария, отсутствует шаг. У него есть пакет GHC и HTTP, но компилятор не знает о пакете.

То, как GHC и пакеты библиотек работают в nix, может быть немного "наизнанку" от того, что вы ожидаете. На самом деле вам нужно установить компилятор, который "зависит" от всех нужных вам библиотек, а не просто устанавливать компилятор и библиотеку по отдельности. Причина в том, что GHC предназначен для добавления пакетов библиотек путем изменения дерева файлов, в котором установлен GHC. В изменяемой файловой системе с установленной только одной системой GHC вы просто изменяете GHC всякий раз, когда была установлена ​​библиотека, но nix не может. Nix должен иметь возможность установить замороженный GHC, который никогда не изменяется, и, возможно, многие из них.

Вместо этого вы устанавливаете крошечную оболочку, которая зависит как от базовой «сырой» установки GHC , так и от всех библиотек, которые вы хотите использовать. Затем оболочка действует как установка GHC, в которой были зарегистрированы эти библиотеки, без необходимости дублировать всю установку GHC. Когда вы просто устанавливаете пакет библиотеки сам по себе, он просто остается там инертным, и ни один GHC не может найти его просто по тому, что он существует.

Фактически, сценарий, который вы здесь показали, на самом деле не указывает, что в нем вообще должен быть установлен компилятор; он просто запрашивает HTTP библиотеку. Когда я попробовал ваш сценарий, я получил command not found: runghc. runghc работает только в вашей системе, потому что он уже был на вашем пути, когда вы запускали это (возможно, потому, что у вас установлен GHC в вашем профиле?), И этот GHC не был установлен с пакетом HTTP и поэтому не может видеть это. nix-shell добавление только библиотеки в среду не помогает.

Вместо этого вам нужно использовать эту строку:

#! nix-shell -i runghc -p "ghc.withPackages (ps: [ ps.HTTP ])"

Вы не устанавливаете ни ghc, ни HTTP напрямую; вместо этого функция ghc.withPackages вычисляет пакет nix, который устанавливает оболочку GHC, которая знает о пакете HTTP Haskell. Под капотом это зависит от "сырого" GHC без дополнительных библиотек, а также от библиотеки HTTP, и они тоже будут установлены.

Если вы используете множество различных сред Haskell (возможно, с помощью таких сценариев nix-shell, для каждой из которых нужен свой набор библиотек), то вы получите уникальную withPackages оболочку, установленную в вашей системе для каждой комбинации библиотек, которую вы когда-либо использовали. Но это нормально, потому что сами обертки крошечные, и nix может совместно использовать и повторно использовать базовые GHC и пакеты библиотек между всеми этими средами.

person Ben    schedule 10.07.2017
comment
Вау, это отличное объяснение, Бен. И действительно, работает отлично. Как только я буду квалифицирован, я предложу усовершенствование man-страницы для nix-shell, но пока что большое спасибо за то, что нашли время, чтобы объяснить, что и почему. Вы оба решили мою непосредственную проблему и дали мне возможность заняться следующей с гораздо более глубоким пониманием. - person user3416536; 11.07.2017
comment
@ user3416536 Возможно, это будет nixos.org/nixpkgs/ manual /, что нужно улучшить? Мне лично кажется, что раздел «Как установить компилятор с библиотеками» выделен недостаточно. - person Zimm i48; 11.07.2017
comment
@ user3416536 К сожалению, справочной страницы nix-shell на самом деле недостаточно, чтобы использовать ее со всем. Этот конкретный момент на самом деле не является следствием того, как работает nix-shell (или даже как работает nix), а как работает GHC и как работает конкретный код nix, используемый для поддержки сред GHC. Есть другие языки, которые работают таким образом в nix (например, python), но есть и другие, которые этого не делают. На самом деле нецелесообразно описывать это конкретно на странице руководства nix-shell, но это означает, что непонятно, почему ваш сценарий не работал, если вы не знаете, что в руководстве nixpkgs есть специальный раздел Haskell. :( - person Ben; 12.07.2017
comment
@ user3416536 В целом с nix кажется, что программы для конечных пользователей довольно просты и забыты, но для довольно технических вещей с множеством независимо устанавливаемых частей (например, библиотек языков программирования) вам часто нужно немного знать о том, как код nix их описывает работает, чтобы работать с ними в системе nix. - person Ben; 12.07.2017
comment
Ваше мнение о том, что это, возможно, слишком глубоко для man-страницы nix-shell, справедливо, но, поскольку в нем есть пример для сценариев haskell, я думаю, что этот пример должен работать! Я утверждаю, что пример следует исправить, и он исправлен; или удален (если мы думаем, что его исправление сделало бы его слишком сложным для справочной страницы). - person user3416536; 12.07.2017
comment
@ user3416536 О, определенно! На самом деле я не понимал, что на странице руководства nix-shell есть конкретный пример Haskell; это было бы ошибкой в ​​документации, если бы она не сработала. - person Ben; 12.07.2017
comment
Похоже, это больше не работает, переключение с одинарных на двойные кавычки выше исправило это для меня. - person C. Hammill; 15.08.2018
comment
@ C.Hammill Спасибо, что заметили это, как странно! Я отредактировал свой ответ, так что пример работает. Я не могу вспомнить сейчас, тестировал ли я версию с одинарными кавычками перед публикацией этого ... возможно, хотя, поскольку я на самом деле не использую вторую функцию nix-shell строки shebang. - person Ben; 15.08.2018