This is guix.ru.info, produced by makeinfo version 6.7 from
guix.ru.texi.

Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021
Ludovic Courtès
Copyright © 2013, 2014, 2016 Andreas Enge
Copyright © 2013 Nikita Karetnikov
Copyright © 2014, 2015, 2016 Alex Kost
Copyright © 2015, 2016 Mathieu Lirzin
Copyright © 2014 Pierre-Antoine Rault
Copyright © 2015 Taylan Ulrich Bayırlı/Kammer
Copyright © 2015, 2016, 2017, 2019, 2020, 2021 Leo Famulari
Copyright © 2015, 2016, 2017, 2018, 2019, 2020 Ricardo Wurmus
Copyright © 2016 Ben Woodcroft
Copyright © 2016, 2017, 2018, 2021 Chris Marusich
Copyright © 2016, 2017, 2018, 2019, 2020, 2021 Efraim Flashner
Copyright © 2016 John Darrington
Copyright © 2016, 2017 Nikita Gillmann
Copyright © 2016, 2017, 2018, 2019, 2020 Jan Nieuwenhuizen
Copyright © 2016, 2017, 2018, 2019, 2020 Julien Lepiller
Copyright © 2016 Alex ter Weele
Copyright © 2016, 2017, 2018, 2019, 2020, 2021 Christopher Baines
Copyright © 2017, 2018, 2019 Clément Lassieur
Copyright © 2017, 2018, 2020, 2021 Mathieu Othacehe
Copyright © 2017 Federico Beffa
Copyright © 2017, 2018 Carlo Zancanaro
Copyright © 2017 Thomas Danckaert
Copyright © 2017 humanitiesNerd
Copyright © 2017, 2021 Christopher Lemmer Webber
Copyright © 2017, 2018, 2019, 2020 Marius Bakke
Copyright © 2017, 2019, 2020 Hartmut Goebel
Copyright © 2017, 2019, 2020, 2021 Maxim Cournoyer
Copyright © 2017, 2018, 2019, 2020, 2021 Tobias Geerinckx-Rice
Copyright © 2017 George Clemmer
Copyright © 2017 Andy Wingo
Copyright © 2017, 2018, 2019, 2020 Arun Isaac
Copyright © 2017 nee
Copyright © 2018 Rutger Helling
Copyright © 2018, 2021 Oleg Pykhalov
Copyright © 2018 Mike Gerwitz
Copyright © 2018 Pierre-Antoine Rouby
Copyright © 2018, 2019 Gábor Boskovits
Copyright © 2018, 2019, 2020 Florian Pelz
Copyright © 2018 Laura Lazzati
Copyright © 2018 Alex Vong
Copyright © 2019 Josh Holland
Copyright © 2019, 2020 Diego Nicola Barbato
Copyright © 2019 Ivan Petkov
Copyright © 2019 Jakob L. Kreuze
Copyright © 2019 Kyle Andrews
Copyright © 2019 Alex Griffin
Copyright © 2019, 2020 Guillaume Le Vaillant
Copyright © 2020 Leo Prikler
Copyright © 2019, 2020 Simon Tournier
Copyright © 2020 Wiktor Żelazny
Copyright © 2020 Damien Cassou
Copyright © 2020 Jakub Kądziołka
Copyright © 2020 Jack Hill
Copyright © 2020 Naga Malleswari
Copyright © 2020 Brice Waegeneire
Copyright © 2020 R Veera Kumar
Copyright © 2020 Pierre Langlois
Copyright © 2020 pinoaffe
Copyright © 2020 André Batista
Copyright © 2020, 2021 Alexandru-Sergiu Marton
Copyright © 2020 raingloom
Copyright © 2020 Daniel Brooks
Copyright © 2020 John Soo
Copyright © 2020 Jonathan Brielmaier
Copyright © 2020 Edgar Vincent
Copyright © 2021 Maxime Devos

   Разрешено копирование, распространение и/или модификация этого
документа на условиях лицензии свободной документации GNU (GNU FDL)
версии 1.3 или любой более поздней версии, опубликованной Фондом
свободного программного обеспечения (FSF), исключая неизменяемые секции,
исключая тексты, размещенные на переплёте и задней стороне обложки.
Копия лицензии включена в документ в разделе под названием "GNU Free
Documentation Licens".
INFO-DIR-SECTION Администрирование системы
START-INFO-DIR-ENTRY
* Guix: (guix).              Управление установленным
                               ПО и настройка системы.
* guix package: (guix)Запуск guix package.  Установка,
                                                    удаление и
                                                    обновление
                                                    пакетов.
* guix gc: (guix)Запуск guix gc.  Освобождение
                                          неиспользуемого
                                          места на диске.
* guix pull: (guix)Запуск guix pull.  Обновление
                                              списка доступных
                                              пакетов.
* guix system: (guix)Запуск guix system.  Управление
                                                  конфигурацией
                                                  ОС.
* guix deploy: (guix)Запуск guix deploy.  Управление
                                                  конфигурациями
                                                  ОС на удалённых
                                                  машинах.
END-INFO-DIR-ENTRY

INFO-DIR-SECTION Разработка программного обеспечения
START-INFO-DIR-ENTRY
* guix environment: (guix)Запуск guix environment.  Сборка
                                                            среды
                                                            разработки
                                                            с помощью
                                                            Guix.
* guix build: (guix)Запуск guix build.  Сборка пакетов.
* guix pack: (guix)Запуск guix pack.  Создание
                                              бинарных пакетов.
END-INFO-DIR-ENTRY


File: guix.ru.info,  Node: Использование отдельного канала Guix,  Next: Копирование Guix,  Prev: Указание дополнительных каналов,  Up: Каналы

6.2 Использование отдельного канала Guix
========================================

