Spec-Zone.ru › Haskell 8

7.9. Пакеты

Пакет — это библиотека модулей Haskell, известная компилятору. GHC поставляется с несколькими пакетами: см. сопроводительную документацию по библиотекам. Дополнительные пакеты можно установить из HackageDB.

Использование пакета не может быть проще: если вы используете --make или GHCi, то большинство установленных пакетов будут автоматически доступны вашей программе без каких-либо дополнительных опций. Исключение из этого правила рассматривается ниже в Использование пакетов.

Создание собственных пакетов также довольно просто: мы предоставляем инфраструктуру Cabal, которая автоматизирует процесс настройки, построения, установки и распространения пакета. Всё, что вам нужно сделать, это написать простой файл конфигурации, поместить несколько файлов в правильные места, и у вас есть пакет. Подробности см. в документации Cabal, а также в библиотеках Cabal (Distribution.Simple, например).

7.9.1. Использование пакетов

GHC знает только о установленных пакетах. Установленные пакеты хранятся в базах данных пакетов. Подробности о базах данных пакетов и о том, как управлять тем, какие базы данных пакетов или какой набор пакетов доступен для GHC, см. в разделе Базы данных пакетов.

Чтобы увидеть, какие пакеты в настоящее время доступны, используйте команду ghc-pkg list:

$ ghc-pkg list
/usr/lib/ghc-6.12.1/package.conf.d:
    Cabal-1.7.4
    array-0.2.0.1
    base-3.0.3.0
    base-4.2.0.0
    bin-package-db-0.0.0.0
    binary-0.5.0.1
    bytestring-0.9.1.4
    containers-0.2.0.1
    directory-1.0.0.2
    (dph-base-0.4.0)
    (dph-par-0.4.0)
    (dph-prim-interface-0.4.0)
    (dph-prim-par-0.4.0)
    (dph-prim-seq-0.4.0)
    (dph-seq-0.4.0)
    extensible-exceptions-0.1.1.0
    ffi-1.0
    filepath-1.1.0.1
    (ghc-6.12.1)
    ghc-prim-0.1.0.0
    haskeline-0.6.2
    haskell98-1.0.1.0
    hpc-0.5.0.2
    integer-gmp-0.1.0.0
    mtl-1.1.0.2
    old-locale-1.0.0.1
    old-time-1.0.0.1
    pretty-1.0.1.0
    process-1.0.1.1
    random-1.0.0.1
    rts-1.0
    syb-0.1.0.0
    template-haskell-2.4.0.0
    terminfo-0.3.1
    time-1.1.4
    unix-2.3.1.0
    utf8-string-0.3.4

Установленный пакет по умолчанию либо экспонирован, либо скрыт. Пакеты, скрытые по умолчанию, перечислены в скобках (например, (lang-1.0)), или, возможно, синим цветом, если ваш терминал поддерживает цвет, в выводе команды ghc-pkg list. Командные флаги, описанные ниже, позволяют экспонировать скрытый пакет или скрыть экспонированный. Только модули из экспонированных пакетов могут быть импортированы в ваш код Haskell; если вы попытаетесь импортировать модуль из скрытого пакета, GHC выведет сообщение об ошибке. Следует отметить, что скрытый пакет все равно может быть связан с вашей программой как зависимость от экспонированного пакета, он просто ограничен в прямом импорте.

Если существует несколько экспонированных версий пакета, GHC отдаст предпочтение последней. Кроме того, некоторые пакеты могут быть неработоспособными: то есть они отсутствуют в базе данных пакетов, или одна из их зависимостей неработоспособна; в этом случае эти пакеты исключаются из набора пакетов по умолчанию.

Примечание

Если вы используете Cabal, то состояние экспонированности или скрытности пакета не имеет значения: доступные пакеты определяются вместо этого зависимостями, перечисленными в вашей .cabal спецификации. Состояние экспонированности/скрытности пакетов имеет значение только при непосредственном использовании ghc или ghci.

Аналогично состоянию скрытности пакета является его состояние доверия. Пакет может быть либо надёжным, либо ненадежным (недоверенным). По умолчанию пакеты недоверенные. Это свойство пакета играет роль только при компиляции кода с помощью функции Safe Haskell GHC (см. Safe Haskell) с флагом -fpackage-trust включённым.

Чтобы увидеть, какие модули предоставляются пакетом, используйте команду ghc-pkg (см. Управление пакетами (команда ghc-pkg)):

$ ghc-pkg field network exposed-modules
exposed-modules: Network.BSD,
                 Network.CGI,
                 Network.Socket,
                 Network.URI,
                 Network

Командные опции GHC, которые управляют пакетами, следующие:

-package ⟨pkg⟩

Эта опция экспонирует установленный пакет ⟨pkg⟩. Пакет ⟨pkg⟩ может быть указан полностью с номером версии (например, network-1.0) или номер версии может быть опущен, в этом случае GHC автоматически экспонирует последнюю работоспособную версию из установленных версий пакета.

По умолчанию (когда -hide-all-packages не указан), GHC экспонирует только одну версию пакета, все остальные версии становятся скрытыми. Если опция -package указана несколько раз для одного и того же пакета, последняя переопределяет предыдущие. С другой стороны, если используется -hide-all-packages, GHC позволяет экспонировать несколько версий пакета, используя опцию -package несколько раз с разными версиями одного и того же пакета.

-package поддерживает тонкие настройки и переименование, описанные в Сжатие и переименование модулей.

Опция -package ⟨pkg⟩ также подключает пакет ⟨pkg⟩ к полученному исполняемому файлу или динамической библиотеке. Способ подключения библиотеки пакета, статически или динамически, контролируется парой флагов -static/ -dynamic.

В режиме --make и режиме --interactive (см. Режимы работы), компилятор обычно определяет, какие пакеты требуются текущими модулями Haskell и подключает только их. Однако в пакетном режиме информация о зависимости недоступна, и при подключении необходимо явно указать опции -package. Ещё один случай, когда вам может понадобиться использовать -package для принудительного подключения пакета, — это когда пакет не содержит модулей Haskell (он может содержать только библиотеку C, например). В этом случае GHC никогда не обнаружит зависимость от него, поэтому его нужно упомянуть явно.

