Spec-Zone.ru › Haskell 9

5.9. Пакеты

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

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

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

5.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.1
    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 передаёт GHC флаги -package-id. -package-id поддерживает утончение и переименование, описанные в Утончение и переименование модулей.

-hide-all-packages

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

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

-hide-package ⟨pkg⟩

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

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

-ignore-package ⟨pkg⟩

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

Указание -ignore-package ⟨pkg⟩ эквивалентно заданию флагов -hide-package ⟨pkg⟩ для ⟨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).

5.9.2. Пакет main

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

/usr/bin/ld: Undefined symbols:
_ZCMain_main_closure

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

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

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

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

5.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.

Импорты пакетов с отображением/переименованием не скрывают другие версии пакета: например, если контейнеры-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.

5.9.5. Пакетные базы данных

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

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

  • Глобальная база данных пакетов, которая поставляется с вашей установкой GHC, например, /usr/lib/ghc-6.12.1/package.conf.d.
  • Пользовательская база данных пакетов, личная для каждого пользователя. В системах Unix это будет $XDG_DATA_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 для указания позиции в стеке, где должна быть загружена пользовательская база данных пакетов.

5.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=$XDG_DATA_HOME/.my-ghc-packages.conf:

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

5.9.5.2. Среды пакетов

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

В случае ghci файл среды будет прочитан один раз во время инициализации. Если файл изменится, вам нужно будет перезапустить 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⟩, или из $XDG_DATA_HOME/ghc/arch-os-version/environments/⟨name⟩. Если установлено значение -, среда пакета не читается.

GHC_ENVIRONMENT

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

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

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

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

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

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

5.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.

5.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⟩ в list, describe и field, где '*' обозначает открытые концы подстроки (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, --unit-id

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

5.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⟩. См. также Параметры, влияющие на генерацию кода о том, как файлы объектов должны быть подготовлены для связывания общих объектов.

  • При построении общей библиотеки необходимо позаботиться о том, чтобы результирующий объект имел соответствующее имя. В частности, GHC ожидает, что имя общего объекта будет иметь вид libHS<unit id>-ghc<ghc version>.<ext>, где идентификатор единицы — идентификатор единицы, заданный во время компиляции с помощью флага -this-unit-id ⟨unit-id⟩, версия ghc — версия GHC, которая создала/использует объект, а расширение — обычное расширение файла общих объектов для хостовой системы.

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

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

5.9.9. InstalledPackageInfo: a package specification

A package specification is a Haskell record; in particular, it is the record Distribution.InstalledPackageInfo.InstalledPackageInfo in the module Distribution.InstalledPackageInfo, which is part of the Cabal package distributed with GHC.

An InstalledPackageInfo has a human readable/writable syntax. The functions parseInstalledPackageInfo and showInstalledPackageInfo read and write this syntax respectively. Here’s an example of the InstalledPackageInfo for the unix package:

$ 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

Here is a brief description of the syntax of this file:

A package description consists of a number of field/value pairs. A field starts with the field name in the left-hand column followed by a “:”, and the value continues until the next line that begins in the left-hand column, or the end of file.

The syntax of the value depends on the field. The various field types are:

freeform

Any arbitrary string, no interpretation or parsing is done.

string

A sequence of non-space characters, or a sequence of arbitrary characters surrounded by quotes "....".

string list

A sequence of strings, separated by commas. The sequence may be empty.

In addition, there are some fields with special syntax (e.g. package names, version, dependencies).

The allowed fields, with their types, are:

name

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

id

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

version

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

license

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

license-file

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

copyright

(optional freeform) Строка авторского права.

maintainer

(optional freeform) Электронный адрес основного разработчика пакета.

stability

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

homepage

(optional freeform) URL домашней страницы пакета.

package-url

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

description

(optional freeform) Описание пакета.

category

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

author

(optional freeform) Автор пакета.

exposed

(bool) Пакет открыт или нет.

exposed-modules

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

hidden-modules

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

reexported-modules

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

trusted

(bool) Пакет доверенный или нет.

import-dirs

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

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

library-dirs

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

hs-libraries

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

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

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

libHSfoo.a

Имя библиотеки в системах Unix и Windows (mingw).

HSfoo.dll

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

HSfoo.o; HSfoo.obj

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

extra-libraries

(string list) Список дополнительных библиотек для этого пакета. Разница между 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

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

includes

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

depends

(package id list) Пакеты, от которых зависит этот пакет.

hugs-options

(string list) Параметры, передаваемые в Hugs для этого пакета.

cc-options

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

ld-options

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

framework-dirs

(string list) В Darwin/MacOS X, список каталогов, содержащих фреймворки для этого пакета. Соответствует опции -framework-path. Игнорируется на всех остальных платформах.

frameworks

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

haddock-interfaces

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

haddock-html

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

[1]

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

5.9.10. Связывание с C++ библиотеками

Использование C++ библиотек требует, чтобы пользователь связал его с стандартной C++ библиотекой хост-системы. Поскольку необходимая для этого конфигурация обычно зависит от платформы, GHC предоставляет встроенный пакет system-cxx-std-lib. Этот пакет содержит конфигурацию для линковки со стандартной C++ библиотекой и может использоваться с флагом -package ⟨pkg⟩ или полем Cabal build-depends для линковки кода со стандартной C++ библиотекой.

© 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/9.12.1/docs/users_guide/packages.html

Spec-Zone.ru

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