The channel called ‘guix’ specifies where Guix itself—its command-line
tools as well as its package collection—should be downloaded.  For
instance, suppose you want to update from another copy of the Guix
repository at ‘example.org’, and specifically the ‘super-hacks’ branch,
you can write in ‘~/.config/guix/channels.scm’ this specification:

     ;; Tell 'guix pull' to use another repo.
     (list (channel
             (name 'guix)
             (url "https://example.org/another-guix.git")
             (branch "super-hacks")))

From there on, ‘guix pull’ will fetch code from the ‘super-hacks’ branch
of the repository at ‘example.org’.  The authentication concern is
addressed below ((*note Аутентификация канала::).


File: guix.ru.info,  Node: Копирование Guix,  Next: Аутентификация канала,  Prev: Использование отдельного канала Guix,  Up: Каналы

6.3 Копирование Guix
====================

Результат ‘guix pull --list-generations’ выше показывает точно, какие
коммиты были использованы для сборки данной инстанции Guix.  Так что мы
можем повторить её, скажем, на другой машине, предоставив объявление
канала в ‘~/.config/guix/channels.scm’, которое завязано на этих
коммитах:

     ;; Deploy specific commits of my channels of interest.
     (list (channel
            (name 'guix)
            (url "https://git.savannah.gnu.org/git/guix.git")
            (commit "6298c3ffd9654d3231a6f25390b056483e8f407c"))
           (channel
            (name 'variant-packages)
            (url "https://example.org/variant-packages.git")
            (commit "dd3df5e2c8818760a8fc0bd699e55d3b69fef2bb")))

   The ‘guix describe --format=channels’ command can even generate this
list of channels directly (*note Вызов guix describe::).  The resulting
file can be used with the -C options of ‘guix pull’ (*note Запуск guix
pull::) or ‘guix time-machine’ (*note Вызов guix time-machine::).

   И тогда две машины будут работать с _полностью одинаковым Guix_, имея
доступ к _абсолютно одинаковым пакетам_.  Результат ‘guix build gimp’ на
одной машине будет совершенно таким же, бит к биту, как результат этой
команды на другой машине.  Это также означает, что обе машины имеют
доступ ко всем исходным кодам Guix, следовательно, ко всем исходным
кодам каждого пакета, определённого в Guix.

   Это даёт вам супервозможности, позволяя вам отслеживать и управлять
происхождением артефактов бинарников с точной детализацией, также
повторять программные окружения — это воспроизводимость высокого уровня.
Смотрите *Note Младшие версии::, чтобы узнать другие преимущества таких
супервозможностей.


File: guix.ru.info,  Node: Аутентификация канала,  Next: Каналы с заменителями,  Prev: Копирование Guix,  Up: Каналы

6.4 Аутентификация канала
=========================

‘guix pull’ и ‘guix time-machine’ “аутентифицируют” код, полученный из
каналов: они гарантируют, что каждый полученный коммит подписан
авторизованным разработчиком.  Цель состоит в том, чтобы защитить канал
от несанкционированных изменений, которые могут привести к запуску
вредоносного кода пользователями.

   Как пользователь, вы должны предоставить “channel introduction” в
вашем файле канала, чтобы Guix знал как авторизовать свой первый коммит.
Спецификация канала, включая введения, выглядит как-то так:

     (channel
       (name 'some-channel)
       (url "https://example.org/some-channel.git")
       (introduction
        (make-channel-introduction
         "6f0d8cc0d88abb59c324b2990bfee2876016bb86"
         (openpgp-fingerprint
          "CABB A931 C0FF EEC6 900D  0CFB 090B 1199 3D9A EBB5"))))

   В приведенной выше спецификации указано имя и URL-адрес канала.
Вызов ‘make-channel-introduction’ выше указывает, что аутентификация
этого канала начинается с коммита ‘6f0d8cc...’, который подписывается
ключом OpenPGP с отпечатком ‘CABB A931...’.

   Для основного канала, называемого ‘guix’, вы автоматически получаете
эту информацию из вашей установки Guix.  Для других каналов, укажите
introduction для канала, предоставленное авторами канала, в ваш файл
‘channels.scm’.  Убедитесь, что вы получили introduction канала из
надежного источника, так как это основа вашего доверия.

   Если вам любопытены механизмы авторизации, читайте дальше!


File: guix.ru.info,  Node: Каналы с заменителями,  Next: Создание канала,  Prev: Аутентификация канала,  Up: Каналы

6.5 Каналы с заменителями
=========================

When running ‘guix pull’, Guix will first compile the definitions of
every available package.  This is an expensive operation for which
substitutes (*note Подстановки::) may be available.  The following
snippet in ‘channels.scm’ will ensure that ‘guix pull’ uses the latest
commit with available substitutes for the package definitions: this is
done by querying the continuous integration server at
<https://ci.guix.gnu.org>.

     (use-modules (guix ci))

     (list (channel-with-substitutes-available
            %default-guix-channel
            "https://ci.guix.gnu.org"))

   Note that this does not mean that all the packages that you will
install after running ‘guix pull’ will have available substitutes.  It
only ensures that ‘guix pull’ will not try to compile package
definitions.  This is particularly useful when using machines with
limited resources.


File: guix.ru.info,  Node: Создание канала,  Next: Пакетные модули в поддиректории,  Prev: Каналы с заменителями,  Up: Каналы

6.6 Создание канала
===================

Let’s say you have a bunch of custom package variants or personal
packages that you think would make little sense to contribute to the
Guix project, but would like to have these packages transparently
available to you at the command line.  You would first write modules
containing those package definitions (*note Пакетные модули::), maintain
them in a Git repository, and then you and anyone else can use it as an
additional channel to get packages from.  Neat, no?

     Внимание: Прежде чем вы крикнете _Ух-ты, это круто!_  и опубликуете
     собственный канал, необходимо учесть некоторые предостережения:

        • Перед публикацией канала, пожалуйста, рассмотрите возможность
          поделиться вашими определениями пакетов со сборником Guix
          (*note Содействие::).  Guix, как проект, открыт свободному
          программному обеспечению любого назначения, и пакеты в
          сборнике Guix готовы и доступны для использования всеми
          пользователями Guix и прошли проверку качества.

        • Когда вы выгружаете определение пакета вне Guix, мы,
          разработчики Guix, полагаем, что вопрос _совместимости ложится
          на вас_.  Учтите, что пакетные модули и определения пакетов —
          это код Scheme, который используют различные программные
          интерфейсы (API). Мы хотим оставить возможность для себя
          изменять эти API, чтобы продолжить улучшать Guix.  И это может
          привести к поломке вашего канала.  Мы никогда не меняем API
          необоснованно, но всё же мы _не_ будем обновлять устаревшие,
          замороженные API.

        • Вывод: если вы используете внешний канал, и этот канал
          ломается, пожалуйста, _заявите об этой проблеме авторам
          каналв_, но не в проект Guix.

     Вы предупреждены!  Обозначив это, мы верим, что внешние каналы —
     это способ для вас проявлять свою свободу и вместе с тем расширять
     коллекцию пакетов Guix и делиться улучшениями, что является
     основными догматами свободного программного обеспечения
     (https://www.gnu.org/philosophy/free-sw.ru.html).  Пожалуйста,
     свяжитесь с нами по e-mail <guix-devel@gnu.org>, если вы хотите
     обсудить это.

   Чтобы создать канал, создайте репозиторий Git, содержащий ваши
собственные пакетные модули, и сделайте его доступным.  Репозиторий
может содержать что-либо, но полезный канал будет содержать модули
Guile, экспортирующие пакеты.  Когда вы начали использовать канал, Guix
будет работать, как будто корневая директория репозитория Git этого
канала добавлена в путь загрузки Guile (*note (guile)Load Paths::).
Например, если ваш канал содержит файл ‘my-packages/my-tools.scm’,
который определяет модуль Guile, тогда модуль будет доступен под именем
‘(my-packages my-tools)’, и вы сможете использовать его, как любой
другой модуль (*note (guile)Модули::).

   Как автор канала, рассмотрите возможность объединения материалов для
аутентификации с вашим каналом, чтобы пользователи могли его
аутентифицировать.  *Note Аутентификация канала:: и *note Указание
авторизаций канала:: для получения информации о том, как это сделать.


File: guix.ru.info,  Node: Пакетные модули в поддиректории,  Next: Объявление зависимостей канала,  Prev: Создание канала,  Up: Каналы

6.7 Пакетные модули в поддиректории
===================================

Как автор канала, вы можете хранить модули канала в подкаталоге.  Если
ваши модули находятся в подкаталоге ‘guix’, вы должны добавить файл
метаданных ‘.guix-channel’, который содержит:

     (channel
       (version 0)
       (directory "guix"))


File: guix.ru.info,  Node: Объявление зависимостей канала,  Next: Указание авторизаций канала,  Prev: Пакетные модули в поддиректории,  Up: Каналы

6.8 Объявление зависимостей канала
==================================

Авторы канала могут решить расширить коллекцию пакетов пакетами, которые
поставляются другими каналами.  Они могут объявить, что их канал зависит
от других каналов, в файле метаданных ‘.guix-channel’, который нужно
разместить в корне репозитория канала.

   Файл метаданных должен содержать простое выражение S-expression как
это:

     (channel
      (version 0)
      (dependencies
       (channel
        (name some-collection)
        (url "https://example.org/first-collection.git")

        ;; The 'introduction' bit below is optional: you would
        ;; provide it for dependencies that can be authenticated.
        (introduction
         (channel-introduction
           (version 0)
           (commit "a8883b58dc82e167c96506cf05095f37c2c2c6cd")
           (signer "CABB A931 C0FF EEC6 900D  0CFB 090B 1199 3D9A EBB5"))))
       (channel
        (name some-other-collection)
        (url "https://example.org/second-collection.git")
        (branch "testing"))))

   В примере выше объявлен канал, который зависит от двух других
каналов, из которых оба будут скачаны автоматически.  Модули,
предоставляемые каналом, будут скомпилированы в окружении, в котором
доступны модули всех этих каналов.

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


File: guix.ru.info,  Node: Указание авторизаций канала,  Next: Основной URL,  Prev: Объявление зависимостей канала,  Up: Каналы

6.9 Указание авторизаций канала
===============================

Как мы видели выше, Guix гарантирует, что исходный код, который он
получает из каналов, поступает от авторизованных разработчиков.  Как
автор канала, вам необходимо указать список авторизованных разработчиков
в файле ‘.guix-authorizations’ в репозитории Git канала.  Правило
аутентификации простое: каждый коммит должен быть подписан ключом,
указанным в файле ‘.guix-authorizations’ его родительского коммита(ов)
(1) файл ‘.guix-authorizations’ выглядит так:

     ;; Пример '.guix-authorizations' файла.

     (authorizations
      (version 0)               ;current file format version

      (("AD17 A21E F8AE D8F1 CC02  DBD9 F8AE D8F1 765C 61E3"
        (name "alice"))
       ("2A39 3FFF 68F4 EF7A 3D29  12AF 68F4 EF7A 22FB B2D5"
        (name "bob"))
       ("CABB A931 C0FF EEC6 900D  0CFB 090B 1199 3D9A EBB5"
        (name "charlie"))))

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

   Это правило аутентификации создает проблему с курицей и яйцом: как мы
аутентифицируем первый коммит?  В связи с этим: как нам поступать с
каналами, история репозитория которых содержит неподписанные коммиты и
не имеет ‘.guix-authorizations’?  И как нам разветвлять существующие
каналы?

   Channel introductory отвечает на данные вопросы, описывая первый
коммит канала, который должен быть аутентифицирован.  При первом вызове
канала с помощью ‘guix pull’ или ‘guix time-machine’ команда ищет
introductory коммит и проверяет, что он подписан указанным ключом
OpenPGP. С этого момента он аутентифицирует коммиты в соответствии с
приведенным выше правилом.

   Кроме того, ваш канал должен предоставлять все ключи OpenPGP, которые
когда-либо упоминались в ‘.guix-authorizations’, хранящиеся как файлы
‘.key’, которые могут быть либо двоичными, либо “ASCII-armored”.  По
умолчанию эти файлы ‘.key’ ищутся в ветке с именем ‘keyring’, но вы
можете указать другое имя ветки в ‘.guix-channel’ следующим образом:

     (channel
       (version 0)
       (keyring-reference "my-keyring-branch"))

   Подытоживая, как автор канала, вы должны сделать три вещи, чтобы
позволить другим пользователям авторизовать ваш код:

  1. Экспортируйте ключи OpenPGP прошлых и нынешних коммиттеров с
     помощью ‘gpg --export’ и сохраните их в файлах ‘.key’, по умолчанию
     в ветке с именем ‘keyring’ (мы рекомендуем сделать это в “orphan
     branch”).

  2. Добавьте ‘.guix-authorizations’ в репозиторий канала.  Сделайте это
     в подписанном коммите (*note Доступ к коммитам::, чтобы узнать, как
     подписывать коммиты Git)

  3. Рекламируйте channel introduction, например, на веб-странице вашего
     канала.  Channel introduction, как мы видели выше, - это пара
     коммит/ключ, то есть коммит, который представляет
     ‘.guix-authorizations’, и отпечаток OpenPGP, использованный для его
     подписи.

   Перед отправкой в ваш общедоступный репозиторий Git вы можете
запустить ‘guix git-authenticate’, чтобы убедиться, что вы подписали все
коммиты, которые собираетесь отправить, авторизованным ключом:

     guix git authenticate COMMIT SIGNER

где COMMIT и SIGNER являются вашим channel introduction.  *Note Запуск
guix git authenticate::, подробнее.

   Публикация подписанного канала требует дисциплины: любая ошибка,
такая как неподписанная фиксация или фиксация, подписанная
неавторизованным ключом, не позволит пользователям pull’ить с вашего
канала - в этом весь смысл аутентификации!  Обратите внимание на merge,
в частности: merge коммиты считаются аутентичными, если и только если
они подписаны ключом, присутствующим в файле ‘.guix-authorizations’
_обоих_ веток.

   ---------- Footnotes ----------

   (1) Git коммитит из “directed acyclic graph”(DAG). У каждого коммита
может быть ноль или более родителей; “обычные” коммиты имеют одного
родителя, а “merge” коммиты имеют два родительских коммита.  Прочтите
Git for Computer Scientists
(https://eagain.net/articles/git-for-computer-scientists/), чтобы
получить больше информации.


File: guix.ru.info,  Node: Основной URL,  Next: Написание новостей канала,  Prev: Указание авторизаций канала,  Up: Каналы

6.10 Основной URL
=================

Авторы каналов могут указать основной URL-адрес репозитория Git своего
канала в файле ‘.guix-channel’, например:

     (channel
       (version 0)
       (url "https://example.org/guix.git"))

   This allows ‘guix pull’ to determine whether it is pulling code from
a mirror of the channel; when that is the case, it warns the user that
the mirror might be stale and displays the primary URL.  That way, users
cannot be tricked into fetching code from a stale mirror that does not
receive security updates.

   Эта функция имеет смысл только для аутентифицированных репозиториев,
таких как официальный канал ‘guix’, для которого ‘guix pull’
гарантирует, что полученный код аутентичен.


File: guix.ru.info,  Node: Написание новостей канала,  Prev: Основной URL,  Up: Каналы

6.11 Написание новостей канала
==============================

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

   Вместо этого каналы могут предоставлять “файл новостей”; когда
пользователи канала запускают ‘guix pull’, этот файл новостей
автоматически читается, и ‘guix pull --news’ может отображать
объявления, которые соответствуют новым зафиксированным коммитам, если
таковые имеются.

   Для этого авторы каналов должны сначала объявить имя файла новостей в
своем файле ‘.guix-channel’:

     (channel
       (version 0)
       (news-file "etc/news.txt"))

   Сам файл новостей, ‘etc/news.txt’ в этом примере, должен выглядеть
примерно так:

     (channel-news
       (version 0)
       (entry (tag "the-bug-fix")
              (title (en "Fixed terrible bug")
                     (fr "Oh la la"))
              (body (en "@emph{Good news}!  It's fixed!")
                    (eo "Certe ĝi pli bone funkcias nun!")))
       (entry (commit "bdcabe815cd28144a2d2b4bc3c5057b051fa9906")
              (title (en "Added a great package")
                     (ca "Què vol dir guix?"))
              (body (en "Don't miss the @code{hello} package!"))))

   В то время как файл новостей использует синтаксис Scheme, избегайте
называть его расширением ‘.scm’, иначе он будет выбран при построении
канала и выдаст ошибку, поскольку это недопустимый модуль.  Кроме того,
вы можете переместить модуль канала в подкаталог и сохранить файл
новостей в другом каталоге.

   Файл состоит из списка “news entries”.  Каждая запись связана с
коммитом или тегом: она описывает изменения, сделанные в этом коммите,
возможно, также и в предыдущих коммитах.  Пользователи видят записи
только при первом получении коммита, на который ссылается запись.

   Поле ‘title’ должно быть однострочным, а ‘body’ может быть
произвольно длинным, и оба могут содержать Texinfo разметку (*note
(texinfo)Overview::).  И заголовок, и тело являются списком языковых
тегов/кортежей сообщений, что позволяет комманде ‘guix pull’ отображать
новости на языке, соответствующем языку пользователя.

   Если вы хотите перевести новости, используя рабочий процесс на основе
gettext, вы можете извлечь переводимые строки с помощью ‘xgettext’
(*note (gettext)xgettext Invocation::).  Например, если вы сначала
пишете новости на английском языке, команда ниже создает PO-файл,
содержащий строки для перевода:

     xgettext -o news.po -l scheme -ken etc/news.txt

   Подводя итог, да, вы можете использовать свой канал в качестве блога.
Но будьте осторожны, это _не совсем_ то, что могут ожидать ваши
пользователи.


File: guix.ru.info,  Node: Разработка,  Next: Программный интерфейс,  Prev: Каналы,  Up: Top

7 Разработка
************

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

   Команда ‘guix environment’ предоставляет удобный способ установить
“окружение разработки” на ваш выбор, содержащее все зависимости и
инструменты, необходимые для работы с пакетом программы.  Команда ‘guix
pack’ позволяет создавать “наборы приложений”, которые могут легко
распространяться для пользователей, которые не используют Guix.

* Menu:

* Запуск guix environment::  Настройка окружения
                                     сборки.
* Запуск guix pack::   Создание наборов
                               программ.
* Тулчейн GCC::       Работа с языками,
                               поддерживаемыми gcc.
* Запуск guix git authenticate::  Аутентификация Git
                                          репозиториев.


File: guix.ru.info,  Node: Запуск guix environment,  Next: Запуск guix pack,  Up: Разработка

7.1 Вызов ‘guix environment’
============================

Цель ‘guix environment’ — помощь программистам в создании окружения
разработки, которое можно повторять, без влияния на профили пакетов.
Инструмент ‘guix environment’ принимает один или более пакетов, собирает
все входные данные для них и создаёт окружение оболочки для их
использования.

   Основной синтаксис:

     guix environment OPTIONS PACKAGE...

   Следующий пример порождает новую оболочку, установленную для
разработки GNU Guile:

     guix environment guile

   Если необходимые зависимости еще не собраны, ‘guix environment’
автоматически построит их.  Среда новой оболочки - это расширенная
версия среды, в которой была запущена ‘guix environment’.  Она содержит
необходимые пути поиска для сборки данного пакета, добавленные к
существующим переменным среды.  Чтобы создать “чистую” среду, в которой
исходные переменные среды не были установлены, используйте параметр
‘--pure’ (1).

   Exiting from a Guix environment is the same as exiting from the
shell, and will place the user back in the old environment before ‘guix
environment’ was invoked.  The next garbage collection (*note Вызов guix
gc::) will clean up packages that were installed from within the
environment and are no longer used outside of it.

   ‘guix environment’ defines the ‘GUIX_ENVIRONMENT’ variable in the
shell it spawns; its value is the file name of the profile of this
environment.  This allows users to, say, define a specific prompt for
development environments in their ‘.bashrc’ (*note (bash)Bash Startup
Files::):

     if [ -n "$GUIX_ENVIRONMENT" ]
     then
         export PS1="\u@\h \w [dev]\$ "
     fi

... или просмотеть профиль:

     $ ls "$GUIX_ENVIRONMENT/bin"

   Дополним, что может быть указано более одного пакета, в таком случае
используется объединённые входные данные для указанных пакетов.
Например, команда ниже порождает оболочку, в котором доступны все
зависимости, как Guile, так и Emacs:

     guix environment guile emacs

   Иногда интерактивная сессия оболочки не нужна.  Можно вызвать
произвольную команду при указании токена ‘--’, который отделяет команду
от остальных аргументов:

     guix environment guile -- make -j4

   В других ситуациях удобнее указать список паетов, необходимых для
окружения.  Например, следующая команда запускает ‘python’ из окружения,
содержащего Python 2.7 и NumPy:

     guix environment --ad-hoc python2-numpy python-2.7 -- python

   Furthermore, one might want the dependencies of a package and also
some additional packages that are not build-time or runtime
dependencies, but are useful when developing nonetheless.  Because of
this, the ‘--ad-hoc’ flag is positional.  Packages appearing before
‘--ad-hoc’ are interpreted as packages whose dependencies will be added
to the environment.  Packages appearing after are interpreted as
packages that will be added to the environment directly.  For example,
the following command creates a Guix development environment that
additionally includes Git and strace:

     guix environment --pure guix --ad-hoc git strace

   Иногда возникает необходимость изолировать окружение настолько,
насколькоо возможно, для максимальной чистоты и воспроизводимости.  В
частности, при использовании Guix на дистрибутиве, отличном от системы
Guix, желательно предотвращать доступ из окружения разработки к
‘/usr/bin’ и другим ресурсам системы.  Например, следующая команда
порождает Guile REPL в "контейнере", в котором монтированы только склад
и текущая рабочая директория:

     guix environment --ad-hoc --container guile -- guile

     Примечание: The ‘--container’ option requires Linux-libre 3.19 or
     newer.

   Another typical use case for containers is to run security-sensitive
applications such as a web browser.  To run Eolie, we must expose and
share some files and directories; we include ‘nss-certs’ and expose
‘/etc/ssl/certs/’ for HTTPS authentication; finally we preserve the
‘DISPLAY’ environment variable since containerized graphical
applications won’t display without it.

     guix environment --preserve='^DISPLAY$' --container --network \
       --expose=/etc/machine-id \
       --expose=/etc/ssl/certs/ \
       --share=$HOME/.local/share/eolie/=$HOME/.local/share/eolie/ \
       --ad-hoc eolie nss-certs dbus --  eolie

   Доступные опции резюмированы ниже.

‘--root=FILE’
‘-r FILE’
     Создать символическую ссылку FILE на профиль этого окружения и
     зарегистрировать её как корень сборщика мусора.

     Это полезно, если вы хотите защитить своё окружение от сборщика
     мусора, сделать его "постоянным".

     Если эта опция пропущена, окружеие защищено от сборщика мусора
     только на время сессии ‘guix environment’.  Это означает, что в
     следующий раз, когда вы создадите такое же окружение, вам
     потребуется пересобирать и скачивать пакеты заново.  *Note Вызов
     guix gc::, for more on GC roots.

‘--expression=EXPR’
‘-e EXPR’
     Создать окружение для пакета или списка пакетов, которые
     соответствуют выражению EXPR.

     Например, запуск:

          guix environment -e '(@ (gnu packages maths) petsc-openmpi)'

     запускает оболочку с окружением для этого специфического варианта
     пакета PETSc.

     Запуск:

          guix environment --ad-hoc -e '(@ (gnu) %base-packages)'

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

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

          guix environment --ad-hoc -e '(list (@ (gnu packages bash) bash) "include")'

‘--load=FILE’
‘-l FILE’
     Создать окружение для пакета или списка пакетов, код которых задан
     в файле FILE.

     Например, FILE может содержать определение (*note Описание
     пакетов::):

          (use-modules (guix)
                       (gnu packages gdb)
                       (gnu packages autotools)
                       (gnu packages texinfo))
          
          ;; Augment the package definition of GDB with the build tools
          ;; needed when developing GDB (and which are not needed when
          ;; simply installing it.)
          (package (inherit gdb)
            (native-inputs `(("autoconf" ,autoconf-2.64)
                             ("automake" ,automake)
                             ("texinfo" ,texinfo)
                             ,@(package-native-inputs gdb))))

‘--manifest=FILE’
‘-m FILE’
     Create an environment for the packages contained in the manifest
     object returned by the Scheme code in FILE.  This option can be
     repeated several times, in which case the manifests are
     concatenated.

     Это то же, что опция с таким же именем в ‘guix package’ (*note
     ‘--manifest’: profile-manifest.) и использует такие же файлы
     манифестов.

‘--ad-hoc’
     Включить все указанные пакеты в результирующее окружение, если бы
     целевой (лат.  ad hoc) пакет имел бы их как входные данные.  Эта
     опция полезна для быстрого создания окружения без необходимости
     писать выражение типа пакет, содержащее желаемые входные данные.

     Например, команда:

          guix environment --ad-hoc guile guile-sdl -- guile

     запускает ‘guile’ в окружении, в котором доступны Guile и
     Guile-SDL.

     Отметим, что этот пример явно запрашивает выходы ‘guile’ и
     ‘guile-sdl’ по умолчанию, но возможно запросить специфичный выход,
     то есть ‘glib:bin’ запрашивает выход ‘bin’ из ‘glib’ (*note Пакеты
     со множественным выходом::).

     This option may be composed with the default behavior of ‘guix
     environment’.  Packages appearing before ‘--ad-hoc’ are interpreted
     as packages whose dependencies will be added to the environment,
     the default behavior.  Packages appearing after are interpreted as
     packages that will be added to the environment directly.

‘--pure’
     Unset existing environment variables when building the new
     environment, except those specified with ‘--preserve’ (see below).
     This has the effect of creating an environment in which search
     paths only contain package inputs.

‘--preserve=REGEXP’
‘-E REGEXP’
     При использовании вместе с ‘--pure’, оставить содержимое переменных
     окружения, соответствующих выражению REGEXP — другими словами,
     включить их в "белый список" переменных окружения, которые не
     должны обнуляться.  Эту опцию можно повторять несколько раз.

          guix environment --pure --preserve=^SLURM --ad-hoc openmpi ... \
            -- mpirun ...

     Этот пример запускает ‘mpirun’ в контексте, в котором определены
     только следующие переменные окружения: ‘PATH’, переменные
     окружения, чьи имена начинаются с ‘SLURM’, а также обычные
     "дорогие" переменные (‘HOME’, ‘USER’, и т.д.).

‘--search-paths’
     Отобразить определения переменных окружения, которые составляют
     окружение.

‘--system=SYSTEM’
‘-s SYSTEM’
     Попытаться собрать систему SYSTEM, то есть ‘i686-linux’.

‘--container’
‘-C’
     Run COMMAND within an isolated container.  The current working
     directory outside the container is mapped inside the container.
     Additionally, unless overridden with ‘--user’, a dummy home
     directory is created that matches the current user’s home
     directory, and ‘/etc/passwd’ is configured accordingly.

     The spawned process runs as the current user outside the container.
     Inside the container, it has the same UID and GID as the current
     user, unless ‘--user’ is passed (see below).

‘--network’
‘-N’
     Разделять пространство сетевых имён контейнера с хостящей системой.
     Контейнеры, созданные без этого флага, могут только иметь доступ к
     петлевому устройству.

‘--link-profile’
‘-P’
     For containers, link the environment profile to ‘~/.guix-profile’
     within the container and set ‘GUIX_ENVIRONMENT’ to that.  This is
     equivalent to making ‘~/.guix-profile’ a symlink to the actual
     profile within the container.  Linking will fail and abort the
     environment if the directory already exists, which will certainly
     be the case if ‘guix environment’ was invoked in the user’s home
     directory.

     Certain packages are configured to look in ‘~/.guix-profile’ for
     configuration files and data;(2) ‘--link-profile’ allows these
     programs to behave as expected within the environment.

‘--user=USER’
‘-u USER’
     Использовать в контейнере имя пользователя USER вместо текущего
     пользователя.  Созданная внутри контейнера запись ‘/etc/passwd’
     будет содержать имя USER, домашняя директория будет ‘/home/USER’,
     но не будут копированы пользовательские данные GECOS. Более того,
     внутри контейнера UID и GID будут 1000.  USER не обязательно должен
     существовать в системе.

     Additionally, any shared or exposed path (see ‘--share’ and
     ‘--expose’ respectively) whose target is within the current user’s
     home directory will be remapped relative to ‘/home/USER’; this
     includes the automatic mapping of the current working directory.

          # will expose paths as /home/foo/wd, /home/foo/test, and /home/foo/target
          cd $HOME/wd
          guix environment --container --user=foo \
               --expose=$HOME/test \
               --expose=/tmp/target=$HOME/target

     Это ограничит утечку данных идентификации пользователя через
     домашние пути и каждое из полей пользователя.  Это один
     единственный компонент расширенного решения приватности/анонимности
     — ничто не войдёт, ничто не выйдет.

‘--no-cwd’
     For containers, the default behavior is to share the current
     working directory with the isolated container and immediately
     change to that directory within the container.  If this is
     undesirable, ‘--no-cwd’ will cause the current working directory to
     _not_ be automatically shared and will change to the user’s home
     directory within the container instead.  See also ‘--user’.

‘--expose=SOURCE[=TARGET]’
‘--share=SOURCE[=TARGET]’
     For containers, ‘--expose’ (resp.  ‘--share’) exposes the file
     system SOURCE from the host system as the read-only (resp.
     writable) file system TARGET within the container.  If TARGET is
     not specified, SOURCE is used as the target mount point in the
     container.

     Пример ниже порождает Guile REPL в контейнере, в котором домашняя
     директория пользователя доступна только для чтения через директорию
     ‘/exchange’:

          guix environment --container --expose=$HOME=/exchange --ad-hoc guile -- guile

   ‘guix environment’ также поддерживает все обычные опции сборки,
которые поддерживает команда ‘guix build’ (*note Стандартные параметры
сборки::), а также опции трансформации пакета (*note Параметры
преобразования пакета::).

   ---------- Footnotes ----------

   (1) Пользователи иногда ошибочно изменяют переменные среды, такие как
‘PATH’, в своем ‘~/.bashrc’ файле.  Как следствие, когда ‘guix
environment’ запускает его, Bash может читать ‘~/.bashrc’, тем самым
вводя “примеси” в эти переменные среды.  Ошибочно определять такие
переменные среды в ‘.bashrc’; вместо этого они должны быть определены в
‘.bash_profile’, источником которого являются только оболочки входа в
систему.  *Note (bash)Bash Startup Files::, для получения подробной
информации о файлах запуска Bash.

   (2) For example, the ‘fontconfig’ package inspects
‘~/.guix-profile/share/fonts’ for additional fonts.


File: guix.ru.info,  Node: Запуск guix pack,  Next: Тулчейн GCC,  Prev: Запуск guix environment,  Up: Разработка

7.2 Вызов ‘guix pack’
=====================

Иногда бывает необходимо передать программу людям, которые (ещё!)  не
являются счастливыми обладателями Guix.  Вы могли бы им рекомендовать
заустить ‘guix package -i SOMETHING’, но в данном случае это не
подхлдит.  Тогда ‘guix pack’ решает вопрос.

     Примечание: Если вы ищете способ обмена бинарниками между машинами,
     работающими с Guix, *note Запуск guix copy::, *note Запуск guix
     publish:: и *note Вызов guix archive::.

   Команда ‘guix pack’ создаёт обёрнутый “набор” или “программный
набор”: она создаёт архив tarball или другой архив, содержащий
исполняемые файлы программного обеспечения, которое вас интересует, а
также все его зависимости.  Результирующий архив может использоваться на
любой машине, которая не имеет Guix, а люди могут запустить совершенно
такие же бинарники, как у вас в Guix.  Набор создаётся со свойством
воспроизводимости до бита, так что любой может проверить, что он
действительно содержит результаты сборок, которые вы поставляете.

   Например, чтобы создать набор, содержащий Guile, Emacs, Geiser и все
их зависимости, можно запустить:

     $ guix pack guile emacs geiser
     ...
     /gnu/store/...-pack.tar.gz

   Результатом будет архив tarball, содержащий директорию ‘/gnu/store’
со всеми соответствующими пакетами.  Результирующий архив содержат
“профиль” с тремя запрошенными пакетами; профиль представляет то же
самое, что можно создать командой ‘guix package -i’.  Это механизм,
который используется, собственно, для создания автономного (standalone)
бинарного архива Guix (*note Бинарная установка::).

   Пользователи этого пакета должны запускать
‘/gnu/store/...-profile/bin/guile’ для запуска Guile, что может быть не
удобно.  Чтобы исправить это, можно создать, например, символическую
ссылку ‘/opt/gnu/bin’ на профиль:

     guix pack -S /opt/gnu/bin=bin guile emacs geiser

Так пользователи смогут благополучно напечатать ‘/opt/gnu/bin/guile’, и
всё хорошо.

   What if the recipient of your pack does not have root privileges on
their machine, and thus cannot unpack it in the root file system?  In
that case, you will want to use the ‘--relocatable’ option (see below).
This option produces “relocatable binaries”, meaning they they can be
placed anywhere in the file system hierarchy: in the example above,
users can unpack your tarball in their home directory and directly run
‘./opt/gnu/bin/guile’.

   В качестве альтернативы можно производить пакет в формате образа
Docker, используя следующую команду:

     guix pack -f docker -S /bin=bin guile guile-readline

Результатом будет архив, который можно передать команде ‘docker load’,
followed by ‘docker run’:

     docker load < FILE
     docker run -ti guile-guile-readline /bin/guile

where FILE is the image returned by GUIX PACK, and
‘guile-guile-readline’ is its “image tag”.  See the Docker documentation
(https://docs.docker.com/engine/reference/commandline/load/) for more
information.

   Ещё одна опция производит образ SquashFS следующей командой:

     guix pack -f squashfs bash guile emacs geiser

Результатом будет образ файловой системы SquashFS, который может
непосредственно монтироваться как образ, содержащий контейнер файловой
системы, с помощью контейнерного окружения Singularity
(https://www.sylabs.io/docs/), используя команды типа ‘singularity
shell’ или ‘singularity exec’.

   Несколько опций командной строки позволяют вам переделывать ваш
пакет:

‘--format=FORMAT’
‘-f FORMAT’
     Произвести пакет в указанном формате FORMAT.

     Возможные форматы:

     ‘tarball’
          Это формат по умолчанию.  Он производит архив tarball,
          содержащий все заданные бинарники и символические ссылки.

     ‘docker’
          This produces a tarball that follows the Docker Image
          Specification
          (https://github.com/docker/docker/blob/master/image/spec/v1.2.md).
          The “repository name” as it appears in the output of the
          ‘docker images’ command is computed from package names passed
          on the command line or in the manifest file.

     ‘squashfs’
          Это создает образ SquashFS, содержащий все указанные двоичные
          файлы и символические ссылки, а также пустые точки
          монтирования для виртуальных файловых систем, таких как
          procfs.

               Примечание: Singularity _требует_, чтобы вы указали ‘/bin
               /sh’ в образе.  По этой причине ‘guix pack -f squashfs’
               всегда подразумевает ‘-S /bin=bin’.  Таким образом, вызов
               ‘guix pack’ всегда должен начинаться с чего-то вроде:

                    guix pack -f squashfs bash ...

               Если вы забудете пакет ‘bash’ (или аналогичный),
               ‘singularity run’ и ‘singularity exec’ выдаст бесполезное
               сообщение “нет такого файла или каталога”.

‘--relocatable’
‘-R’
     Создавать “relocatable binaries” — то есть двоичные файлы, которые
     можно разместить в любом месте иерархии файловой системы и
     запускать оттуда.

     Когда эта опция передается один раз, конечные двоичные файлы
     требуют поддержки “user namespaces” в ядре Linux; при передаче
     _дважды_(1), Relocatable двоичные файлы возвращаются к другим
     методам, если пользовательские пространства имен недоступны, и по
     существу работают где угодно - см.  ниже что под этим
     подразумевается.

     Например, если вы создаете пакет, содержащий Bash, с помощью:

          guix pack -RR -S /mybin=bin bash

     ... вы можете скопировать этот пакет на машину, на которой
     отсутствует Guix, и из своего домашнего каталога как обычный
     пользователь запустите:

          tar xf pack.tar.gz
          ./mybin/sh

     В этой оболочке, если вы наберете ‘ls /gnu/store’, вы заметите, что
     отобразятся ‘/gnu/store’ и содержатся все зависимости ‘bash’, даже
     если на машине нет ‘/gnu/store’!  Это, вероятно, самый простой
     способ установить программное обеспечение, созданное с помощью
     Guix, на машине, отличной от Guix.

          Примечание: По умолчанию relocatable двоичные файлы полагаются
          на функцию “user namespace” ядра Linux, которая позволяет
          непривилегированным пользователям монтировать или изменять
          root.  Старые версии Linux не поддерживали его, а некоторые
          дистрибутивы GNU/Linux его отключили.

          Чтобы создать relocatable двоичные файлы, которые работают
          даже при отсутствии пользовательских пространств имен,
          передайте ‘--relocatable’ или ‘-R’ _дважды_.  В этом случае
          двоичные файлы будут пытаться использовать пространство имен
          пользователей и возвращаться к другому “механизму выполнения”,
          если пространства имен пользователей не поддерживаются.
          Поддерживаются следующие механизмы выполнения:

          ‘default’
               Попробовать использовать пространства имен пользователей
               и вернуться к PRoot, если пространства имен пользователей
               не поддерживаются (см.  ниже).

          ‘performance’
               Попробовать использовать пространства имен пользователей
               и вернуться к Fakechroot, если пространства имен
               пользователей не поддерживаются (см.  ниже).

          ‘userns’
               Запустить программу через пользовательские пространства
               имен и прервать, если они не поддерживаются.

          ‘proot’
               Запустить PRoot.  Программа PRoot
               (https://proot-me.github.io/) обеспечивает необходимую
               поддержку виртуализации файловой системы.  Это
               достигается с помощью системного вызова ‘ptrace’ в
               запущенной программе.  Преимущество этого подхода
               заключается в том, что это не требует специальной
               поддержки ядра, но это требует дополнительных затрат
               времени выполнения каждый раз, когда выполняется
               системный вызов.

          ‘fakechroot’
               Запустить Fakechroot.  Fakechroot
               (https://github.com/dex4er/fakechroot/) виртуализирует
               доступ к файловой системе путем перехвата вызовов функций
               библиотеки C, таких как ‘open’, ‘stat’, ‘exec’ и т.п.  В
               отличие от PRoot, накладных расходов очень мало.  Однако
               это не всегда работает: например, некоторые обращения к
               файловой системе, сделанные из библиотеки C, не
               перехватываются, а обращения к файловой системе,
               сделанные через прямые системные вызовы, также не
               перехватываются, что приводит к нестабильному поведению.

          При запуске обернутой программы вы можете явно запросить один
          из механизмов выполнения, перечисленных выше, установив
          соответствующую переменную среды ‘GUIX_EXECUTION_ENGINE’.

‘--entry-point=COMMAND’
     Используйте COMMAND в качестве “точки входа” конечного пакета, если
     формат пакета поддерживает это — в настоящее время ‘docker’ и
     ‘squashfs’ (Singularity) поддерживают это.  COMMAND должна
     относиться к профилю, содержащемуся в пакете.

     Точка входа указывает команду, которую по умолчанию автоматически
     запускают такие инструменты, как ‘docker run’ или ‘singularity
     run’.  Например, вы можете сделать:

          guix pack -f docker --entry-point=bin/guile guile

     Полученный пакет может быть легко импортирован, и запущен через
     ‘docker run’ без дополнительных аргументов, пораждая ‘bin/guile’:

          docker load -i pack.tar.gz
          docker run IMAGE-ID

‘--expression=EXPR’
‘-e EXPR’
     Процедура, при выполнении которой возвращается пакет.

     This has the same purpose as the same-named option in ‘guix build’
     (*note ‘--expression’ in ‘guix build’: Дополнительные параметры
     сборки.).

‘--manifest=FILE’
‘-m FILE’
     Use the packages contained in the manifest object returned by the
     Scheme code in FILE.  This option can be repeated several times, in
     which case the manifests are concatenated.

     Она служит для того же, что и одноименная опция в ‘guix package’
     (*note ‘--manifest’: profile-manifest.) и использует те же файлы
     манифеста.  Она позволяет вам один раз определить набор пакетов и
     использовать его как для создания профилей, так и для создания
     архивов для использования на машинах, на которых не установлен
     Guix.  Обратите внимание, что вы можете указать _либо_ файл
     манифеста _либо_ список пакетов, но не то и другое вместе.

‘--system=SYSTEM’
‘-s SYSTEM’
     Предпринять попытку собрать систему SYSTEM, т.е.  ‘i686-linux’,
     вместо типа системы хоста сборки.

‘--target=TRIPLET’
     Cross-сборка для TRIPLET, который должен быть допустимым GNU
     triplet, например ‘\ "aarch64-linux-gnu\"’ (*note GNU configuration
     triplets: (autoconf)Specifying target triplets.).

‘--compression=TOOL’
‘-C TOOL’
     Compress the resulting tarball using TOOL—one of ‘gzip’, ‘zstd’,
     ‘bzip2’, ‘xz’, ‘lzip’, or ‘none’ for no compression.

‘--symlink=SPEC’
‘-S SPEC’
     Добавить в пакет символические ссылки, указанные в SPEC.  Эта опция
     может быть указана несколько раз.

     SPEC имеет вид ‘SOURCE=TARGET’, где SOURCE - это символическая
     ссылка, которая будет создана, а TARGET - это цель символьной
     ссылки.

     Например, ‘-S /opt/gnu/bin=bin’ создает символическую ссылку
     ‘/opt/gnu/bin’, указывающую на подкаталог ‘bin’ профиля.

‘--save-provenance’
     Сохранить информацию о происхождении пакетов, переданных в
     командной строке.  Информация о происхождении включает в себя URL и
     фиксацию используемых каналов (*note Каналы::).

     Информация о происхождении сохраняется в файле
     ‘/gnu/store/...-profile/manifest’ в пакете вместе с обычными
     метаданными пакета - названием и версией каждого пакета, их
     propagated inputs и т.п.  Это полезная информация для получателя
     pack, который исходя из нее знает, как (предположительно) был
     собран pack.

     Этот параметр не включен по умолчанию, поскольку, как и временные
     метки, информация о происхождении не влияет на процесс сборки.
     Другими словами, существует бесконечное количество URL-адресов
     каналов и ID коммитов, которые могут привести к одному и тому же
     pack.  Таким образом, запись таких “тихих” метаданных в output
     потенциально нарушает свойство побитовой воспроизводимости.

‘--root=FILE’
‘-r FILE’
     Make FILE a symlink to the resulting pack, and register it as a
     garbage collector root.

‘--localstatedir’
‘--profile-name=NAME’
     Включите в конечный пакет “локальный каталог состояния”,
     ‘/var/guix’ и, в частности, профиль
     ‘/var/guix/profiles/per-user/root/NAME’ — по умолчанию NAME - это
     ‘guix-profile’, что соответствует ‘~root/.guix-profile’.

     ‘/var/guix’ содержит базу данных store (*note Хранилище::), а также
     корни сборщика мусора (*note Вызов guix gc::).  Предоставление ее в
     pack означает, что store является “полным” и управляемым Guix;
     отсутствие в pack означает, что store “мертв”: пакеты нельзя
     добавить в него или удалить из него после извлечения pack.

     Одним из вариантов использования является включающий себя двоичный
     архив Guix (*note Бинарная установка::).

‘--derivation’
‘-d’
     Выведите имя derivation, которая создает pack.

‘--bootstrap’
     Использовать bootstrap бинарники для сборки пакета.  Эта опция
     полезна только разработчикам Guix.

   Кроме того, ‘guix pack’ поддерживает все стандартные параметры сборки
(*note Стандартные параметры сборки::) и все параметры преобразования
пакетов (*note Параметры преобразования пакета::).

   ---------- Footnotes ----------

   (1) Вот трюк, чтобы запомнить его: ‘-RR’, который добавляет поддержку
PRoot, можно рассматривать как сокращение от “Really Relocatable”.
Удобно, не правда ли?


File: guix.ru.info,  Node: Тулчейн GCC,  Next: Запуск guix git authenticate,  Prev: Запуск guix pack,  Up: Разработка

7.3 Тулчейн GCC
===============

If you need a complete toolchain for compiling and linking C or C++
source code, use the ‘gcc-toolchain’ package.  This package provides a
complete GCC toolchain for C/C++ development, including GCC itself, the
GNU C Library (headers and binaries, plus debugging symbols in the
‘debug’ output), Binutils, and a linker wrapper.

   The wrapper’s purpose is to inspect the ‘-L’ and ‘-l’ switches passed
to the linker, add corresponding ‘-rpath’ arguments, and invoke the
actual linker with this new set of arguments.  You can instruct the
wrapper to refuse to link against libraries not in the store by setting
the ‘GUIX_LD_WRAPPER_ALLOW_IMPURITIES’ environment variable to ‘no’.

   Пакет ‘gfortran-toolchain’ предоставляет полный набор инструментов
GCC для разработки Fortran.  Для других языков используйте ‘guix search
gcc toolchain’ (*note Invoking guix package: guix-search.).


File: guix.ru.info,  Node: Запуск guix git authenticate,  Prev: Тулчейн GCC,  Up: Разработка

7.4 Invoking ‘guix git authenticate’
====================================

Команда ‘guix git Authenticate’ аутентифицирует проверку Git по тому же
правилу, что и для каналов (*note channel authentication:
channel-authentication.).  То есть, начиная с данного коммита, он
гарантирует, что все последующие коммиты подписаны ключом OpenPGP,
отпечаток которого указан в файле ‘.guix-authorizations’ его
родительского коммита(ов).

   Вы найдете эту команду полезной, если будете поддерживать канал.  Но
на самом деле этот механизм аутентификации полезен в более широком
контексте, поэтому вы можете использовать его для репозиториев Git,
которые не имеют ничего общего с Guix.

   Основной синтаксис:

     guix git authenticate COMMIT SIGNER [OPTIONS...]

   По умолчанию эта команда аутентифицирует проверку Git в текущем
каталоге; она ничего не выводит и завершает работу с нулевым кодом в
случае успеха и ненулевым в случае неудачи.  COMMIT выше обозначает
первый коммит, в котором происходит аутентификация, а SIGNER - это
отпечаток открытого ключа OpenPGP, используемый для подписи COMMIT.
Вместе они образуют “channel introduction” (*note channel introduction:
channel-authentication.).  Указанные ниже параметры позволяют вам точно
настроить процесс.

‘--repository=DIRECTORY’
‘-r DIRECTORY’
     Открыть репозиторий Git в DIRECTORY вместо текущего каталога.

‘--keyring=REFERENCE’
‘-k REFERENCE’
     Загрузить связку ключей OpenPGP из REFERENCE, ссылки на branch,
     например ‘origin/keyring’ или ‘my-keyring’.  branch должна
     содержать открытые ключи OpenPGP в файлах ‘.key’ либо в двоичной
     форме, либо в “ASCII-armored” виде.  По умолчанию связка ключей
     загружается из branch с именем ‘keyring’.

‘--stats’
     Отобразить статистику подписания commit’ов по завершению.

‘--cache-key=KEY’
     Ранее аутентифицированные коммиты кэшируются в файле под
     ‘~/.cache/guix/authentication’.  Эта опция заставляет хранить кеш в
     файле KEY в этом каталоге.

‘--historical-authorizations=FILE’
     По умолчанию любой коммит, родительский коммит которого не содержит
     файла ‘.guix-authorizations’, считается недостоверным.  Напротив,
     эта опция учитывает авторизацию в FILE для любого коммита, в
     котором отсутствует ‘.guix-authorizations’.  Формат FILE такой же,
     как у ‘.guix-authorizations’ (*note ‘.guix-authorizations’ format:
     channel-authorizations.).


File: guix.ru.info,  Node: Программный интерфейс,  Next: Утилиты,  Prev: Разработка,  Up: Top

8 Программный интерфейс
***********************

GNU Guix предоставляет несколько Scheme программных интерфейсов (API)
для определения, сборки и запроса пакетов.  Первый интерфейс позволяет
пользователям писать высокоуровневые определения пакетов.  Эти
определения относятся к знакомым концепциям упаковки, таким как имя и
версия пакета, его система сборки и зависимости.  Затем эти определения
можно превратить в конкретные действия по сборке.

   Действия по сборке выполняются демоном Guix от имени пользователей.
В стандартной настройке демон имеет доступ на запись в хранилище—каталог
‘/gnu/store’—, в то время как пользователи не имеют.  Рекомендуемая
установка также предусматривает, что демон выполняет сборки в chroot,
под определенными пользователями сборки, чтобы минимизировать влияние на
остальную систему.

   Доступны API нижнего уровня для взаимодействия с демоном и
хранилищем.  Чтобы дать демону команду выполнить действие сборки,
пользователи фактически предоставляют ему “derivation”.  Derivation -
это низкоуровневое представление действий сборки, которые должны быть
предприняты, и среды, в которой они должны происходить - derivation’ы
относятся к определениям пакетов, как сборка для программ на C. Термин
“derivation” происходит от того факта, что результаты сборки
_производные_ от них.

   В этой главе описываются все эти API по очереди, начиная с
определений пакетов высокого уровня.

* Menu:

* Пакетные модули::  Пакеты с точки зрения
                                     программиста.
* Описание пакетов::  Описание новых
                                       пакетов.
* Defining Package Variants::  Кастомизация пакетов.
* Системы сборки::  Задание параметров
                                   сборки пакетов.
* Фазы сборки::    Фазы процесса сборки
                               пакета.
* Build Utilities::          Helpers for your package definitions and more.
* Хранилище::       Работа с хранилищем
                               пакетов.
* Деривации::       Низкоуровневый интерфейс
                               дериваций пакетов.
* Устройство склада::  Чисто
                                         функциональный
                                         интерфейс доступа к
                                         складу.
* G-Expressions::            Управление механизмом
                               сборки.
* Запуск guix repl::   Программирование Guix в Guile


File: guix.ru.info,  Node: Пакетные модули,  Next: Описание пакетов,  Up: Программный интерфейс

8.1 Пакетные модули
===================

С точки зрения программирования, определения пакетов дистрибутива GNU
предоставляются модулями Guile в пространстве имен ‘(gnu packages ...)’
(1) (*note Guile modules: (guile)Модули.)).  Например, модуль ‘(gnu
packages emacs)’ экспортирует переменную с именем ‘emacs’, которая
привязана к ‘<package>’ объекту (*note Описание пакетов::).

   Пространство имен модуля ‘(gnu packages ...)’ автоматически
сканируется на наличие пакетов с помощью инструментов командной строки.
Например, при запуске ‘guix install emacs’ все модули ‘(gnu packages
...)’ сканируются до тех пор, пока не будет найден тот, который
экспортирует объект пакета с именем ‘emacs’.  Это средство поиска
пакетов реализовано в модуле ‘(gnu packages)’.

   Пользователи могут хранить определения пакетов в модулях с разными
именами - например, ‘(my-packages emacs)’ (2).  Есть два способа сделать
эти определения пакетов видимыми для пользовательских интерфейсов:

  1. Добавить каталог, содержащий модули вашего пакета, в пути поиска с
     помощью флага ‘-L’ команды ‘guix package’ и другие команды (*note
     Стандартные параметры сборки::) или указать переменную окружения
     ‘GUIX_PACKAGE_PATH’, описанную ниже.

  2. Определить “канал” и настроить ‘guix pull’ так, чтобы он учитывал
     его.  Канал - это, по сути, репозиторий Git, содержащий модули
     пакетов.  *Note Каналы::, чтобы узнать больше о том, как определять
     и использовать каналы.

   ‘GUIX_PACKAGE_PATH’ работает аналогично другим переменным пути
поиска:

 -- Environment Variable: GUIX_PACKAGE_PATH
     Это список каталогов, разделенных двоеточиями, для поиска
     дополнительных модулей пакета.  Каталоги, перечисленные в этой
     переменной, имеют приоритет над собственными модулями дистрибутива.

   Дистрибутив полностью “bootstrapped” и “самодостаточный”: каждый
пакет построен исключительно на основе других пакетов в дистрибутиве.
Корнем этого графа зависимостей является небольшой набор “bootstrap
бинарный файлы”, предоставляемых модулем ‘(gnu packages bootstrap)’.
Для получения дополнительной информации о начальной загрузке *note
Начальная загрузка::.

   ---------- Footnotes ----------

   (1) Обратите внимание, что пакеты в ‘(gnu packages ...)’ пространстве
имен модуля не обязательно являются “пакетами GNU”.  Эта схема
именования модулей соответствует обычному соглашению об именах модулей
Guile: ‘gnu’ означает, что эти модули распространяются как часть системы
GNU, а ‘packages’ идентифицирует модули, которые определяют пакеты.

   (2) Обратите внимание, что имя файла и имя модуля должны совпадать.
Например, модуль ‘(my-packages emacs)’ должен храниться в файле
‘my-packages/emacs.scm’ относительно пути загрузки, указанного с помощью
‘--load-path’ или ‘GUIX_PACKAGE_PATH’.  *Note (guile)Modules and the
File System::, для подробностей.


File: guix.ru.info,  Node: Описание пакетов,  Next: Defining Package Variants,  Prev: Пакетные модули,  Up: Программный интерфейс

8.2 Описание пакетов
====================

Интерфейс высокого уровня к определениям пакетов реализован в модулях
‘(guix packages)’ и ‘(guix build-system)’.  Например, определение пакета
или “рецепта” для пакета GNU Hello выглядит так:

     (define-module (gnu packages hello)
       #:use-module (guix packages)
       #:use-module (guix download)
       #:use-module (guix build-system gnu)
       #:use-module (guix licenses)
       #:use-module (gnu packages gawk))

     (define-public hello
       (package
         (name "hello")
         (version "2.10")
         (source (origin
                   (method url-fetch)
                   (uri (string-append "mirror://gnu/hello/hello-" version
                                       ".tar.gz"))
                   (sha256
                    (base32
                     "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"))))
         (build-system gnu-build-system)
         (arguments '(#:configure-flags '("--enable-silent-rules")))
         (inputs `(("gawk" ,gawk)))
         (synopsis "Hello, GNU world: An example GNU package")
         (description "Guess what GNU Hello prints!")
         (home-page "https://www.gnu.org/software/hello/")
         (license gpl3+)))

Не будучи Scheme экспертом, вы можете догадаться о значении различных
полей.  Это выражение связывает переменную ‘hello’ с объектом
‘<package>’, который по сути является record (*note Scheme records:
(guile)SRFI-9.).  Этот объект пакета можно проверить с помощью процедур
из модуля ‘(guix packages)’; например, ‘(package-name hello)’
возвращает—сюрприз!—‘"hello"’.

   Если повезет, вы сможете импортировать часть или все определение
интересующего вас пакета из другого репозитория с помощью команды ‘guix
import’ (*note Запуск guix import::).

   В приведенном выше примере ‘hello’ определен в собственном модуле
‘(gnu packages hello)’.  Технически в этом нет строгой необходимости, но
это удобно: все пакеты, определенные в модулях под ‘(gnu packages ...)’,
автоматически становятся известны инструментам командной строки (*note
Пакетные модули::).

   В приведенном выше определении пакета стоит отметить несколько
моментов:

   • Поле ‘source’ пакета представляет собой объект ‘<origin>’ (*note
     Интерфейс origin::, for the complete reference).  Здесь
     используется метод ‘url-fetch’ из ‘(guix download)’, что означает,
     что источником является файл, который нужно загрузить через FTP или
     HTTP.

     Префикс ‘mirror://gnu’ указывает ‘url-fetch’ использовать одно из
     зеркал GNU, определенных в ‘(guix download)’.

     Поле ‘sha256’ указывает ожидаемый хэш SHA256 загружаемого файла.
     Это обязательно и позволяет Guix проверять целостность файла.
     Форма ‘(base32 ...)’ указывает представление хеша в формате base32.
     Вы можете получить эту информацию с помощью ‘guix download’ (*note
     Запуск guix download::) ‘guix hash’ (*note Запуск guix hash::).

     При необходимости форма ‘origin’ может также иметь поле ‘patches’
     со списком исправлений, которые необходимо применить, и поле
     ‘snippet’, содержащее Scheme выражение для изменения исходного
     кода.

   • Поле ‘build-system’ указывает процедуру сборки пакета (*note
     Системы сборки::).  Здесь ‘gnu-build-system’ представляет знакомую
     систему сборки GNU, в которой пакеты могут быть настроены, собраны
     и установлены с помощью обычной последовательности команд
     ‘./configure && make && make check && make install’.

     Когда вы начинаете упаковывать нетривиальное программное
     обеспечение, вам могут потребоваться инструменты для управления
     этими этапами сборки, управления файлами и т.д.  *Note Утилиты::,
     чтобы узнать об этом подробнее.

   • Поле ‘arguments’ определяет параметры для системы сборки (*note
     Системы сборки::).  В примере это интерпретируется
     ‘gnu-build-system’ как запуск запроса ‘configure’ с флагом
     ‘--enable-silent-rules’.

     А как насчет этих символов кавычек (‘'’)?  Это синтаксис Scheme для
     представления literal списка; ‘'’ является синонимом ‘цитата’.
     *Note quoting: (guile)Expression Syntax, для подробностей.  Здесь
     значение поля ‘arguments’ представляет собой список аргументов,
     переданных системе сборки в будущем, как и в случае с ‘apply’
     (*note ‘apply’: (guile)Fly Evaluation.).

     Последовательность хэш-двоеточие (‘#:’) определяет Scheme “ключевое
     слово” (*note (guile)Keywords::), а ‘#:configure-flags’ - это
     ключевое слово, используемое для передачи аргумента ключевого слова
     системе сборки (*note (guile)Coding With Keywords::).

   • Поле ‘inputs’ указывает входные данные для процесса сборки, т.е.
     зависимости пакета во время сборки или выполнения.  Здесь мы
     определяем input с именем ‘"gawk"’, значение которого совпадает со
     значением переменной ‘gawk’; ‘gawk’ сам связан с объектом
     ‘<package>’.

     Опять же, ‘`’ (обратная кавычка, синоним ‘quasiquote’) позволяет
     нам ввести literal список в поле ‘inputs’, а ‘,’ (запятая, синоним
     ‘unquote’) позволяет нам вставить значение в этот список (*note
     unquote: (guile)Expression Syntax.).

     Обратите внимание, что GCC, Coreutils, Bash и другие важные
     инструменты не нужно указывать здесь в качестве inputs.  Вместо
     этого ‘gnu-build-system’ позаботится об их наличии (*note Системы
     сборки::).

     Однако любые другие зависимости необходимо указать в поле ‘inputs’.
     Любая не указанная здесь зависимость будет просто недоступна для
     процесса сборки, что может привести к сбою сборки.

   *Note ссылка на пакет::, для полного описания возможных полей.

   После того, как определение пакета введено, пакет может быть
фактически собран с помощью инструмента командной строки ‘guix build’
(*note Запуск guix build::), устраняя любые возникающие ошибки сборки
(*note Отладка ошибок сборки::).  Вы можете легко вернуться к
определению пакета с помощью команды ‘guix edit’ (*note Запуск guix
edit::).  *Note Принципы опакечивания:: для получения дополнительной
информации о том, как тестировать определения пакетов, и *note Запуск
guix lint:: для получения информации о том, как проверить определение на
соответствие стилю.  Наконец, *note Каналы::, чтобы узнать, как
расширить дистрибутив, добавив собственные определения пакетов в
“канал”.

   Наконец, обновление определения пакета до новой исходной версии можно
частично автоматизировать с помощью команды ‘guix refresh’ (*note Запуск
guix refresh::).

   За кулисами derivation, соответствующая объекту ‘<package>’, сначала
вычисляется с помощью процедуры ‘package-diveration’.  Этот вывод
хранится в файле ‘.drv’ в каталоге ‘/gnu/store’.  Действия сборки,
которые он предписывает, затем могут быть реализованы с помощью
процедуры ‘build-derivations’ (*note Хранилище::).

 -- Процедура Scheme: package-derivation STORE PACKAGE [SYSTEM]
     Возвращает the ‘<derivation>’ объект PACKAGE для SYSTEM (*note
     Деривации::).

     PACKAGE должен быть допустимым объектом ‘<package>’, а SYSTEM
     должен быть строкой, обозначающей тип системы—например,
     ‘"x86_64-linux"’ для системы GNU на базе x86_64 Linux.  STORE
     должен быть подключен к демону, который работает с хранилищем
     (*note Хранилище::).

Точно так же можно вычислить derivation, которая cross собирает пакет
для некоторой другой системы:

 -- Процедура Scheme: package-cross-derivation STORE PACKAGE TARGET
          [SYSTEM] Возвращает ‘<derivation>’
     объект PACKAGE cross-собранный из SYSTEM в TARGET.

     TARGET должен быть допустимым GNU triplet’ом, обозначающим желамое
     оборудование и операционную систему, например ‘"aarch64-linux-gnu"’
     (*note (autoconf)Specifying Target Triplets::).

   Once you have package definitions, you can easily define _variants_
of those packages.  *Note Описание пакетов::, for more on that.

* Menu:

* ссылка на пакет::  Тип данных package.
* Интерфейс origin::  Тип данных origin.


File: guix.ru.info,  Node: ссылка на пакет,  Next: Интерфейс origin,  Up: Описание пакетов

8.2.1 ‘package’ Ссылка
----------------------

В этом разделе перечислены все параметры, доступные в объявлениях
‘package’ (*note Описание пакетов::).

 -- Тип данных: package
     Это тип данных, представляющий рецепт пакета.

     ‘name’
          Название пакета в виде строки.

     ‘версия’
          Версия пакета, в виде строки.

     ‘источник’
          Объект, указывающий, как должен быть получен исходный код
          пакета.  В большинстве случаев это объект ‘origin’, который
          обозначает файл, полученный из Интернета (*note Интерфейс
          origin::).  Это также может быть любой другой объект, подобный
          файлу, например ‘local-file’, который представляет собой файл
          из локальной файловой системы (*note ‘local-file’:
          G-Expressions.).

     ‘система сборки’
          Система сборки, которую следует использовать для сборки пакета
          (*note Системы сборки::).

     ‘arguments’ (default: ‘'()’)
          Аргументы, которые следует передать системе сборки.  Это
          список, обычно содержащий последовательные пары ключевого
          слова и значения.

     ‘inputs’ (default: ‘'()’)
     ‘native-inputs’ (default: ‘'()’)
     ‘propagated-inputs’ (default: ‘'()’)
          В этих полях перечислены зависимости пакета.  Каждый из них
          представляет собой список кортежей, где каждый кортеж имеет
          метку для ввода (строку) в качестве своего первого элемента,
          пакет, источник или derivation в качестве второго элемента и,
          необязательно, имя его вывода, которое следует использовать,
          которое по умолчанию является ‘"out"’ (*note Пакеты со
          множественным выходом::, for more on package outputs).
          Например, в списке ниже указаны три входа:

               `(("libffi" ,libffi)
                 ("libunistring" ,libunistring)
                 ("glib:bin" ,glib "bin"))  ;the "bin" output of Glib

          Различие между ‘native-inputs’ и ‘inputs’ необходимо при
          рассмотрении кросс-компиляции.  При кросс-компиляции
          зависимости, перечисленные в ‘input’, создаются для
          архитектуры _target_; и наоборот, зависимости, перечисленные в
          ‘native-inputs’, созданы для архитектуры машины, выполняющей
          _сборку_.

          ‘native-inputs’ обычно используется для перечисления
          инструментов, необходимых во время сборки, но не во время
          выполнения, таких как Autoconf, Automake, pkg-config, Gettext
          или Bison.  ‘guix lint’ может сообщить о вероятных ошибках в
          этой области (*note Запуск guix lint::).

          Наконец, ‘propagated-inputs’ похоже на ‘inputs’, но указанные
          пакеты будут автоматически установлены в профили (*note the
          role of profiles in Guix: Особенности.) вместе с пакетом,
          которому они принадлежат (*note ‘guix package’:
          package-cmd-propagated-inputs, for information on how ‘guix
          package’ deals with propagated inputs).

          Например, это необходимо при упаковке библиотеки C/C++,
          которой для компиляции требуются заголовки другой библиотеки,
          или когда файл pkg-config ссылается на другое поле через его
          ‘Requires’.

          Другой пример использования ‘propagated-inputs’ - это языки, в
          которых отсутствует возможность записывать путь поиска во
          время выполнения, аналогичный ‘RUNPATH’ файлов ELF; сюда
          входят Guile, Python, Perl и другие.  При упаковке библиотек,
          написанных на этих языках, убедитесь, что они могут найти код
          библиотеки, от которого они зависят, во время выполнения,
          указав зависимости времени выполнения в ‘propagated-inputs’, а
          не в ‘inputs’.

     ‘outputs’ (default: ‘'("out")’)
          Список выходных имен пакета.  *Note Пакеты со множественным
          выходом::, для типичного использования дополнительных выходов.

     ‘native-search-paths’ (default: ‘'()’)
     ‘search-paths’ (по умолчанию: ‘'()’)
          Список объектов ‘search-path-specification’, описывающих
          переменные среды пути поиска, учитываемые пакетом.

     ‘replacement’ (по умолчанию: ‘#f’)
          Это должен быть либо ‘#f’, либо объект пакета, который будет
          использоваться как “замена” для этого пакета.  *Note grafts:
          Обновления безопасности, чтобы узнать подробности.

     ‘synopsis’
          Описание пакета в одну строку.

     ‘description’
          Более подробное описание пакета.

     ‘license’
          Лицензия пакета; значение из ‘(guix licenses)’ или список
          таких значений.

     ‘home-page’
          URL-адрес домашней страницы пакета в виде строки.

     ‘supported-systems’ (default: ‘%supported-systems’)
          Список систем, поддерживаемых пакетом, в виде строк вида
          ‘architecture-kernel’, например ‘"x86_64-linux"’.

     ‘location’ (default: source location of the ‘package’ form)
          Исходное расположение пакета.  Это полезно переопределить при
          наследовании от другого пакета, и в этом случае это поле не
          корректируется автоматически.

 -- Scheme Syntax: this-package
     При использовании в _lexical scope_ определения поля пакета этот
     идентификатор преобразуется в определяемый пакет.

     В приведенном ниже примере показано, как добавить пакет в качестве
     собственного ввода при кросс-компиляции:

          (package
            (name "guile")
            ;; ...

            ;; When cross-compiled, Guile, for example, depends on
            ;; a native version of itself.  Add it here.
            (native-inputs (if (%current-target-system)
                               `(("self" ,this-package))
                               '())))

     Ссылка на ‘this-package’ вне определения пакета является ошибкой.

   Поскольку пакеты являются обычными Scheme объектами, которые
захватывают полный граф зависимостей и связанные процедуры сборки, часто
бывает полезно написать процедуры, которые принимают пакет и возвращают
его измененную версию в соответствии с некоторыми параметрами.  Ниже
приведены несколько примеров.

 -- Scheme Procedure: package-with-c-toolchain PACKAGE TOOLCHAIN
     Вернуть вариант PACKAGE, в котором используется TOOLCHAIN вместо
     стандартного набора инструментов GNU C/C++.  TOOLCHAIN должен быть
     списком входов (кортежи меток/пакетов), обеспечивающих
     эквивалентную функциональность, например, пакет ‘gcc-toolchain’.

     Пример ниже возвращает вариант пакета ‘hello’, созданный с помощью
     GCC 10.x и остальной части GNU утилит (Binutils и библиотеки GNU C)
     вместо цепочки инструментов по умолчанию:

          (let ((toolchain (specification->package "gcc-toolchain@10")))
            (package-with-c-toolchain hello `(("toolchain" ,toolchain))))

     Инструменты сборки являются частью “неявных входных данных” пакетов
     - обычно они не указываются как часть различных полей “входных
     данных”, а вместо этого извлекается системой сборки.
     Следовательно, эта процедура работает путем изменения системы
     сборки PACKAGE, так что она использует TOOLCHAIN вместо значений по
     умолчанию.  *note Системы сборки::, чтобы узнать больше о системах
     сборки.


File: guix.ru.info,  Node: Интерфейс origin,  Prev: ссылка на пакет,  Up: Описание пакетов

8.2.2 ‘origin’ Reference
------------------------

Этот раздел документирует “origins”.  Объявление ‘origin’ определяет
данные, которые должны быть “произведены”—обычно загружены—и чей хэш
содержимого известен заранее.  Origins в основном используются для
представления исходного кода пакетов (*note Описание пакетов::).  По
этой причине форма ‘origin’ позволяет вам объявлять исправления для
применения к исходному коду, а также фрагменты кода для его изменения.

 -- Тип данных: origin
     Это тип данных, представляющий источник исходного кода.

     ‘uri’
          Объект, содержащий URI источника.  Тип объекта зависит от
          ‘method’ (см.  ниже).  Например, при использовании метода
          URL-FETCH для ‘(guix download)’ допустимые значения ‘uri’:
          URL, представленный в виде строки, или их список.

     ‘метод’
          A monadic procedure that handles the given URI.  The procedure
          must accept at least three arguments: the value of the ‘uri’
          field and the hash algorithm and hash value specified by the
          ‘hash’ field.  It must return a store item or a derivation in
          the store monad (*note Устройство склада::); most methods
          return a fixed-output derivation (*note Деривации::).

          Обычно используемые методы включают ‘url-fetch’, который
          извлекает данные из URL-адреса, и ‘git-fetch’, который
          извлекает данные из репозитория Git (см.  ниже).

     ‘sha256’
          Байт-вектор, содержащий хэш SHA-256 источника.  Это эквивалент
          предоставлению объекта SHA256 ‘content-hash’ в поле ‘hash’,
          описанном ниже.

     ‘hash’
          Объект ‘content-hash’ источника—см.  ниже, как использовать
          ‘content-hash’.

          Вы можете получить эту информацию, используя ‘guix download’
          (*note Запуск guix download::) или ‘guix hash’ (*note Запуск
          guix hash::).

     ‘file-name’ (по умолчанию: ‘#f’)
          Имя файла, под которым должен быть сохранен исходный код.
          Когда это ‘#f’, в большинстве случаев будет использоваться
          разумное значение по умолчанию.  В случае, если источник
          извлекается из URL-адреса, будет использоваться имя файла из
          URL-адреса.  Для проверок контроля версий рекомендуется явно
          указывать имя файла, поскольку значение по умолчанию не очень
          информативно.

     ‘patches’ (по умолчанию: ‘'()’)
          Список имен файлов, источников или объектов подобных файлами
          (*note file-like objects: G-Expressions.), указывающих на
          исправления, которые будут применены к источнику.

          Данный список исправлений должен быть безвариативным.  В
          частности, он не может зависеть от значения ‘%current-system’
          или ‘%current-target-system’.

     ‘snippet’ (по умолчанию: ‘#f’)
          G-выражение (*note G-Expressions::) или S-выражение, которое
          будет выполнено в исходном каталоге.  Это удобный способ
          изменить исходный код, иногда более удобный, чем патч.

     ‘patch-flags’ (по умолчанию: ‘'("-p1")’)
          Список флагов командной строки, которые следует передать
          команде ‘patch’.

     ‘patch-inputs’ (по умолчанию: ‘#f’)"
          Входные пакеты или derivation’ы для процесса исправления.
          Когда это ‘#f’, предоставляется обычный набор входных данных,
          необходимых для исправления, например GNU Patch.

     ‘modules’ (по умолчанию: ‘'()’)
          Список модулей Guile, которые должны быть загружены в процессе
          установки исправлений и при выполнении кода, в поле ‘snippet’.

     ‘patch-guile’ (по умолчанию: ‘#f’)
          Пакет Guile, который следует использовать в процессе установки
          исправлений.  Когда это ‘#f’, используется разумное значение
          по умолчанию.

 -- Тип данных: content-hash VALUE [ALGORITHM]
     Создать объект хэша содержимого для заданного ALGORITHM и с VALUE в
     качестве его хеш-значения.  Если ALGORITHM опущен, предполагается,
     что это ‘sha256’.

     VALUE может быть буквальной строкой, и в этом случае она
     декодируется с помощью base32, или может быть байтовым вектором.

     The following forms are all equivalent:

          (content-hash "05zxkyz9bv3j9h0xyid1rhvh3klhsmrpkf3bcs6frvlgyr2gwilj")
          (content-hash "05zxkyz9bv3j9h0xyid1rhvh3klhsmrpkf3bcs6frvlgyr2gwilj"
                        sha256)
          (content-hash (base32
                         "05zxkyz9bv3j9h0xyid1rhvh3klhsmrpkf3bcs6frvlgyr2gwilj"))
          (content-hash (base64 "kkb+RPaP7uyMZmu4eXPVkM4BN8yhRd8BTHLslb6f/Rc=")
                        sha256)

     Технически ‘content-hash’ в настоящее время реализован как макрос.
     Он выполняет проверки работоспособности во время раскрытия макроса,
     когда это возможно, например, гарантирует, что VALUE имеет
     правильный размер для ALGORITHM.

   Как мы видели выше, то, как именно извлекаются данные, на которые
ссылается источник, определяется его полем ‘method’.  Модуль ‘(guix
download)’ предоставляет наиболее распространенный метод ‘url-fetch’,
описанный ниже.

 -- Scheme Procedure: url-fetch URL HASH-ALGO HASH [name] [#:executable?
          #f] Возвращает derivation с фиксированным выводом,
     которая извлекает данные из URL (строка или список строк,
     обозначающих альтернативные URL-адреса), который, как ожидается,
     будет иметь хэш HASH типа HASH-ALGO (символ).  По умолчанию имя
     файла - это базовое имя URL-адреса; при желании NAME может
     указывать другое имя файла.  Если EXECUTABLE? истинно, загруженный
     файл будет исполняемым.

     Когда один из URL-адресов начинается с ‘mirror://’, тогда его
     хост-часть интерпретируется как имя схемы зеркала, взятой из
     ‘%mirror-file’.

     В качестве альтернативного варианта, если URL-адрес начинается с
     ‘file://’, вернуть соответствующее имя файла в store.

   Likewise, the ‘(guix git-download)’ module defines the ‘git-fetch’
origin method, which fetches data from a Git version control repository,
and the ‘git-reference’ data type to describe the repository and
revision to fetch.

 -- Scheme Procedure: git-fetch REF HASH-ALGO HASH
     Вернуть derivation с фиксированным выводом, которая выбирает объект
     REF, ‘<git-reference>’.  Ожидается, что на выходе будет рекурсивный
     хеш HASH типа HASH-ALGO (символ).  Использовать NAME в качестве
     имени файла или общее имя, если ‘#f’.

 -- Data Type: git-reference
     This data type represents a Git reference for ‘git-fetch’ to
     retrieve.

     ‘url’
          URL-адрес репозитория Git для клонирования.

     ‘commit’
          Эта строка обозначает либо коммит для загрузки
          (шестнадцатеричная строка, либо полный SHA1 коммит, либо
          “short” коммит строка; последнее не рекомендуется), либо тег.

     ‘recursive?’ (default: ‘#f’)
          This Boolean indicates whether to recursively fetch Git
          sub-modules.

     Пример ниже обозначает тег ‘v2.10’ репозитория GNU Hello:

          (git-reference
            (url "https://git.savannah.gnu.org/git/hello.git")
            (commit "v2.10"))

     Это эквивалентно приведенной ниже ссылке, которая явно называет
     коммит:

          (git-reference
            (url "https://git.savannah.gnu.org/git/hello.git")
            (commit "dc7dc56a00e48fe6f231a58f6537139fe2908fb9"))

   For Mercurial repositories, the module ‘(guix hg-download)’ defines
the ‘hg-fetch’ origin method and ‘hg-reference’ data type for support of
the Mercurial version control system.

 -- Scheme Procedure: hg-fetch REF HASH-ALGO HASH [name] Return a
          fixed-output derivation that fetches REF, a
     ‘<hg-reference>’ object.  The output is expected to have recursive
     hash HASH of type HASH-ALGO (a symbol).  Use NAME as the file name,
     or a generic name if ‘#false’.


File: guix.ru.info,  Node: Defining Package Variants,  Next: Системы сборки,  Prev: Описание пакетов,  Up: Программный интерфейс

8.3 Defining Package Variants
=============================

One of the nice things with Guix is that, given a package definition,
you can easily _derive_ variants of that package—for a different
upstream version, with different dependencies, different compilation
options, and so on.  Some of these custom packages can be defined
straight from the command line (*note Параметры преобразования
пакета::).  This section describes how to define package variants in
code.  This can be useful in “manifests” (*note ‘--manifest’:
profile-manifest.) and in your own package collection (*note Создание
канала::), among others!

   As discussed earlier, packages are first-class objects in the Scheme
language.  The ‘(guix packages)’ module provides the ‘package’ construct
to define new package objects (*note ссылка на пакет::).  The easiest
way to define a package variant is using the ‘inherit’ keyword together
with ‘package’.  This allows you to inherit from a package definition
while overriding the fields you want.

   For example, given the ‘hello’ variable, which contains a definition
for the current version of GNU Hello, here’s how you would define a
variant for version 2.2 (released in 2006, it’s vintage!):

     (use-modules (gnu packages base))    ;for 'hello'

     (define hello-2.2
       (package
         (inherit hello)
         (version "2.2")
         (source (origin
                   (method url-fetch)
                   (uri (string-append "mirror://gnu/hello/hello-" version
                                       ".tar.gz"))
                   (sha256
                    (base32
                     "0lappv4slgb5spyqbh6yl5r013zv72yqg2pcl30mginf3wdqd8k9"))))))

   The example above corresponds to what the ‘--with-source’ package
transformation option does.  Essentially ‘hello-2.2’ preserves all the
fields of ‘hello’, except ‘version’ and ‘source’, which it overrides.
Note that the original ‘hello’ variable is still there, in the ‘(gnu
packages base)’ module, unchanged.  When you define a custom package
like this, you are really _adding_ a new package definition; the
original one remains available.

   You can just as well define variants with a different set of
dependencies than the original package.  For example, the default ‘gdb’
package depends on ‘guile’, but since that is an optional dependency,
you can define a variant that removes that dependency like so:

     (use-modules (gnu packages gdb)    ;for 'gdb'
                  (srfi srfi-1))        ;for 'alist-delete'

     (define gdb-sans-guile
       (package
         (inherit gdb)
         (inputs (alist-delete "guile"
                               (package-inputs gdb)))))

   The ‘alist-delete’ call above removes the tuple from the ‘inputs’
field that has ‘"guile"’ as its first element (*note (guile)SRFI-1
Association Lists::).

   In some cases, you may find it useful to write functions
(“procedures”, in Scheme parlance) that return a package based on some
parameters.  For example, consider the ‘luasocket’ library for the Lua
programming language.  We want to create ‘luasocket’ packages for major
versions of Lua.  One way to do that is to define a procedure that takes
a Lua package and returns a ‘luasocket’ package that depends on it:

     (define (make-lua-socket name lua)
       ;; Return a luasocket package built with LUA.
       (package
         (name name)
         (version "3.0")
         ;; several fields omitted
         (inputs
          `(("lua" ,lua)))
         (synopsis "Socket library for Lua")))

     (define-public lua5.1-socket
       (make-lua-socket "lua5.1-socket" lua-5.1))

     (define-public lua5.2-socket
       (make-lua-socket "lua5.2-socket" lua-5.2))

   Here we have defined packages ‘lua5.1-socket’ and ‘lua5.2-socket’ by
calling ‘make-lua-socket’ with different arguments.  *Note
(guile)Procedures::, for more info on procedures.  Having top-level
public definitions for these two packages means that they can be
referred to from the command line (*note Пакетные модули::).

   These are pretty simple package variants.  As a convenience, the
‘(guix transformations)’ module provides a high-level interface that
directly maps to the more sophisticated package transformation options
(*note Параметры преобразования пакета::):

 -- Scheme Procedure: options->transformation OPTS
     Return a procedure that, when passed an object to build (package,
     derivation, etc.), applies the transformations specified by OPTS
     and returns the resulting objects.  OPTS must be a list of
     symbol/string pairs such as:

          ((with-branch . "guile-gcrypt=master")
           (without-tests . "libgcrypt"))

     Each symbol names a transformation and the corresponding string is
     an argument to that transformation.

   For instance, a manifest equivalent to this command:

     guix build guix \
       --with-branch=guile-gcrypt=master \
       --with-debug-info=zlib

...  would look like this:

     (use-modules (guix transformations))

     (define transform
       ;; The package transformation procedure.
       (options->transformation
        '((with-branch . "guile-gcrypt=master")
          (with-debug-info . "zlib"))))

     (packages->manifest
      (list (transform (specification->package "guix"))))

   The ‘options->transformation’ procedure is convenient, but it’s
perhaps also not as flexible as you may like.  How is it implemented?
The astute reader probably noticed that most package transformation
options go beyond the superficial changes shown in the first examples of
this section: they involve “input rewriting”, whereby the dependency
graph of a package is rewritten by replacing specific inputs by others.

   Dependency graph rewriting, for the purposes of swapping packages in
the graph, is what the ‘package-input-rewriting’ procedure in ‘(guix
packages)’ implements.

 -- Процедура Scheme: package-input-rewriting REPLACEMENTS
          [REWRITE-NAME] [#:deep? #t] Возвращает процедуру, которая при
          передаче
     пакета заменяет его прямые и косвенные зависимости, включая неявные
     входы, когда DEEP? истинна, согласно REPLACEMENTS.  REPLACEMENTS -
     это список пар пакетов; первый элемент каждой пары - это заменяемый
     пакет, а второй - заменяющий.

     При необходимости, REWRITE-NAME - это процедура с одним аргументом,
     которая принимает имя пакета и возвращает его новое имя после
     перезаписи.

Рассмотрим пример:

     (define libressl-instead-of-openssl
       ;; This is a procedure to replace OPENSSL by LIBRESSL,
       ;; recursively.
       (package-input-rewriting `((,openssl . ,libressl))))

     (define git-with-libressl
       (libressl-instead-of-openssl git))

Здесь мы сначала определяем процедуру перезаписи, которая заменяет
OPENSSL на LIBRESSL.  Затем мы используем это, чтобы определить
“вариант” пакета GIT, который использует LIBRESSL вместо OPENSSL.  Это
именно то, что делает параметр командной строки ‘--with-input’ (*note
‘--with-input’: Параметры преобразования пакета.).

   Следующий вариант ‘package-input-rewriting’ может сопоставлять
пакеты, подлежащие замене, по имени, а не по идентификатору.

 -- Scheme Procedure: package-input-rewriting/spec REPLACEMENTS [#:deep?
          #t]
     Возвращает процедуру, которая для данного пакета применяет заданные
     REPLACEMENTS ко всему графу пакета, включая неявные входные данные,
     если DEEP? не ложно.  REPLACEMENTS - это список пары
     спецификация/процедуры; каждая спецификация - это спецификация
     пакета, такая как ‘"gcc"’ или ‘"guile@2"’, и каждая процедура берет
     соответствующий пакет и возвращает замену для этого пакета.

   Приведенный выше пример можно переписать так:

     (define libressl-instead-of-openssl
       ;; Replace all the packages called "openssl" with LibreSSL.
       (package-input-rewriting/spec `(("openssl" . ,(const libressl)))))

   Ключевое отличие здесь в том, что на этот раз пакеты сопоставляются
по спецификации, а не по идентичности.  Другими словами, любой пакет в
графе, который называется ‘openssl’, будет заменен.

   Более общая процедура для перезаписи графа зависимостей пакетов - это
‘package-mapping’: она поддерживает произвольные изменения узлов в
графе.

 -- Scheme Procedure: package-mapping PROC [CUT?] [#:deep? #f]
     Вернуть процедуру, которая для данного пакета применяет PROC ко
     всем зависимым пакетам и возвращает полученный пакет.  Процедура
     останавливает рекурсию, когда CUT? возвращает истину для данного
     пакета.  Когда DEEP? истинно, PROC также применяется к неявным
     входным данным.


File: guix.ru.info,  Node: Системы сборки,  Next: Фазы сборки,  Prev: Defining Package Variants,  Up: Программный интерфейс

8.4 Системы сборки
==================

В каждом определении пакета указывается “система сборки” и аргументы для
этой системы сборки (*note Описание пакетов::).  Это поле ‘build-system’
представляет процедуру сборки пакета, а также неявные зависимости этой
процедуры сборки.

   Системы сборки - это объекты ‘<build-system>’.  Интерфейс для их
создания и управления ими предоставляется модулем ‘(guix build-system)’,
а фактические системы сборки экспортируются определенными модулями.

   Под капотом системы сборки сначала компилируют объекты пакета в
“bag”.  “bag” похож на пакет, но с меньшим количеством украшений—другими
словами, bag - это представление пакета нижнего уровня, которое включает
в себя все входные данные этого пакета, включая те, которые были неявно
добавлены система сборки.  Это промежуточное представление затем
компилируется в derivation (*note Деривации::).
‘package-with-c-toolchain’ - это пример способа изменить неявные входные
данные, которые использует система сборки пакета (*note
‘package-with-c-toolchain’: ссылка на пакет.).

   Системы сборки принимают необязательный список из “arguments”.  В
определениях пакетов они передаются через поле ‘arguments’ (*note
Описание пакетов::).  Обычно это аргументы ключевого слова (*note
keyword arguments in Guile: (guile)Optional Arguments.).  Значение этих
аргументов обычно оценивается в “build stratum”—то есть процессом Guile,
запущенным демоном (*note Деривации::).

   Основная система сборки - это ‘gnu-build-system’, которая реализует
стандартную процедуру сборки для GNU и многих других пакетов.  Она
предоставляется модулем ‘(guix build-system gnu)’.

 -- Scheme Variable: gnu-build-system
     ‘gnu-build-system’ представляет систему сборки GNU и ее варианты
     (*note configuration and makefile conventions:
     (standards)Configuration.).

     Вкратце, пакеты, использующие его, настраиваются, собираются и
     устанавливаются с помощью обычной последовательности команд ‘./
     configure && make && make check && make install’.  На практике
     часто требуется несколько дополнительных шагов.  Все эти шаги
     разбиты на отдельные “фазы”.  *Note Фазы сборки::, чтобы узнать
     больше о фазах сборки и способах их настройки.

     Кроме того, эта система сборки гарантирует, что доступна
     “стандартная” среда для пакетов GNU. Сюда входят такие инструменты,
     как GCC, libc, Coreutils, Bash, Make, Diffutils, grep и sed (полный
     список см.  в модуле ‘(guix build-system gnu)’).  Мы называем их
     “неявными входами” пакета, потому что в определениях пакетов они не
     упоминаются.

     This build system supports a number of keyword arguments, which can
     be passed via the ‘arguments’ field of a package.  Here are some of
     the main parameters:

     ‘#:phases’
          This argument specifies build-side code that evaluates to an
          alist of build phases.  *Note Фазы сборки::, for more
          information.

     ‘#:configure-flags’
          This is a list of flags (strings) passed to the ‘configure’
          script.  *Note Описание пакетов::, for an example.

     ‘#:make-flags’
          This list of strings contains flags passed as arguments to
          ‘make’ invocations in the ‘build’, ‘check’, and ‘install’
          phases.

     ‘#:out-of-source?’
          This Boolean, ‘#f’ by default, indicates whether to run builds
          in a build directory separate from the source tree.

          When it is true, the ‘configure’ phase creates a separate
          build directory, changes to that directory, and runs the
          ‘configure’ script from there.  This is useful for packages
          that require it, such as ‘glibc’.

     ‘#:tests?’
          This Boolean, ‘#t’ by default, indicates whether the ‘check’
          phase should run the package’s test suite.

     ‘#:test-target’
          This string, ‘"check"’ by default, gives the name of the
          makefile target used by the ‘check’ phase.

     ‘#:parallel-build?’
     ‘#:parallel-tests?’
          These Boolean values specify whether to build, respectively
          run the test suite, in parallel, with the ‘-j’ flag of ‘make’.
          When they are true, ‘make’ is passed ‘-jN’, where N is the
          number specified as the ‘--cores’ option of ‘guix-daemon’ or
          that of the ‘guix’ client command (*note ‘--cores’:
          Стандартные параметры сборки.).

     ‘#:validate-runpath?’
          This Boolean, ‘#t’ by default, determines whether to
          “validate” the ‘RUNPATH’ of ELF binaries (‘.so’ shared
          libraries as well as executables) previously installed by the
          ‘install’ phase.

          This validation step consists in making sure that all the
          shared libraries needed by an ELF binaries, which are listed
          as ‘DT_NEEDED’ entries in its ‘PT_DYNAMIC’ segment, appear in
          the ‘DT_RUNPATH’ entry of that binary.  In other words, it
          ensures that running or using those binaries will not result
          in a “file not found” error at run time.  *Note ‘-rpath’:
          (ld)Options, for more information on ‘RUNPATH’.

     ‘#:substitutable?’
          This Boolean, ‘#t’ by default, tells whether the package
          outputs should be substitutable—i.e., whether users should be
          able to obtain substitutes for them instead of building
          locally (*note Подстановки::).

     ‘#:allowed-references’
     ‘#:disallowed-references’
          When true, these arguments must be a list of dependencies that
          must not appear among the references of the build results.
          If, upon build completion, some of these references are
          retained, the build process fails.

          This is useful to ensure that a package does not erroneously
          keep a reference to some of it build-time inputs, in cases
          where doing so would, for example, unnecessarily increase its
          size (*note Запуск guix size::).

     Most other build systems support these keyword arguments.

   Другие объекты ‘<build-system>’ определены для поддержки других
соглашений и инструментов, используемых пакетами свободного программного
обеспечения.  Они наследуют большую часть ‘gnu-build-system’ и
различаются в основном набором входных данных, неявно добавляемых в
процесс сборки, и списком выполняемых фаз.  Некоторые из этих систем
сборки перечислены ниже.

 -- Scheme Variable: ant-build-system
     Эта переменная экспортируется ‘(guix build-system ant)’.  Она
     реализует процедуру сборки пакетов Java, которые можно собрать с
     помощью Ant build tool (https://ant.apache.org/).

     Она добавляет к набору входных данных как ‘ant’, так и “Java
     Development Kit” (JDK), предоставленные пакетом ‘icedtea’.
     Различные пакеты можно указать с помощью параметров ‘#:ant’ и
     ‘#:jdk’ соответственно.

     Когда исходный пакет не предоставляет подходящий файл сборки Ant,
     параметр ‘#:jar-name’ можно использовать для создания минимального
     файла сборки Ant ‘build.xml’ с задачами для создания указанного
     архива jar.  В этом случае параметр ‘#:source-dir’ можно
     использовать для указания подкаталога источника, по умолчанию -
     src.

     The ‘#:main-class’ parameter can be used with the minimal ant
     buildfile to specify the main class of the resulting jar.  This
     makes the jar file executable.  The ‘#:test-include’ parameter can
     be used to specify the list of junit tests to run.  It defaults to
     ‘(list "**/*Test.java")’.  The ‘#:test-exclude’ can be used to
     disable some tests.  It defaults to ‘(list "**/Abstract*.java")’,
     because abstract classes cannot be run as tests.

     Параметр ‘#:build-target’ можно использовать для указания задачи
     Ant, которая должна выполняться на этапе ‘build’.  По умолчанию
     будет запущена задача jar.

 -- Scheme Variable: android-ndk-build-system
     Эта переменная экспортируется ‘(guix build-system android-ndk)’.
     Она реализует процедуру сборки пакетов Android NDK (собственный
     комплект разработки) с использованием процесса сборки, специфичного
     для Guix.

     Система сборки предполагает, что пакеты устанавливают свои файлы
     общедоступного интерфейса (заголовки) в подкаталог ‘include’ вывода
     ‘out’, а их библиотеки - в подкаталог ‘lib’ вывода ‘out’.

     Также предполагается, что объединение всех зависимостей пакета не
     имеет конфликтующих файлов.

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

 -- Scheme Variable: asdf-build-system/source
 -- Scheme Variable: asdf-build-system/sbcl
 -- Scheme Variable: asdf-build-system/ecl

     These variables, exported by ‘(guix build-system asdf)’, implement
     build procedures for Common Lisp packages using “ASDF”
     (https://common-lisp.net/project/asdf/).  ASDF is a system
     definition facility for Common Lisp programs and libraries.

     The ‘asdf-build-system/source’ system installs the packages in
     source form, and can be loaded using any common lisp
     implementation, via ASDF.  The others, such as
     ‘asdf-build-system/sbcl’, install binary systems in the format
     which a particular implementation understands.  These build systems
     can also be used to produce executable programs, or lisp images
     which contain a set of packages pre-loaded.

     В системе сборки используются соглашения об именах.  Для бинарных
     пакетов перед именем пакета должен стоять префикс реализации lisp,
     например ‘sbcl-’ для ‘asdf-build-system/sbcl’.

     Кроме того, соответствующий исходный пакет должен быть помечен с
     использованием того же соглашения, что и пакеты python (см.  *note
     Модули Python::), с использованием префикса ‘cl-’.

     In order to create executable programs and images, the build-side
     procedures ‘build-program’ and ‘build-image’ can be used.  They
     should be called in a build phase after the
     ‘create-asdf-configuration’ phase, so that the system which was
     just built can be used within the resulting image.  ‘build-program’
     requires a list of Common Lisp expressions to be passed as the
     ‘#:entry-program’ argument.

     By default, all the ‘.asd’ files present in the sources are read to
     find system definitions.  The ‘#:asd-files’ parameter can be used
     to specify the list of ‘.asd’ files to read.  Furthermore, if the
     package defines a system for its tests in a separate file, it will
     be loaded before the tests are run if it is specified by the
     ‘#:test-asd-file’ parameter.  If it is not set, the files
     ‘<system>-tests.asd’, ‘<system>-test.asd’, ‘tests.asd’, and
     ‘test.asd’ will be tried if they exist.

     If for some reason the package must be named in a different way
     than the naming conventions suggest, or if several systems must be
     compiled, the ‘#:asd-systems’ parameter can be used to specify the
     list of system names.

 -- Scheme Variable: cargo-build-system
     Эта переменная экспортируется ‘(guix build-system cargo)’.  Она
     поддерживает сборку пакетов с использованием Cargo, инструмента
     сборки языка программирования Rust (https://www.rust-lang.org).

     Она добавляет ‘rustc’ и ‘cargo’ к набору входных данных.  Другой
     пакет Rust можно указать с помощью параметра ‘#:rust’.

     Regular cargo dependencies should be added to the package
     definition similarly to other packages; those needed only at build
     time to native-inputs, others to inputs.  If you need to add
     source-only crates then you should add them to via the
     ‘#:cargo-inputs’ parameter as a list of name and spec pairs, where
     the spec can be a package or a source definition.  Note that the
     spec must evaluate to a path to a gzipped tarball which includes a
     ‘Cargo.toml’ file at its root, or it will be ignored.  Similarly,
     cargo dev-dependencies should be added to the package definition
     via the ‘#:cargo-development-inputs’ parameter.

     In its ‘configure’ phase, this build system will make any source
     inputs specified in the ‘#:cargo-inputs’ and
     ‘#:cargo-development-inputs’ parameters available to cargo.  It
     will also remove an included ‘Cargo.lock’ file to be recreated by
     ‘cargo’ during the ‘build’ phase.  The ‘package’ phase will run
     ‘cargo package’ to create a source crate for future use.  The
     ‘install’ phase installs the binaries defined by the crate.  Unless
     ‘install-source? #f’ is defined it will also install a source crate
     repository of itself and unpacked sources, to ease in future
     hacking on rust packages.

 -- Scheme Variable: chicken-build-system
     This variable is exported by ‘(guix build-system chicken)’.  It
     builds CHICKEN Scheme (https://call-cc.org/) modules, also called
     “eggs” or “extensions”.  CHICKEN generates C source code, which
     then gets compiled by a C compiler, in this case GCC.

     Эта система сборки добавляет ‘chicken’ к входным данным (inputs)
     пакета, а также к пакетам ‘gnu-build-system’.

     The build system can’t (yet) deduce the egg’s name automatically,
     so just like with ‘go-build-system’ and its ‘#:import-path’, you
     should define ‘#:egg-name’ in the package’s ‘arguments’ field.

     For example, if you are packaging the ‘srfi-1’ egg:

          (arguments '(#:egg-name "srfi-1"))

     Egg dependencies must be defined in ‘propagated-inputs’, not
     ‘inputs’ because CHICKEN doesn’t embed absolute references in
     compiled eggs.  Test dependencies should go to ‘native-inputs’, as
     usual.

 -- Scheme Variable: copy-build-system
     Эта переменная экспортируется в ‘(guix build-system copy)’.  Она
     поддерживает сборку простых пакетов, которые не требуют большой
     компиляции, в основном просто перемещения файлов.

     Она добавляет большую часть пакетов ‘gnu-build-system’ в набор
     входных данных.  По этой причине ‘copy-build-system’ не требуется
     весь шаблонный код, часто необходимый для ‘trivial-build-system’.

     Чтобы еще больше упростить процесс установки файла, предоставляется
     аргумент ‘#:install-plan’, позволяющий упаковщику указывать, какие
     файлы куда установить.  План установки представляет собой список
     ‘(SOURCE TARGET [FILTERS])’.  FILTERS необязательны.

        • Когда SOURCE соответствует файл или каталог без косой черты,
          установить его в TARGET.
             • Если TARGET имеет косую черту в конце, установить SOURCE
               basename ниже TARGET.
             • В противном случае установите SOURCE как TARGET.

        • Когда SOURCE - это каталог с косой чертой в конце или когда
          используются FILTERS, завершающая косая черта TARGET
          подразумевается с тем же значением, что и выше.
             • Без FILTER установить _содержимое_ SOURCE в TARGET.
             • С FILTERS среди ‘#:include’, ‘#:include-regexp’,
               ‘#:exclude’, ‘#:exclude-regexp’, установить только
               избранные файлы в зависимости от фильтров.  Каждый фильтр
               определяется списком строк.
                  • С помощью ‘#:include’ установите все файлы, суффикс
                    пути которых соответствует хотя бы одному из
                    элементов в данном списке.
                  • С помощью ‘#:include-regex’ установить все файлы,
                    подкаталоги которых соответствуют хотя бы одному из
                    регулярных выражений в данном списке.
                  • Фильтры ‘#:exclude’ и ‘#:exclude-regexp’ являются
                    дополнением к своим аналогам включения.  Без флагов
                    ‘#:include’ установить все файлы, кроме тех, которые
                    соответствуют фильтрам исключения.  Если указаны и
                    включения, и исключения, то исключения выполняются
                    поверх включений.
          В любом случае пути, относительные к SOURCE, сохраняются в
          TARGET.

     Примеры:

        • ‘("foo/bar" "share/my-app/")’: Установить ‘bar’ в
          ‘share/my-app/bar’.
        • ‘("foo/bar" "share/my-app/baz")’: Установить ‘bar’ в
          ‘share/my-app/baz’.
        • ‘("foo/" "share/my-app")’: Установить содержимое ‘foo’ в
          ‘share/my-app’, например, установить ‘foo/sub/file’ в
          ‘share/my-app/sub/file’.
        • ‘("foo/" "share/my-app" #:include ("sub/file"))’: Установить
          только ‘foo/sub/file’ в ‘share/my-app/sub/file’.
        • ‘("foo/sub" "share/my-app" #:include ("file"))’: Установить
          ‘foo/sub/file’ в ‘share/my-app/file’.

 -- Scheme Variable: clojure-build-system
     Эта переменная экспортируется ‘(guix build-system clojure)’.  Она
     реализует простую процедуру сборки пакетов Clojure
     (https://clojure.org/) с использованием простого старого ‘compile’
     в Clojure.  Кросс-компиляция пока не поддерживается.

     Она добавляет ‘clojure’, ‘icedtea’ и ‘zip’ к набору входных данных.
     Различные пакеты можно указать с помощью параметров ‘#:clojure’,
     ‘#:jdk’ и ‘#:zip’ соответственно.

     Список исходных каталогов, тестовых каталогов и имен jar-файлов
     можно указать с помощью параметров ‘#:source-dirs’, ‘#:test-dirs’ и
     ‘#:jar-names’ соответственно.  Каталог компиляции и основной класс
     можно указать с помощью параметров ‘#:compile-dir’ и ‘#:main-class’
     соответственно.  Остальные параметры описаны ниже.

     Эта система сборки является расширением ‘ant-build-system’, но со
     следующими изменениями:

     ‘build’
          На этом этапе вызывается ‘compile’ в Clojure для компиляции
          исходных файлов и запускается ‘jar’ для создания jar-файлов
          как из исходных файлов, так и из скомпилированных файлов в
          соответствии со списком включения и списком исключений,
          указанным в ‘#:aot-include’ и ‘#:aot-exclude’ соответственно.
          Список исключений имеет приоритет над списком включения.  Эти
          списки состоят из символов, представляющих библиотеки Clojure,
          или специального ключевого слова ‘#:all’, представляющего все
          библиотеки Clojure, находящиеся в исходных каталогах.
          Параметр ‘#:omit-source?’ определяет, следует ли включать
          исходники в jar-файлы.

     ‘check’
          На этом этапе выполняются тесты в соответствии со списком
          включения и списком исключений, указанными в ‘#:test-include’
          и ‘#:test-exclude’ соответственно.  Их значения аналогичны
          значениям ‘#:aot-include’ и ‘#:aot-exclude’, за исключением
          того, что специальное ключевое слово ‘#:all’ теперь обозначает
          все библиотеки Clojure, находящиеся в каталогах test.
          Параметр ‘#:tests?’ определяет, нужно ли запускать тесты.

     ‘установка’
          На этом этапе устанавливаются все созданные ранее jars.

     Помимо вышесказанного, эта система сборки также содержит
     дополнительную фазу:

     ‘install-doc’
          На этом этапе устанавливаются все файлы верхнего уровня с
          базовым именем, совпадающим с ‘%doc-regex’.  Другое регулярное
          выражение можно указать с помощью параметра ‘#:doc-regex’.
          Все файлы (рекурсивно) в каталогах документации, указанные в
          ‘#:doc-dirs’, также устанавливаются.

 -- Scheme переменная: cmake-build-system
     Эта переменная экспортируется ‘(guix build-system cmake)’.  Она
     реализует процедуру сборки пакетов с использованием инструмента
     сборки CMake (https://www.cmake.org).

     Она автоматически добавляет пакет ‘cmake’ в набор входных данных.
     Какой пакет используется, можно указать с помощью параметра
     ‘#:cmake’.

     Параметр ‘#:configure-flags’ используется как список флагов,
     переданных команде ‘cmake’.  Параметр ‘#:build-type’ абстрактно
     определяет флаги, передаваемые компилятору; по умолчанию
     используется ‘"RelWithDebInfo"’ (сокращение от “release mode с
     отладочной информацией”), что примерно означает, что код
     компилируется с помощью ‘-O2 -g’, как в случае пакетов на основе
     Autoconf по умолчанию.

 -- Scheme переменная: dune-build-system
     Эта переменная экспортируется в ‘(guix build-system dune)’.  Она
     поддерживает сборку пакетов с использованием Dune
     (https://dune.build/), инструмента сборки для языка
     программирования OCaml.  Она реализована как расширение
     ‘ocaml-build-system’, описанную ниже.  Таким образом, в эту систему
     сборки можно передать параметры ‘#:ocaml’ и ‘#:findlib’.

     Она автоматически добавляет пакет ‘dune’ в набор входных данных.
     Какой пакет используется, можно указать с помощью параметра
     ‘#:dune’.

     Фаза ‘configure’ отсутствует, потому что dune пакеты обычно не
     нужно настраивать.  Параметр ‘#:build-flags’ используется как
     список флагов, переданных команде ‘dune’ во время сборки.

     Параметр ‘#:jbuild?’ можно передать для использования команды
     ‘jbuild’ вместо более новой команды ‘dune’ при сборке пакета.  Его
     значение по умолчанию - ‘#f’.

     Параметр ‘#:package’ может быть передан для указания имени пакета,
     что полезно, когда пакет содержит несколько пакетов, и вы хотите
     создать только один из них.  Это эквивалентно передаче аргумента
     ‘-p’ в ‘dune’.

 -- Scheme переменная: go-build-system
     Эта переменная экспортируется ‘(guix build-system go)’.  Онf
     реализует процедуру сборки пакетов Go с использованием стандартного
     механизмов сборки Go
     (https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies).

     Ожидается, что пользователь предоставит значение для ключа
     ‘#:import-path’ и, в некоторых случаях, ‘#:unpack-path’.  import
     path (https://golang.org/doc/code.html#ImportPaths) соответствует
     пути к файловой системе, ожидаемому сценариями сборки пакета и
     любыми ссылочными пакетами, и обеспечивает уникальный способ ссылки
     на Go пакет.  Обычно он основан на комбинации удаленного URI
     исходного кода пакета и иерархической структуры файловой системы.
     В некоторых случаях вам нужно будет распаковать исходный код пакета
     в другую структуру каталогов, отличную от той, которая указана в
     пути импорта, и в таких случаях следует использовать
     ‘#:unpack-path’.

     Пакеты, которые предоставляют библиотеки Go, должны устанавливать
     свой исходный код во встроенные выходные данные.  Ключ
     ‘#:install-source?’, который по умолчанию равен ‘#t’, определяет,
     установливается ли исходный код.  Для пакетов, которые
     предоставляют только исполняемые файлы, может быть установлено
     значение ‘#f’.

 -- Scheme переменная: glib-or-gtk-build-system
     Эта переменная экспортируется в ‘(guix build-system glib-or-gtk)’.
     Она предназначена для использования с пакетами, использующими GLib
     или GTK+.

     Эта система сборки добавляет следующие две фазы к тем, которые
     определены в ‘gnu-build-system’:

     ‘glib-or-gtk-wrap’
          Фаза ‘glib-or-gtk-wrap’ гарантирует, что программы в ‘bin/’
          смогут найти GLib “schemas” и модули GTK+
          (https://developer.gnome.org/gtk3/stable /gtk-running.html).
          Это достигается путем включения программ в сценарии запуска,
          которые соответствующим образом устанавливают переменные среды
          ‘XDG_DATA_DIRS’ и ‘GTK_PATH’.

          Можно исключить определенные выходные данные пакета из этого
          процесса упаковки, указав их имена в параметре
          ‘#:glib-or-gtk-wrap-excluded-output’.  Это полезно, когда
          известно, что выходной файл не содержит двоичных файлов GLib
          или GTK+, и где wrapping может произвольно добавить
          зависимость этого вывода от GLib и GTK+.

     ‘glib-or-gtk-compile-schemas’
          Фаза ‘glib-or-gtk-compile-schemas’ гарантирует, что все
          GSettings schemas
          (https://developer.gnome.org/gio/stable/glib-compile-schemas.html)
          в GLib скомпилированы.  Компиляция выполняется программой
          ‘glib-compile-schemas’.  Она предоставляется пакетом
          ‘glib:bin’, который автоматически импортируется системой
          сборки.  Пакет ‘glib’, предоставляющий ‘glib-compile-schemas’,
          можно указать с помощью параметра ‘#:glib’.

     Обе фазы выполняются после фазы ‘install’.

 -- Scheme переменная: guile-build-system
     Эта система сборки предназначена для пакетов Guile, которые состоят
     исключительно из кода Scheme и настолько скудны, что у них даже нет
     make-файла, не говоря уже о сценарии ‘configure’.  Она компилирует
     Scheme код с помощью ‘guild compile’ (*note (guile)Compilation::) и
     устанавливает файлы ‘.scm’ и ‘.go’ в нужное место.  Она также
     устанавливает документацию.

     Эта система сборки поддерживает кросс-компиляцию с использованием
     параметра ‘--target’ в ‘guild compile’.

     Пакеты, созданные с помощью ‘guile-build-system’, должны содержать
     пакет Guile в поле ‘native-inputs’.

 -- Scheme переменная: julia-build-system
     This variable is exported by ‘(guix build-system julia)’.  It
     implements the build procedure used by julia
     (https://julialang.org/) packages, which essentially is similar to
     running ‘julia -e 'using Pkg; Pkg.add(package)'’ in an environment
     where ‘JULIA_LOAD_PATH’ contains the paths to all Julia package
     inputs.  Tests are run by calling ‘/test/runtests.jl’.

     The Julia package name is read from the file ‘Project.toml’.  This
     value can be overridden by passing the argument
     ‘#:julia-package-name’ (which must be correctly capitalized).

     Julia packages usually manage their binary dependencies via
     ‘JLLWrappers.jl’, a Julia package that creates a module (named
     after the wrapped library followed by ‘_jll.jl’.

     To add the binary path ‘_jll.jl’ packages, you need to patch the
     files under ‘src/wrappers/’, replacing the call to the macro
     ‘JLLWrappers.@generate_wrapper_header’, adding as a second argument
     containing the store path the binary.

     As an example, in the MbedTLS Julia package, we add a build phase
     (*note Фазы сборки::) to insert the absolute file name of the
     wrapped MbedTLS package:

          (add-after 'unpack 'override-binary-path
            (lambda* (#:key inputs #:allow-other-keys)
              (for-each (lambda (wrapper)
                          (substitute* wrapper
                            (("generate_wrapper_header.*")
                             (string-append
                              "generate_wrapper_header(\"MbedTLS\", \""
                              (assoc-ref inputs "mbedtls-apache") "\")\n"))))
                        ;; There's a Julia file for each platform, override them all.
                        (find-files "src/wrappers/" "\\.jl$"))))

     Some older packages that aren’t using ‘Package.toml’ yet, will
     require this file to be created, too.  The function
     ‘julia-create-package-toml’ helps creating the file.  You need to
     pass the outputs and the source of the package, it’s name (the same
     as the ‘file-name’ parameter), the package uuid, the package
     version, and a list of dependencies specified by their name and
     their uuid.

 -- Scheme Variable: maven-build-system
     Эта переменная экспортируется в ‘(guix build-system maven)’.  Она
     реализует процедуру сборки пакетов Maven
     (https://maven.apache.org).  Maven - это инструмент для управления
     зависимостями и жизненным циклом Java.  Пользователь Maven
     указывает зависимости и плагины в файле ‘pom.xml’, который читает
     Maven.  Когда Maven не имеет одной из зависимостей или плагинов в
     своем репозитории, он загружает их и использует для сборки пакета.

     Система сборки maven гарантирует, что maven не будет пытаться
     загрузить какие-либо зависимости, работая в offline режиме.  Maven
     завершится ошибкой, если зависимость отсутствует.  Перед запуском
     Maven ‘pom.xml’ (и подпроекты) модифицируются, чтобы указать версию
     зависимостей и плагинов, которые соответствуют версиям, доступным в
     среде сборки guix.  Зависимости и плагины должны быть установлены в
     поддельном репозитории maven по адресу ‘lib/m2’ и перед запуском
     maven привязаны к соответствующему репозиторию.  Maven получает
     указание использовать этот репозиторий для сборки и устанавливает
     туда созданные артефакты.  Измененные файлы копируются в каталог
     ‘lib/m2’ выходных данных пакета.

     Вы можете указать файл ‘pom.xml’ с аргументом ‘#:pom-file’ или
     позволить системе сборки использовать файл ‘pom.xml’ по умолчанию в
     источниках.

     Если вам нужно указать версию зависимости вручную, вы можете
     использовать аргумент ‘#:local-packages’.  Он принимает список
     ассоциаций, где ключ - это groupId пакета, а его значение - это
     список ассоциаций, где ключ - это artifactId пакета, а его значение
     - это версия, которую вы хотите переопределить в ‘pom.xml’.

     Некоторые пакеты используют зависимости или плагины, которые не
     используются ни во время выполнения, ни во время сборки в Guix.  Вы
     можете изменить файл ‘pom.xml’, чтобы удалить их, используя
     аргумент ‘#:exclude’.  Его значение - это список ассоциаций, где
     ключ - это groupId плагина или зависимости, которые вы хотите
     удалить, а значение - это список artifactId, которые вы хотите
     удалить.

     Вы можете переопределить пакеты по умолчанию ‘jdk’ и ‘maven’ с
     помощью соответствующего аргумента, ‘#:jdk’ и ‘#:maven’.

     Аргумент ‘#:maven-plugins’ - это список подключаемых модулей maven,
     используемых во время сборки, в том же формате, что и поля ‘inputs’
     в объявлении пакета.  Его значение по умолчанию -
     ‘(default-maven-plugins)’, которое также экспортируется.

 -- Scheme переменная: minify-build-system
     Эта переменная экспортируется в ‘(guix build-system minify)’.  Она
     реализует процедуру минификации для простых пакетов JavaScript.

     Он добавляет ‘uglify-js’ к набору входных данных и использует его
     для сжатия всех файлов JavaScript в каталоге ‘src’.  Другой
     minifier пакет можно указать с помощью параметра ‘#:uglify-js’, но
     ожидается, что этот пакет запишет минимизированный код в
     стандартный вывод.

     Когда не все входные файлы JavaScript находятся в каталоге ‘src’,
     можно использовать параметр ‘#:javascript-files’, чтобы указать
     список имен файлов для передачи в minifier.

 -- Scheme переменная: ocaml-build-system
     Эта переменная экспортируется в ‘(guix build-system ocaml)’.  Она
     реализует процедуру сборки пакетов OCaml (https://ocaml.org),
     которая заключается в выборе правильного набора команд для запуска
     для каждого пакета.  Пакеты OCaml могут ожидать выполнения
     множества различных команд.  Эта система сборки попробует некоторые
     из них.

     Если в пакете есть файл ‘setup.ml’ на верхнем уровне, он будет
     запускать ‘ocaml setup.ml -configure’, ‘ocaml setup.ml -build’ и
     ‘ocaml setup.ml -install’.  Система сборки предполагает, что этот
     файл был сгенерирован OASIS (http://oasis.forge.ocamlcore.org/), и
     позаботится об установке префикса и включении тестов, если они не
     отключены.  Вы можете передать флаги конфигурации и сборки с
     помощью ‘#:configure-flags’ и ‘#:build-flags’.  Ключ ‘#:test-flags’
     может быть передан для изменения набора флагов, используемых для
     включения тестов.  Ключ ‘#:use-make?’ можно использовать для обхода
     этой системы на этапах сборки и установки.

     Когда в пакете есть файл ‘configure’, предполагается, что это
     созданный вручную скрипт настройки, для которого требуется другой
     формат аргументов, чем в ‘gnu-build-system’.  Вы можете добавить
     дополнительные флаги с помощью клавиши ‘#:configure-flags’.

     Когда в пакете есть файл ‘Makefile’ (или ‘#:use-make?’ - это ‘#t’),
     он будет использоваться, и дополнительные флаги могут быть переданы
     на этапы сборки и установки с ‘#:make-flags’ ключом.

     Наконец, некоторые пакеты не имеют этих файлов и используют
     стандартное расположение для своей системы сборки.  В этом случае
     система сборки запустит ‘ocaml pkg/pkg.ml’ или ‘ocaml pkg/build.ml’
     и позаботится о предоставлении пути к необходимому модулю findlib.
     Дополнительные флаги можно передать с помощью ключа
     ‘#:build-flags’.  Об установке позаботится ‘opam-installer’.  В
     этом случае пакет ‘opam’ необходимо добавить в поле ‘native-inputs’
     в определении пакета.

     Обратите внимание, что большинство пакетов OCaml предполагают, что
     они будут установлены в том же каталоге, что и OCaml, что не
     является тем, что мы хотим в guix.  В частности, они устанавливают
     файлы ‘.so’ в каталог своего модуля, что обычно нормально, потому
     что он находится в каталоге компилятора OCaml.  Однако в guix эти
     библиотеки нельзя найти, и мы используем ‘CAML_LD_LIBRARY_PATH’.
     Эта переменная указывает на ‘lib/ocaml/site-lib/stubslibs’, и
     именно здесь должны быть установлены библиотеки ‘.so’.

 -- Scheme переменная: python-build-system
     Эта переменная экспортируется в ‘(guix build-system python)’.  Она
     реализует более или менее стандартную процедуру сборки,
     используемую пакетами Python, которая заключается в запуске ‘python
     setup.py build’, а затем ‘python setup.py install
     --prefix=/gnu/store/...’.

     Для пакетов, которые устанавливают само-достаточные программы
     Python в ‘bin/’, она заботится об обертке этих программ, чтобы их
     переменная среды ‘PYTHONPATH’ указывала на все библиотеки Python,
     от которых они зависят.

     Какой пакет Python используется для сборки, можно указать с помощью
     параметра ‘#:python’.  Это полезный способ принудительно создать
     пакет для определенной версии интерпретатора Python, что может
     потребоваться, если пакет совместим только с одной версией
     интерпретатора.

     По умолчанию guix вызывает ‘setup.py’ под управлением ‘setuptools’,
     как и ‘pip’.  Некоторые пакеты несовместимы с setuptools (и pip),
     поэтому вы можете отключить это, установив для параметра
     ‘#:use-setuptools?’ значение ‘#f’.

 -- Scheme Variable: perl-build-system
     Эта переменная экспортируется в ‘(guix build-system perl)’.  Она
     реализует стандартную процедуру сборки для пакетов Perl, которая
     заключается либо в запуске ‘perl Build.PL --prefix=/gnu/store/...’,
     за которым следуют ‘Build’ и ‘Build install’; или при запуске ‘perl
     Makefile.PL PREFIX=/gnu/store/...’, за которым следуют ‘make’ и
     ‘make install’, в зависимости от того, какой из ‘Build.PL’ или
     ‘Makefile.PL’ присутствует в дистрибутиве пакета.  Предпочтение
     отдается первому, если в дистрибутиве пакета есть и ‘Build.PL’, и
     ‘Makefile.PL’.  Это предпочтение можно отменить, указав ‘#t’ для
     параметра ‘#:make-maker?’.

     Первоначальный вызов ‘perl Makefile.PL’ или ‘perl Build.PL’
     передает флаги, указанные в параметре ‘#:make-maker-flags’ или
     ‘#:module-build-flags’, соответственно.

     Какой пакет Perl используется, можно указать с помощью ‘#:perl’.

 -- Scheme Variable: renpy-build-system
     This variable is exported by ‘(guix build-system renpy)’.  It
     implements the more or less standard build procedure used by Ren’py
     games, which consists of loading ‘#:game’ once, thereby creating
     bytecode for it.

     It further creates a wrapper script in ‘bin/’ and a desktop entry
     in ‘share/applications’, both of which can be used to launch the
     game.

     Which Ren’py package is used can be specified with ‘#:renpy’.
     Games can also be installed in outputs other than “out” by using
     ‘#:output’.

 -- Scheme переменная: qt-build-system
     Эта переменная экспортируется в ‘(guix build-system qt)’.  Она
     предназначена для использования с приложениями, использующими Qt
     или KDE.

     Эта система сборки добавляет следующие две фазы к тем, которые
     определены в ‘cmake-build-system’:

     ‘check-setup’
          Фаза ‘check-setup’ подготавливает среду к запуску проверок,
          которые обычно используются тестовыми программами Qt.  Пока
          это устанавливает только некоторые переменные среды:
          ‘QT_QPA_PLATFORM=offscreen’, ‘DBUS_FATAL_WARNINGS=0’ и
          ‘CTEST_OUTPUT_ON_FAILURE=1’.

          Этот этап добавляется перед этапом ‘check’.  Это отдельный
          этап для облегчения настройки.

     ‘qt-wrap’
          Фаза ‘qt-wrap’ ищет пути к плагинам Qt5, пути QML и некоторый
          XDG во входных и выходных данных.  Если путь найден, все
          программы в выходных каталогах ‘bin/’, ‘sbin/’, ‘libexec/’ и
          ‘lib/libexec/’ заключены в сценарии, определяющие необходимые
          environment переменные.

          Можно исключить определенные выходные данные пакета из этого
          процесса упаковки, указав их имена в параметре
          ‘#:qt-wrap-excluded-output’.  Это полезно, когда известно, что
          вывод не содержит никаких двоичных файлов Qt, и когда обертка
          может произвольно добавить зависимость этого вывода от Qt, KDE
          и т.п.

          Эта фаза добавляется после фазы ‘install’.

 -- Scheme Variable: r-build-system
     Эта переменная экспортируется в ‘(guix build-system r)’.  Она
     реализует процедуру сборки, используемую пакетами R
     (https://r-project.org), которая, по сути, немного больше, чем
     запуск ‘R CMD INSTALL --library=/gnu/store/...’ в среде, где
     ‘R_LIBS_SITE’ содержит пути ко всем входам пакета R. Тесты
     запускаются после установки с использованием R-функции
     ‘tools::testInstalledPackage’.

 -- Scheme переменная: rakudo-build-system
     Эта переменная экспортируется ‘(guix build-system rakudo)’.
     Которая реализует систем сборки, используемую Rakudo
     (https://rakudo.org/) для Perl6 (https://perl6.org/) пакетов.  Она
     устанавливает: пакет в ‘/gnu/store/.../NAME-VERSION/share/perl6’;
     двоичные файлы, библиотеки и ресурсы; помещает файлы в ‘bin/’.
     Тесты можно пропустить, передав ‘#f’ параметру ‘tests?’.

     Какой пакет rakudo используется, можно указать с помощью ‘rakudo’.
     Какой пакет perl6-tap-harness, используемый для тестов, можно
     указать с помощью ‘#:verify6’ или удалить, передав ‘#f’ в параметр
     ‘with-verify6?’.  Какой пакет perl6-zef, используемый для
     тестирования и установки, можно указать с помощью ‘#:zef’ или
     удалить, передав ‘#f’ в параметр ‘with-zef?’.

 -- Scheme переменная: texlive-build-system
     Эта переменная экспортируется в ‘(guix build-system texlive)’.  Она
     используется для сборки пакетов TeX в batch режиме с указанным
     движком.  Система сборки устанавливает переменную ‘TEXINPUTS’ для
     поиска всех исходных файлов TeX во входных данных.

     По умолчанию она запускает ‘luatex’ для всех файлов,
     заканчивающихся на ‘ins’.  Другой механизм и формат можно указать с
     помощью аргумента ‘#:tex-format’.  Различные цели сборки могут быть
     указаны с помощью аргумента ‘#:build-target’, который ожидает
     список имен файлов.  Система сборки добавляет к входам только
     ‘texlive-bin’ и ‘texlive-latex-base’ (оба из ‘(gnu packages tex’).
     Оба могут быть переопределены с помощью аргументов ‘#:texlive-bin’
     и ‘#:texlive-latex-base’ соответственно.

     Параметр ‘#:tex-directory’ сообщает системе сборки, где установить
     созданные файлы в дереве texmf.

 -- Scheme переменная: ruby-build-system
     Эта переменная экспортируется в ‘(guix build-system ruby)’.  Она
     реализует процедуру сборки RubyGems, используемую пакетами Ruby,
     которая включает запуск ‘gem build’, за которым следует ‘gem
     install’.

     Поле ‘source’ пакета, использующего эту систему сборки, обычно
     ссылается на gem архив, поскольку это формат, который разработчики
     Ruby используют при выпуске своего программного обеспечения.
     Система сборки распаковывает gem архив, потенциально исправляет
     исходный код, запускает набор тестов, переупаковывает gem и
     устанавливает его.  Кроме того, на каталоги и архивы можно
     ссылаться, чтобы можно было создавать unreleased gem’ы из Git или
     традиционного архива с исходным кодом.

     Какой пакет Ruby используется, можно указать с помощью параметра
     ‘#:ruby’.  Список дополнительных флагов, передаваемых команде
     ‘gem’, можно указать с помощью параметра ‘#:gem-flags’.

 -- Scheme переменная: waf-build-system
     Эта переменная экспортируется в ‘(guix build-system waf)’.  Она
     реализует процедуру сборки вокруг сценария ‘waf’.  Общие
     этапы—‘configure’, ‘build’ и ‘install’—реализуются путем передачи
     их имен в качестве аргументов сценарию ‘waf’.

     Скрипт ‘waf’ выполняется интерпретатором Python.  Какой пакет
     Python используется для запуска сценария, можно указать с помощью
     параметра ‘#:python’.

 -- Scheme переменная: scons-build-system
     Эта переменная экспортируется в ‘(guix build-system scons)’.  Она
     реализует процедуру сборки, используемую инструментом сборки
     программного обеспечения SCons.  Эта система сборки запускает
     ‘scons’ для сборки пакета, ‘scons test’ для запуска тестов и затем
     ‘scons install’ для установки пакета.

     Дополнительные флаги, передаваемые в ‘scons’, можно указать с
     помощью параметра ‘#:scons-flags’.  Цели сборки и установки по
     умолчанию могут быть переопределены с помощью ‘#:build-target’ и
     ‘#:install-target’ соответственно.  Версия Python, используемая для
     запуска SCons, может быть указана путем выбора соответствующего
     пакета SCons с параметром ‘#:scons’.

 -- Scheme переменная: haskell-build-system
     Эта переменная экспортируется в ‘(guix build-system haskell)’.  Она
     реализует процедуру сборки Cabal, используемую пакетами Haskell,
     которая включает запуск ‘runhaskell Setup.hs configure
     --prefix=/gnu/store/...’ и ‘runhaskell Setup.hs build’.  Вместо
     установки пакета путем запуска ‘runhaskell Setup.hs install’, чтобы
     избежать попыток регистрации библиотек в каталоге хранилища
     компилятора только для чтения, система сборки использует
     ‘runhaskell Setup.hs copy’, за которым следует ‘runhaskell Setup.hs
     register’.  Кроме того, система сборки генерирует документацию по
     пакету, запуская ‘runhaskell Setup.hs haddock’, если только
     ‘#:haddock? #f’ пройден.  Дополнительные параметры можно передать с
     помощью параметра ‘#:haddock-flags’.  Если файл ‘Setup.hs’ не
     найден, система сборки вместо этого ищет ‘Setup.lhs’.

     Какой компилятор Haskell используется, можно указать с помощью
     параметра ‘#:haskell’, который по умолчанию равен ‘ghc’.

 -- Scheme переменная: dub-build-system
     Эта переменная экспортируется в ‘(guix build-system dub)’.  Она
     реализует процедуру сборки Dub, используемую пакетами D, которая
     включает запуск ‘dub build’ и ‘dub run’.  Установка осуществляется
     путем копирования файлов вручную.

     Какой компилятор D используется, можно указать с помощью параметра
     ‘#:ldc’, который по умолчанию равен ‘ldc’.

 -- Scheme переменная: emacs-build-system
     Эта переменная экспортируется в ‘(guix build-system emacs)’.  Она
     реализует процедуру установки, аналогичную системе упаковки самого
     Emacs (*note (emacs)Packages::).

     Сначала она создает файл ‘package-autoloads.el’, а затем
     байт-компилирует все файлы Emacs Lisp.  В отличие от системы
     упаковки Emacs, файлы документации Info перемещаются в стандартный
     каталог документации, а файл ‘dir’ удаляется.  Файлы пакета Elisp
     устанавливаются непосредственно в ‘share/emacs/site-lisp’.

 -- Scheme переменная: font-build-system
     Эта переменная экспортируется в ‘(guix build-system font)’.  Она
     реализует процедуру установки для пакетов шрифтов, в которой
     upstream предоставляет предварительно скомпилированные файлы
     TrueType, OpenType и т.д. файлы шрифтов, которые необходимо просто
     скопировать на место.  Она копирует файлы шрифтов в стандартные
     места выходного каталога.

 -- Scheme переменная: meson-build-system
     Эта переменная экспортируется в ‘(guix build-system meson)’.  Она
     реализует процедуру сборки для пакетов, которые используют Meson
     (https://mesonbuild.com) в качестве своей системы сборки.

     Она добавляет к набору входов как Meson, так и Ninja
     (https://ninja-build.org/), и их можно изменить с помощью
     параметров ‘#:meson’ и ‘#:ninja’.  если нужно.  По умолчанию Meson
     - это ‘meson-for-build’, что является особенным, потому что он не
     очищает ‘RUNPATH’ от двоичных файлов и библиотек при их установке.

     Эта система сборки является расширением ‘gnu-build-system’, но со
     следующими фазами, измененными на некоторые специфичные для Meson:

     ‘configure’
          На этапе выполняется ‘meson’ с флагами, указанными в
          ‘#:configure-flags’.  Флаг ‘--buildtype’ всегда установлен на
          ‘debugoptimized’, если что-то еще не указано в ‘#:build-type’.

     ‘build’
          На этапе выполняется ‘ninja’ для параллельной сборки пакета по
          умолчанию, но это можно изменить с помощью
          ‘#:parallel-build?’.

     ‘check’
          На этапе выполняется ‘ninja’ с целью, указанной в
          ‘#:test-target’, по умолчанию это ‘"test"’.

     ‘установка’
          Фаза выполняется ‘ninja install’ и не может быть изменен.

     Помимо этого, система сборки также добавляет следующие фазы:

     ‘fix-runpath’
          Эта фаза гарантирует, что все двоичные файлы могут найти
          нужные библиотеки.  Она ищет необходимые библиотеки в
          подкаталогах собираемого пакета и, при необходимости,
          добавляет их в ‘RUNPATH’.  Она также удаляет ссылки на
          библиотеки, оставшиеся от фазы сборки ‘meson-for-build’, такие
          как тестовые зависимости, которые на самом деле не требуются
          для запуска программы.

     ‘glib-or-gtk-wrap’
          Эта фаза предоставляется ‘glib-or-gtk-build-system’ и по
          умолчанию не включена.  Ее можно включить с помощью
          ‘#:glib-or-gtk?’.

     ‘glib-or-gtk-compile-schemas’
          Эта фаза предоставляется ‘glib-or-gtk-build-system’ и по
          умолчанию не включена.  Ее можно включить с помощью
          ‘#:glib-or-gtk?’.

 -- Scheme переменная: linux-module-build-system
     ‘linux-module-build-system’ позволяет создавать модули ядра Linux.

     Эта система сборки является расширением ‘gnu-build-system’, но со
     следующими изменениями:

     ‘configure’
          На этой фазе среда настраивается таким образом, чтобы Makefile
          ядра Linux можно было использовать для сборки внешнего модуля
          ядра.

     ‘build’
          На этой фазе используется Makefile ядра Linux для сборки
          внешнего модуля ядра.

     ‘установка’
          На этой фазе используется Makefile ядра Linux для установки
          внешнего модуля ядра.

     Возможно и полезно указать ядро Linux, которое будет использоваться
     для сборки модуля (в форме ‘arguments’ пакета с использованием
     ‘linux-module-build-system’ используйте ключ ‘#:linux’, чтобы
     указать это).

 -- Scheme переменная: node-build-system
     Эта переменная экспортируется в ‘(guix build-system node)’.  Она
     реализует процедуру сборки, используемую Node.js
     (https://nodejs.org), которая реализует аппроксимацию команды ‘npm
     install’, за которой следует команда ‘npm test’.

     Какой пакет Node.js используется для интерпретации команд ‘npm’,
     можно указать с помощью параметра ‘#:node’, который по умолчанию
     равен ‘node’.

   Наконец, для пакетов, которым не нужно ничего столь же сложного,
предоставляется “trivial” система сборки.  Она тривиальна в том смысле,
что она практически не оказывает поддержки при сборке: она не извлекает
никаких неявных входных данных и не имеет понятия о этапах сборки.

 -- Scheme переменная: trivial-build-system
     Эта переменная экспортируется ‘(guix build-system trivial)’.

     Эта система сборки требует аргумента ‘#:builder’.  Этот аргумент
     должен быть Scheme выражением, которое строит выходные данные
     пакета—как с ‘build-expression->derivation’ (*note
     ‘build-expression->derivation’: Деривации.).


File: guix.ru.info,  Node: Фазы сборки,  Next: Build Utilities,  Prev: Системы сборки,  Up: Программный интерфейс

8.5 Фазы сборки
===============

Почти все системы сборки пакетов реализуют понятие “фазы сборки”:
последовательность действий, которые система сборки выполняет при сборке
пакета, что приводит к установке побочных продуктов в store.  Заметным
исключением является “bare-bones” ‘trivial-build-system’ (*note Системы
сборки::).

   As discussed in the previous section, those build systems provide a
standard list of phases.  For ‘gnu-build-system’, the main build phases
are the following:

‘unpack’
     Распаковать архив исходных текстов и измените текущий каталог на
     извлеченное дерево исходных текстов.  Если источник на самом деле
     является каталогом, скопировать его в дерево сборки и войдите в
     этот каталог.

‘patch-source-shebangs’
     Изменить shebang, встречающиеся в исходных файлах, чтобы они
     ссылались на правильные имена файлов хранилища.  Например, это
     изменяет ‘#!/bin/sh’ на ‘#!/gnu/store/...-bash-4.3/bin/sh’.

‘configure’
     Запустить сценарий ‘configure’ с несколькими параметрами по
     умолчанию, такими как ‘--prefix=/gnu/store/...’, а также
     параметрами, указанными в ‘#:configure-flags’ аргументе.

‘build’
     Запустить ‘make’ со списком флагов, указанным с помощью
     ‘#:make-flags’.  Если аргумент ‘#:parallel-build?’ истинен (по
     умолчанию), выполнить сборку с ‘make -j’.

‘check’
     Запустить ‘make check’ или другой target, указанный с помощью
     ‘#:test-target’, если только ‘#:tests? #f’ пройден.  Если аргумент
     ‘#:parallel-tests?’ истинен (по умолчанию), запустить ‘make check
     -j’.

‘установка’
     Запустить ‘make install’ с флагами, перечисленными в
     ‘#:make-flags’.

‘patch-shebangs’
     Изменить shebangs на установленные исполняемые файлы.

‘strip’
     Удалить символы отладки из файлов ELF (если ‘#:strip-binaries?’ не
     является ложным), скопировав их в выходные данные ‘debug’, если они
     доступны (*note Установка файлов отладки::).

   Other build systems have similar phases, with some variations.  For
example, ‘cmake-build-system’ has same-named phases but its ‘configure’
phases runs ‘cmake’ instead of ‘./configure’.  Others, such as
‘python-build-system’, have a wholly different list of standard phases.
All this code runs on the “build side”: it is evaluated when you
actually build the package, in a dedicated build process spawned by the
build daemon (*note Вызов guix-daemon::).

   Этапы сборки представлены в виде ассоциативных списков или “alists”
(*note (guile)Association Lists::), где каждый ключ является символом
имени фазы, а соответствующее значение - процедурой, которая принимает
произвольное количество аргументов.  По соглашению эти процедуры
получают информацию о сборке в виде “ключевых параметров”, которые они
могут использовать или игнорировать.

   Например, вот как ‘(guix build gnu-build-system)’ определяет
‘%standard-phase’, переменную, содержащую список фаз сборки (1):

     ;; The build phases of 'gnu-build-system'.

     (define* (unpack #:key source #:allow-other-keys)
       ;; Extract the source tarball.
       (invoke "tar" "xvf" source))

     (define* (configure #:key outputs #:allow-other-keys)
       ;; Run the 'configure' script.  Install to output "out".
       (let ((out (assoc-ref outputs "out")))
         (invoke "./configure"
                 (string-append "--prefix=" out))))

     (define* (build #:allow-other-keys)
       ;; Compile.
       (invoke "make"))

     (define* (check #:key (test-target "check") (tests? #true)
                     #:allow-other-keys)
       ;; Run the test suite.
       (if tests?
           (invoke "make" test-target)
           (display "test suite not run\n")))

     (define* (install #:allow-other-keys)
       ;; Install files to the prefix 'configure' specified.
       (invoke "make" "install"))

     (define %standard-phases
       ;; The list of standard phases (quite a few are omitted
       ;; for brevity).  Each element is a symbol/procedure pair.
       (list (cons 'unpack unpack)
             (cons 'configure configure)
             (cons 'build build)
             (cons 'check check)
             (cons 'install install)))

   Это показывает, как ‘%standard-phase’ определяется как список пар
символ/процедура (*note (guile)Pairs::).  Первая пара связывает
процедуру ‘unpack’ с символом ‘unpack’—именем; вторая пара аналогичным
образом определяет фазу ‘configure’ и так далее.  При сборке пакета,
который использует ‘gnu-build-system’ со списком фаз по умолчанию, эти
фазы выполняются последовательно.  Вы можете увидеть название каждой
фазы, запущенной и завершенной, в журнале сборки пакетов, которые вы
собираете.

   Теперь посмотрим на сами процедуры.  Каждая из них определяется с
помощью ‘define*’: ‘#:key’ перечисляет параметры ключевого слова,
которые принимает процедура, возможно, со значением по умолчанию, а
‘#:allow-other-keys’ указывает, что другие параметры ключевого слова
являются игнорируется (*note (guile)Optional Arguments::).

   Процедура ‘unpack’ учитывает параметр ‘source’, который система
сборки использует для передачи имени файла исходного архива (или
checkout контроля версий), и игнорирует другие параметры.  Фаза
‘configure’ касается только параметра ‘output’, списка имен выходных
пакетов, отображающих имена файлов хранилища (*note Пакеты со
множественным выходом::).  Она извлекает имя файла для ‘out’, вывода по
умолчанию, и передает его ‘./configure’ в качестве префикса установки,
что означает, что ‘make install’ в конечном итоге скопирует все файлы в
этом каталоге (*note configuration and makefile conventions:
(standards)Configuration.).  ‘build’ и ‘install’ игнорируют все свои
аргументы.  ‘check’ учитывает аргумент ‘test-target’, который указывает
имя цели Makefile для запуска тестов; она печатает сообщение и
пропускает тесты, если ‘tests?’ ложно.

   Список фаз, используемых для конкретного пакета, можно изменить с
помощью параметра ‘#:phase’ системы сборки.  Изменение набора фаз сборки
сводится к созданию нового списка фаз на основе списка
‘%standard-phase’, описанного выше.  Это можно сделать с помощью
стандартных процедур списков, таких как ‘alist-delete’ (*note
(guile)SRFI-1 Association Lists::); однако это удобнее делать с помощью
‘modify-phase’ (*note ‘modify-phases’: Утилиты.).

   Вот пример определения пакета, который удаляет фазу ‘configure’ из
‘%standard-phase’ и вставляет новую фазу перед фазой ‘build’, которая
называется ‘set-prefix-in- makefile’:

     (define-public example
       (package
         (name "example")
         ;; other fields omitted
         (build-system gnu-build-system)
         (arguments
          '(#:phases (modify-phases %standard-phases
                       (delete 'configure)
                       (add-before 'build 'set-prefix-in-makefile
                         (lambda* (#:key outputs #:allow-other-keys)
                           ;; Modify the makefile so that its
                           ;; 'PREFIX' variable points to "out".
                           (let ((out (assoc-ref outputs "out")))
                             (substitute* "Makefile"
                               (("PREFIX =.*")
                                (string-append "PREFIX = "
                                               out "\n")))
                             #true))))))))

   Новая вставляемая фаза записывается как анонимная процедура,
представленная с помощью ‘lambda*’; она учитывает параметр ‘output’,
который мы видели ранее.  *Note Утилиты::, чтобы узнать больше о
помощниках, используемых в этой фазе, и получить больше примеров
‘modify-phase’.

   Имейте в виду, что фазы сборки - это код, выполняемый во время
фактической сборки пакета.  Это объясняет, почему приведенное выше
выражение ‘modify-phase’ целиком (оно идет после ‘'’ или апострофа): это
“staged” для последующего выполнения.  *Note G-Expressions:: для
объяснения staging кода и задействованных “code strata”.

   ---------- Footnotes ----------

   (1) Мы представляем упрощенное представление этих фаз сборки, но
обязательно взгляните на ‘(guix build gnu-build-system)’, чтобы увидеть
все подробности!


File: guix.ru.info,  Node: Build Utilities,  Next: Хранилище,  Prev: Фазы сборки,  Up: Программный интерфейс

8.6 Build Utilities
===================

Как только вы начнете писать нетривиальные определения пакетов (*note
Описание пакетов::) или другие действия сборки (*note G-Expressions::),
вы, скорее всего, начнете искать помощников для действий, подобных
оболочке—создание каталогов, рекурсивное копирование и удаление файлов,
управление этапами сборки и т.д.  Модуль ‘(guix build utils)’
предоставляет такие служебные процедуры.

   Большинство систем сборки загружают ‘(guix build utils)’ (*note
Системы сборки::).  Таким образом, при написании настраиваемых фаз
сборки для определений пакетов вы обычно можете предположить, что эти
процедуры входят в область действия.

   При написании G-выражений вы можете импортировать ‘(guix build
utils)’ на “стороне сборки”, используя ‘with-import-modules’, а затем
поместить его в область видимости с помощью формы ‘use-modules’ (*note
(guile)Using Guile Modules::):

     (with-imported-modules '((guix build utils))  ;import it
       (computed-file "empty-tree"
                      #~(begin
                          ;; Put it in scope.
                          (use-modules (guix build utils))

                          ;; Happily use its 'mkdir-p' procedure.
                          (mkdir-p (string-append #$output "/a/b/c")))))

   Оставшаяся часть этого раздела является справочником по большинству
служебных процедур, предоставляемых ‘(guix build utils)’.

8.6.1 Работа с именами файлов в store
-------------------------------------

В этом разделе описаны процедуры, относящиеся к именам файлов в store.

 -- Scheme Procedure: %store-directory
     Return the directory name of the store.

 -- Scheme Procedure: store-file-name? FILE
     Return true if FILE is in the store.

 -- Scheme Procedure: strip-store-file-name FILE
     Удалиnm ‘/gnu/store’ и хэш из FILE, имени файла в store.
     Результатом обычно является строка ‘"PACKAGE-VERSION"’.

 -- Scheme Procedure: package-name->name+version NAME
     Учитывая NAME, имя пакета, такое как ‘"foo-0.9.1b"’, возвращает два
     значения: ‘"foo"’ и ‘"0.9.1b"’.  Если часть версии недоступна,
     возвращаются NAME и ‘#f’.  Считается, что первый дефис, за которым
     следует цифра, обозначает часть версии.

8.6.2 File Types
----------------

The procedures below deal with files and file types.

 -- Scheme Procedure: directory-exists? DIR
     Вернуть ‘#t’, если DIR существует и является каталогом.

 -- Scheme Procedure: executable-file? FILE
     Вернуть ‘#t’, если FILE существует и исполняемый файл.

 -- Scheme Procedure: symbolic-link? FILE
     Вернуть ‘#t’, если FILE является символической ссылкой (также
     известной как “символическая ссылка”).

 -- Scheme Procedure: elf-file? FILE
 -- Scheme Procedure: ar-file? FILE
 -- Scheme Procedure: gzip-file? FILE
     Вернуть ‘#t’, если FILE является, соответственно, файлом ELF,
     архивом ‘ar’ (например, статической библиотекой ‘.a’) или файлом
     gzip.

 -- Scheme Procedure: reset-gzip-timestamp FILE [#:keep-mtime? #t]
     Если FILE является файлом gzip, сбросить его timestamp (как в
     случае ‘gzip --no-name’) и вернуть истину.  В противном случае
     вернуть ‘#f’.  Когда KEEP-MTIME? истинна, сохранить время
     модификации FILE.

8.6.3 Управление файлами
------------------------

Следующие процедуры и макросы помогают создавать, изменять и удалять
файлы.  Они обеспечивают функциональность, сопоставимую с такими
обычными утилитами оболочки, как ‘mkdir -p’, ‘cp -r’, ‘rm -r’ и ‘sed’.
Они дополняют обширный, но низкоуровневый интерфейс файловой системы
Guile (*note (guile)POSIX::).

 -- Scheme Syntax: with-directory-excursion DIRECTORY BODY...
     Запустить BODY с DIRECTORY в качестве текущего каталога процесса.

     По сути, этот макрос изменяет текущий каталог на DIRECTORY перед
     вычислением BODY, используя ‘chdir’ (*note (guile)Processes::).
     Она возвращается в исходный каталог, когда остается динамический
     extent BODY, будь то через возврат нормальной процедуры или через
     нелокальный выход, такой как исключение.

 -- Scheme Procedure: mkdir-p DIR
     Создать каталог DIR и всех его предков.

 -- Scheme Procedure: install-file FILE DIRECTORY
     Создать КАТАЛОГ, если он не существует, и скопировать туда FILE под
     тем же именем.

 -- Scheme Procedure: make-file-writable FILE
     Сделать FILE доступным для записи его владельцу.

 -- Scheme Procedure: copy-recursively SOURCE DESTINATION [#:log
          (current-output-port)] [#:follow-symlinks? #f] [#:keep-mtime?
          #f]
     Скопировать каталог SOURCE в DESTINATION.  Следовать символическим
     ссылкам, если FOLLOW-SYMLINKS? истинна; в противном случае просто
     сохранить их.  Когда KEEP-MTIME? истинна, оставить время изменения
     файлов в SOURCE таким же, как у DESTINATION.  Записывать подробный
     вывод в порт LOG.

 -- Scheme Procedure: delete-file-recursively DIR [#:follow-mounts? #f]
          DIR рекурсивно, как ‘rm -rf’, без
     использования символических ссылок.  Также не следовать точкам
     монтирования, если FOLLOW-MOUNTS? не истинна.  Сообщать об ошибках,
     но игнорировать их.

 -- Scheme Syntax: substitute* FILE ((REGEXP MATCH-VAR...) BODY...) ...
          Заменить
     REGEXP в FILE строкой, возвращаемой BODY.  BODY вычисляется с
     каждой привязкой MATCH-VAR к соответствующему подвыражению
     позиционного регулярного выражения.  Например:

          (substitute* file
            (("hello")
             "good morning\n")
            (("foo([a-z]+)bar(.*)$" all letters end)
             (string-append "baz" letter end)))

     Здесь, когда строка FILE содержит ‘hello’, она заменяется на ‘good
     morning’.  Каждый раз, когда строка FILE соответствует второму
     регулярному выражению, ‘all’ привязывается к полному совпадению,
     ‘letters’ привязано к первому подвыражению, а ‘end’ привязано к
     последнему.

     Когда одно из MATCH-VAR - ‘_’, никакая переменная не связана с
     соответствующей подстрокой соответствия.

     В качестве альтернативы FILE может быть списком имен файлов, и в
     этом случае все они могут быть заменены.

     В качестве альтернативы FILE может быть списком имен файлов, и в
     этом случае все они могут быть заменены.

8.6.4 File Search
-----------------

В этом разделе описаны процедуры поиска и фильтрации файлов.

 -- Scheme Procedure: file-name-predicate REGEXP
     Вернуть предикат, который возвращает истину при передаче имени
     файла, базовое имя которого совпадает с REGEXP.

 -- Scheme Procedure: find-files DIR [PRED] [#:stat lstat]
          [#:directories? #f] [#:fail-on-error? #f] Возвращает
     лексикографически отсортированный список файлов в DIR, для которых
     PRED возвращает истину.  PRED передается два аргумента: абсолютное
     имя файла и его буфер статистики; предикат по умолчанию всегда
     возвращает истину.  PRED также может быть регулярным выражением, в
     этом случае оно эквивалентно ‘(file-name-predicate PRED)’.  STAT
     используется для получения информации о файле; использование
     ‘lstat’ означает, что символические ссылки не соблюдаются.  Если
     DIRECTORIES? истина, то каталоги также будут включены.  Если
     FAIL-ON-ERROR? истина, генерировать исключение при ошибке.

   Вот несколько примеров, в которых мы предполагаем, что текущий
каталог является корнем дерева исходников Guix:

     ;; List all the regular files in the current directory.
     (find-files ".")
     ⇒ ("./.dir-locals.el" "./.gitignore" ...)

     ;; List all the .scm files under gnu/services.
     (find-files "gnu/services" "\\.scm$")
     ⇒ ("gnu/services/admin.scm" "gnu/services/audio.scm" ...)

     ;; List ar files in the current directory.
     (find-files "." (lambda (file stat) (ar-file? file)))
     ⇒ ("./libformat.a" "./libstore.a" ...)

 -- Scheme Procedure: which PROGRAM
     Вернуть полное имя файла для PROGRAM, как в ‘$PATH’, или ‘#f’, если
     PROGRAM не найдена.

8.6.5 Фазы сборки
-----------------

‘(guix build utils)’ также содержит инструменты для управления фазами
сборки, которые используются системами сборки (*note Системы сборки::).
Фазы сборки представлены в виде ассоциативных списков или “alists”
(*note (guile)Association Lists::), где каждый ключ представляет собой
символ, обозначающий фазу, а связанное значение представляет собой
процедуру (*note Фазы сборки::).

   Ядро Guile и модуль ‘(srfi srfi-1)’ предоставляют инструменты для
управления списками.  Модуль ‘(guix build utils)’ дополняет их
инструментами, написанными с учетом фаз сборки.

 -- Scheme Syntax: modify-phases PHASES CLAUSE...
     Изменить PHASES последовательно в соответствии с каждым CLAUSE,
     которое может иметь одну из следующих форм:

          (delete OLD-PHASE-NAME)
          (replace OLD-PHASE-NAME NEW-PHASE)
          (add-before OLD-PHASE-NAME NEW-PHASE-NAME NEW-PHASE)
          (add-after OLD-PHASE-NAME NEW-PHASE-NAME NEW-PHASE)

     Где каждая PHASE-NAME выше - это выражение, преобразующееся в
     символ, а NEW-PHASE - выражение, преобразующееся в процедуру.

   Пример ниже взят из определения пакета ‘grep’.  Он добавляет фазу для
запуска после фазы ‘install’, которая называется ‘fix-egrep-and-fgrep’.
Эта фаза представляет собой процедуру (‘lambda*’ обозначает анонимную
процедуру), которая принимает аргумент ключевого слова ‘#:output’ и
игнорирует дополнительные аргументы ключевого слова (*note
(guile)Optional Arguments::, for more on ‘lambda*’ and optional and
keyword arguments.)  В фазе используется ‘substitute*’ для изменения
установленных сценариев ‘egrep’ и ‘fgrep’, чтобы они ссылались на ‘grep’
по абсолютному имени файла:

     (modify-phases %standard-phases
       (add-after 'install 'fix-egrep-and-fgrep
         ;; Patch 'egrep' and 'fgrep' to execute 'grep' via its
         ;; absolute file name instead of searching for it in $PATH.
         (lambda* (#:key outputs #:allow-other-keys)
           (let* ((out (assoc-ref outputs "out"))
                  (bin (string-append out "/bin")))
             (substitute* (list (string-append bin "/egrep")
                                (string-append bin "/fgrep"))
               (("^exec grep")
                (string-append "exec " bin "/grep")))
             #t))))

   В приведенном ниже примере фазы изменяются двумя способами:
стандартная фаза ‘configure’ удаляется, предположительно потому, что в
пакете нет сценария ‘configure’ или чего-то подобного, и фаза ‘install’
по умолчанию заменяется файлом, который вручную копирует устанавливаемые
исполняемые файлы:

     (modify-phases %standard-phases
       (delete 'configure)      ;no 'configure' script
       (replace 'install
         (lambda* (#:key outputs #:allow-other-keys)
           ;; The package's Makefile doesn't provide an "install"
           ;; rule so do it by ourselves.
           (let ((bin (string-append (assoc-ref outputs "out")
                                     "/bin")))
             (install-file "footswitch" bin)
             (install-file "scythe" bin)
             #t))))


File: guix.ru.info,  Node: Хранилище,  Next: Деривации,  Prev: Build Utilities,  Up: Программный интерфейс

8.7 Хранилище
=============

Концептуально “store” - это место, где хранятся успешно построенные
derivation’ы - по умолчанию ‘/gnu/store’.  Подкаталоги в store
называются “store items” или иногда “store paths”.  У store есть
связанная база данных, которая содержит такую информацию, как store
paths, на которые ссылается каждый store path, и список _валидных_ store
item’ов—результаты успешных сборок.  Эта база данных находится в
‘LOCALSTATEDIR/guix/db’, где LOCALSTATEDIR - это каталог состояний,
указанный через ‘--localstatedir’ во время configure, обычно ‘/var’.

   Демон _всегда_ обращается к store от имени своих клиентов (*note
Вызов guix-daemon::).  Чтобы управлять store, клиенты подключаются к
демону через сокет домена Unix, отправляют ему запросы и читают
результат - это вызовы удаленных процедур или RPC.

     Примечание: Пользователи должны _никогда_ напрямую изменять файлы в
     ‘/gnu/store’.  Это приведет к несоответствиям и нарушит
     предположения о неизменности функциональной модели Guix (*note
     Введение::).

     *Note ‘guix gc --verify’: Вызов guix gc, для получения информации о
     том, как проверить целостность store и попытаться восстановить его
     после случайных изменений.

   Модуль ‘(guix store)’ предоставляет процедуры для подключения к
демону и выполнения RPC. Они описаны ниже.  По умолчанию
‘open-connection’ и, следовательно, все команды ‘guix’ подключаются к
локальному демону или к URI, указанному в переменной среды
‘GUIX_DAEMON_SOCKET’.

 -- Environment Variable: GUIX_DAEMON_SOCKET
     Если установлено, значение этой переменной должно быть именем файла
     или URI, обозначающим конечную точку демона.  Когда это имя файла,
     оно обозначает сокет домена Unix, к которому нужно подключиться.
     Помимо имен файлов, поддерживаются следующие схемы URI:

     ‘file’
     ‘unix’
          Это для сокетов домена Unix.
          ‘file:///var/guix/daemon-socket/socket’ эквивалентен
          ‘/var/guix/daemon-socket/socket’.

     ‘guix’
          Эти URI обозначают соединения через TCP/IP без шифрования и
          аутентификации удаленного хоста.  В URI необходимо указать имя
          хоста и, возможно, номер порта (по умолчанию используется порт
          44146):

               guix://master.guix.example.org:1234

          Эта настройка подходит для локальных сетей, таких как
          кластеры, где только доверенные узлы могут подключаться к
          демону сборки по адресу ‘master.guix.example.org’.

          Параметр ‘--listen’ команды ‘guix-daemon’ можно использовать
          для указания ему прослушивать TCP-соединения (*note
          ‘--listen’: Вызов guix-daemon.).

     ‘ssh’
          These URIs allow you to connect to a remote daemon over SSH.
          This feature requires Guile-SSH (*note Требования::) and a
          working ‘guile’ binary in ‘PATH’ on the destination machine.
          It supports public key and GSSAPI authentication.  A typical
          URL might look like this:

               ssh://charlie@guix.example.org:22

          Что касается ‘guix copy’, учитываются обычные файлы
          конфигурации клиента OpenSSH (*note Запуск guix copy::).

     В будущем могут поддерживаться дополнительные схемы URI.

          Примечание: Возможность подключения к демонам удаленной сборки
          считается экспериментальной с 1.3.0.  Пожалуйста, свяжитесь с
          нами, чтобы поделиться любыми проблемами или предложениями,
          которые могут у вас возникнуть (*note Содействие::).

 -- Scheme Procedure: open-connection [URI] [#:reserve-space? #t]
     Подключится к демону через сокет домена Unix по адресу URI
     (строка).  Когда RESERVE-SPACE? истинна, указать ему, чтобы он
     зарезервировал немного дополнительного места в файловой системе,
     чтобы сборщик мусора мог работать, если диск заполнится.  Вернуть
     объект сервера.

     FILE по умолчанию - ‘%default-socket-path’, что является обычным
     расположением с учетом параметров, переданных в ‘configure’.

 -- Scheme Procedure: close-connection SERVER
     Закрыть соединение с SERVER.

 -- Scheme Variable: current-build-output-port
     Эта переменная привязана к параметру SRFI-39, который относится к
     порту, на который должны быть записаны журналы сборки и ошибок,
     отправляемые демоном.

   Процедуры, которые заставляют все RPC принимать объект сервера в
качестве своего первого аргумента.

 -- Scheme Procedure: valid-path? SERVER PATH
     Возвращать ‘#t’, когда PATH обозначает допустимый элемент
     хранилища, и ‘#f’ в противном случае (недопустимый элемент может
     существовать на диске, но по-прежнему быть недопустимым, например,
     потому что он является результатом прерывания или неудачной
     сборки).

     Условие ‘&store-protocol-error’ возникает, если PATH не имеет
     префикса в каталоге store (‘/gnu/store’).

 -- Scheme Procedure: add-text-to-store SERVER NAME TEXT [REFERENCES]
     Добавить TEXT в файл NAME в store и вернуть его store path.
     REFERENCES - это список store path’ы, на которые ссылается конечный
     store path.

 -- Scheme Procedure: build-derivations STORE DERIVATIONS [MODE] Собрать
          DERIVATIONS, список объектов ‘<derivation>’,
     имен файлов ‘.drv’ или пар derivation/output, используя указанный
     MODE—‘(build-mode normal)’ по умолчанию.

   Обратите внимание, что модуль ‘(guix monads)’ предоставляет как
монаду, так и монадические версии вышеупомянутых процедур с целью
сделать более удобной работу с кодом, который обращается к store (*note
Устройство склада::).

   Этот раздел в настоящее время не завершен.


File: guix.ru.info,  Node: Деривации,  Next: Устройство склада,  Prev: Хранилище,  Up: Программный интерфейс

8.8 Деривации
=============

Действия низкоуровневой сборки и среда, в которой они выполняются,
представлены через “derivations”.  Derivation содержит следующую
информацию:

   • The outputs of the derivation—derivations создают по крайней мере
     один файл или каталог в store, но могут создавать и больше.

   • Входные данные производных—то есть его build-time зависимости -
     которые могут быть другими derivation’ами или простыми файлами в
     store (патчи, скрипты сборки и т.д.).

   • Тип системы, на который нацелена derivation - например,
     ‘x86_64-linux’.

   • Имя файла скрипта сборки в store вместе с передаваемыми
     аргументами.

   • Список переменных среды, которые необходимо определить.

   Derivation’ы позволяют клиентам демона передавать действия сборки в
store.  Они существуют в двух формах: как представление в памяти, как на
стороне клиента, так и на стороне демона, и в виде файлов в хранилище,
имена которых заканчиваются на ‘.drv’ - эти файлы называются “derivation
paths”.  Derivation paths могут быть переданы в процедуру
‘build-derivations’ для выполнения действий сборки, которые они
предписывают (*note Хранилище::).

   Такие операции, как загрузка файлов и проверка версий, для которых
заранее известен ожидаемый хэш содержимого, моделируются как
“fixed-output derivations”.  В отличие от обычных дериваций, выходные
данные деривации с фиксированным выходом не зависят от его входных
данных - например, загрузка исходного кода дает тот же результат
независимо от метода загрузки и используемых инструментов.

   Outputs of derivations—то есть результаты сборки—имеют множество
“references”, в соответствии с указаниями RPC ‘references’ или команды
‘guix gc --references’ (*note Вызов guix gc::).  References - это набор
run-time зависимостей результатов сборки.  References - это подмножество
входных данных derivation; это подмножество автоматически вычисляется
демоном сборки путем сканирования всех файлов в выходных данных.

   Модуль ‘(guix diverations)’ предоставляет представление derivation’ов
в виде Scheme объектов, а также процедуры для создания derivation’ов и
других манипуляций с ними.  Самым низкоуровневым примитивом для создания
derivation’а является процедура ‘derivation’:

 -- Scheme Procedure: derivation STORE NAME BUILDER ARGS [#:outputs
          '(\"out\")] [#:hash #f] [#:hash-algo #f] [#:recursive? #f]
          [#:inputs '()] [#:env-vars '()]  [#:system
     (%current-system)] [#:references-graphs #f]  [#:allowed-references
     #f] [#:disallowed-references #f]  [#:leaked-env-vars #f]
     [#:local-build?  #f]  [#:substitutable?  #t] [#:properties ’()]
     Собрать производную с заданными аргументами и вернуть полученный
     объект ‘<derivation>’.

     Когда заданы HASH и HASH-ALGO, создается “fixed-output derivation”
     - то есть результат, который известен заранее, например, загрузка
     файла.  Кроме того, если RECURSIVE? истинна, то этот фиксированный
     вывод может быть исполняемым файлом или каталогом, а HASH должен
     быть хешем архива, содержащего этот вывод.

     Когда LINKS-GRAPHS истинна, данная переменная должна быть списком
     из пар имя файла и путь к store.  В этом случае граф ссылок каждого
     store path экспортируется в среду сборки в соответствующий файл в
     простом текстовом формате.

     Когда ALLOWED-LINKS истинна, данная переменная должна быть списком
     store item’ов или выходных данных, на которые может ссылаться выход
     derivation’а.  Аналогично, DISALLOWED-LINKS, если она истинна,
     данная переменная должна быть списком сущностей, на которые _не_
     могут ссылаться выходные данные.

     Когда LEAKED-ENV-VARS истинна, данная переменная должна быть
     списком строк, обозначающих переменные среды, которым разрешено
     “просачиваться” из среды демона в среду сборки.  Это применимо
     только к fixed-output derivation’ам, т.е.  когда HASH истинна.
     Основное использование - разрешить передачу таких переменных, как
     ‘http_proxy’, derivation’ам, которые загружают файлы.

     Когда LOCAL-BUILD? истинна, объявить, что производная не является
     хорошим кандидатом для offload и должна быть собрана локально
     (*note Установка демона разгрузки::).  Это справедливо для
     небольших derivation’ов, когда затраты на передачу данных
     перевешивают выгоды.

     Когда SUBSTITUTABLE? ложно, объявить, что substitutes derivation’ов
     не должны использоваться (*note Подстановки::).  Это полезно,
     например, при создании пакетов, которые фиксируют подробности
     набора команд центрального процессора.

     PROPERTIES должна быть списком ассоциаций, описывающих “свойства”
     derivation’а.  При выводе они сохраняются как есть, без
     интерпретации.

Вот пример со shell скриптом в качестве его builder’а, предполагая, что
STORE является открытым соединением с демоном, а BASH указывает на
исполняемый файл Bash в store:

     (use-modules (guix utils)
                  (guix store)
                  (guix derivations))

     (let ((builder   ; add the Bash script to the store
             (add-text-to-store store "my-builder.sh"
                                "echo hello world > $out\n" '())))
       (derivation store "foo"
                   bash `("-e" ,builder)
                   #:inputs `((,bash) (,builder))
                   #:env-vars '(("HOME" . "/homeless"))))
     ⇒ #<derivation /gnu/store/...-foo.drv => /gnu/store/...-foo>

   Как можно догадаться, этот примитив неудобно использовать напрямую.
Конечно, лучший подход - писать скрипты сборки на Scheme!  Лучше всего
для этого написать код сборки как “G-выражение” и передать его в
‘gexp->derivation’.  Для получения дополнительной информации, *note
G-Expressions::.

   Когда-то давно ‘gexp->derivation’ не существовала, и построение
derivation’ов с помощью кода сборки, написанного на Scheme, достигалось
с помощью ‘build-expression->derivation’, описанной ниже.  Эта процедура
теперь устарела и заменена более приятным ‘gexp->derivation’.

 -- Scheme Procedure: build-expression->derivation STORE NAME EXP
           [#:system (%current-system)] [#:inputs '()] [#:outputs
          '(\"out\")] [#:hash #f] [#:hash-algo #f]  [#:recursive? #f]
     [#:env-vars ’()] [#:modules ’()]  [#:references-graphs #f]
     [#:allowed-references #f]  [#:disallowed-references #f]
      [#:local-build?  #f] [#:substitutable?  #t] [#:guile-for-build #f]
     Возвращает derivation, которая исполняет Scheme выражение EXP как
     builder для derivation’а NAME.  INPUTS должна быть списком кортежей
     ‘(name drv-path sub-drv)’; когда SUB-DRV опущена, предполагается
     ‘"out"’.  MODULES - это список имен модулей Guile из текущего пути
     поиска, которые будут скопированы в store, скомпилированы и станут
     доступными в пути загрузки во время выполнения EXP—например,
     ‘((guix build utils) (guix build gnu-build-system))’.

     EXP выполняется в среде, где ‘%output’ привязан к списку пар
     output/path, а где ‘%build-inputs’ привязан к списку пар
     строка/output-path сделаными из INPUT.  Необязательно, ENV-VARS -
     это список пар строк, определяющих имя и значение переменных среды,
     видимых builder’у.  Builder завершает работу, передавая результат
     EXP в ‘exit’; таким образом, когда EXP возвращает ‘#f’, сборка
     считается неудачной.

     EXP собирается с использованием GUILE-FOR-BUILD (derivation).
     Когда GUILE-FOR-BUILD опущена или равна ‘#f’, вместо этого
     используется значение fluid’а ‘%guile-for-build’.

     См.  в процедуре ‘derivation’ значение REFERENCES-GRAPHS,
     ALLOWED-REFERENCES, DISALLOWED-REFERENCES, LOCAL-BUILD? и
     SUBSTITUTABLE?.

Вот пример single-output derivation’а, которая создает каталог,
содержащий один файл:

     (let ((builder '(let ((out (assoc-ref %outputs "out")))
                       (mkdir out)    ; create /gnu/store/...-goo
                       (call-with-output-file (string-append out "/test")
                         (lambda (p)
                           (display '(hello guix) p))))))
       (build-expression->derivation store "goo" builder))

     ⇒ #<derivation /gnu/store/...-goo.drv => ...>


File: guix.ru.info,  Node: Устройство склада,  Next: G-Expressions,  Prev: Деривации,  Up: Программный интерфейс

8.9 Устройство склада
=====================

Все процедуры, которые работают с store, описанные в предыдущих
разделах, принимают открытое соединение с демоном сборки в качестве
первого аргумента.  Хотя основная модель является функциональной, они
либо имеют побочные эффекты, либо зависят от текущего состояния store.

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

   Здесь на помощь приходит модуль ‘(guix monads)’.  Этот модуль
предоставляет основу для работы с “monads” и особенно полезную монаду
для наших целей - “store monad”.  Монады - это конструкции, которая
позволяют две вещи: связывать “контекст” со значениями (в нашем случае
контекст - это store) и строить последовательности вычислений (здесь
вычисления включают доступ к store).  Значения в монаде—значения,
которые несут этот дополнительный контекст—называются “монадическими
значениями”; процедуры, возвращающие такие значения, называются
“монадическими процедурами”.

   Рассмотрим эту “нормальную” процедуру:

     (define (sh-symlink store)
       ;; Return a derivation that symlinks the 'bash' executable.
       (let* ((drv (package-derivation store bash))
              (out (derivation->output-path drv))
              (sh  (string-append out "/bin/bash")))
         (build-expression->derivation store "sh"
                                       `(symlink ,sh %output))))

   Используя ‘(guix monads)’ и ‘(guix gexp)’, ее можно переписать как
монадическую функцию:

     (define (sh-symlink)
       ;; Same, but return a monadic value.
       (mlet %store-monad ((drv (package->derivation bash)))
         (gexp->derivation "sh"
                           #~(symlink (string-append #$drv "/bin/bash")
                                      #$output))))

   Во второй версии следует отметить несколько моментов: параметр
‘store’ теперь является неявным и является “threaded” в вызовах
‘package->derivation’ и ‘gexp->derivation’ монадические процедуры, а
монадическим значением, возвращаемым ‘package->derivation’, является
“bound” с использованием ‘mlet’ вместо простого ‘let’.

   Оказывается, вызов ‘package->derivation’ можно даже опустить,
поскольку она будет выполняться неявно, как мы увидим позже (*note
G-Expressions::):

     (define (sh-symlink)
       (gexp->derivation "sh"
                         #~(symlink (string-append #$bash "/bin/bash")
                                    #$output)))

   Вызов монадического ‘sh-symlink’ ни на что не влияет.  Как кто-то
однажды сказал: “Вы выходите из монады, как вы выходите из горящего
здания: by running”.  Итак, чтобы выйти из монады и получить желаемый
эффект, нужно использовать ‘run-with-store’:

     (run-with-store (open-connection) (sh-symlink))
     ⇒ /gnu/store/...-sh-symlink

   Обратите внимание, что модуль ‘(guix monad-repl)’ расширяет Guile
REPL новыми “метакомандами”, чтобы упростить работу с монадическими
процедурами: ‘run-in-store’ и ‘Enter-store-monad’.  Первая используется
для “run” одного монадического значения через store:

     scheme@(guile-user)> ,run-in-store (package->derivation hello)
     $1 = #<derivation /gnu/store/...-hello-2.9.drv => ...>

   Последний входит в рекурсивный REPL, где все возвращаемые значения
автоматически проходят через хранилище:

     scheme@(guile-user)> ,enter-store-monad
     store-monad@(guile-user) [1]> (package->derivation hello)
     $2 = #<derivation /gnu/store/...-hello-2.9.drv => ...>
     store-monad@(guile-user) [1]> (text-file "foo" "Hello!")
     $3 = "/gnu/store/...-foo"
     store-monad@(guile-user) [1]> ,q
     scheme@(guile-user)>

Обратите внимание, что немонадические значения не могут быть возвращены
в REPL ‘store-monad’.

   Основные синтаксические формы для работы с монадами в целом
предоставляются модулем ‘(guix monads)’ и описаны ниже.

 -- Scheme Syntax: with-monad MONAD BODY ...
     Evaluate any ‘>>=’ or ‘return’ forms in BODY as being in MONAD.

 -- Scheme Syntax: return VAL
     Return a monadic value that encapsulates VAL.

 -- Scheme Syntax: >>= MVAL MPROC ...
     “Bind” monadic value MVAL, passing its “contents” to monadic
     procedures MPROC...(1).  There can be one MPROC or several of them,
     as in this example:

          (run-with-state
              (with-monad %state-monad
                (>>= (return 1)
                     (lambda (x) (return (+ 1 x)))
                     (lambda (x) (return (* 2 x)))))
            'some-state)

          ⇒ 4
          ⇒ some-state

 -- Scheme Syntax: mlet MONAD ((VAR MVAL) ...) BODY ...
 -- Scheme Syntax: mlet* MONAD ((VAR MVAL) ...) BODY ... Bind the
          variables VAR to the monadic values
     MVAL in BODY, which is a sequence of expressions.  As with the bind
     operator, this can be thought of as “unpacking” the raw,
     non-monadic value “contained” in MVAL and making VAR refer to that
     raw, non-monadic value within the scope of the BODY.  The form (VAR
     -> VAL) binds VAR to the “normal” value VAL, as per ‘let’.  The
     binding operations occur in sequence from left to right.  The last
     expression of BODY must be a monadic expression, and its result
     will become the result of the ‘mlet’ or ‘mlet*’ when run in the
     MONAD.

     ‘mlet*’ is to ‘mlet’ what ‘let*’ is to ‘let’ (*note (guile)Local
     Bindings::).

 -- Scheme System: mbegin MONAD MEXP ...
     Bind MEXP and the following monadic expressions in sequence,
     returning the result of the last expression.  Every expression in
     the sequence must be a monadic expression.

     This is akin to ‘mlet’, except that the return values of the
     monadic expressions are ignored.  In that sense, it is analogous to
     ‘begin’, but applied to monadic expressions.

 -- Scheme System: mwhen CONDITION MEXP0 MEXP* ...
     When CONDITION is true, evaluate the sequence of monadic
     expressions MEXP0..MEXP* as in an ‘mbegin’.  When CONDITION is
     false, return ‘*unspecified*’ in the current monad.  Every
     expression in the sequence must be a monadic expression.

 -- Scheme System: munless CONDITION MEXP0 MEXP* ...
     When CONDITION is false, evaluate the sequence of monadic
     expressions MEXP0..MEXP* as in an ‘mbegin’.  When CONDITION is
     true, return ‘*unspecified*’ in the current monad.  Every
     expression in the sequence must be a monadic expression.

   The ‘(guix monads)’ module provides the “state monad”, which allows
an additional value—the state—to be _threaded_ through monadic procedure
calls.

 -- Scheme Variable: %state-monad
     The state monad.  Procedures in the state monad can access and
     change the state that is threaded.

     Consider the example below.  The ‘square’ procedure returns a value
     in the state monad.  It returns the square of its argument, but
     also increments the current state value:

          (define (square x)
            (mlet %state-monad ((count (current-state)))
              (mbegin %state-monad
                (set-current-state (+ 1 count))
                (return (* x x)))))

          (run-with-state (sequence %state-monad (map square (iota 3))) 0)
          ⇒ (0 1 4)
          ⇒ 3

     When “run” through ‘%state-monad’, we obtain that additional state
     value, which is the number of ‘square’ calls.

 -- Monadic Procedure: current-state
     Вернуть текущее состояние в виде монадического значения.

 -- Monadic Procedure: set-current-state VALUE
     Set the current state to VALUE and return the previous state as a
     monadic value.

 -- Monadic Procedure: state-push VALUE
     Push VALUE to the current state, which is assumed to be a list, and
     return the previous state as a monadic value.

 -- Monadic Procedure: state-pop
     Pop a value from the current state and return it as a monadic
     value.  The state is assumed to be a list.

 -- Scheme Procedure: run-with-state MVAL [STATE]
     Run monadic value MVAL starting with STATE as the initial state.
     Return two values: the resulting value, and the resulting state.

   The main interface to the store monad, provided by the ‘(guix store)’
module, is as follows.

 -- Scheme Variable: %store-monad
     The store monad—an alias for ‘%state-monad’.

     Values in the store monad encapsulate accesses to the store.  When
     its effect is needed, a value of the store monad must be
     “evaluated” by passing it to the ‘run-with-store’ procedure (see
     below).

 -- Scheme Procedure: run-with-store STORE MVAL [#:guile-for-build]
          [#:system (%current-system)]
     Run MVAL, a monadic value in the store monad, in STORE, an open
     store connection.

 -- Monadic Procedure: text-file NAME TEXT [REFERENCES]
     Return as a monadic value the absolute file name in the store of
     the file containing TEXT, a string.  REFERENCES is a list of store
     items that the resulting text file refers to; it defaults to the
     empty list.

 -- Monadic Procedure: binary-file NAME DATA [REFERENCES]
     Return as a monadic value the absolute file name in the store of
     the file containing DATA, a bytevector.  REFERENCES is a list of
     store items that the resulting binary file refers to; it defaults
     to the empty list.

 -- Monadic Procedure: interned-file FILE [NAME] [#:recursive? #t]
          [#:select? (const #t)] Return the name of FILE once
     interned in the store.  Use NAME as its store name, or the basename
     of FILE if NAME is omitted.

     When RECURSIVE? is true, the contents of FILE are added
     recursively; if FILE designates a flat file and RECURSIVE? is true,
     its contents are added, and its permission bits are kept.

     When RECURSIVE? is true, call ‘(SELECT? FILE STAT)’ for each
     directory entry, where FILE is the entry’s absolute file name and
     STAT is the result of ‘lstat’; exclude entries for which SELECT?
     does not return true.

     The example below adds a file to the store, under two different
     names:

          (run-with-store (open-connection)
            (mlet %store-monad ((a (interned-file "README"))
                                (b (interned-file "README" "LEGU-MIN")))
              (return (list a b))))

          ⇒ ("/gnu/store/rwm...-README" "/gnu/store/44i...-LEGU-MIN")

   The ‘(guix packages)’ module exports the following package-related
monadic procedures:

 -- Monadic Procedure: package-file PACKAGE [FILE] [#:system
          (%current-system)] [#:target #f]  [#:output "out"] Return as a
     monadic value in the absolute file name of FILE within the OUTPUT
     directory of PACKAGE.  When FILE is omitted, return the name of the
     OUTPUT directory of PACKAGE.  When TARGET is true, use it as a
     cross-compilation target triplet.

     Note that this procedure does _not_ build PACKAGE.  Thus, the
     result might or might not designate an existing file.  We recommend
     not using this procedure unless you know what you are doing.

 -- Monadic Procedure: package->derivation PACKAGE [SYSTEM]
 -- Monadic Procedure: package->cross-derivation PACKAGE TARGET [SYSTEM]
          Monadic version of ‘package-derivation’ and
     ‘package-cross-derivation’ (*note Описание пакетов::).

   ---------- Footnotes ----------

   (1) This operation is commonly referred to as “bind”, but that name
denotes an unrelated procedure in Guile.  Thus we use this somewhat
cryptic symbol inherited from the Haskell language.


File: guix.ru.info,  Node: G-Expressions,  Next: Запуск guix repl,  Prev: Устройство склада,  Up: Программный интерфейс

8.10 G-Expressions
==================

So we have “derivations”, which represent a sequence of build actions to
be performed to produce an item in the store (*note Деривации::).  These
build actions are performed when asking the daemon to actually build the
derivations; they are run by the daemon in a container (*note Вызов
guix-daemon::).

   It should come as no surprise that we like to write these build
actions in Scheme.  When we do that, we end up with two “strata” of
Scheme code(1): the “host code”—code that defines packages, talks to the
daemon, etc.—and the “build code”—code that actually performs build
actions, such as making directories, invoking ‘make’, and so on (*note
Фазы сборки::).

   To describe a derivation and its build actions, one typically needs
to embed build code inside host code.  It boils down to manipulating
build code as data, and the homoiconicity of Scheme—code has a direct
representation as data—comes in handy for that.  But we need more than
the normal ‘quasiquote’ mechanism in Scheme to construct build
expressions.

   The ‘(guix gexp)’ module implements “G-expressions”, a form of
S-expressions adapted to build expressions.  G-expressions, or “gexps”,
consist essentially of three syntactic forms: ‘gexp’, ‘ungexp’, and
‘ungexp-splicing’ (or simply: ‘#~’, ‘#$’, and ‘#$@’), which are
comparable to ‘quasiquote’, ‘unquote’, and ‘unquote-splicing’,
respectively (*note ‘quasiquote’: (guile)Expression Syntax.).  However,
there are major differences:

   • Gexps are meant to be written to a file and run or manipulated by
     other processes.

   • When a high-level object such as a package or derivation is
     unquoted inside a gexp, the result is as if its output file name
     had been introduced.

   • Gexps carry information about the packages or derivations they
     refer to, and these dependencies are automatically added as inputs
     to the build processes that use them.

   This mechanism is not limited to package and derivation objects:
“compilers” able to “lower” other high-level objects to derivations or
files in the store can be defined, such that these objects can also be
inserted into gexps.  For example, a useful type of high-level objects
that can be inserted in a gexp is “file-like objects”, which make it
easy to add files to the store and to refer to them in derivations and
such (see ‘local-file’ and ‘plain-file’ below).

   To illustrate the idea, here is an example of a gexp:

     (define build-exp
       #~(begin
           (mkdir #$output)
           (chdir #$output)
           (symlink (string-append #$coreutils "/bin/ls")
                    "list-files")))

   This gexp can be passed to ‘gexp->derivation’; we obtain a derivation
that builds a directory containing exactly one symlink to
‘/gnu/store/...-coreutils-8.22/bin/ls’:

     (gexp->derivation "the-thing" build-exp)

   As one would expect, the ‘"/gnu/store/...-coreutils-8.22"’ string is
substituted to the reference to the COREUTILS package in the actual
build code, and COREUTILS is automatically made an input to the
derivation.  Likewise, ‘#$output’ (equivalent to ‘(ungexp output)’) is
replaced by a string containing the directory name of the output of the
derivation.

   In a cross-compilation context, it is useful to distinguish between
references to the _native_ build of a package—that can run on the
host—versus references to cross builds of a package.  To that end, the
‘#+’ plays the same role as ‘#$’, but is a reference to a native package
build:

     (gexp->derivation "vi"
        #~(begin
            (mkdir #$output)
            (mkdir (string-append #$output "/bin"))
            (system* (string-append #+coreutils "/bin/ln")
                     "-s"
                     (string-append #$emacs "/bin/emacs")
                     (string-append #$output "/bin/vi")))
        #:target "aarch64-linux-gnu")

In the example above, the native build of COREUTILS is used, so that
‘ln’ can actually run on the host; but then the cross-compiled build of
EMACS is referenced.

   Another gexp feature is “imported modules”: sometimes you want to be
able to use certain Guile modules from the “host environment” in the
gexp, so those modules should be imported in the “build environment”.
The ‘with-imported-modules’ form allows you to express that:

     (let ((build (with-imported-modules '((guix build utils))
                    #~(begin
                        (use-modules (guix build utils))
                        (mkdir-p (string-append #$output "/bin"))))))
       (gexp->derivation "empty-dir"
                         #~(begin
                             #$build
                             (display "success!\n")
                             #t)))

In this example, the ‘(guix build utils)’ module is automatically pulled
into the isolated build environment of our gexp, such that ‘(use-modules
(guix build utils))’ works as expected.

   Usually you want the _closure_ of the module to be imported—i.e., the
module itself and all the modules it depends on—rather than just the
module; failing to do that, attempts to use the module will fail because
of missing dependent modules.  The ‘source-module-closure’ procedure
computes the closure of a module by looking at its source file headers,
which comes in handy in this case:

     (use-modules (guix modules))   ;for 'source-module-closure'

     (with-imported-modules (source-module-closure
                              '((guix build utils)
                                (gnu build vm)))
       (gexp->derivation "something-with-vms"
                         #~(begin
                             (use-modules (guix build utils)
                                          (gnu build vm))
                             ...)))

   In the same vein, sometimes you want to import not just pure-Scheme
modules, but also “extensions” such as Guile bindings to C libraries or
other “full-blown” packages.  Say you need the ‘guile-json’ package
available on the build side, here’s how you would do it:

     (use-modules (gnu packages guile))  ;for 'guile-json'

     (with-extensions (list guile-json)
       (gexp->derivation "something-with-json"
                         #~(begin
                             (use-modules (json))
                             ...)))

   The syntactic form to construct gexps is summarized below.

 -- Scheme Syntax: #~EXP
 -- Scheme Syntax: (gexp EXP)
     Return a G-expression containing EXP.  EXP may contain one or more
     of the following forms:

     ‘#$OBJ’
     ‘(ungexp OBJ)’
          Introduce a reference to OBJ.  OBJ may have one of the
          supported types, for example a package or a derivation, in
          which case the ‘ungexp’ form is replaced by its output file
          name—e.g., ‘"/gnu/store/...-coreutils-8.22’.

          If OBJ is a list, it is traversed and references to supported
          objects are substituted similarly.

          If OBJ is another gexp, its contents are inserted and its
          dependencies are added to those of the containing gexp.

          If OBJ is another kind of object, it is inserted as is.

     ‘#$OBJ:OUTPUT’
     ‘(ungexp OBJ OUTPUT)’
          This is like the form above, but referring explicitly to the
          OUTPUT of OBJ—this is useful when OBJ produces multiple
          outputs (*note Пакеты со множественным выходом::).

     ‘#+OBJ’
     ‘#+OBJ:output’
     ‘(ungexp-native OBJ)’
     ‘(ungexp-native OBJ OUTPUT)’
          Same as ‘ungexp’, but produces a reference to the _native_
          build of OBJ when used in a cross compilation context.

     ‘#$output[:OUTPUT]’
     ‘(ungexp output [OUTPUT])’
          Insert a reference to derivation output OUTPUT, or to the main
          output when OUTPUT is omitted.

          This only makes sense for gexps passed to ‘gexp->derivation’.

     ‘#$@LST’
     ‘(ungexp-splicing LST)’
          Like the above, but splices the contents of LST inside the
          containing list.

     ‘#+@LST’
     ‘(ungexp-native-splicing LST)’
          Like the above, but refers to native builds of the objects
          listed in LST.

     G-expressions created by ‘gexp’ or ‘#~’ are run-time objects of the
     ‘gexp?’ type (see below).

 -- Scheme Syntax: with-imported-modules MODULES BODY...
     Mark the gexps defined in BODY... as requiring MODULES in their
     execution environment.

     Each item in MODULES can be the name of a module, such as ‘(guix
     build utils)’, or it can be a module name, followed by an arrow,
     followed by a file-like object:

          `((guix build utils)
            (guix gcrypt)
            ((guix config) => ,(scheme-file "config.scm"
                                            #~(define-module ...))))

     In the example above, the first two modules are taken from the
     search path, and the last one is created from the given file-like
     object.

     This form has _lexical_ scope: it has an effect on the gexps
     directly defined in BODY..., but not on those defined, say, in
     procedures called from BODY....

 -- Scheme Syntax: with-extensions EXTENSIONS BODY...
     Mark the gexps defined in BODY... as requiring EXTENSIONS in their
     build and execution environment.  EXTENSIONS is typically a list of
     package objects such as those defined in the ‘(gnu packages guile)’
     module.

     Concretely, the packages listed in EXTENSIONS are added to the load
     path while compiling imported modules in BODY...; they are also
     added to the load path of the gexp returned by BODY....

 -- Scheme Procedure: gexp? OBJ
     Return ‘#t’ if OBJ is a G-expression.

   G-expressions are meant to be written to disk, either as code
building some derivation, or as plain files in the store.  The monadic
procedures below allow you to do that (*note Устройство склада::, for
more information about monads).

 -- Monadic Procedure: gexp->derivation NAME EXP [#:system
          (%current-system)] [#:target #f] [#:graft? #t]  [#:hash #f]
     [#:hash-algo #f]  [#:recursive?  #f] [#:env-vars ’()] [#:modules
     ’()]  [#:module-path ‘%load-path’]  [#:effective-version "2.2"]
      [#:references-graphs #f] [#:allowed-references #f]
      [#:disallowed-references #f]  [#:leaked-env-vars #f]
      [#:script-name (string-append NAME "-builder")]
      [#:deprecation-warnings #f]  [#:local-build?  #f]
     [#:substitutable?  #t]  [#:properties ’()] [#:guile-for-build #f]
     Return a derivation NAME that runs EXP (a gexp) with
     GUILE-FOR-BUILD (a derivation) on SYSTEM; EXP is stored in a file
     called SCRIPT-NAME.  When TARGET is true, it is used as the
     cross-compilation target triplet for packages referred to by EXP.

     MODULES is deprecated in favor of ‘with-imported-modules’.  Its
     meaning is to make MODULES available in the evaluation context of
     EXP; MODULES is a list of names of Guile modules searched in
     MODULE-PATH to be copied in the store, compiled, and made available
     in the load path during the execution of EXP—e.g., ‘((guix build
     utils) (guix build gnu-build-system))’.

     EFFECTIVE-VERSION determines the string to use when adding
     extensions of EXP (see ‘with-extensions’) to the search path—e.g.,
     ‘"2.2"’.

     GRAFT? determines whether packages referred to by EXP should be
     grafted when applicable.

     When REFERENCES-GRAPHS is true, it must be a list of tuples of one
     of the following forms:

          (FILE-NAME PACKAGE)
          (FILE-NAME PACKAGE OUTPUT)
          (FILE-NAME DERIVATION)
          (FILE-NAME DERIVATION OUTPUT)
          (FILE-NAME STORE-ITEM)

     The right-hand-side of each element of REFERENCES-GRAPHS is
     automatically made an input of the build process of EXP.  In the
     build environment, each FILE-NAME contains the reference graph of
     the corresponding item, in a simple text format.

     ALLOWED-REFERENCES must be either ‘#f’ or a list of output names
     and packages.  In the latter case, the list denotes store items
     that the result is allowed to refer to.  Any reference to another
     store item will lead to a build error.  Similarly for
     DISALLOWED-REFERENCES, which can list items that must not be
     referenced by the outputs.

     DEPRECATION-WARNINGS determines whether to show deprecation
     warnings while compiling modules.  It can be ‘#f’, ‘#t’, or
     ‘'detailed’.

     The other arguments are as for ‘derivation’ (*note Деривации::).

   The ‘local-file’, ‘plain-file’, ‘computed-file’, ‘program-file’, and
‘scheme-file’ procedures below return “file-like objects”.  That is,
when unquoted in a G-expression, these objects lead to a file in the
store.  Consider this G-expression:

     #~(system* #$(file-append glibc "/sbin/nscd") "-f"
                #$(local-file "/tmp/my-nscd.conf"))

   The effect here is to “intern” ‘/tmp/my-nscd.conf’ by copying it to
the store.  Once expanded, for instance via ‘gexp->derivation’, the
G-expression refers to that copy under ‘/gnu/store’; thus, modifying or
removing the file in ‘/tmp’ does not have any effect on what the
G-expression does.  ‘plain-file’ can be used similarly; it differs in
that the file content is directly passed as a string.

 -- Scheme Procedure: local-file FILE [NAME] [#:recursive? #f]
          [#:select? (const #t)] Return an object representing local
     file FILE to add to the store; this object can be used in a gexp.
     If FILE is a literal string denoting a relative file name, it is
     looked up relative to the source file where it appears; if FILE is
     not a literal string, it is looked up relative to the current
     working directory at run time.  FILE will be added to the store
     under NAME–by default the base name of FILE.

     When RECURSIVE? is true, the contents of FILE are added
     recursively; if FILE designates a flat file and RECURSIVE? is true,
     its contents are added, and its permission bits are kept.

     When RECURSIVE? is true, call ‘(SELECT? FILE STAT)’ for each
     directory entry, where FILE is the entry’s absolute file name and
     STAT is the result of ‘lstat’; exclude entries for which SELECT?
     does not return true.

     This is the declarative counterpart of the ‘interned-file’ monadic
     procedure (*note ‘interned-file’: Устройство склада.).

 -- Scheme Procedure: plain-file NAME CONTENT
     Return an object representing a text file called NAME with the
     given CONTENT (a string or a bytevector) to be added to the store.

     This is the declarative counterpart of ‘text-file’.

 -- Scheme Procedure: computed-file NAME GEXP [#:local-build? #t]
          [#:options '()] Return an object representing the store
     item NAME, a file or directory computed by GEXP.  When LOCAL-BUILD?
     is true (the default), the derivation is built locally.  OPTIONS is
     a list of additional arguments to pass to ‘gexp->derivation’.

     This is the declarative counterpart of ‘gexp->derivation’.

 -- Monadic Procedure: gexp->script NAME EXP [#:guile (default-guile)]
          [#:module-path %load-path]  [#:system
     (%current-system)] [#:target #f] Return an executable script NAME
     that runs EXP using GUILE, with EXP’s imported modules in its
     search path.  Look up EXP’s modules in MODULE-PATH.

     The example below builds a script that simply invokes the ‘ls’
     command:

          (use-modules (guix gexp) (gnu packages base))

          (gexp->script "list-files"
                        #~(execl #$(file-append coreutils "/bin/ls")
                                 "ls"))

     When “running” it through the store (*note ‘run-with-store’:
     Устройство склада.), we obtain a derivation that produces an
     executable file ‘/gnu/store/...-list-files’ along these lines:

          #!/gnu/store/...-guile-2.0.11/bin/guile -ds
          !#
          (execl "/gnu/store/...-coreutils-8.22"/bin/ls" "ls")

 -- Scheme Procedure: program-file NAME EXP [#:guile #f] [#:module-path
          %load-path] Return an object representing the
     executable store item NAME that runs GEXP.  GUILE is the Guile
     package used to execute that script.  Imported modules of GEXP are
     looked up in MODULE-PATH.

     This is the declarative counterpart of ‘gexp->script’.

 -- Monadic Procedure: gexp->file NAME EXP [#:set-load-path? #t]
          [#:module-path %load-path]  [#:splice? #f]  [#:guile
     (default-guile)] Return a derivation that builds a file NAME
     containing EXP.  When SPLICE? is true, EXP is considered to be a
     list of expressions that will be spliced in the resulting file.

     When SET-LOAD-PATH? is true, emit code in the resulting file to set
     ‘%load-path’ and ‘%load-compiled-path’ to honor EXP’s imported
     modules.  Look up EXP’s modules in MODULE-PATH.

     The resulting file holds references to all the dependencies of EXP
     or a subset thereof.

 -- Scheme Procedure: scheme-file NAME EXP [#:splice? #f]
          [#:set-load-path? #t] Возвращает объект, представляющий
     Scheme файл file NAME содержащий EXP.

     This is the declarative counterpart of ‘gexp->file’.

 -- Monadic Procedure: text-file* NAME TEXT ...
     Return as a monadic value a derivation that builds a text file
     containing all of TEXT.  TEXT may list, in addition to strings,
     objects of any type that can be used in a gexp: packages,
     derivations, local file objects, etc.  The resulting store file
     holds references to all these.

     This variant should be preferred over ‘text-file’ anytime the file
     to create will reference items from the store.  This is typically
     the case when building a configuration file that embeds store file
     names, like this:

          (define (profile.sh)
            ;; Return the name of a shell script in the store that
            ;; initializes the 'PATH' environment variable.
            (text-file* "profile.sh"
                        "export PATH=" coreutils "/bin:"
                        grep "/bin:" sed "/bin\n"))

     In this example, the resulting ‘/gnu/store/...-profile.sh’ file
     will reference COREUTILS, GREP, and SED, thereby preventing them
     from being garbage-collected during its lifetime.

 -- Scheme Procedure: mixed-text-file NAME TEXT ...
     Return an object representing store file NAME containing TEXT.
     TEXT is a sequence of strings and file-like objects, as in:

          (mixed-text-file "profile"
                           "export PATH=" coreutils "/bin:" grep "/bin")

     Это декларативный аналог ‘text-file*’.

 -- Scheme Procedure: file-union NAME FILES
     Return a ‘<computed-file>’ that builds a directory containing all
     of FILES.  Each item in FILES must be a two-element list where the
     first element is the file name to use in the new directory, and the
     second element is a gexp denoting the target file.  Here’s an
     example:

          (file-union "etc"
                      `(("hosts" ,(plain-file "hosts"
                                              "127.0.0.1 localhost"))
                        (\"bashrc\" ,(plain-file "bashrc"
                                               "alias ls='ls --color=auto'"))))

     This yields an ‘etc’ directory containing these two files.

 -- Scheme Procedure: directory-union NAME THINGS
     Return a directory that is the union of THINGS, where THINGS is a
     list of file-like objects denoting directories.  For example:

          (directory-union "guile+emacs" (list guile emacs))

     yields a directory that is the union of the ‘guile’ and ‘emacs’
     packages.

 -- Scheme Procedure: file-append OBJ SUFFIX ...
     Return a file-like object that expands to the concatenation of OBJ
     and SUFFIX, where OBJ is a lowerable object and each SUFFIX is a
     string.

     В качестве примера рассмотрим этот gexp:

          (gexp->script "run-uname"
                        #~(system* #$(file-append coreutils
                                                  "/bin/uname")))

     Такого же эффекта можно добиться с помощью:

          (gexp->script "run-uname"
                        #~(system* (string-append #$coreutils
                                                  "/bin/uname")))

     There is one difference though: in the ‘file-append’ case, the
     resulting script contains the absolute file name as a string,
     whereas in the second case, the resulting script contains a
     ‘(string-append ...)’ expression to construct the file name _at run
     time_.

 -- Scheme Syntax: let-system SYSTEM BODY...
 -- Scheme Syntax: let-system (SYSTEM TARGET) BODY...
     Привязать SYSTEM к текущей целевой системе—например,
     ‘\"x86_64-linux\"’—в BODY.

     In the second case, additionally bind TARGET to the current
     cross-compilation target—a GNU triplet such as
     ‘"arm-linux-gnueabihf"’—or ‘#f’ if we are not cross-compiling.

     ‘let-system’ is useful in the occasional case where the object
     spliced into the gexp depends on the target system, as in this
     example:

          #~(system*
             #+(let-system system
                 (cond ((string-prefix? "armhf-" system)
                        (file-append qemu "/bin/qemu-system-arm"))
                       ((string-prefix? "x86_64-" system)
                        (file-append qemu "/bin/qemu-system-x86_64"))
                       (else
                        (error "dunno!"))))
             "-net" "user" #$image)

 -- Scheme Syntax: with-parameters ((PARAMETER VALUE) ...) EXP
     This macro is similar to the ‘parameterize’ form for
     dynamically-bound “parameters” (*note (guile)Parameters::).  The
     key difference is that it takes effect when the file-like object
     returned by EXP is lowered to a derivation or store item.

     A typical use of ‘with-parameters’ is to force the system in effect
     for a given object:

          (with-parameters ((%current-system "i686-linux"))
            coreutils)

     The example above returns an object that corresponds to the i686
     build of Coreutils, regardless of the current value of
     ‘%current-system’.

   Of course, in addition to gexps embedded in “host” code, there are
also modules containing build tools.  To make it clear that they are
meant to be used in the build stratum, these modules are kept in the
‘(guix build ...)’ name space.

   Internally, high-level objects are “lowered”, using their compiler,
to either derivations or store items.  For instance, lowering a package
yields a derivation, and lowering a ‘plain-file’ yields a store item.
This is achieved using the ‘lower-object’ monadic procedure.

 -- Monadic Procedure: lower-object OBJ [SYSTEM] [#:target #f] Return as
          a value in ‘%store-monad’ the derivation or
     store item corresponding to OBJ for SYSTEM, cross-compiling for
     TARGET if TARGET is true.  OBJ must be an object that has an
     associated gexp compiler, such as a ‘<package>’.

   ---------- Footnotes ----------

   (1) The term “stratum” in this context was coined by Manuel Serrano
et al. in the context of their work on Hop.  Oleg Kiselyov, who has
written insightful essays and code on this topic
(http://okmij.org/ftp/meta-programming/#meta-scheme), refers to this
kind of code generation as “staging”.


File: guix.ru.info,  Node: Запуск guix repl,  Prev: G-Expressions,  Up: Программный интерфейс

8.11 Вызов ‘guix repl’
======================

The ‘guix repl’ command makes it easier to program Guix in Guile by
launching a Guile “read-eval-print loop” (REPL) for interactive
programming (*note (guile)Using Guile Interactively::), or by running
Guile scripts (*note (guile)Running Guile Scripts::).  Compared to just
launching the ‘guile’ command, ‘guix repl’ guarantees that all the Guix
modules and all its dependencies are available in the search path.

   Основной синтаксис:

     guix repl OPTIONS [FILE ARGS]

   When a FILE argument is provided, FILE is executed as a Guile
scripts:

     guix repl my-script.scm

   To pass arguments to the script, use ‘--’ to prevent them from being
interpreted as arguments to ‘guix repl’ itself:

     guix repl -- my-script.scm --input=foo.txt

   To make a script executable directly from the shell, using the guix
executable that is on the user’s search path, add the following two
lines at the top of the script:

     #!/usr/bin/env -S guix repl --
     !#

   Without a file name argument, a Guile REPL is started:

     $ guix repl
     scheme@(guile-user)> ,use (gnu packages base)
     scheme@(guile-user)> coreutils
     $1 = #<package coreutils@8.29 gnu/packages/base.scm:327 3e28300>

   In addition, ‘guix repl’ implements a simple machine-readable REPL
protocol for use by ‘(guix inferior)’, a facility to interact with
“inferiors”, separate processes running a potentially different revision
of Guix.

   The available options are as follows:

‘--type=TYPE’
‘-t TYPE’
     Start a REPL of the given TYPE, which can be one of the following:

     ‘guile’
          This is default, and it spawns a standard full-featured Guile
          REPL.
     ‘компьютер’
          Spawn a REPL that uses the machine-readable protocol.  This is
          the protocol that the ‘(guix inferior)’ module speaks.

‘--listen=ENDPOINT’
     By default, ‘guix repl’ reads from standard input and writes to
     standard output.  When this option is passed, it will instead
     listen for connections on ENDPOINT.  Here are examples of valid
     options:

     ‘--listen=tcp:37146’
          Accept connections on localhost on port 37146.

     ‘--listen=unix:/tmp/socket’
          Accept connections on the Unix-domain socket ‘/tmp/socket’.

‘--load-path=DIRECTORY’
‘-L DIRECTORY’
     Add DIRECTORY to the front of the package module search path (*note
     Пакетные модули::).

     This allows users to define their own packages and make them
     visible to the script or REPL.

‘-q’
     Inhibit loading of the ‘~/.guile’ file.  By default, that
     configuration file is loaded when spawning a ‘guile’ REPL.


File: guix.ru.info,  Node: Утилиты,  Next: Конфигурирование системы,  Prev: Программный интерфейс,  Up: Top

9 Утилиты
*********

В этом разделе описаны утилиты командной строки Guix.  Некоторые из них
в первую очередь нацелены на разработчиков и пользователей, которые
пишут новые определения пакетов, в то время как другие полезны в целом.
Они удобно дополняют программный интерфейс Scheme в Guix.

* Menu:

* Запуск guix build::  Сборка пакетов в
                               командной строке.
* Запуск guix edit::   Редактирование описания
                               пакета.
* Запуск guix download::  Загрузка файла и вывод
                                  его хэша.
* Запуск guix hash::   Вычисление
                               криптографического хеша
                               файла.
* Запуск guix import::  Импорт описаниий
                                пакетов.
* Запуск guix refresh::  Обновление описаний
                                 пакетов.
* Запуск guix lint::   Поиск ошибок в описаниях
                               пакетов.
* Запуск guix size::   Обзор использования
                               диска.
* Запуск guix graph::  Визуализация графа
                               пакета.
* Запуск guix publish::  Совместное
                                 использование
                                 подстановок.
* Запуск guix challenge::  Соперничающие серверы
                                   подстановок.
* Запуск guix copy::   Копирование из и в
                               удалённый склад.
* Запуск guix container::  Изоляция процесса.
* Запуск guix weather::  Оценка доступности
                                 подстановок.
* Запуск guix processes::  Чтение клиентских
                                   процессов.


File: guix.ru.info,  Node: Запуск guix build,  Next: Запуск guix edit,  Up: Утилиты

9.1 Запуск ‘guix build’
=======================

Команда ‘guix build’ собирает пакеты или производные и их зависимости и
выводит полученные пути в хранилище (store paths).  Обратите внимание,
что она не изменяет профиль пользователя—это задача команды ‘guix
package’ (*note Вызов guix package::).  Таким образом, это в основном
полезно для разработчиков дистрибутива.

   Основной синтаксис:

     guix build OPTIONS PACKAGE-OR-DERIVATION...

   В качестве примера следующая команда собирает последние версии Emacs
и Guile, отображает их логи и, наконец, отображает полученные
директории:

     guix build emacs guile

   Аналогичным образом следующая команда собирает все доступные пакеты:

     guix build --quiet --keep-going \
       $(guix package -A | cut -f1,2 --output-delimiter=@)

   PACKAGE-OR-DERIVATION может быть именем пакета, найденного в
дистрибутиве программного обеспечения, например ‘coreutils’ или
‘coreutils@8.20’, или производным, например
‘/gnu/store/...-coreutils-8.19.drv’.  В первом случае пакет с
соответствующим именем (и, возможно, версией) ищется среди модулей
дистрибутива GNU (*note Пакетные модули::).

   В качестве альтернативы можно использовать параметр ‘--expression’,
чтобы указать выражение на языке Scheme, оценивающее пакет; это полезно,
когда требуется устранение неоднозначности между несколькими пакетами с
одинаковыми именами или вариантами пакетов.

   Может быть ноль или больше OPTIONS.  Доступные параметры описаны в
подразделах ниже.

* Menu:

* Стандартные параметры сборки::  Параметры
                                                              сборки
                                                              для
                                                              большинства
                                                              команд.
* Параметры преобразования пакета::  Создание
                                                                    вариантов
                                                                    пакетов.
* Дополнительные параметры сборки::  Особые
                                                                    параметры
                                                                    для
                                                                    ’guix
                                                                    build’.
* Отладка ошибок сборки::  Жизненный опыт в
                                                сборке пакетов.