Например, чтобы подключить программу, состоящую из объектов Foo.o и Main.o, где мы использовали пакет network, нам нужно дать GHC флаг -package, таким образом:

$ ghc -o myprog Foo.o Main.o -package network

Тот же флаг необходим даже если мы скомпилировали модули из исходного кода, потому что GHC по-прежнему считает, что он в пакетном режиме:

$ ghc -o myprog Foo.hs Main.hs -package network
-package-id ⟨unit-id⟩

Экспонирует пакет, как и -package ⟨pkg⟩, но имя пакета задаётся его идентификатором единицы (т.е. значением id в его записи в базе данных установленных пакетов, ранее также известное как идентификатор установленного пакета) вместо имени. Это более надёжный способ именования пакетов и может использоваться для выбора пакетов, которые в противном случае могут быть скрыты. Cabal передаёт флаги -package-id в GHC. -package-id поддерживает тонкие настройки и переименование, описанные в Сжатие и переименование модулей.

-hide-all-packages

Игнорировать флаг экспонированности установленных пакетов и скрывать их по умолчанию. Если вы используете этот флаг, то все необходимые вам пакеты (включая base) нужно явно экспонировать с помощью опций -package ⟨pkg⟩.

Это хороший способ изолировать вашу программу от различий в глобально экспонированных пакетах, и явное указание зависимостей пакетов — это хорошо. Cabal всегда передаёт флаг -hide-all-packages в GHC, именно по этой причине.

-hide-package ⟨pkg⟩

Эта опция делает обратное -package ⟨pkg⟩: она скрывает указанный пакет, что означает, что ни один из его модулей не будет доступен для импорта с помощью директив Haskell import.

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

-ignore-package ⟨pkg⟩

Заставляет компилятор вести себя так, как будто пакет ⟨pkg⟩ и все пакеты, от него зависящие, вообще не установлены.

Указание -ignore-package ⟨pkg⟩ эквивалентно указанию флагов -hide-package ⟨pkg⟩ для ⟨pkg⟩ и всех пакетов, от него зависящих. Иногда мы не знаем заранее, какие пакеты, зависящие от ⟨pkg⟩, будут установлены, вот когда и может пригодиться флаг -ignore-package ⟨pkg⟩.

-no-auto-link-packages

По умолчанию GHC автоматически подключает пакеты base и rts. Этот флаг отключает это поведение.

-this-unit-id ⟨unit-id⟩

Указывает GHC, что компилируемый модуль является частью идентификатора единицы ⟨unit-id⟩; внутренне эти ключи используются для определения равенства типов и символов компоновщика. Начиная с GHC 8.0, идентификаторы единиц должны состоять только из буквенно-цифровых символов, дефисов, нижних подчеркиваний и точек. GHC оставляет за собой право интерпретировать другие символы особым образом в будущих релизах.

-trust ⟨pkg⟩

Эта опция заставляет компилятор GHC экспонировать и доверять пакету ⟨pkg⟩. Эта команда работает очень похожим образом на команду -package ⟨pkg⟩, но дополнительно устанавливает выбранные пакеты в качестве надёжных для GHC независимо от содержимого базы данных пакетов. (см. Safe Haskell).

-distrust ⟨pkg⟩

Эта опция заставляет компилятор GHC экспонировать и недоверять пакету ⟨pkg⟩. Эта команда работает очень похожим образом на команду -package ⟨pkg⟩, но дополнительно устанавливает выбранные пакеты в качестве недоверенных для GHC независимо от содержимого базы данных пакетов. (см. Safe Haskell).

-distrust-all-packages

Игнорировать флаг доверия для установленных пакетов и по умолчанию не доверять им. Если вы используете этот флаг и Safe Haskell, то любые пакеты, которым требуется доверие (включая base), необходимо явно доверять, используя опции -trust ⟨pkg⟩. Этот параметр не изменяет статус видимости/скрытности пакета, поэтому он не эквивалентен применению -distrust ⟨pkg⟩ ко всем пакетам в системе. (см. Safe Haskell).

7.9.2. Пакет main

Всякая полная программа на Haskell должна определять main в модуле Main в пакете main. Пропуск флага -this-unit-id ⟨unit-id⟩ компилирует код для пакета main. Отсутствие этого приводит к несколько неясной ошибке на этапе компоновки вида:

/usr/bin/ld: Undefined symbols:
_ZCMain_main_closure

7.9.3. Последствия использования пакетов в языке Haskell

Возможно, при использовании пакетов вы получите программу, содержащую два модуля с одинаковым именем: возможно, вы использовали пакет P, который имеет скрытый модуль M, а также есть модуль M в вашей программе. Или, возможно, зависимости используемых пакетов содержат некоторые перекрывающиеся модули. Возможно, программа даже содержит несколько версий определенного пакета из-за зависимостей от других пакетов.

Ни один из этих сценариев не вызывает ошибки сам по себе 1, но они могут иметь некоторые интересные последствия. Например, если у вас есть тип M.T из версии 1 пакета P, то это не то же самое, что тип M.T из версии 2 пакета P, и GHC сообщит об ошибке, если вы попытаетесь использовать один там, где ожидается другой.

Формально говоря, в Haskell 98 сущность (функция, тип или класс) в программе однозначно определяется парой имени модуля, в котором она определена, и её именем. В GHC сущность однозначно определяется тройкой: пакет, модуль и имя.

7.9.4. Уточнение и переименование модулей

При включении пакетов из нескольких источников вы можете столкнуться с ситуацией, когда несколько пакетов публикуют модули с одинаковым именем. Раньше единственным способом отличить эти модули было использование импортов с указанием пакета. Однако с GHC 7.10 флаги -package ⟨pkg⟩ (и их варианты) были расширены, чтобы позволить пользователю явно контролировать, какие модули пакет включает в область видимости, по аналогии со списками импорта, которые пользователи могут прикрепить к импортам модулей.

Основной синтаксис состоит в том, что вместо указания имени пакета P для флага пакета -package мы указываем имя пакета и список импортируемых имён модулей в скобках, разделённых запятыми. Например, -package "base (Data.List, Data.Bool)" делает видимыми только Data.List и Data.Bool из пакета base. Мы также поддерживаем переименование модулей, в случае необходимости одновременной ссылки на оба модуля; это поддерживается записью OldModName as NewModName, например, -package "base (Data.Bool as Bool). Вы также можете написать -package "base with (Data.Bool as Bool), чтобы включить все исходные связи (например, переименование строго добавляется). Важно указывать кавычки, чтобы ваша оболочка передавала имя пакета и список уточнения/переименования как один аргумент GHC.

Импорты пакетов с уточнением/переименованием не скрывают другие версии пакета: например, если containers-0.9 уже показан, -package "containers-0.8 (Data.List as ListV8)" добавит только дополнительное связывание в среду. Аналогично, -package "base (Data.Bool as Bool)" -package "base (Data.List as List)" эквивалентно -package "base (Data.Bool as Bool, Data.List as List)". Буквенные имена должны ссылаться на модули, определенные исходным пакетом, поэтому, например, -package "base (Data.Bool as Bool, Bool as Baz)" недействительно, если модуль Bool не был определен в исходном пакете. Скрытие пакета также очищает все его переименования.

Вы можете использовать переименование для предоставления альтернативного префикса, например, -hide-all-packages -package "basic-prelude (BasicPrelude as Prelude)", вместо расширения Переопределяемый синтаксис и неявный импорт Prelude.

7.9.5. Базы данных пакетов

База данных пакетов — это место, где хранятся данные об установленных пакетах. Это каталог, обычно называемый package.conf.d, который содержит файл для каждого пакета, а также бинарный кэш данных пакета в файле package.cache. Обычно вам не нужно будет просматривать или изменять содержимое базы данных пакетов напрямую; все управление базами данных пакетов можно выполнить с помощью инструмента ghc-pkg (см. Управление пакетами (команда ghc-pkg)).

GHC знает о двух конкретных базах данных пакетов:

  • Глобальная база данных пакетов, которая поставляется с вашей установкой GHC, например, /usr/lib/ghc-6.12.1/package.conf.d.
  • Пользовательская база данных пакетов, личная для каждого пользователя. В системах Unix это будет $HOME/.ghc/arch-os-version/package.conf.d, а в Windows — что-то вроде C:\Documents And Settings\user\ghc\package.conf.d. Инструмент ghc-pkg знает, где должен находиться этот файл и создаст его, если он не существует (см. Управление пакетами (команда ghc-pkg)).

Стек базы данных пакетов: Базы данных пакетов организованы в структуре стека. При запуске GHC он добавляет глобальную и пользовательскую базы данных пакетов в стек в таком порядке, если не указан GHC_PACKAGE_PATH. Если указан GHC_PACKAGE_PATH, то он определит начальный стек баз данных. Несколько командных опций, описанных ниже, могут далее изменять этот начальный стек. Вы можете просмотреть эффективный стек баз данных пакетов GHC, запустив GHC с флагом -v.

Эта структура стека означает, что порядок флагов -package-db ⟨file⟩ или GHC_PACKAGE_PATH важен. Каждый подстек стека должен быть корректным (пакеты в базах данных вверху стека могут ссылаться на пакеты ниже, но не наоборот).

Затенение пакетов: При использовании нескольких баз данных пакетов возможно, хотя и редко, что один и тот же идентификатор установленного пакета присутствует в более чем одной базе данных. В этом случае пакеты, расположенные ближе к вершине стека, перекрывают (затеняют) пакеты ниже их. Если конфликтующие пакеты окажутся эквивалентными (по сравнению с хэшем ABI), то один из них заменит все ссылки на другой, в противном случае перекрытый пакет и все пакеты, от него зависящие, будут удалены.

Выбор версии пакета: При выборе пакета GHC будет искать пакеты во всех доступных базах данных. Если доступны несколько версий одного пакета, будет выбрана последняя работоспособная версия.

Разрешение конфликтов версий: Если GHC выбрал несколько экземпляров версии пакета, то GHC выберет неуказанный экземпляр.

Вы можете контролировать стек базы данных пакетов GHC с помощью следующих опций:

-package-db ⟨file⟩

Добавить базу данных пакетов ⟨file⟩ поверх текущего стека.

-no-global-package-db

Удалить глобальную базу данных пакетов из стека баз данных пакетов.

-no-user-package-db

Запретить загрузку локальной базы данных пакетов пользователя в начальном стеке.

-clear-package-db

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

-global-package-db

Добавить глобальную базу данных пакетов поверх текущего стека. Эта опция может использоваться после -no-global-package-db для указания позиции в стеке, где должна быть загружена глобальная база данных пакетов.

-user-package-db

Добавить пользовательскую базу данных пакетов поверх текущего стека. Эта опция может использоваться после -no-user-package-db для указания позиции в стеке, где должна быть загружена пользовательская база данных пакетов.

7.9.5.1. Переменная среды GHC_PACKAGE_PATH

GHC_PACKAGE_PATH

Переменная среды GHC_PACKAGE_PATH может быть установлена в список файлов, содержащих базы данных пакетов, разделённых : (на Windows - ;). Этот список баз данных пакетов, используемый GHC и ghc-pkg, определяет стек баз данных пакетов сверху вниз. Такой порядок выбран для соответствия поведению переменной среды PATH, где записи раньше в PATH переопределяют записи, которые следуют позже. Подробности о том, как используется стек базы данных пакетов, см. в разделе Базы данных пакетов.

Обычно GHC_PACKAGE_PATH заменяет стандартный стек баз данных пакетов. Например, все следующие команды эквивалентны, создавая стек с db1 на вершине, а затем db2 (используйте ; вместо : в Windows):

$ ghc -clear-package-db -package-db db2.conf -package-db db1.conf
$ env GHC_PACKAGE_PATH=db1.conf:db2.conf ghc
$ env GHC_PACKAGE_PATH=db2.conf ghc -package-db db1.conf

Однако, если GHC_PACKAGE_PATH заканчивается разделителем, к пути добавляются базовые базы данных (т.е. пользовательская и глобальная базы данных пакетов в таком порядке). Например, чтобы добавить собственную базу данных пакетов к обычному набору, можно указать (в Unix):

$ export GHC_PACKAGE_PATH=$HOME/.my-ghc-packages.conf:

Чтобы проверить, правильно ли настроена переменная GHC_PACKAGE_PATH, ghc-pkg list выведет все используемые базы данных в обратном порядке их проверки.

7.9.5.2. Окружения пакетов

Файл среды пакета — это файл, который указывает ghc, какие именно пакеты должны быть видны. Он может использоваться для создания сред для ghc или ghci, которые локальны для сеанса оболочки или какой-либо папки. Они предназначены для управления инструментами сборки/пакетирования, чтобы позволить ghc и ghci автоматически использовать среду, созданную инструментом.

Файл содержит идентификаторы пакетов и необязательно базы данных пакетов, по одной директиве на строке:

clear-package-db
global-package-db
user-package-db
package-db db.d/
package-id id_1
package-id id_2
...
package-id id_n

Если такой файл среды пакета найден, это эквивалентно передаче этих аргументов командной строки в ghc:

-hide-all-packages
-clear-package-db
-global-package-db
-user-package-db
-package-db db.d/
-package-id id_1
-package-id id_2
...
-package-id id_n

Обратите внимание на неявное использование -hide-all-packages и тот факт, что это -package-id ⟨unit-id⟩, а не -package ⟨pkg⟩. Это связано с тем, что среда точно определяет, какие пакеты должны быть видны.

Обратите внимание, что для директивы package-db, если указан относительный путь, он должен быть относительным к расположению файла среды пакета.

-package-env ⟨file⟩|⟨name⟩

Использовать среду пакета из файла ⟨file⟩, или из $HOME/.ghc/arch-os-version/environments/⟨name⟩ Если установлено значение -, то среда пакета не будет читаться.

GHC_ENVIRONMENT

Указывает путь к файлу среды пакета, который будет использоваться GHC. Переопределяется флагом -package-env ⟨file⟩|⟨name⟩, если он установлен.

В порядке ghc будет искать среду пакета в следующих местах:

  • Файл ⟨file⟩, если вы передаете опцию -package-env ⟨file⟩|⟨name⟩.
  • Файл $HOME/.ghc/arch-os-version/environments/name, если вы передаете опцию -package-env ⟨name⟩.
  • Файл ⟨file⟩, если переменная окружения GHC_ENVIRONMENT установлена в ⟨file⟩.
  • Файл $HOME/.ghc/arch-os-version/environments/name, если переменная окружения GHC_ENVIRONMENT установлена в ⟨name⟩.

Кроме того, если не указано -hide-all-packages, ghc также будет искать среду пакета в следующих местах:

  • Файл .ghc.environment.arch-os-version, если он существует в текущей директории или любой родительской директории (но не в домашней директории пользователя).
  • Файл $HOME/.ghc/arch-os-version/environments/default, если он существует.

Среды пакетов могут быть изменены дополнительными аргументами командной строки; например, если вы укажете -package foo в командной строке, то пакет ⟨foo⟩ будет виден, даже если он не указан в активной среде пакета.

7.9.6. Идентификаторы установленных пакетов, зависимости и неисправные пакеты

Каждый установленный пакет имеет уникальный идентификатор (”идентификатор установленного пакета”), который отличает его от всех других установленных пакетов в системе. Чтобы увидеть идентификаторы установленных пакетов, связанные с каждым установленным пакетом, используйте ghc-pkg list -v:

$ ghc-pkg list -v
using cache: /usr/lib/ghc-6.12.1/package.conf.d/package.cache
/usr/lib/ghc-6.12.1/package.conf.d
   Cabal-1.7.4 (Cabal-1.7.4-48f5247e06853af93593883240e11238)
   array-0.2.0.1 (array-0.2.0.1-9cbf76a576b6ee9c1f880cf171a0928d)
   base-3.0.3.0 (base-3.0.3.0-6cbb157b9ae852096266e113b8fac4a2)
   base-4.2.0.0 (base-4.2.0.0-247bb20cde37c3ef4093ee124e04bc1c)
   ...

Строка в скобках после имени пакета — это идентификатор установленного пакета: обычно она начинается с имени и версии пакета, и заканчивается строкой хэша, полученной из скомпилированного пакета. Зависимости между пакетами выражаются через идентификаторы установленных пакетов, а не только через пакеты и версии. Например, рассмотрим зависимости пакета haskell98:

$ ghc-pkg field haskell98 depends
depends: array-0.2.0.1-9cbf76a576b6ee9c1f880cf171a0928d
         base-4.2.0.0-247bb20cde37c3ef4093ee124e04bc1c
         directory-1.0.0.2-f51711bc872c35ce4a453aa19c799008
         old-locale-1.0.0.1-d17c9777c8ee53a0d459734e27f2b8e9
         old-time-1.0.0.1-1c0d8ea38056e5087ef1e75cb0d139d1
         process-1.0.1.1-d8fc6d3baf44678a29b9d59ca0ad5780
         random-1.0.0.1-423d08c90f004795fd10e60384ce6561

Цель идентификатора установленного пакета заключается в обнаружении проблем, вызванных повторной установкой пакета без повторной компиляции пакетов, от которых он зависит. Повторная компиляция зависимостей необходима, потому что вновь скомпилированный пакет может иметь другой ABI (интерфейс двоичного кода приложения), чем предыдущая версия, даже если оба пакета были скомпилированы из одного исходного кода с использованием одного и того же компилятора. С помощью идентификаторов установленных пакетов перекомпилированный пакет будет иметь другой идентификатор установленного пакета, чем предыдущая версия, поэтому пакеты, зависевшие от предыдущей версии, теперь являются “сиротами” — одна из их зависимостей не удовлетворена. Пакеты, которые нарушены таким образом, отображаются в выводе ghc-pkg list либо красным цветом (если это возможно), либо в скобках. В следующем примере мы перекомпилировали и переустановили пакет filepath, и это привело к нарушению различных зависимостей, включая Cabal:

$ ghc-pkg list
WARNING: there are broken packages.  Run 'ghc-pkg check' for more details.
/usr/lib/ghc-6.12.1/package.conf.d:
    {Cabal-1.7.4}
    array-0.2.0.1
    base-3.0.3.0
    ... etc ...

Кроме того, ghc-pkg list напоминает вам о наличии неисправных пакетов и предлагает ghc-pkg check, которое отображает больше информации о природе сбоя:

$ ghc-pkg check
There are problems in package ghc-6.12.1:
  dependency "filepath-1.1.0.1-87511764eb0af2bce4db05e702750e63" doesn't exist
There are problems in package haskeline-0.6.2:
  dependency "filepath-1.1.0.1-87511764eb0af2bce4db05e702750e63" doesn't exist
There are problems in package Cabal-1.7.4:
  dependency "filepath-1.1.0.1-87511764eb0af2bce4db05e702750e63" doesn't exist
There are problems in package process-1.0.1.1:
  dependency "filepath-1.1.0.1-87511764eb0af2bce4db05e702750e63" doesn't exist
There are problems in package directory-1.0.0.2:
  dependency "filepath-1.1.0.1-87511764eb0af2bce4db05e702750e63" doesn't exist

The following packages are broken, either because they have a problem
listed above, or because they depend on a broken package.
ghc-6.12.1
haskeline-0.6.2
Cabal-1.7.4
process-1.0.1.1
directory-1.0.0.2
bin-package-db-0.0.0.0
hpc-0.5.0.2
haskell98-1.0.1.0

Для решения проблемы необходимо перекомпилировать неисправные пакеты с новыми зависимостями. Самый простой способ сделать это — использовать cabal-install или загрузить пакеты из HackageDB и собрать и установить их как обычно.

Будьте осторожны, не перекомпилируйте пакеты, от которых зависит сам GHC, так как это может привести к поломке самого пакета ghc, и ghc не может быть просто перекомпилирован. Единственный способ исправить это — переустановить GHC.

7.9.7. Управление пакетами (команда ghc-pkg)

Инструмент ghc-pkg предназначен для запроса и изменения баз данных пакетов. Чтобы увидеть, какие базы данных пакетов используются, используйте ghc-pkg list. Стек баз данных, о которых ghc-pkg знает, может быть изменён с помощью переменной окружения GHC_PACKAGE_PATH (см. Переменная среды GHC_PACKAGE_PATH) и с помощью опций -package-db ⟨file⟩ в командной строке ghc-pkg.

При запросе изменения базы данных, ghc-pkg изменяет глобальную базу данных по умолчанию. Указание --user заставляет её действовать над пользовательской базой данных, или --package-db можно использовать для работы с другой базой данных полностью. При задании нескольких таких опций используется самая правая.

Команды, которые запрашивают базу данных пакетов (список, последняя, описание, поле, точка) работают со списком баз данных, указанных флагами --user, --global и --package-db. Если ни один из этих флагов не задан, по умолчанию используется --global --user.

Если переменная окружения GHC_PACKAGE_PATH установлена, и её значение не заканчивается разделителем (: в Unix, ; в Windows), то последняя база данных считается глобальной базой данных и по умолчанию будет изменяться командой ghc-pkg. Здесь предполагается, что GHC_PACKAGE_PATH можно использовать для создания виртуальной среды пакетов, в которую можно устанавливать пакеты Cabal, не настраивая ничего, кроме GHC_PACKAGE_PATH.

Программа ghc-pkg может быть запущена способами, перечисленными ниже. Если требуется имя пакета, пакет может быть указан полностью, включая номер версии (например, network-1.0), или без номера версии. Указание пакета без номера версии соответствует всем версиям пакета; указанное действие будет применено ко всем соответствующим пакетам. Указатель пакета, который соответствует всем версиям пакета, также может быть записан ⟨pkg⟩ -*, чтобы яснее указать, что сопоставляется несколько пакетов. Для сопоставления с идентификатором установленного пакета вместо просто имени и версии пакета передайте флаг --ipid.

ghc-pkg init path

Создаёт новую пустую базу данных пакетов по адресу ⟨path⟩, которая не должна уже существовать.

ghc-pkg register ⟨file⟩

Читает спецификацию пакета из ⟨file⟩ (которое может быть «-» для указания стандартного ввода) и добавляет его в базу данных установленных пакетов. Синтаксис ⟨file⟩ приведён в InstalledPackageInfo: спецификация пакета.

Спецификация пакета должна описывать пакет, который ещё не установлен.

ghc-pkg update ⟨file⟩

То же, что и register, за исключением того, что если пакет с тем же именем уже установлен, он заменяется новым.

ghc-pkg unregister ⟨P⟩

Удаляет указанный пакет из базы данных.

ghc-pkg check

Проверяет непротиворечивость зависимостей в базе данных пакетов и сообщает о пакетах с отсутствующими зависимостями.

ghc-pkg expose ⟨P⟩

Устанавливает флаг exposed для пакета ⟨P⟩ в значение True.

ghc-pkg hide ⟨P⟩

Устанавливает флаг exposed для пакета ⟨P⟩ в значение False.

ghc-pkg trust ⟨P⟩

Устанавливает флаг trusted для пакета ⟨P⟩ в значение True.

ghc-pkg distrust ⟨P⟩

Устанавливает флаг trusted для пакета ⟨P⟩ в значение False.

ghc-pkg list [⟨P⟩] [--simple-output]

Этот параметр отображает текущие установленные пакеты для каждой базы данных, известной ghc-pkg. Включает глобальную базу данных, локальную базу данных пользователя и любые дополнительные файлы, указанные с помощью параметра -f в командной строке.

Скрытые пакеты (для которых флаг exposed равен False) отображаются в скобках в списке пакетов.

Если указан необязательный идентификатор пакета ⟨P⟩, то отображаются только пакеты, соответствующие этому идентификатору.

Если параметр --simple-output указан, то пакеты перечисляются в одной строке, разделённые пробелами, а имена баз данных не включаются. Это призвано облегчить парсинг вывода ghc-pkg list с помощью скрипта.

ghc-pkg find-module ⟨M⟩ [--simple-output]

Этот параметр перечисляет зарегистрированные пакеты, экспортирующие модуль ⟨M⟩. Примеры:

$ ghc-pkg find-module Var
c:/fptools/validate/ghc/driver/package.conf.inplace:
    (ghc-6.9.20080428)

$ ghc-pkg find-module Data.Sequence
c:/fptools/validate/ghc/driver/package.conf.inplace:
    containers-0.1

В противном случае он ведёт себя как ghc-pkg list, включая параметры.

ghc-pkg latest ⟨P⟩

Выводит последнюю доступную версию пакета ⟨P⟩.

ghc-pkg describe ⟨P⟩

Выводит полное описание указанного пакета. Описание представлено в формате InstalledPackageInfo, таком же, как формат входного файла для ghc-pkg register. Подробности см. в InstalledPackageInfo: спецификация пакета.

Если шаблон соответствует нескольким пакетам, описание каждого пакета выводится, разделённое строкой --- на отдельной строке.

ghc-pkg field ⟨P⟩ ⟨field⟩[,⟨field⟩]*

Отображает только одно поле описания установленного пакета для P. Несколько полей могут быть выбраны, разделив их запятыми

ghc-pkg dot

Генерирует график зависимостей пакетов в формате, пригодном для использования инструментами graphviz. Например, для генерации PDF-файла графа зависимостей:

ghc-pkg dot | tred | dot -Tpdf >pkgs.pdf
ghc-pkg dump

Выводит полное описание каждого пакета в формате InstalledPackageInfo. Несколько описаний пакетов разделяются строкой --- на отдельной строке.

Это почти то же самое, что ghc-pkg describe '*', за исключением того, что ghc-pkg dump предназначен для использования инструментами, которые анализируют результаты. Так, например, где ghc-pkg describe '*' выдаст ошибку, если не найдёт ни одного пакета, соответствующего шаблону, ghc-pkg dump просто ничего не выведет.

ghc-pkg recache

Пересоздаёт файл кэша двоичных файлов package.cache для выбранной базы данных. Это может потребоваться, если кэш каким-то образом вышел из синхронизации с содержимым базы данных (ghc-pkg предупредит вас, если это может быть так).

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

Поддержка подстрочного поиска поддерживается для ⟨M⟩ в find-module и для ⟨P⟩ в describe, field и *infix*, где '*' обозначает открытые окончания подстроки (prefix*, *suffix, *infix*). Примеры (вывод опущен):

-- list all regex-related packages
ghc-pkg list '*regex*' --ignore-case
-- list all string-related packages
ghc-pkg list '*string*' --ignore-case
-- list OpenGL-related packages
ghc-pkg list '*gl*' --ignore-case
-- list packages exporting modules in the Data hierarchy
ghc-pkg find-module 'Data.*'
-- list packages exporting Monad modules
ghc-pkg find-module '*Monad*'
-- list names and maintainers for all packages
ghc-pkg field '*' name,maintainer
-- list location of haddock htmls for all packages
ghc-pkg field '*' haddock-html
-- dump the whole database
ghc-pkg describe '*'

Кроме того, следующие флаги принимаются ghc-pkg:

-f ⟨file⟩, -package-db ⟨file⟩

Добавляет ⟨file⟩ в стек баз данных пакетов. Кроме того, ⟨file⟩ также будет базой данных, модифицируемой командой register, unregister, expose или hide, если не будет переопределено последующим параметром --package-db, --user или --global.

--force

Заставляет ghc-pkg игнорировать отсутствующие зависимости, директории и библиотеки при регистрации пакета и просто добавлять его. Это может быть полезно, если вашей системе установки пакетов нужно добавить пакет в GHC перед компиляцией и установкой файлов.

--global

Работает с глобальной базой данных пакетов (это значение по умолчанию). Этот флаг влияет на команды register, update, unregister, expose и hide.

--help, -?

Выводит синтаксис командной строки.

--user

Работает с локальной базой данных пакетов текущего пользователя. Этот флаг влияет на команды register, update, unregister, expose и hide.

-v [⟨n⟩], --verbose [=⟨n⟩]

Управляет объёмом вывода. Уровни объёма вывода варьируются от 0 до 2, при этом по умолчанию установлен уровень 1, а только -v выбирает уровень 2.

-V; --version

Выводит номер версии ghc-pkg.

--ipid

Заставляет ghc-pkg интерпретировать аргументы как идентификаторы установленных пакетов (например, идентификатор, подобный unix-2.3.1.0-de7803f1a8cd88d2161b29b083c94240). Это полезно, если предоставление только имени пакета и версии неоднозначно (в старых версиях GHC это гарантировало уникальность, но это свойство больше не обязательно соблюдается).

--package-key

Заставляет ghc-pkg интерпретировать аргументы как идентификаторы единиц (например, идентификатор, подобный I5BErHzyOm07EBNpKBEeUv). Ключи пакетов используются для префикса названий символов, которые GHC генерирует (например, 6VWy06pWzzJq9evDvK2d4w6_DataziByteStringziInternal_unsafePackLenChars_info), поэтому если вам нужно выяснить, к какому пакету принадлежит символ, используйте ghc-pkg с этим флагом.

7.9.8. Компоновка пакета из исходного кода Haskell

Мы не рекомендуем компоновать пакеты сложным способом. Вместо этого, используйте инфраструктуру Cabal, если это возможно. Если ваш пакет особенно сложен или требует много конфигурации, возможно, придётся вернуться к низкоуровневым механизмам, поэтому для тех, кто на это решится, следуют несколько советов.

Вам необходимо создать файл «информации об установке пакета» для передачи в ghc-pkg при установке вашего пакета. Содержимое этого файла описано в InstalledPackageInfo: спецификация пакета.

Код Haskell в пакете может быть скомпонован в одну или несколько архивных библиотек (например, libHSfoo.a) или в один общий объект (например, libHSfoo.dll/.so/.dylib). Ограничение одним общим объектом обусловлено тем, что система пакетов используется для указания компилятору, когда следует выполнять вызов между общими объектами, а не внутри общего объекта (вызовы между общими объектами требуют дополнительного уровня косвенности).

  • Создание статической библиотеки выполняется с помощью инструмента ar, например так:

    ar cqs libHSfoo-1.0.a A.o B.o C.o ...
    

    где A.o, B.o и так далее являются скомпилированными модулями Haskell, а libHSfoo.a — это библиотека, которую вы хотите создать. Синтаксис может незначительно отличаться на вашей системе, поэтому проверьте документацию, если у вас возникнут трудности.

  • Для загрузки пакета foo, GHCi может загрузить его libHSfoo.a библиотеку напрямую, но также может загрузить пакет в виде одного HSfoo.o файла, который был предварительно связан. Загрузка .o файла немного быстрее, но за счёт наличия ещё одной копии скомпилированного пакета. Правило гласит, что если модули пакета были скомпилированы с -split-sections, то создание HSfoo.o стоит, потому что это экономит время при загрузке пакета в GHCi. Без -split-sections разница во времени загрузки между .o и .a библиотеками не так значительна, поэтому лучше сохранить место на диске и сохранить только .a. В дистрибутиве GHC мы предоставляем файлы .o для большинства пакетов, за исключением самого пакета GHC.

    Файл HSfoo.o создаётся автоматически Cabal; используйте --disable-library-for-ghci для его отключения. Чтобы создать его вручную, можно использовать следующую команду GNU ld:

    ld -r --whole-archive -o HSfoo.o libHSfoo.a
    

    (замените --whole-archive на -all_load на MacOS X)

  • При построении пакета в качестве динамической библиотеки, GHC может быть использован для выполнения шага компоновки. Это скрывает некоторые детали базового компоновщика и предоставляет общий интерфейс для всех вариантов динамических библиотек, поддерживаемых GHC (DLL, ELF DSO и Mac OS dylib). Динамическая библиотека должна быть названа определённым образом по двум причинам: (1) имя должно содержать версию компилятора GHC, чтобы два варианта библиотек, скомпилированные разными версиями GHC, не сталкивались, что, скорее всего, будет несовместимо относительно соглашений вызовов, (2) оно должно отличаться от статического имени, иначе мы не сможем контролировать компоновщик настолько точно, насколько необходимо, чтобы сделать флаги -static/-dynamic работоспособными, см. Параметры, влияющие на компоновку.

    ghc -shared -dynamic -o libHSfoo-1.0-ghcGHCVersion.so A.o B.o C.o
    

    Использование номера версии GHC в имени динамической библиотеки позволяет устанавливать разные версии библиотек, скомпилированные разными версиями GHC, в стандартных системных местоположениях, например, под *nix /usr/lib. Чтобы получить номер версии GHC, вызовите ghc --numeric-version и используйте его вывод вместо ⟨GHCVersion⟩. См. также Параметры, влияющие на генерацию кода по подготовке объектных файлов для компоновки динамической библиотеки.

Для компиляции модуля, который должен быть частью нового пакета, используйте опции -package-name (для определения имени пакета) и -library-name (для определения версии и хешей версий его идентификаторов). (Использование пакетов). Отсутствие этих опций при компиляции пакета, вероятно, приведёт к катастрофе, но вы об этом узнаете только позже, когда попытаетесь импортировать модули из пакета. В этот момент GHC пожалуется, что имя пакета, которое он ожидал получить от модуля, не совпадает с именем пакета, хранящимся в файле .hi.

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

7.9.9. InstalledPackageInfo: спецификация пакета

Спецификация пакета представляет собой Haskell-запись; в частности, это запись Distribution.InstalledPackageInfo.InstalledPackageInfo в модуле Distribution.InstalledPackageInfo, который входит в состав пакета Cabal, поставляемого с GHC.

У InstalledPackageInfo есть читаемый/записываемый синтаксис. Функции parseInstalledPackageInfo и showInstalledPackageInfo соответственно считывают и записывают этот синтаксис. Вот пример InstalledPackageInfo для пакета unix:

$ ghc-pkg describe unix
name: unix
version: 2.3.1.0
id: unix-2.3.1.0-de7803f1a8cd88d2161b29b083c94240
license: BSD3
copyright:
maintainer: libraries@haskell.org
stability:
homepage:
package-url:
description: This package gives you access to the set of operating system
             services standardised by POSIX 1003.1b (or the IEEE Portable
             Operating System Interface for Computing Environments -
             IEEE Std. 1003.1).
             .
             The package is not supported under Windows (except under Cygwin).
category: System
author:
exposed: True
exposed-modules: System.Posix System.Posix.DynamicLinker.Module
                 System.Posix.DynamicLinker.Prim System.Posix.Directory
                 System.Posix.DynamicLinker System.Posix.Env System.Posix.Error
                 System.Posix.Files System.Posix.IO System.Posix.Process
                 System.Posix.Process.Internals System.Posix.Resource
                 System.Posix.Temp System.Posix.Terminal System.Posix.Time
                 System.Posix.Unistd System.Posix.User System.Posix.Signals
                 System.Posix.Signals.Exts System.Posix.Semaphore
                 System.Posix.SharedMem
hidden-modules:
trusted: False
import-dirs: /usr/lib/ghc-6.12.1/unix-2.3.1.0
library-dirs: /usr/lib/ghc-6.12.1/unix-2.3.1.0
hs-libraries: HSunix-2.3.1.0
extra-libraries: rt util dl
extra-ghci-libraries:
include-dirs: /usr/lib/ghc-6.12.1/unix-2.3.1.0/include
includes: HsUnix.h execvpe.h
depends: base-4.2.0.0-247bb20cde37c3ef4093ee124e04bc1c
hugs-options:
cc-options:
ld-options:
framework-dirs:
frameworks:
haddock-interfaces: /usr/share/doc/ghc/html/libraries/unix/unix.haddock
haddock-html: /usr/share/doc/ghc/html/libraries/unix

Вот краткое описание синтаксиса этого файла:

Описание пакета состоит из ряда пар имя/значение. Имя поля начинается в левом столбце, за которым следует ":", а значение продолжается до следующей строки, начинающейся в левом столбце, или конца файла.

Синтаксис значения зависит от поля. Различные типы полей:

freeform

Любая произвольная строка, интерпретация или разбор не выполняются.

string

Последовательность неразрывных символов или последовательность произвольных символов, заключённых в кавычки "....".

список строк

Последовательность строк, разделенных запятыми. Последовательность может быть пустой.

Кроме того, некоторые поля имеют специальный синтаксис (например, имена пакетов, версии, зависимости).

Разрешенные поля с их типами:

name

(string) Название пакета (без версии).

id

(string) Идентификатор установленного пакета. Вы выбираете его самостоятельно.

version

(string) Версия пакета, обычно в формате A.B (разрешается любое количество компонентов).

license

(string) Тип лицензии, под которой распространяется этот пакет. Это поле — значение типа Distribution.License.License.

license-file

(необязательная строка) Название файла с подробной информацией о лицензии этого пакета.

copyright

(необязательная строка произвольного формата) Строка авторских прав.

maintainer

(необязательная строка произвольного формата) Электронный адрес основного разработчика пакета.

stability

(необязательная строка произвольного формата) Строка, описывающая стабильность пакета (например, stable, provisional или experimental).

homepage

(необязательная строка произвольного формата) URL домашней страницы пакета.

package-url

(необязательная строка произвольного формата) URL для загрузки дистрибутива этого пакета. Дистрибутив должен быть пакетом Cabal.

description

(необязательная строка произвольного формата) Описание пакета.

category

(необязательная строка произвольного формата) К какой категории принадлежит пакет. Это поле предназначено для использования в сочетании с будущей централизованной системой распространения пакетов, предварительно названной Hackage.

author

(необязательная строка произвольного формата) Автор пакета.

exposed

(bool) Является ли пакет экспортируемым.

exposed-modules

(список строк) Модули, экспортируемые этим пакетом.

hidden-modules

(список строк) Модули, предоставляемые этим пакетом, но не экспортируемые программисту. Эти модули не могут быть импортированы, но все ещё подчиняются ограничению пересечения: ни один другой пакет в той же программе не может предоставить модуль с таким же именем.

reexported-modules

Модули, повторно экспортируемые этим пакетом. Этот список имеет вид pkg:OldName as NewName (A@orig-pkg-0.1-HASH): первая часть строки — спецификация повторного экспорта, написанная пользователем (возможно, без квалификатора пакета и переименования), а скобки — оригинальный пакет, который экспортировал модуль под этим именем. Для повторно экспортируемых модулей существует ослабленное ограничение пересечения: два пакета могут повторно экспортировать один и тот же модуль под одним и тем же именем, если этот повторно экспортируемый модуль идентичен.

trusted

(bool) Является ли пакет надёжным.

import-dirs

(список строк) Список каталогов, содержащих файлы интерфейса (файлы .hi) для этого пакета.

Если пакет содержит библиотеки профилирования, то файлы интерфейса для этих модулей библиотек должны иметь суффикс .p_hi. Таким образом, пакет может содержать как обычные, так и профилирующие версии одной и той же библиотеки без конфликтов (см. также library_dirs ниже).

library-dirs

(список строк) Список каталогов, содержащих библиотеки для этого пакета.

hs-libraries

(список строк) Список библиотек, содержащих код Haskell для этого пакета, без суффиксов .a или .dll. При построении пакетов как библиотек также опускается префикс lib.

Для использования с GHCi каждая библиотека должна иметь также файл объекта. Имя файла объекта не имеет префикса lib и имеет обычный суффикс объекта для вашей платформы.

Например, если мы указали Haskell-библиотеку как HSfoo в спецификации пакета, то различные типы библиотек, которые фактически использует GHC, будут называться:

libHSfoo.a

Название библиотеки на системах Unix и Windows (mingw). Обратите внимание, что мы не поддерживаем построение динамических библиотек кода Haskell на системах Unix.

HSfoo.dll

Имя динамической библиотеки на системах Windows (необязательно).

HSfoo.o; HSfoo.obj

Объектная версия библиотеки, используемой GHCi.

extra-libraries

(список строк) Список дополнительных библиотек для этого пакета. Разница между hs-libraries и extra-libraries заключается в том, что hs-libraries обычно имеют несколько версий для поддержки профилирования, параллельности и других вариантов построения. Разным версиям присваиваются различные суффиксы для их различения, например, профилирующая версия стандартной библиотеки префиксов называется libHSbase_p.a с _p, указывающей, что это профилирующая версия. Суффикс автоматически добавляется GHC только для hs-libraries, а для библиотек в extra-libraries суффикс не добавляется.

Библиотеки, перечисленные в extra-libraries, могут быть любыми библиотеками, поддерживаемыми компоновщиком вашей системы, включая динамические библиотеки (.so на Unix, .DLL на Windows).

Также extra-libraries помещаются в командную строку компоновщика после hs-libraries для того же пакета. Если ваш пакет имеет зависимости в обратном направлении (т. е. extra-libraries зависит от hs-libraries), и библиотеки статичны, вам может потребоваться создать два отдельных пакета.

include-dirs

(список строк) Список каталогов, содержащих C-заголовки для этого пакета.

includes

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

depends

(список идентификаторов пакетов) Пакеты, от которых зависит этот пакет.

hugs-options

(список строк) Параметры для Hugs для этого пакета.

cc-options

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

ld-options

(список строк) Дополнительные аргументы, которые необходимо добавить в командную строку gcc (для компоновки) при использовании этого пакета.

framework-dirs

(список строк) На Darwin/MacOS X, список каталогов, содержащих фреймворки для этого пакета. Это соответствует параметру -framework-path. Игнорируется на всех других платформах.

frameworks

(список строк) На Darwin/MacOS X, список фреймворков, к которым следует подключиться. Обратитесь к документации разработчика Apple, чтобы узнать, что такое фреймворки на самом деле. Это поле игнорируется на всех других платформах.

haddock-interfaces

(список строк) Список имен файлов, содержащих файлы интерфейса Haddock (файлы .haddock) для этого пакета.

haddock-html

(необязательная строка) Каталог, содержащий сгенерированный Haddock HTML для этого пакета.

1

Использовалось в GHC 6.4, но не использовалось с 6.6.

© 2002–2007 The University Court of the University of Glasgow. All rights reserved.
Licensed under the Glasgow Haskell Compiler License.
https://downloads.haskell.org/~ghc/8.10.2/docs/html/users_guide/packages.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API