Руководство по GNU Guix

Table of Contents

Next: , Up: (dir)   [Contents][Index]

GNU Guix

В этом документе описывается GNU Guix версии 887a5fd — менеджер пакетов, написанный для системы GNU.

Это руководство доступно также на (упрощённом) китайском языке (see GNU Guix参考手册), на французском (see Manuel de référence de GNU Guix), немецком (see Referenzhandbuch zu GNU Guix), испанском (see Manual de referencia de GNU Guix) и русском (see Руководство по GNU Guix) языках. Если вы хотите перевести его на свой язык, присоединяйтесь к Проекту переводов Проект переводов.


Next: , Previous: , Up: Top   [Contents][Index]

1 Введение

GNU Guix1 — это утилита для управления пакетами и дистрибутив системы GNU. Guix позволяет непривилегированным пользователям устанавливать, обновлять и удалять программные пакеты, откатываться до предыдущих наборов пакетов, собирать пакеты из исходников и обеспечивает создание и поддержку программного окружения в целом.

Вы можете установить GNU Guix поверх существующей системы GNU/Linux, и она дополнит функции системы новой утилитой, не внося помехи (see Установка). Или можно использовать отдельную операционную систему — Guix System2. See Дистрибутив GNU.


Next: , Up: Введение   [Contents][Index]

1.1 Управление программным обеспечением Guix Way

Guix предоставляет интерфейс командной строки для управления пакетами (see Управление пакетами), инструменты, которые помогают в разработке программного обеспечения (see Разработка), более сложные утилиты командной строки (see Утилиты), а также программный интерфейс Scheme (see Программный интерфейс). Его демон сборки отвечает за сборку пакетов по запросам пользователей (see Настройка демона) и за скачивание компилированных бинарников из авторизованных ресурсов (see Подстановки).

Guix включает определения пакетов для множества проектов GNU и не-GNU, каждый из которых уважает свободу пользователя в работе за компьютером. Он расширяемый: пользователи могут писать свои собственные определения пакетов (see Описание пакетов) и делать их доступными как независимые пакетные модули (see Пакетные модули). Он также настраиваемый: пользователи могут получать специальные определения пакетов из существующих, в том числе через командную строку (see Параметры преобразования пакета).

Под капотом Guix работает как функциональный пакетный менеджер — принцип, впервые введённый Nix (see Благодарности). В Guix процесс сборки и установки пакета рассматривается как функция в математическом смысле. Эта функция принимает входные данные, как например, скрипты сборки, компилятор, её результат зависит только от входных данных, и он не может зависеть от программ или скриптов, которые не подаются на вход явным образом. Функция сборки всегда производит один результат, когда получает один и тот же набор входных данных. Она не может как-либо изменять окружение запущенной системы; например, она не может создавать, изменять или удалять файлы за пределами её директорий сборки и установки. Это достигается так: процесс сборки запускается в изолированном окружении (или контейнере), в котором видны только входные данные, заданные явно.

Результат работы функций сборки пакетов кешируется в файловой системе в специальной директории, называемой склад (see Хранилище).Каждый пакет устанавливается в собственную директорию склада, по умолчанию — под /gnu/store. Имя директории содержит хеш всех входных данных, используемых для сборки этого пакета, так что изменение входных данных порождает различные имена директорий.

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


Previous: , Up: Введение   [Contents][Index]

1.2 Дистрибутив GNU

Guix поставляется с дистрибутивом системы GNU, полностью состоящим из свободного программного обеспечения 3. Дистрибутив можно установить отдельно (see Установка системы), но также можно установить Guix в качестве пакетного менеджера поверх установленной системы GNU/Linux (see Установка). Когда нам нужно провести различие между ними, мы называем самодостаточный дистрибутив Guix System.

Дистрибутив предоставляет основные пакеты GNU, такие как GNU libc, GCC и Binutils, а также многие приложения GNU и не-GNU. Полный список доступных пакетов можно просмотреть по онлайн или запустив guix package (see Вызов guix package):

guix package --list-available

Наша цель — предоставить состоящий на 100% из свободного программного обеспечения рабочий дистрибуив Linux или другие варианты GNU. Мы ориентируемся на продвижении и полноценной интеграции компонентов GNU и поддержке программ и утилит, которые помогают пользователям реализовать их свободы.

Пакеты в данные момент доступны для следующих платформ:

x86_64-linux

архитектура Intel/AMD x86_64 с ядром Linux-Libre.

i686-linux

архитектура Intel 32-bit (IA32) с ядром Linux-Libre.

armhf-linux

Архитектура ARMv7-A с hard float, Thumb-2 и NEON, используя двочиный интерфейс приложений EABI hard-float (ABI), с ядром Linux-Libre.

aarch64-linux

процессоры little-endian 64-bit ARMv8-A с ядром Linux-Libre.

i586-gnu

GNU/Hurd на 32 битной архитектуре Intel (IA32).

Эта конфигурация является экспериментальной и находится в разработке. Самый простой способ попробовать - настроить экземпляр hurd-vm-service-type на вашем GNU/Linux компьютере (see hurd-vm-service-type). See Содействие, о том, как помочь!

mips64el-linux (unsupported)

64-разрядные little-endian процессоры MIPS порядком байтов, в частности серии Loongson, n32 ABI и ядро Linux-Libre. Эта конфигурация больше не поддерживается полностью; в частности, фермы сборки проекта больше не предоставляют замены этой архитектуре.

powerpc-linux (unsupported)

big-endian 32-bit PowerPC processors, specifically the PowerPC G4 with AltiVec support, and Linux-Libre kernel. This configuration is not fully supported and there is no ongoing work to ensure this architecture works.

aarch64-linux

64-битные процессоры Power ISA с прямым порядком байтов, ядро Linux-Libre. Сюда входят системы POWER9, такие какRYF Talos II mainboard. Эта платформа доступна как «предварительная версия»: хотя она и поддерживается, заменители еще не доступны (see Подстановки), а некоторые пакеты могут не собираться (see Отслеживание ошибок и патчей) . Тем не менее, сообщество Guix активно работает над улучшением этой поддержки, и сейчас отличное время, чтобы попробовать и принять участие!

riscv64-linux

little-endian 64-bit RISC-V processors, specifically RV64GC, and Linux-Libre kernel. This playform is available as a "technology preview": although it is supported, substitutes are not yet available from the build farm (see Подстановки), and some packages may fail to build (see Отслеживание ошибок и патчей). That said, the Guix community is actively working on improving this support, and now is a great time to try it and get involved!

Пользуясь системой Guix, вы объявляете все аспекты конфигурации системы, и Guix выполняет установку инстранции ОС транзакционным, повторяемым способом, не имеющей состояния (stateless) (see Конфигурирование системы). Система Guix использует ядро Linux-libre, систему инициализации Shepherd (see Введение in The GNU Shepherd Manual), хорошо известные утилиты и тулчейны GNU, а также графическое окружение на выбор.

Guix System is available on all the above platforms except mips64el-linux, powerpc-linux, powerpc64le-linux and riscv64-linux.

Информация о портировании на другие архитектуры и ядра доступна в see Портирование.

Дистрибутив созаётся совместными усилиями, приглашаем вас! См. See Содействие, чтобы узнать о том, как вы можете помочь.


Next: , Previous: , Up: Top   [Contents][Index]

2 Установка

Примечание: Мы рекомендуем использовать этот скрипт установки для установки Guix на существующую систему GNU/Linux, называемый далее чужой дистрибутив.4 Скрипт автоматизирует скачивание, установку и начальную конфигурацию Guix. Он должен запускаться от пользователя root.

При установке на чужой дистрибутив GNU Guix дополняет доступные утилиты без внесения помех. Его данные живут только в двух директориях — обычно /gnu/store и /var/guix; другие файлы вашей системы, как /etc, остаются нетронутыми.

Установленный Guix можно обновлять командой guix pull (see Запуск guix pull).

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


Next: , Up: Установка   [Contents][Index]

2.1 Бинарная установка

Этот раздел описывает, как установить Guix на обычную систему из отдельного архива, который содержит бинарники Guix и все его зависимости. Это обычно быстрее установки из исходных кодов, которая описана в следующем разделе. Единственное требование - иметь GNU tar и Xz.

Примечание: Мы рекомендуем использовать этот установочный скрипт. Скрипт автоматизирует скачивание, установку и начальные шаги конфигурации, описанные ниже. Он должен запускаться от пользователя root. Как root вы можете запустить это:

cd /tmp
wget https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh
chmod +x guix-install.sh
./guix-install.sh

If you’re running Debian or a derivative such as Ubuntu, you can instead install the package (it might be a version older than 887a5fd but you can update it afterwards by running ‘guix pull’):

sudo apt install guix

Likewise on openSUSE:

sudo zypper install guix

Когда закончите, вам может понадобиться see Установка приложения для дополнительной настройки и Начиная!

Установка производится следующими образом:

  1. Скачайте архив с бинарником из ‘https://ftp.gnu.org/gnu/guix/guix-binary-887a5fd.system.tar.xz’, где system — это x86_64-linux для машины x86_64, на которой уже запущено ядро Linux, и так далее.

    Убедитесь в аутентичности архива, скачав файл .sig и запустив:

    $ wget https://ftp.gnu.org/gnu/guix/guix-binary-887a5fd.x86_64-linux.tar.xz.sig
    $ gpg --verify guix-binary-887a5fd.x86_64-linux.tar.xz.sig
    

    Если это завершается ошибкой, значит у вас нет необходимого публичного ключа, тогда запустите команду для импорта ключа:

    $ wget 'https://sv.gnu.org/people/viewgpg.php?user_id=127547' \
          -qO - | gpg --import -
    

    и запустите команду gpg --verify.

    Обратите внимание, что предупреждение по типу «Этот ключ не сертифицирован с доверенной подписью!» является нормальным.

  2. Теперь вам необходимы привилегии пользователя root. В зависимости от вашего дистрибутива, можно запустить su - или sudo -i. Под root запустите:
    # cd /tmp
    # tar --warning=no-timestamp -xf \
         /path/to/guix-binary-887a5fd.x86_64-linux.tar.xz
    # mv var/guix /var/ && mv gnu /
    

    Это создаёт /gnu/store (see Хранилище) и /var/guix. Последнее содержит готовый к использованию профиль для root (подробнее в следующем шаге).

    Не распаковывайте архив в работающую систему Guix, так как это перезапишет её основные файлы.

    Опция --warning=no-timestamp необходима, чтобы удостовериться, что GNU tar не вызывает ошибок об "устаревшей дате", подобные ошибки появлялись в GNU tar 1.26 и старше, в последних версиях всё в порядке). Они возникают из-за того, что архив имеет нулевую дату модификации (что соответствует 1 января 1970). Это сделано с той целью, чтобы удостовериться, что содержимое архива не засисит от даты его создания, что делает его воспроизводимым (повторяемым).

  3. Сделайте профиль доступным по пути ~root/.config/guix/current, куда guix pull будет устанавливать обновления (see Запуск guix pull):
    # mkdir -p ~root/.config/guix
    # ln -sf /var/guix/profiles/per-user/root/current-guix \
             ~root/.config/guix/current
    

    Добавьте etc/profile в PATH и другие уместные переменные окружения:

    # GUIX_PROFILE="`echo ~root`/.config/guix/current" ; \
      source $GUIX_PROFILE/etc/profile
    
  4. Создайте группу и пользовательские учётные записи, как это обозначено в (see Установка окружения сборки).
  5. Запустите демон и сделайте добавьте его в автоззагрузку после старта.

    Если ваш дистрибутив использует систему инициализации systemd, этого можно добиться следующими командами:

    # cp ~root/.config/guix/current/lib/systemd/system/gnu-store.mount \
         ~root/.config/guix/current/lib/systemd/system/guix-daemon.service \
        /etc/systemd/system/
    # systemctl enable --now gnu-store.mount guix-daemon
    

    You may also want to arrange for guix gc to run periodically:

    # cp ~root/.config/guix/current/lib/systemd/system/guix-gc.service \
         ~root/.config/guix/current/lib/systemd/system/guix-gc.timer \
         /etc/systemd/system/
    # systemctl enable --now guix-gc.timer
    

    You may want to edit guix-gc.service to adjust the command line options to fit your needs (see Вызов guix gc).

    Если ваш дистрибутив использует систему инициализации Upstart:

    # initctl reload-configuration
    # cp ~root/.config/guix/current/lib/upstart/system/guix-daemon.conf \
         /etc/init/
    # start guix-daemon
    

    Или можно запускать демон вручную так:

    # ~root/.config/guix/current/bin/guix-daemon \
           --build-users-group=guixbuild
    
  6. Сделайте команду guix доступной для других пользователей машины, например, так:
    # mkdir -p /usr/local/bin
    # cd /usr/local/bin
    # ln -s /var/guix/profiles/per-user/root/current-guix/bin/guix
    

    Хорошо также предоставить доступ к Info-версии руководства так:

    # mkdir -p /usr/local/share/info
    # cd /usr/local/share/info
    # for i in /var/guix/profiles/per-user/root/current-guix/share/info/* ;
      do ln -s $i ; done
    

    Таким образом, если предположить, что /usr/local/share/info находится в пути поиска, запуск info guix откроет это руководство (см., see Other Info Directories in GNU Texinfo).

  7. To use substitutes from ci.guix.gnu.org, bordeaux.guix.gnu.org or a mirror (see Подстановки), authorize them:
    # guix archive --authorize < \
         ~root/.config/guix/current/share/guix/ci.guix.gnu.org.pub
    # guix archive --authorize < \
         ~root/.config/guix/current/share/guix/bordeaux.guix.gnu.org.pub
    

    Примечание: If you do not enable substitutes, Guix will end up building everything from source on your machine, making each installation and upgrade very expensive. See Касательно проверенных бинарников, for a discussion of reasons why one might want do disable substitutes.

  8. Каждый пользователь, возможно, должен выполнить дополнительные шаги, чтобы сделать их окружение Guix готовым к использованию see Установка приложения.

Вуаля! Установка завершена!

Вы можете проверить, что Guix работает, установив тестовый пакет для профиля root:

# guix install hello

Архив для бинарной установки может быть воспроизведён (повторён) и проверен простым запуском следующей команды в дереве исходников Guix:

make guix-binary.system.tar.xz

..., что в свою очередь, выполнит:

guix pack -s system --localstatedir \
  --profile-name=current-guix guix

See Запуск guix pack для подробной информации об этом полезном инструменте.


Next: , Previous: , Up: Установка   [Contents][Index]

2.2 Требования

Этот раздел содержит требования для сборки Guix из исходников. Пожалуйста, смотрите файлы README и INSTALL в дереве исходников Guix для подробной информации.

GNU Guix доступен для скачивания на сайте https://www.gnu.org/software/guix/.

GNU Guix зависит от следующих пакетов:

Следующие зависимости необязательны:

Если строка --disable-daemon не использовалась в configure, тогда необходимы также следующие пакеты:

Если Guix развёртывается в системе, где уже был установлен Guix, необходимо указать главный каталог предыдущей инсталляции, используя параметр --localstatedir в скрипте configure (see localstatedir in GNU Coding Standards). Скрипт configure защищает от ошибок в конфигурации localstatedir, предотвращая непреднамеренное повреждение хранилища (see Хранилище).


Next: , Previous: , Up: Установка   [Contents][Index]

2.3 Запуск набора тестов

После успешного завершения configure и make хорошо бы выполнить набор тестов. Это поможет выявить проблемы установки или в окружении, как и баги самого Guix (на самом деле, отчёты об ошибках тестов помогают улучшить ПО). Чтобы запустить тесты, напечатайте:

make check

Тесты можно выполнять параллельно при включении опции -j в GNU make, так быстрее. Первый запуск может длиться несколько минут на топовой машине, последующие запуски будут быстрее, так как склад, который создаётся для тестов, уже закеширует различные вещи.

Также можно запустить отдельные наборы тестов, используя переменную TESTS, как в примере:

make check TESTS="tests/store.scm tests/cpio.scm"

По умолчанию результаты тестов выводятся в файл. Чтобы просмотреть результаты каждого отдельного теста, нужно задать переменную makifile SCM_LOG_DRIVER_FLAGS, как в примере:

make check TESTS="tests/base64.scm" SCM_LOG_DRIVER_FLAGS="--brief=no"

Лежащий в основе кастомный SRFI 64 Automake тестовый драйвер, используемый для ’проверки’ набора тестов (расположенный в build-aux/test-driver.scm) также позволяет выбрать, какие тестовые случаи запускать на более высоком уровне, при помощи опций --select и --exclude. Вот пример для запуска всех тестовых случаев из файла tests/packages.scm, чьи имена начинаются с “transaction-upgrade-entry”:

export SCM_LOG_DRIVER_FLAGS="--select=^transaction-upgrade-entry"
make check TESTS="tests/packages.scm"

Желающие проверить результаты неудачных тестов прямо из командной строки могут добавить --errors-only=yes к makefile переменнойSCM_LOG_DRIVER_FLAGS и задать Automake makefile переменную VERBOSE, как в:

make check TESTS="tests/base64.scm" SCM_LOG_DRIVER_FLAGS="--brief=no"

Опция --show-duration=yes может быть использована чтобы отобразить продолжительность отдельных тестовых случаев, когда использована вместе с --brief=no:

make check TESTS="tests/base64.scm" SCM_LOG_DRIVER_FLAGS="--brief=no"

See Parallel Test Harness in GNU Automake для получения дополнительной информации о Automake Parallel Test Harness.

В случае ошибки, пожалуйста, отправьте сообщение на bug-guix@gnu.org и присоедините файл test-suite.log. Пожалуйста, обозначьте в сообщении используемую версию Guix, а также номера версий зависимостей (see Требования).

Guix также идёт с набором тестов для всей системы, который проверяет нстранцию системы Guix. Их можно запустить только в системах, где Guix уже установлен, так:

make check-system

или, опять же, задав TESTS, чтобы выбрать список тестов для запуска:

make check-system TESTS="basic mcron"

Тесты системы определены в модулях (gnu tests …). При работе они запускают операционную систему под легковесным инструментарием в виртуальной машине. Они могут выполнять тяжёлые вычисления или довольно простые в зависимости от наличия подстановок их зависимостей (see Подстановки). Некоторые из них требуют много места для работы с образами виртуальной машины.

Конечно, в случае неудачных тестов, пожалуйста, направьте детали на bug-guix@gnu.org.


Next: , Previous: , Up: Установка   [Contents][Index]

2.4 Настройка демона

Такие операции, как сборка пакета или запуск сборщика мусора, выполняются запуском специальных процесса — демона сборки — по запросам клиентов. Только демон имеет доступ к складу и его базе данных. Так что операции управления складом выполняются с помощью демона. Например, инструменты командной строки, как guix package и guix build, обычно взаимодействуют с демоном через удалённый вызов процедур (RPC) и сообщают, что необходимо сделать.

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


Next: , Up: Настройка демона   [Contents][Index]

2.4.1 Установка окружения сборки

В случае стандартной многопользовательской установки Guix и его демон (программа guix-daemon) установливаются системным администратором; /gnu/store принадлежит root, и guix-daemon запущен от root. Непривилегированные пользователи могут пользоваться инструментами Guix, чтобы собирать пакеты или получить доступ к складу с какой-либо целью, и демон выполнит это по их запросу, убедившись, что склад находится в должном состоянии, и разрешив сборку пакетов и разделение их между пользователями.

Когда guix-daemon запущен от root, возможно, из соображений безопасности вы не примете того, что процессы сборки пакетов тоже выполняются от root. Чтобы избежать этого, необходимо создать специальных пользователей для сборки. Ими будет пользоваться процесс сборки, запускаемый демоном. Эти пользователи сборки не должны иметь оболочки и домашней директории — они просто будут использоваться, когда демон сбрасывает привилегии root в процессе сборки. Наличие нескольких таких пользователей позволит демону запускать отдельные процессы сборки под отдельными UID, что гарантирует, что они не будут помехой друг другу — важная особенность, учитывая, что сборка рассматривается как чистая функция (see Введение).

В системе GNU/Linux набор пользователей для сборки может быть создан так (используя синтаксис команды Bash shadow):

# groupadd --system guixbuild
# for i in `seq -w 1 10`;
  do
    useradd -g guixbuild -G guixbuild           \
            -d /var/empty -s `which nologin`    \
            -c "Guix build user $i" --system    \
            guixbuilder$i;
  done

Число пользователей для сборки определяет, сколько задач сборки может быть запущено параллельно. Это задаётся опцией --max-jobs (see --max-jobs). Чтобы использовать guix system vm и подобные, вам потребуется добавить пользователей для сборки в группу kvm, так чтобы они имели доступ к /dev/kvm, используя -G guixbuild,kvm вместо -G guixbuild (see Вызов guix system).

The guix-daemon program may then be run as root with the following command5:

# guix-daemon --build-users-group=guixbuild

Так демон стартует процессы сборки в chroot под одним из пользователей группы guixbuilder. В GNU/Linux по умолчанию окружение chroot содержит только следующее:

The chroot does not contain a /home directory, and the HOME environment variable is set to the non-existent /homeless-shelter. This helps to highlight inappropriate uses of HOME in the build scripts of packages.

Можно указать директорию, в которую демон сохраняет деревья сборки через переменную окружения TMPDIR. Однако дерево сборки внутри chroot всегда называется /tmp/guix-build-name.drv-0, где name - это имя деривации, то есть, например, coreutils-8.24. Так значение TMPDIR не проникает внутрь окружения сборки, что предотвращает расхождения и случаях, когда процессы сборки имеют иные имена их деревьев сборки.

Демон также уважаем переменную окружения http_proxy, когда выполняет скачивание по HTTP как для дериваций с фиксированным результатом (see Деривации), так и для подстановок (see Подстановки).

Если вы устанавливаете Guix как непривилегированный пользователь, всё ещё возможно запустить guix-daemon с указанием --disable-chroot. Однако процессы сборки не будут изолированы один от другого, а также от остальной системы. Так процессы сборки смогут внести помехи в работу друг друга, смогут получить доступ к программам, библиотекам и другим файлам, доступным в системе, что конечно, делает затруднительным рассмотрение сборки как чистой функции.


Next: , Previous: , Up: Настройка демона   [Contents][Index]

2.4.2 Использование функционала разгрузки

При желании демон сборки может offload производные сборки на других машинах, на которых запущен Guix, используя offload build hook7. Когда данная функция включена, список указанных пользователем машин для сборки считывается из /etc/guix/machines.scm; каждый раз, когда запрашивается сборка, например через guix build, демон пытается выгрузить ее на одну из машин, удовлетворяющих ограничениям производной сборки, в частности, ее системным типам—например, x86_64-linux. На одной машине можеь быть несколько типов систем, либо потому, что архитектура изначально поддерживает ее, либо через эмуляцию (see Transparent Emulation with QEMU). Отсутствующие необходимые условия для сборки копируются по SSH на целевой компьютер, который затем продолжает сборку; в случает успеха выходные данные копируются на исходную машину. Средство разгрузки поставляется с базовым планировщиком, который пытается выбрать лучшую машину. Лучшая машина выбирается среди доступных машин на основании такиз критериев как:

  1. Наличие слота для сборки. Машина для сборки может иметь столько слотов для сборки (соединений), сколько указано в значении parallel-builds определения объекта build-machine.
  2. Ее относительная скорость, указанная через значение speed определения объекта build-machine.
  3. Ее нагрузка. Нормализованная нагрузка на машину должна быть ниже порогового значения, которое можно настроить с помощью поля overload-threshold объекта build-machine.
  4. Доступность дискового пространства. Должно быть доступно более 100 МБ.

Файл /etc/guix/machines.scm обычно выглядит так:

(list (build-machine
           (name "eightysix.example.org")
           (systems (list "x86_64-linux" "i686-linux"))
           (host-key "ssh-ed25519 AAAAC3Nza…")
           (user "bob")
           (speed 2.))     ;incredibly fast!

      (build-machine
        (name "armeight.example.org")
        (systems (list "aarch64-linux"))
        (host-key "ssh-rsa AAAAB3Nza…")
        (user "alice")

        ;; Remember 'guix offload' is spawned by
        ;; 'guix-daemon' as root.
        (private-key "/root/.ssh/identity-for-guix")))

В примере выше мы обозначили список, состоящий из двух машин: одна — для архитектуры x86_64, а другая — для архитектуры mips64el.

По факту, этот файл, что не удивительно, является файлом Scheme, и он имеет значение, когда запускается хук разгрузки. Он возвращает объекты класса build-machine. Приведённый пример показывает фиксированный список машин для сборки, но можно представить, скажем, используя DNS-SD, он может возвращать список потенциальных машин, обнаруженных в локальной сети (see Guile-Avahi in Using Avahi in Guile Scheme Programs). Тип данных build-machine описан ниже.

Тип данных: build-machine

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

name

Имя хоста удалённой машины.

systems

Тип системы удалённой машины, то есть x86_64-linux.

user

Аккаунт пользователя, используемый для соединения с удалённой машиной через SSH. Отметим, что ключ-пара SSH не должна быть защищена парольной фразой, чтобы разрешить не интерактивные авторизации.

host-key

Это публичный ключ хоста в формает OpenSSH. Он используется при аутентификации машины, когда мы подсоединяемс к ней. Это длинная строка, которая выглядит примерно так:

ssh-ed25519 AAAAC3NzaC…mde+UhL hint@example.org

Если на машине запущен демон OpenSSH sshd, ключ хоста может быть найден в файле под директорией /etc/ssh, например, /etc/ssh/ssh_host_ed25519_key.pub.

Если на машине запущен демон SSH GNU lsh, lshd, тогда ключ хоста расположен в /etc/lsh/host-key.pub или подобном файле. Его можно конвертировать в формат OpenSSH, используя lsh-export-key (see Converting keys in LSH Manual):

$ lsh-export-key --openssh < /etc/lsh/host-key.pub
ssh-rsa AAAAB3NzaC1yc2EAAAAEOp8FoQAAAQEAs1eB46LV…

Список необязательных полей:

port (default: 22)

Номер порта сервера SSH на машине.

private-key (default: ~root/.ssh/id_rsa)

Файл приватного ключа в формате OpenSSH, используемого в соединении с машиной. Этот ключ не должен быть защищён парольной фразой.

Отметим, что значение по умолчанию — приватный ключ аккаунта root. Убедитесь, что он существует, если вы используете настройки по умолчанию.

compression (default: "zlib@openssh.com,zlib")
compression-level (default: 3)

Методы компрессии уровня SSH и уровень компрессии.

Отметим, что разгрузка зависит от компрессии SSH, что уменьшает использование траффика при передаче файлов на и с машин для сборки.

daemon-socket (default: "/var/guix/daemon-socket/socket")

Имя файла сокета Unix-домена, который слушает guix-daemon на удалённой машине.

port (default: 22)

Порог нагрузки, выше которого потенциальная offload машина не учитывается offload планировщиком. Это значение примерно соответствует общему использованию процессора машиной сборки в диапазоне от 0,0 (0%) до 1,0 (100%). Это также можно отключить, установив overload-threshold в #f.

parallel-builds (default: 1)

Число сборок, которые могут быть запущены на машине.

speed (default: 1.0)

Показатель скорости. Планировщик разгрузки предпримет попытку выбрать машину с наибольшим показателем скорости.

features (default: '())

Набор строк, описывающий специфические функции, которые поддерживаются на машине. Например, "kvm" для машин, которые имеют модули Linux KVM и соответствующую поддерку аппаратного обеспечения. Деривации могут запрашивать функции по имени, и тогда они будут запранированы на соответствующих машинах для сборки.

Команда guix должна быть в путях для поиска на машинах лоя сборки. Можно проверить это, выполнив:

ssh build-machine guix repl --version

Есть ещё одна вещь, которую нужно выполнить после размещения machines.scm. Выше описано, что при разгрузке файлы передаются вперёд и назад между складами на машинах. Для этого необходимо сгенерировать ключ-пару на кадой машине, чтобы позволить демону экспортировать подписанные архивы файлов из склада (see Вызов guix archive):

# guix archive --generate-key

Каждая машина для сорки должна авторизовать ключ машины-инициатора, чтобы принимать элементы из склада, которые присылает инициатор:

# guix archive --authorize < master-public-key.txt

Точно так же машина-инициатор должна авторизовать ключ каждой машины для сборки.

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

Чтобы проверить работоспособность настроек, запустите следующую команду на инициирующем узле:

# guix offload test

Это выполнит попытку соединиться с каждой из машин для сборки, обозначенных в /etc/guix/machines.scm, проверит наличие модулей Guile и Guix на каждой машине, а также сделает попытку экспортировать и импортировать, а затем выведет отчёт об этом процессе.

Если нужно тестировать другой файл с описанием машин, просто приведите его в командной строке:

# guix offload test machines-qualif.scm

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

# guix offload test machines.scm '\.gnu\.org$'

Чтобы отобразить текущую загрузку всех машин для сборки, запустите команду на инициирущем узле:

# guix offload status

Previous: , Up: Настройка демона   [Contents][Index]

2.4.3 Поддержка SELinux

Guix включает файл политик SELinnux etc/guix-daemon.cil, который может устанавливаться в систему, в которой включен SELinux, тогда файлы Guix будут помечены и настроены для соответствующего поведения демона. Так как система Guix не предоставляет политику SELinux, политика демона не может использоваться в системе Guix.

2.4.3.1 Установка политики SELinux

Чтобы установить политику, запустите следующую команду от root:

semodule -i etc/guix-daemon.cil

Затем измените метку файловой системы с restorecon или другим механизмом, поставляемым вашей системой.

Когда политика установлена, изменена метка файловой системы и демон перезапущен, она должна работать в контексте guix_daemon_t. Можно проверить это следующей командой:

ps -Zax | grep guix-daemon

Наблюдайте файлы логов SELinux во время работы команды guix build hello, чтобы удостовериться, что SELinux позволяет выполнение необходимых операций.

2.4.3.2 Ограничения

Эта политика не совершенна. Тут есть ряд ограничений или причуд, который нужно учитывать при разворачивании политики SELinux для демона Guix.

  1. guix_daemon_socket_t на самом деле не используется. Никакие операции с сокетом не выполняются. Ничего плохого в том, чтобы иметь эту неиспользуемую метку, но желательно определить правила сокета для этой метки.
  2. guix gc не может получить доступ к обычным ссылкам профилей. По задумке метка файла назначения символической ссылки не зависит от метки файла самой ссылки. Хотя все профили под $localstatedir помечены, ссылки на эти профили не наследуют метку директории, в которой они находятся. Для ссылок на домашние директории пользователей это будет user_home_t. Но для ссылок из домашней директории root, а также /tmp или рабочей директории HTTP-сервера и т.п., это не работает. guix gc не будет допускаться к чтению и следованию по этим ссылкам.
  3. Функция демона прослушивать соединения TCP может более не работать. Это может потребовать дополнительных правил, потому что SELinux относится к сетевым сокетам иначе, чем к файлам.
  4. В настоящее время всем файлам с именами, соответствующими регулярному выражению /gnu/store/.+-(guix-.+|profile)/bin/guix-daemon, присвоена метка guix_daemon_exec_t; это означает, что любому файлу с таким именем в любом профиле разрешён запуск в домене guix_daemon_t. Это не идеально. Атакующий может собрать пакет, который содержит исполняемый файл и убеить пользователя установить и запустить его, и таким образом он получит доступ к домену guix_daemon_t. В этой связи SELinux мог бы не давать ему доступ к файлам, которые разрешены для процессов в этом домене.

    Вам нужно будет изменить метку (label) каталога хранилища после всех обновлений до guix-daemon, например, после запуска guix pull. Предполагая, что хранилище в /gnu, вы можете это сделать с restorecon -vR /gnu, или другими способами, предусмотренными вашей операционной системой.

    Мы можем создать политику с большими ограничениями во время установки, так чтобы только точное имя исполняемого файла установленного в данный момент guix-daemon было помечено меткой guix_daemon_exec_t вместо того, чтобы использовать регулярное выражение, выбирающее большой ряд файлов. Проблемой в данном случае будет то, что root потребуется устанавливать или обновлять политику во время любой установки в случае, если обновлён исполняемый файл guix-daemon.


Next: , Previous: , Up: Установка   [Contents][Index]

2.5 Вызов guix-daemon

Программа guix-daemon реализует весь функционал доступа к складу. Это включает запуск процессов сборки, запуск сборщика мусора, проверка доступности результата сборки и т.д. Он должен быть запущен от root так:

# guix-daemon --build-users-group=guixbuild

This daemon can also be started following the systemd “socket activation” protocol (see make-systemd-constructor in The GNU Shepherd Manual).

Для подробностей о том, как настроить его, смотрите see Настройка демона.

По умолчанию guix-daemon запускает процессы сборки под различными UID, от пользователей из группы, обозначенной в --build-users-group. В дополнение каждый процесс сборки запускается в окружении chroot, которое содержит только набор элементов склада, от которых зависит процесс сборки, как это обозначено в деривации (see derivation), а также набор специфичных системных директорий. По умолчанию последнее включает /dev и /dev/pts. Более того, под GNU/Linux окружение сборки — это контейнер: в дополнение к тому, что он имеет собственное дерево файловой системы, он также имеет отдельное пространство имён монтирования, своё собственное пространство имён процессов PID, пространство сетевых имён и т.д. Это позволяет получить воспроизводимые сборки (see Особенности).

Когда демон выполняет сборку по запросу пользователя, он создаёт директорию под /tmp или под директорией, заданной его переменной окружения TMPDIR. Эта директория разделяется с контейнером на время сборки, хотя внутри контейнера дерево сборки всегда называется /tmp/guix-build-name.drv-0.

Директория сборки автоматически удаляется по завершении, если конечно, сборка не завершилась с ошибкой, и клиент не обозначил --keep-failed (see --keep-failed).

Демон слушает соединения и порождает один под-процесс для каждой сессии, запускаемой клиентом (одну из подкоманд guix). Команда guix processes позволяет мониторить активность вашей системы, предоставляя обзор каждой активной сессии и клиентов. Смотрите See Запуск guix processes для подробной информации.

Поддерживаются следующие опции командной строки:

--build-users-group=group

Использовать пользователей из группы group для запуска процессов сборки (see build users).

--no-substitutes

Не использовать подстановки для сборок. Это означает — собирать элементы локально вместо того, чтобы скачивать собранные бинарники (see Подстановки).

Когда демон работает с --no-substitutes, клиенты всё ещё могут явно включить подстановку с помощью удалённого вызова процедур set-build-options (see Хранилище).

--substitute-urls=urls

Использовать адреса urls, разделённые пробелом по умолчанию, как список источников подстановок. Когда эта опция пропущена, используется ‘https://ci.guix.gnu.org https://bordeaux.guix.gnu.org’.

Это означает, что подстановки могут скачиваться из адресов urls, если конечно они подписаны доверенной подписью (see Подстановки).

See Получение заменителей с других серверов, для получения дополнительной информации о том, как настроить демон для получения заменителей с других серверов.

--no-offload

Не использовать подстановки для сборок. Это означает — собирать элементы локально вместо того, чтобы скачивать собранные бинарники (see Подстановки).

--cache-failures

Кешировать ошибки сборки. По умолчанию кешируются только успешные сборки.

При установке этой опции можно использовать guix gc --list-failures, чтобы просматривать элементы склада, помеченные как ошибочные; guix gc --clear-failures удаляет элементы склада из кеша ошибок. See Вызов guix gc.

--cores=n
-c n

Использовать n ядер процессора для сборки каждой деривации; 0 означает использовать все доступные.

Значение по умолчанию - 0, но оно может быть изменено клиентами, в частности, опцией --cores команды guix build (see Запуск guix build).

В результате устанавливается переменная окружения NIX_BUILD_CORES для процесса сборки, который затем может использовать её для применения внутреннего параллелизма, например, для запуска make -j$NIX_BUILD_CORES.

--max-jobs=n
-M n

Разрешить максимум n параллельных задач сборки. Значение по умолчанию - 1. Установка в 0 означает, чтоб сборки не будут выполняться локально, вместо этого, демон будет разгружать сборки (see Установка демона разгрузки) или просто отчитается об ошибке.

--max-silent-time=seconds

Когда процесс сборки или подстановки молчит более seconds секунд, завершить его и отчитаться об ошибке сборки.

Значение по умолчанию - 0, что значит отключить таймаут.

Значение, заданное здесь, может быть переопределено клиентами (see --max-silent-time).

--timeout=seconds

Точно так же, когда процесс сборки или подстановки длится более seconds, завершить его и отчитаться об ошибке сборки.

Значение по умолчанию - 0, что значит отключить таймаут.

Значение, заданное здесь, может быть переопределено клиентами (see --timeout).

--rounds=N

Собирать каждую деривацию n раз подряд и вызывать ошибку, если результаты последовательных сборок не идентичны бит-к-биту. Отметим, что эта настройка может быть переопределена клиентами в команде, например, guix build (see Запуск guix build).

При использовании вместе с --keep-failed различные результаты сохраняются на складе под /gnu/store/…-check. Это делает возможным просмотр различий между двумя результатами.

--debug

Выводить отладочную информацию.

Это полезно для отладки проблем запуска демона, но затем это может быть переопределено клиентами, например, опцией --verbosity команды guix build (see Запуск guix build).

--chroot-directory=dir

Добавить директорию dir в chroot сборки.

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

--disable-chroot

Отключить chroot для сборки.

Использование этой опции не рекомендуется, так как опять же это позволит процессам сборки получить доступ к не объявленным зависимостям. Это важно, даже если guix-daemon запущен под аккаунтом непривилегированного пользователя.

--log-compression=type

Архивировать логи сборки методом type. Это один из: gzip, bzip2 или none.

Unless --lose-logs is used, all the build logs are kept in the localstatedir. To save space, the daemon automatically compresses them with gzip by default.

--discover[=yes|no]

Следует ли обнаруживать сервера с заменителями в локальной сети с помощью mDNS and DNS-SD.

Эта функция все еще экспериментальная. Однако есть несколько соображений.

  1. Это может быть быстрее/дешевле, чем загрузка (fetching) с удаленных серверов;
  2. Никаких угроз безопасности, будут использоваться только подлинные заменители (see Аутентификация подстановок);
  3. Объявление злоумышленника guix publish в вашей локальной сети не могут предоставить вам вредоносные двоичные файлы, но они могут узнать, какое программное обеспечение вы устанавливаете;
  4. Серверы могут предоставить заменители через HTTP в незашифрованном виде, поэтому любой в локальной сети может видеть, какое программное обеспечение вы устанавливаете.

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

herd discover guix-daemon on
herd discover guix-daemon off
--disable-deduplication

Отключить автоматическую "дедупликацию" файлов на складе.

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

--gc-keep-outputs[=yes|no]

Сообщить, должен ли сборщик мусора (GC) сохранять выходные данные живой деривации.

При установке в "yes" (да), сборщик мусора (GC) будет сохранять результаты любой живой деривации, доступной на складе, — файлы .drv. Значение по умолчанию - "no" (нет) - означает, что результаты дериваций хранятся только, если они доступны из корней сборщика мусора (GC roots). Смотрите See Вызов guix gc для информации о корнях сборщика мусора.

--gc-keep-derivations[=yes|no]

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

При указании "yes" (да), что является значением по умолчанию, сборщик мусора сохраняет деривации, то есть файлы .drv, до тех пор, пока любой из их выходов остаётся живым. Это позволяет пользователям отслеживать исходники элементов на складе. Установка в "no" (нет) немного экономит место на диске.

Таким образом, установка --gc-keep-derivations в "yes" (да) даётт возможность пройти от результатов до дериваций, а установка --gc-keep-outputs в "yes" (да), делает возможным пройти от дериваций до результатов. Если оба установлены в "yes", тогда это сохранит всё используемое для сборки (исходники, компилятор, библиотеки и другие инструменты сборки) живых объектов на складе, без учёта, доступны эти инструменты сборки из корней сборщика мусора или нет. Это удобно для разработчиков, так как это сокращает пересборки или скачивания.

--impersonate-linux-2.6

На системах, основанных на Linux, выдавать себя за Linux 2.6. Это означает, что системный вызов ядра uname будет выдавать 2.6 номером релиза.

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

--lose-logs

Не сохранять логи сборки. По умолчанию они сохраняются под localstatedir/guix/log.

--system=system

Считать system текущим типом системы. По умолчанию это пара архитектура/ядро, обнаруженная во время конфигурации, например, x86_64-linux.

--listen=endpoint

Слушать соединения с endpoint. endpoint интерпретируется как имя файла сокета Unix-домена, если начинается с / (знак слеша). В противном случае endpoint интерпретируется как имя хоста или им хоста и порт для прослушивания. Вот несколько примеров:

--listen=/gnu/var/daemon

Слушать соединения с сокетом Unix-домена /gnu/var/daemon, который создаётся при необходимости.

--listen=localhost

Слушать соединения TCP сетевого интерфейса, относящиеся к localhost, на порту 44146.

--listen=128.0.0.42:1234

Слушать соединения TCP сетевого интерфейса, относящиеся к 128.0.0.42, на порту 1234.

Эта опция может повторяться много раз, в таком случае guix-daemon принимает соединения на всех обозначенных точках. Пользователи могут через клиентские команды сообщать, через какие точки соединяться, для этого нужно устанавливать переменную окружения GUIX_DAEMON_SOCKET (see GUIX_DAEMON_SOCKET).

Примечание: Протокол демона неаутентичный и нешифрованный. Использование --listen=host подходит локальным сетям, как например, кластерам, где только доверенные узлы могут соединяться с демоном сборки. В других случаях, когда необходим удалённый доступ к демону рекомендуется использовать сокеты Unix-домена вместе с SSH.

Когда --listen пропущена, guix-daemon слушает соединения с сокетом Unix-домена, расположенным в localstatedir/guix/daemon-socket/socket.


Next: , Previous: , Up: Установка   [Contents][Index]

2.6 Установка приложения

При использовании дистрибутива GNU/Linux, отличного от системы, называемого также чужой дистрибутив, необходимо несколько дополнительных шагов, чтобы всё работало. Вот некоторые из них.

2.6.1 Региональные настройки

Пакеты, установленные с помощью Guix, не будут использовать данные локали хост-системы. Вместо этого вы должны вначале установить один из пакетов локали, доступных в Guix, а затем определить переменную окружения GUIX_LOCPATH:

$ guix install glibc-locales
$ export GUIX_LOCPATH=$HOME/.guix-profile/lib/locale

Note that the glibc-locales package contains data for all the locales supported by the GNU libc and weighs in at around 930 MiB8. If you only need a few locales, you can define your custom locales package via the make-glibc-utf8-locales procedure from the (gnu packages base) module. The following example defines a package containing the various Canadian UTF-8 locales known to the GNU libc, that weighs around 14 MiB:

(use-modules (gnu packages base))

(define my-glibc-locales
  (make-glibc-utf8-locales
   glibc
   #:locales (list "en_CA" "fr_CA" "ik_CA" "iu_CA" "shs_CA")
   #:name "glibc-canadian-utf8-locales"))

Переменная GUIX_LOCPATH играет ту же роль, что и LOCPATH (see LOCPATH in The GNU C Library Reference Manual). Но есть два существенных различия:

  1. GUIX_LOCPATH учитывается только libc в Guix, но не учитывается libc, предоставляемым чужим дистрибутивом. Так что использование GUIX_LOCPATH позволяет вам убедиться, что программы чужого дистрибутива не будут производить загрузку несовместимых данных локали.
  2. libc добавляет суффиксы /X.Y к каждому компоненту GUIX_LOCPATH, где X.Y - это версия libc, например, 2.22. Это значит, что если ваш профиль Guix будет содержать смесь программ, связанных с дугой версией libc, каждая версия libc будет пытаться загружать только данные локали в правильном формате.

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

2.6.2 Служба выбора имён

При использовании Guix на чужом дистрибутиве мы настойчиво рекомендуем, чтобы система запускала демон кеша имён сервисов библиотеки GNU C, nscd, который должен слушать сокет /var/run/nscd/socket. Если это не сделано, приложения, установленные Guix, могут некорректно адресовать имена хостов или аккаунты пользователей и даже падать. Ниже объясняется почему.

Библиотека GNU C реализует выбор имён сервисов (NSS), который представляет собой расширяемый механизм для резолвинга имён в целом: резолвинг имён хостов, аккаунтов пользователей и другое (see Служба выбора имён in The GNU C Library Reference Manual).

Будучи расширяемым, NSS поддерживает плагины, которые предоставляют реализации разрешения новых имён: плагин nss-mdns резолвит имена хостов .local, плагин nis адресует пользовательские аккаунты, используя сервис сетевой информации (NIS) и т.д. Эти дополнительные сервисы адресации настраиваются для всей системы в /etc/nsswitch.conf, и все запущенные в системе программы учитывают эти настройки (see NSS Configuration File in The GNU C Reference Manual).

Когда выполняется разрешение имён, например, вызовом функции C getaddrinfo, приложения вначале делают попытку соединиться с nscd; в случае успеха nscd выполняет разрешение имён по их запросу. Если nscd не запущен, тогда они выполняют разрешение имён самостоятельно, загружая сервисы разрешения имён в их собственные адресные пространства и запуская их. Эти сервисы разрешения имён — файлы libnss_*.so — запускаются dlopen, но они могут поставляться системной библиотекой C, а не библиотекой C, с которой залинковано приложение (библиотека C из Guix).

Вот где кроется проблема — если ваше приложение залинковано с библиотекой C Guix (скажем, glibc 2.24) и пытается загрузить плагины NSS из другой библиотеки C (скажем, libnss_mdns.so для glibc 2.22), это вероятно вызовет падение или резолвинг имени завершится с ошибкой.

Запуск nscd в системе, помимо преимуществ, также исключает эту проблему несовместимости программ, потому что файлы libnss_*.so загружены в процессе nscd, а не в самом приложении.

2.6.3 Шрифты X11

The majority of graphical applications use Fontconfig to locate and load fonts and perform X11-client-side rendering. The fontconfig package in Guix looks for fonts in $HOME/.guix-profile by default. Thus, to allow graphical applications installed with Guix to display fonts, you have to install fonts with Guix as well. Essential font packages include font-ghostscript, font-dejavu, and font-gnu-freefont.

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

guix install fontconfig
fc-cache -rv

Для отображения в графических приложениях текста на китайском, японском, корейском нужно установить font-adobe-source-han-sans или font-wqy-zenhei. Первый имеет множественный выход, один для языковой семьи (see Пакеты со множественным выходом). Например, следующая команда устанавливает шрифты для китайских языков:

guix install font-adobe-source-han-sans:cn

Старые программы, например, xterm, не используют Fontconfig, а вместо этого вызывают рендеринг шрифтов на стороне сервера. Таким программам необходимо указывать полное имя шрифта, используя XLFD (X Logical Font Description), примерно так:

-*-dejavu sans-medium-r-normal-*-*-100-*-*-*-*-*-1

Чтобы иметь возможность использовать такие полные имена для шрифтов TrueType, установленных в вашем профиле Guix, вам нужно расширить пути шрифтов X-сервера:

xset +fp $(dirname $(readlink -f ~/.guix-profile/share/fonts/truetype/fonts.dir))

После этого можно запустить xlsfonts (из пакета xlsfonts), чтобы убедиться, что ваши шрифты TrueType находятся там.

2.6.4 Сертификаты X.509

Пакет nss-certs предоставялет сертификаты X.509, которые позволяют программам аутентифицировать веб-серверы и работать через HTTPS.

При использовании Guix на чужом дистрибутиве можно установить этот пакет и определить соответствующие переменные окружения, чтобы пакеты знали, где искать сертификаты. Смотрите See Сертификаты X.509 для подробной информации.

2.6.5 Пакеты Emacs

Когда вы устанавливаете пакеты Emacs с Guix, файлы пакетов помещаются в каталог share/emacs/site-lisp/ того профиля, в котором они установлены. Библиотеки Elisp доступны для Emacs через переменную среды EMACSLOADPATH, которая устанавливается при установке самого Emacs.

По умолчанию Emacs (установленный Guix) "знает", куда размещаются эти пакеты, так что вам не нужно выполнять конфигурацию. Если по каким-либо причинам вы хотите отменить автозагрузку пакетов Emacs, установленных с помощью Guix, вы можете это сделать, запустив Emacs с опцией --no-site-file (see Init File in The GNU Emacs Manual).


Previous: , Up: Установка   [Contents][Index]

2.7 Обновление Guix

Чтобы обновить Guix, запустите:

guix pull

See Запуск guix pull для дополнительной информации.

В ином дистрибутиве вы можете обновить демон сборки, запустив:

sudo -i guix pull

затем (при условии, что ваш дистрибутив использует инструмент управления сервисами systemd):

systemctl restart guix-daemon.service

В системе Guix обновление демона достигается путем перенастройки системы (see guix system reconfigure).


Next: , Previous: , Up: Top   [Contents][Index]

3 Установка системы

Этот раздел объясняет, как установить систему Guix на компьютер. Guix, как пакетный менеджер, можно также установить на уже установленную систему GNU/Linux (see Установка).


Next: , Up: Установка системы   [Contents][Index]

3.1 Ограничения

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

Тем не менее, перед началом установки, ознакомьтесь с важной информацией об ограничениях версии 887a5fd:

Мы настойчиво призываем вас присылать отчёты о проблемах (или историиуспеха!). Присоединяйтесь к нам, если вы хотите улучшить Guix. Смотрите See Содействие, чтобы узнать больше.


Next: , Previous: , Up: Установка системы   [Contents][Index]

3.2 По поводу железа

GNU Guix особенно заботится об уважении свободы пользователя при работе за компьютером. Она построена на ядре Linux-libre, что означает, что поддерживается только аппаратное обеспечение, которое имеет свободные драйверы и прошивки. Сегодня широкий список наличествующей аппаратуры поддерживается GNU/Linux-libre — от клавиатур и графических карт до сканеров и контроллеров Ethernet. К сожалению, всё ещё остаётся ряд производителей железа, которые запрещают пользователям управлять их устройствами, и такое аппаратное обеспечение не поддерживается системой Guix.

Основной областью, в которой отсутствуют свободные драйверы и прошивки, являются устройства Wi-Fi. Работают устройства Wi-Fi, которые используют платы Atheros (AR9271 и AR7010) и взаимодействуют с драйвером Linux-libre ath9k, также использующие платы Broadcom/AirForce (BCM43xx with Wireless-Core Revision 5), которые работают с драйвером Linux-libre b43-open. Свободная прошивка существует для обоих и доступна в системе Guix из коробки как часть %base-firmware (see firmware).

Фонд свободного программного обспечения FSF ведёт Уважение вашей свободы (RYF) — программу сертификации аппаратного обеспечения, которое уважает вашу свободу и вашу безопасность и утверждает, что вы имеете контроль над вашими устройствами. Мы побуждаем вас проверить список устройств, сертифицированных RYF.

Другой полезный ресурс — сайт H-Node. Он содержит каталог устройств с информацией об их поддержке в GNU/Linux.


Next: , Previous: , Up: Установка системы   [Contents][Index]

3.3 Установочная флеш и DVD

Установочный образ ISO-9660 может быть записан на USB-флеш или DVD, скачать его можно по адресу: ‘https://alpha.gnu.org/gnu/guix/guix-system-install-887a5fd.system.iso’, где system одна из следующих:

x86_64-linux

для системы GNU/Linux на 64-битных Intel/AMD-совместимых процессорах;

i686-linux

для системы GNU/Linux на 32-битных Intel-совместимых процессорах.

Обязательно скачайте связанный файл подписи .sig и проверьте аутентичность образа так:

$ wget https://ftp.gnu.org/gnu/guix/guix-system-install-887a5fd.x86_64-linux.iso.sig
$ gpg --verify guix-system-install-887a5fd.x86_64-linux.iso.sig

Если это завершается ошибкой, значит у вас нет необходимого публичного ключа, тогда запустите команду для импорта ключа:

$ wget https://sv.gnu.org/people/viewgpg.php?user_id=127547 \
      -qO - | gpg --import -

и запустите команду gpg --verify.

Обратите внимание, что предупреждение по типу «Этот ключ не сертифицирован с доверенной подписью!» является нормальным.

Этот образ содержит инструменты, необходимые для установки. Он должен копироваться как есть на большую USB-флеш или DVD.

Запись на USB-флеш

Вставьте в компьютер USB-флеш объёмом 1 Гб или более и определите его имя. Учитывая имя (обычно соответствующее /dev/sdX) скопируйте образ на него:

dd if=guix-system-install-887a5fd.x86_64-linux.iso of=/dev/sdX status=progress
sync

Доступ к /dev/sdX обычно требует привилегий root.

Запись на DVD

Вставьте чистый DVD в компьютер и определите имя устройства. Обычно DVD определяется как /dev/srX, скопируйте образ так:

growisofs -dvd-compat -Z /dev/srX=guix-system-install-887a5fd.x86_64-linux.iso

Доступ к /dev/srX обычно требует привилегий root.

Загрузка

Когда это сделано, вы должны перезагрузить систему и загрузиться с USB-флеш или DVD. Последнее обычно требует доступа к меню BIOS или UEFI, где можно выбрать загрузку с USB-флеш.

Смотрите See Установка Guix на виртуальную машину, если вы хотите установить систему Guix на виртуальную машину (VM).


Next: , Previous: , Up: Установка системы   [Contents][Index]

3.4 Подготовка к установке

Когда вы загрузитесь, вы можете использовать графическую установку, которая намного проще для начала (see Графическая установка в GUI). Или если вы уже знакомы с GNU/Linux или вы хотите больший контроль, чем это предоставляет графическая установка, вы можете выбрать ручной процесс установки (see Ручная установка).

Графическа установка доступна в TTY1. Вы можете запустить оболочку root в TTY 3-6, нажимая ctrl-alt-f3, ctrl-alt-f4 и т.д. TTY2 отображает эту документацию, открыть его можно клавишами ctrl-alt-f2. Листать документацию можно командами просмотрщика Info (see Stand-alone GNU Info). Установка системы запускает демона мыши GPM, который позволяет вам выделять текст лековй кнопкой мыши и вставлять средней кнопкой.

Примечание: Установка требует доступа к Интернету, чтобы скачивать любые отсутствующие зависимости в вашей конфигурации системы. Смотрите раздел "Сеть" ниже.


Next: , Previous: , Up: Установка системы   [Contents][Index]

3.5 Графическая установка в GUI

Графический установщик представляет собой текстовый интерфейс. Он взаимодействует через диалоговые блоки, проходя шаги установки системы GNU Guix.

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

networking setup with the graphical
installer

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

partitioning with the graphical
installer

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

resuming the installation process

Когда настройки выполнены, установщик сгенерирует конфигурацию операционной системы и отобразит её (see Использование системы конфигурации). На этом этапе нажатие “OK” запустит установку. После успешнго завершения нужно перезагрузиться и использовать новую систему. Смотрите See После установки системы, чтобы узнать ещё больше!


Next: , Previous: , Up: Установка системы   [Contents][Index]

3.6 Ручная установка

Этот раздел описывает, как можно вручную установить систему GNU Guix на вашу машину. Это потребует знаний GNU/Linux, оболочки и инструментов администрирования. Если вы считаете, это не для вас, используйте вариант графической установки (see Графическая установка в GUI).

The installation system provides root shells on TTYs 3 to 6; press ctrl-alt-f3, ctrl-alt-f4, and so on to reach them. It includes many common tools needed to install the system, but is also a full-blown Guix System. This means that you can install additional packages, should you need it, using guix package (see Вызов guix package).


Next: , Up: Ручная установка   [Contents][Index]

3.6.1 Раскладка клавиатуры, Сеть, Разметка диска

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

3.6.1.1 Раскладка клавиатуры

Установочный образ использует раскладку клавиатуры US qwerty. Если нужно поменять её, можно пользоваться командой loadkeys. Например, следующая команда выбирает раскладку клавиатуры Dvorak:

loadkeys dvorak

Смотрите файлы в /run/current-system/profile/share/keymaps, чтобы найти список доступных раскладок. Запустите man loadkeys, чтобы узнать больше.

3.6.1.2 Сеть

Запустите следующую команду, чтобы узнать имена сетевых интерфейсов:

ifconfig -a

… или используйте специальную команду GNU/Linux ip:

ip address

Проводные интерфейсы называются на букву ‘e’; например, интерфейс, соответствующий первому контроллеру Ethernet на материнской плате, называется ‘eno1’. Беспроводные интерфейсы имеют имена, начинающиеся с ‘w’, как ‘w1p2s0’.

Проводное соединение

Чтобы настроить проводную сеть, запустите следующую команду, заменив interface именем проводного интерфейса, который вы хотите использовать.

ifconfig interface up

… или используйте специальную команду GNU/Linux ip:

ifconfig interface up
Беспроводное соединение

Чтобы настроить беспроводную сеть, можно создать конфигурционный файл для wpa_supplicant (расположение файла неважно). Можно пользоваться любым доступным текстовым редактором, например, nano:

nano wpa_supplicant.conf

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

network={
  ssid="my-ssid"
  key_mgmt=WPA-PSK
  psk="the network's secret passphrase"
}

Запустите сервис беспроводной сети в фоновом режиме следующей командой (замените interface именем сетевого интерфейса, который вы используете):

wpa_supplicant -c wpa_supplicant.conf -i interface -B

Запустите man wpa_supplicant, чтобы узнать больше.

Теперь нужно получить IP-адрес. В случае сети, где IP-адреса автоматически распределяются с помощью DHCP, можно запустить:

dhclient -v interface

Попробуйте пинговать сервер, чтобы узнать, работает ли сеть:

ping -c 3 gnu.org

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

Если вам нужено настроить доступ HTTP и HTTPS прокси, выполните следующую команду:

herd set-http-proxy guix-daemon URL

где URL адрес прокси, например http://example.org:8118.

Если желаете, вы можете продолжить установку удалённо, запустив SSH-сервер:

herd start ssh-daemon

Не забудьте задать пароль командой passwd или настроить публичный ключ OpenSSH для аутентификации, чтобы иметь возможность подключиться.

3.6.1.3 Разметка диска

Если это ещё не сделано, тогда нужно разделить диск, а затем отформатировать целевой(-ые) раздел(ы).

Установочный образ содержит несколько инструментов для разметки, включая Parted (see Overview in GNU Parted User Manual), fdisk и cfdisk. Запустите и настройте ваш диск, используя план разметки, который нужен:

cfdisk

Если ваш диск использует формат GUID Partition Table (GPT), и вы планируете использовать GRUB, работающий с BIOS (что по умолчанию), убедитесь, что раздел BIOS Boot Partition доступен (see BIOS installation in GNU GRUB manual).

Если вместо этого вы хотите использовать GRUB, работающий с EFI, тогда необходима разметка система EFI FAT32 (ESP). Такая разметка может, например, монтироваться в /boot/efi и должна иметь флаг esp. То есть в случае parted:

parted /dev/sda set 1 esp on

Примечание: Не уверенны, что выбрать: GRUB, взаимодействующий с EFI или BIOS? Если существует директория /sys/firmware/efi в установочом образе, тогда вам следует использовать установку EFI и grub-efi-bootloader. В противном случае нужно использовать GRUB, работающий с BIOS, называемый grub-bootloader. Смотрите See Настройка загрузчика для большей информации о загрузчиках.

Когда разметка целевого диска выполнена, нужно создать файловую систему на соответствующем(-их) разделе(-ах)9. В случае ESP, если у вас раздел /dev/sda1, выполните:

mkfs.fat -F32 /dev/sda1

Для корневой файловой системы наиболее широко используется формат ext4. Другие файловые системы, такие как Btrfs, поддерживают сжатие, которое, как известно, прекрасно дополняет дедупликацию файлов, которую демон выполняет независимо от файловой системы (see deduplication).

Желательно добавить метки файловых систем, чтобы вы могли ссылаться на них по именам в объявлениях file-system (see Файловые системы). Обычно это можно сделать опцией -L в mkfs.ext4, например. Допустим, раздел root располагается в /dev/sda2, можно добавить метку my-root следующим образом:

mkfs.ext4 -L my-root /dev/sda2

If you are instead planning to encrypt the root partition, you can use the Cryptsetup/LUKS utilities to do that (see man cryptsetup for more information).

Внимание: Note that GRUB can unlock LUKS2 devices since version 2.06, but only supports the PBKDF2 key derivation function, which is not the default for cryptsetup luksFormat. You can check which key derivation function is being used by a device by running cryptsetup luksDump device, and looking for the PBKDF field of your keyslots.

Assuming you want to store the root partition on /dev/sda2, the command sequence to format it as a LUKS2 partition would be along these lines:

cryptsetup luksFormat --type luks2 --pbkdf pbkdf2 /dev/sda2
cryptsetup open /dev/sda2 my-partition
mkfs.ext4 -L my-root /dev/mapper/my-partition

Когда это сделано, монтируйте целевую файловую систему под /mnt следующей командой (опять же полагая, что метка раздела root — my-root):

mount LABEL=my-root /mnt

Также монтируйте любые другие файловые системы внутрь целевой файловой системы. Если например, выбрана точка монтирования EFI /boot/efi, монтируйте её в /mnt/boot/efi, так, чтобы она обнаруживалась после запуска guix system init.

Finally, if you plan to use one or more swap partitions (see Swap Space), make sure to initialize them with mkswap. Assuming you have one swap partition on /dev/sda3, you would run:

mkswap /dev/sda3
swapon /dev/sda3

Возможно, вместо этого вы используете swap-файл. Например, предположим, вы хотите использовать в новой системе swap-файл в /swapfile, тогда нужно выполнить10:

# This is 10 GiB of swap space.  Adjust "count" to change the size.
dd if=/dev/zero of=/mnt/swapfile bs=1MiB count=10240
# For security, make the file readable and writable only by root.
chmod 600 /mnt/swapfile
mkswap /mnt/swapfile
swapon /mnt/swapfile

Заметим, что если вы шифруете раздел root и создаёте swap-файл в его файловой системе, как это описано выше, шифрование также будет защищать swap-файл, как и любой другой файл в этой файловой системе.


Previous: , Up: Ручная установка   [Contents][Index]

3.6.2 В продолжении установки

Когда целевые разделы готовы и раздел root монтирован под /mnt, всё готово для старта. Сначала запустите:

herd start cow-store /mnt

Это сделает /gnu/store копируемым при записи (copy-on-write), что заставит систему записывать пакеты, добавляемые в систему на этапе установки, на целевой диск под /mnt, а не держать их в памяти. Это важно, потому что по команде guix system init (смотрите ниже) будут скачиваться или собираться пакеты в /gnu/store, которая изначально находится в файловой системе, загрузженной в память.

Next, you have to edit a file and provide the declaration of the operating system to be installed. To that end, the installation system comes with three text editors. We recommend GNU nano (see GNU nano Manual), which supports syntax highlighting and parentheses matching; other editors include mg (an Emacs clone), and nvi (a clone of the original BSD vi editor). We strongly recommend storing that file on the target root file system, say, as /mnt/etc/config.scm. Failing to do that, you will have lost your configuration file once you have rebooted into the newly-installed system.

Смотрите See Использование системы конфигурации для подробностей о конфигурационном файле. Конфигурационный файл для примера доступен под /etc/configuration установочного образа. Например, чтобы получить систему с графическим сервером (т.е. десктопную систему), можно это сделать примерно так:

# mkdir /mnt/etc
# cp /etc/configuration/desktop.scm /mnt/etc/config.scm
# nano /mnt/etc/config.scm

Нужно уделить внимание содержимому конфигурационного файла, в частности:

Когда вы подготовили конфигурационный файл, нужно инициализировать новую систему (помните, что целевой раздел root монтирован под /mnt):

guix system init /mnt/etc/config.scm /mnt

Это копирует все нужные файлы и устанавливает GRUB в /dev/sdX, если конечно, вы не задали опцию --no-bootloader. Подробнее - see Вызов guix system. Эта команда может вызывать скачивание или сборку отсутствующих пакетов, что может занять время.

Когда эта команда завершена, надеемся, успешно, можно запустить reboot и загрузиться в новую систему. Пароль root в новой системе изначально пустой; пароли других пользователей должны быть заданы командой passwd от root, если конечно, ваша конфиурация не содержит указания (see user account passwords). Смотрите See После установки системы, чтобы узнать, что дальше!


Next: , Previous: , Up: Установка системы   [Contents][Index]

3.7 После установки системы

Замечательно! Теперь вы загрузились в систему Guix! Теперь можно обновить систему, когда у вас будет на это время, запустив, например:

guix pull
sudo guix system reconfigure /etc/config.scm

Это соберёт поколение (generation) системы с последними пакетами и сервисами (see Вызов guix system). Мы рекомендуем делать это регулярно, чтобы ваша система содержала обновления безопасности (see Обновления безопасности).

Примечание: Отметим, что sudo guix запускает команду guix от вашего пользователя, но не от root, потому что sudo не меняет PATH. Чтобы вместо этого запустить guix от root, напечатайте sudo -i guix ….

Разница важна, потому что guix pull обновляет команду guix и определения пакетов только для пользователя, от имени которого она запускается. Это означает, что если вы решите использовать guix system reconfigure от имени root, вам нужно будет запустить guix pull отдельно.

Присоединяйтесь к нашему IRC-каналу #guix в сети Freenode или пишите на guix-devel@gnu.org, чтобы поделиться опытом!


Next: , Previous: , Up: Установка системы   [Contents][Index]

3.8 Установка Guix на виртуальную машину (VM)

Если вы хотите установить систему Guix на виртуальную машину (VM) или на виртуальный приватный сервер (VPS) вместо вашей любимой машины, этот раздел для вас.

Чтобы загрузить Guix в QEMU VM и установить образ, выполните шаги:

  1. Во-первых, найдите и распакуйте установочный образ системы Guix, как описано ранее (see Установочная флеш и DVD).
  2. Создайте образ диска, который будет содержать установленную систему. Чтобы создать образ диска qcow2, используйте команду qemu-img:
    qemu-img create -f qcow2 guixsd.img 50G
    

    Результирующий файл будет намного меньше 50Гб (обычно менее 1Мб), но он будет увеличиваться с заполнение виртуального устройства.

  3. Загрузите установочный образ USB в VM:
    qemu-system-x86_64 -m 1024 -smp 1 -enable-kvm \
      -nic user,model=virtio-net-pci -boot menu=on,order=d \
      -drive file=guix-system.img \
      -drive media=cdrom,file=guix-system-install-887a5fd.system.iso
    

    -enable-kvm опционален, но значительно улучшает производительность, see Запуск Guix на виртуальной машине.

  4. Теперь вы в корне VM, проделайте процесс установки See Подготовка к установке и последующие инструкции.

Когда установка завершена, можно загрузиться в систему, которая расположена в образе guixsd.img. Смотрите See Запуск Guix на виртуальной машине, чтобы узнать, как это сделать.


Previous: , Up: Установка системы   [Contents][Index]

3.9 Сборка установочного образа

Установочный образ, описанный выше, собран командой guix system, а именно:

guix system disk-image -t iso9660 gnu/system/install.scm

Нужно просмотреть gnu/system/install.scm в дереве исходников, а также Вызов guix system, чтобы получить больше информации об установочном образе.

3.10 Сбрка и установка образа для плат ARM

Многие платы ARM требуют специфический вариант загрузчика U-Boot.

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

guix system disk-image --system=armhf-linux -e '((@ (gnu system install) os-with-u-boot) (@ (gnu system install) installation-os) "A20-OLinuXino-Lime2")'

A20-OLinuXino-Lime2 — это имя материнской платы. Если вы обозначите недействительную плату, будет выведен список возможных плат.


Next: , Previous: , Up: Top   [Contents][Index]

4 System Troubleshooting Tips

Guix System allows rebooting into a previous generation should the last one be malfunctioning, which makes it quite robust against being broken irreversibly. This feature depends on GRUB being correctly functioning though, which means that if for whatever reasons your GRUB installation becomes corrupted during a system reconfiguration, you may not be able to easily boot into a previous generation. A technique that can be used in this case is to chroot into your broken system and reconfigure it from there. Such technique is explained below.


Up: System Troubleshooting Tips   [Contents][Index]

4.1 Chrooting into an existing system

This section details how to chroot to an already installed Guix System with the aim of reconfiguring it, for example to fix a broken GRUB installation. The process is similar to how it would be done on other GNU/Linux systems, but there are some Guix System particularities such as the daemon and profiles that make it worthy of explaining here.

  1. Obtain a bootable image of Guix System. It is recommended the latest development snapshot so the kernel and the tools used are at least as as new as those of your installed system; it can be retrieved from the https://ci.guix.gnu.org URL. Follow the see Установочная флеш и DVD section for copying it to a bootable media.
  2. Boot the image, and proceed with the graphical text-based installer until your network is configured. Alternatively, you could configure the network manually by following the manual-installation-networking section. If you get the error ‘RTNETLINK answers: Operation not possible due to RF-kill’, try ‘rfkill list’ followed by ‘rfkill unblock 0’, where ‘0’ is your device identifier (ID).
  3. Switch to a virtual console (tty) if you haven’t already by pressing simultaneously the Control + Alt + F4 keys. Mount your file system at /mnt. Assuming your root partition is /dev/sda2, you would do:
    mount /dev/sda2 /mnt
    
  4. Mount special block devices and Linux-specific directories:
    mount --bind /proc /mnt/proc
    mount --bind /sys /mnt/sys
    mount --bind /dev /mnt/dev
    

    If your system is EFI-based, you must also mount the ESP partition. Assuming it is /dev/sda1, you can do so with:

    mount /dev/sda1 /mnt/boot/efi
    
  5. Enter your system via chroot:
    chroot /mnt /bin/sh
    
  6. Source your user profile to setup the environment, where user is the user name used for the Guix System you are attempting to repair:
    source /home/user/.guix-profile/etc/profile
    

    To ensure you are working with the Guix revision you normally would as your normal user, also source your current Guix profile:

    source /home/user/.config/guix/current/etc/profile
    
  7. Start a minimal guix-daemon in the background:
    guix-daemon --build-users-group=guixbuild --disable-chroot &
    
  8. Edit your Guix System configuration if needed, then reconfigure with:
    guix system reconfigure your-config.scm
    
  9. Finally, you should be good to reboot the system to test your fix.

Next: , Previous: , Up: Top   [Contents][Index]

5 Начиная

Предположительно, вы попали в этот раздел, потому что либо вы установили Guix поверх другого дистрибутива (see Установка), либо вы установили отдельную операционную систему Guix (see Установка системы). Пора вам начать использовать Guix, и этот раздел призван помочь вам в этом.

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

guix search text editor

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

guix install emacs

Вы установили свой первый пакет, поздравляю! В процессе вы, вероятно, заметили, что Guix загружает заранее собранные двоичные файлы; или, если вы явно решили не использовать предварительно созданные двоичные файлы, то, вероятно, Guix все еще собирает программное обеспечение (see Подстановки, для дополнительной информации).

Пока вы используете Guix System, guix install команда должна выводить данную подсказку:

hint: Consider setting the necessary environment variables by running:

     GUIX_PROFILE=\"$HOME/.guix-profile\"
     . \"$GUIX_PROFILE/etc/profile\"

Или смотрите `guix package --search-paths -p "$HOME/.guix-profile"'.

Indeed, you must now tell your shell where emacs and other programs installed with Guix are to be found. Pasting the two lines above will do just that: it will add $HOME/.guix-profile/bin—which is where the installed package is—to the PATH environment variable. You can paste these two lines in your shell so they take effect right away, but more importantly you should add them to ~/.bash_profile (or equivalent file if you do not use Bash) so that environment variables are set next time you spawn a shell. You only need to do this once and other search paths environment variables will be taken care of similarly—e.g., if you eventually install python and Python libraries, GUIX_PYTHONPATH will be defined.

Вы можете продолжать установку пакетов по своему желанию. Чтобы вывести список установленных пакетов, запустите:

guix package --list-installed

Для удаления пакета вы можете выполнить команду guix remove. Отличительная черта - возможность откатить любую операцию, которую вы сделали (установка, удаление, обновление):

guix package --roll-back

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

guix package --list-generations

Теперь вы знаете основы управления пакетами!

Больше информации: See Управление пакетами, для получения дополнительной информации об управлении пакетами. Вам может понравиться декларативное управление пакетами с помощью guix package --manifest, управление отдельными профилями с помощью --profile, удаление старых поколений, сбор мусора и другие полезные функции, которые помогут пригодится по мере того, как вы ближе познакомитесь с Guix. Если вы разработчик, see Разработка для получения дополнительных инструментов. И если вам интересно, see Особенности, чтобы заглянуть под капот.

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

guix pull

Конечным результатом является новая команда guix в ~/.config/guix/current/bin. Если вы не используете Guix System, при первом запуске guix pull обязательно следуйте подсказке, которую выводит команда, и, подобно тому, что мы видели выше, вставьте эти две строки в свой терминал и .bash_profile:

GUIX_PROFILE="$HOME/.config/guix/current/etc/profile"
. "$GUIX_PROFILE/etc/profile"

Вы также должны указать своей оболочке, чтобы она указывала на новую команду guix:

hash guix

На данный момент вы используете новый Guix. Вы можете обновить все ранее установленные пакеты:

guix upgrade

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

Вы можете отобразить точную версию Guix, которую сейчас используете, запустив:

guix describe

Отображаемая информация - это все, что нужно для воспроизведения того же самого Guix, будь то в другой момент времени или на другой машине.

Больше информации: See Запуск guix pull, для дополнительной информации. See Каналы, как указать дополнительные каналы для получения пакетов, как реплицировать Guix и т. д. Также команда time-machine может оказаться полезной (see Вызов guix time-machine).

Если вы установили Guix System, первое, что вам нужно сделать, это обновить вашу систему. После того, как вы запустите команду guix pull, чтобы получить последнюю версию Guix, вы можете обновить систему следующим образом:

sudo guix system reconfigure /etc/config.scm

По завершении в системе будут запущены последние версии пакетов. Когда вы перезагрузите машину, вы заметите подменю в загрузчике “Old system generations”: это то, что позволяет вам загружать старшее поколение вашей системы, если последнее поколение “сломано” или не соответствует вашим ожиданиям. Как и в случае с пакетами, вы всегда можете откатиться на предыдущее поколение всей системы:

sudo guix system roll-back

Есть много вещей, которые вы, вероятно, захотите настроить в своей системе: добавление новых учетных записей пользователей, добавление новых системных служб, изменение конфигурации этих служб и т.д. Конфигурация системы полностью определена в файле /etc/config.scm. See Использование системы конфигурации, узнать о настройке системы.

Теперь вы знаете достаточно, чтобы начать!

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

Мы надеемся, что вам понравится Guix так же, как и сообществу нравится его создавать!


Next: , Previous: , Up: Top   [Contents][Index]

6 Управление пакетами

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

Этот раздел описывает основные особенности Guix и предоставляемые им инструменты управления пакетами. Кроме интерфейса командной строки, который описан ниже (see guix package), можно также использовать интерфейс Emacs-Guix (see The Emacs-Guix Reference Manual), если установить пакет emacs-guix (выполните команду M-x guix-help, чтобы начать работу с ним):

guix install emacs-guix

Next: , Up: Управление пакетами   [Contents][Index]

6.1 Особенности

Здесь мы предполагаем, что вы уже сделали свои первые шаги с Guix (see Начиная) и хотели бы получить обзор того, что происходит под капотом.

При использовании Guix каждый пакет после установки размещается в package store, в собственной директории, например, /gnu/store/xxx-package-1.2, где xxx - это строка base32.

Вместо того, чтобы ссылаться на эти директории, пользователям нужно обращаться к их профилям, профиль указывает на пакеты, которые они хотят использовать. Эти профили хранятся в домашней директории каждого пользователя в $HOME/.guix-profile.

Например, alice устанавливает GCC 4.7.2. В результате /home/alice/.guix-profile/bin/gcc указывает на /gnu/store/…-gcc-4.7.2/bin/gcc. Допустим, на той же машине bob установил GCC 4.8.0. Профиль пользователя bob просто указывает на /gnu/store/…-gcc-4.8.0/bin/gcc. То есть обе версии GCC присутствуют в одной системе без помех.

Команда guix package — главный инструмент для управления пакетами (see Вызов guix package). Она работает с профилями пользователей, которые имеют права обычных пользователей.

Команда предоставляет обязательные операции установки, удаления и обновления. Каждый вызов представляет собой транзакцию, независимо от того, выполнены успешно заданные операции, или ничего не произошло. Так, если процесс guix package завершился во время транзакции, или произошёл сбой питания во время транзакции, тогда профиль пользователя остаётся в исходном состоянии, готовом к использованию.

В дополнение, каждую транзакцию, которая работает с пакетами, можно откатить. Так если, например, обновление устанавливает новую версию пакета, которая имеет серьёзный баг, пользователи могут откатиться до предыдущей инстанции своего профиля, который работал нормально. Точно так же, глобальные настройки системы Guix являются объектом транзакционных обновлений и откатов (see Использование системы конфигурации).

Все пакеты на складе могут быть собраны как мусор. Guix может определить, какие пакеты всё ещё используются профилями пользователей, и удалить те, которые однозначно больше не используются (see Вызов guix gc). Также пользователи могут явно удалить старые поколения (generations) их профилей, поэтому пакеты, на которые ссылались старые профили, могут быть удалены.

Guix реализует чисто функциональный подход к управлению пакетами, как описано во введении (see Введение). В /gnu/store имя директории каждого пакета содержит хеш всех входных данных, которые использовались при сборке пакета: компилятор, библиотеки, скрипты сборки и т.д. Это прямое соответствие позволяет пользователям убедиться, что данная установка пакета соответствует текущему состоянию дистрибутива. Также это помогает улучшить воспроизводимость сборки: благодаря изолированному окружению сборки, которая используется при установке пакета, результат сборки содержит точно такие же файлы на разных машинах (see container).

Эта концепция позволяет Guix поддерживать прозрачное внедрение бинарников/исходников. Когда доступен элемент /gnu/store, собранный заранее на внешнем источнике, то есть готова подстановка, Guix просто скачивает и распаковывает его. В противном случае он собирает пакет из исходников на локальной машине (see Подстановки). Так как результаты сборки обычно воспроизводимы бит-к-биту, пользователи не должны доверять серверам, которые поставляют подстановки — они могут целенаправленно запросить локальную сборку и не пользоваться серверами подстановки (see Запуск guix challenge).

Control over the build environment is a feature that is also useful for developers. The guix shell command allows developers of a package to quickly set up the right development environment for their package, without having to manually install the dependencies of the package into their profile (see Запуск guix shell).

Guix и его определения пакетов подчняются контролю версиями, и guix pull позволяет "путешествовать во времени" по истории Guix (see Запуск guix pull). Это позволяет повторять инстанцию Guix на разных машинах или по прошествию времени, что в свою очередь позволяет вам повторять полностью программное окружение из достпуных трекеров источников программного обеспечения.


Next: , Previous: , Up: Управление пакетами   [Contents][Index]

6.2 Вызов guix package

Команда guix package — инструмент, который позволяет пользователям устанавливать, обновлять и удалять пакеты, а также откатываться до предыдущих конфигураций (see Особенности). Его синтаксис:

guix package options

В первую очередь, options (опции) задают операции, которые нужно выполнить в транзакции. По завершении создаётся новый профиль, а предыдущие поколения (generations) профиля остаются доступными, если пользователь решит откатиться.

Например, чтобы удалить lua и устанвоить guile и guile-cairo в одной транзакции, напечатайте:

guix package -r lua -i guile guile-cairo

Для вашего удобства мы также предоставляем следующие синонимы:

Эти синонимы не такие мощные, как guix package, и предоставляют меньше опций, так что в некоторых случаях вам скорее нужно пользоваться непосредственно guix package.

guix package также поддерживает декларативный подход, с помощью которого пользователь зааёт точный набор пакетов, которые должны быть доступны, и передаёт его в опции --manifest (see --manifest).

Для каждого пользователя автоматически создаётся символическая ссылка на профиль по умолчанию, она располагается в файле $HOME/.guix-profile. Эта ссылка всегда указывает на текущее поколение пользовательского профиля по умолчанию. Так пользователи могут добавить $HOME/.guix-profile/bin в свою переменную окружения PATH и прочее. Если вы не используете систему Guix, предполагается добавление следующих строк в ваш ~/.bash_profile (see Bash Startup Files in The GNU Bash Reference Manual), чтобы порождаемые оболочки получили все необходимые определения переменных окружения:

GUIX_PROFILE="$HOME/.guix-profile" ; \
source "$GUIX_PROFILE/etc/profile"

В случае многопользовательской установки, профили пользователей сохраняются в месте, которое зарегстрировано как garbage-collector root, которое указывет на $HOME/.guix-profile (see Вызов guix gc). Эта директория обычно ссылается на localstatedir/guix/profiles/per-user/user, где localstatedir — значение, переданное скрипту configure опцией --localstatedir, а user — имя пользователя. Директория per-user создаёся, когда запускается guix-daemon, а поддиректория user создаётся guix package.

Опции options могут быть следующими:

--install=package
-i package

Установить заданный пакет.

Каждый package может задавать простое имя пакета, как например, guile, или имя пакета с указанием номера версии, например, guile@1.8.8 или просто guile@1.8 (в последнем случае выбирается самая новая версия с префиксом 1.8).

Если не задан номер версии, тогда будет выбрана самая новая доступная версия. Добавм, что package может содержать двоеточие и одно имя выходных данных пакета, как gcc:doc или binutils@2.22:lib (see Пакеты со множественным выходом). Пакеты с соответствующим именем (и опционально, версией) будут отыскиваться в модулях дистрибутива GNU (see Пакетные модули).

Иногда пакеты имеют распространённые входные данные (propagated inputs) — это зависимости, которые устанавливаются автоматически вместе с требуемыми пакетами (см. see propagated-inputs in package objects для подробной информации о распространяемых входных днных в определениях пакетов).

Примером является библиотека GNU MPC: его файлы заголовков C ссылаются на файлы библиотеки GNU MPFR, которые в свою очередь, ссылаются на библиотеку GMP. Так при установке MPC, также в профиль будут устанволены библиотеки MPFR и GMP; удаление MPC также удалит MPFR и GMP, если конечно, они не были явно установлены пользователем.

Кроме того, пакеты иногда зависят от переменных окружения — от их путей поиска (смотрите разъяснение --search-paths ниже). Любая отсутствующая или, возможно, некорректная переменная окружения вызывает сообщение отчета.

--install-from-expression=exp
-e exp

Устанавить пакет, соответствующий exp.

exp должно быть выражением Scheme, которое определяет объект <package>. Эта опция полезна, чтобы указать однозначно пакет, который имеет схожие варианты имён, например, выражением (@ (gnu packages base) guile-final).

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

--install-from-file=file
-f file

Устанавить пакет, который определён в файле.

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

(use-modules (guix)
             (guix build-system gnu)
             (guix licenses))

(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)
  (synopsis "Hello, GNU world: An example GNU package")
  (description "Guess what GNU Hello prints!")
  (home-page "http://www.gnu.org/software/hello/")
  (license gpl3+))

Developers may find it useful to include such a guix.scm file in the root of their project source tree that can be used to test development snapshots and create reproducible development environments (see Запуск guix shell).

file может также содержать JSON-представление одного или нескольких определений пакетов. Запуск guix package -f на файле hello.json со следующим содержимым, установит пакет greeter после сборки myhello:

(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 (modify-inputs (package-native-inputs gdb)
                   (prepend autoconf-2.64 automake texinfo))))
--remove=package
-r package

Удалить обозначенный пакет.

Касаемо --install, каждый пакет package может задавать номер версии и имя содержимого в добавлении к имени пакета. Например, -r glibc:debug удалит содержимое debug из glibc.

--upgrade[=regexp …]
-u [regexp …]

Обновить все устанволенные пакеты. Если задано одно или более значений regexp, обновление затронет только пакеты, которые соответствуют regexp. Также смотрите опцию --do-not-upgrade ниже.

Отметим, что это обновляет пакеты, которые установлены в системе, до последних версий, имеющихся в дистрибутиве. Чтобы обновить дистрибутив, нужно регулярно запускать guix pull (see Запуск guix pull).

При обновлении автоматически применяются преобразования пакета, которые были первоначально применены при создании профиля (see Параметры преобразования пакета). Например, предположим, что вы сначала установили Emacs из ветки разработки с помощью:

guix install emacs-next --with-branch=emacs-next=master

В следующий раз, когда вы запустите guix upgrade, Guix снова посмотрит на ветку разработки Emacs и соберет новый emacs-next.

Обратите внимание, что параметры преобразования, такие как --with-branch и --with-source, зависят от внешнего состояния; вам решать, чтобы они работали должным образом. Вы также можете отменить преобразования, которые применяются к пакету, запустив:

guix install package
--do-not-upgrade[=regexp …]

При совместном использовании с опцией --upgrade не обновляет ни один пакет, чьё имя соответствует regexp. Например, обновить все пакеты в текущем профиле , кроме тех, которые содержат подстроку "emacs":

$ guix package --upgrade . --do-not-upgrade emacs
--manifest=file
-m file

Создаёт новую версию профиля из объекта манифеста, возвращаемого кодом Scheme в file. Этот параметр можно указывать несколько раз. В результате манифесты будут объединены в один.

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

file должен возвращать объект manifest, который, грубо говоря, является списком пакетов:

(use-package-modules guile emacs)

(packages->manifest
 (list emacs
       guile-2.0
       ;; Use a specific package output.
       (list guile-2.0 "debug")))

See Writing Manifests, for information on how to write a manifest. See --export-manifest, to learn how to obtain a manifest file from an existing profile.

--roll-back

Откатиться до предыдущего поколения профиля, то есть отменить последнюю транзакцию.

При сочетании с опциеями как --install, откат выполняется до всех прочих действий.

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

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

--switch-generation=pattern
-S pattern

Переключиться на определённое поколение, опрделённое pattern.

pattern может быть либо номером поколения или числом с префиксом "+" или "-". Последнее означает сменить вперёд/назад на обозначенное число поколений. Например, если вы хотите вернуться к последнему поколению после --roll-back, используйте --switch-generation=+1.

Разница между --roll-back и --switch-generation=-1 заключается в том, что --switch-generation не создаёт нулевое поколение, так что если заданное поколение не существует, текущее поколение не будет изменено.

--search-paths[=kind]

Вывести отчёт об определениях переменных окружения в синтаксисе Bash. Это может понадобиться для использования набора установленных пакетов. Эти переменные окружения используются некоторыми установленными пакетами для поиска файлов.

For example, GCC needs the CPATH and LIBRARY_PATH environment variables to be defined so it can look for headers and libraries in the user’s profile (see Environment Variables in Using the GNU Compiler Collection (GCC)). If GCC and, say, the C library are installed in the profile, then --search-paths will suggest setting these variables to profile/include and profile/lib, respectively (see Search Paths, for info on search path specifications associated with packages.)

Обычный способ определить эти переменные окружения в оболочке:

$ eval $(guix package --search-paths)

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

Эта опция также может использоваться для вычисления комбинированных путей поиска нескольких профилей. Рассмотрим пример:

$ guix package -p foo -i guile
$ guix package -p bar -i guile-json
$ guix package -p foo -p bar --search-paths

Последняя команда выше составляет отчёт о переменной GUILE_LOAD_PATH, даже если по отдельности ни foo, ни bar не предшествуют рекомендациям.

--profile=profile
-p profile

Использовать profile вместо пользовательского профиля по умолчанию.

profile должен быть именем файла, который будет создан по завершении. Конкретно profile будет простой символической ссылкой (“символическая ссылка”), указывающей на текущий профиль, в котором установлены пакеты:

$ guix install hello -p ~/code/my-profile
…
$ ~/code/my-profile/bin/hello
Hello, world!

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

$ rm ~/code/my-profile ~/code/my-profile-*-link
--list-profiles

Перечислить все профили пользователя:

$ guix package --list-profiles
/home/charlie/.guix-profile
/home/charlie/code/my-profile
/home/charlie/code/devel-profile
/home/charlie/tmp/test

При запуске от имени root будут перечислены все профили всех пользователей.

--allow-collisions

Разрешить соперничающие пакеты в новом профиле. Используйте на свой собственный страх и риск!

По умолчанию guix package делает отчёт о противоречиях collisions в профиле. Противоречия происходят, когда дви или более разных версии или варианта данного пакета присутсвуют в профиле.

--bootstrap

Использовать бутстрап Guile для сборки профиля. Эта опция полезна только разработчикам дистрибутива.

В дополнение к этим действиям guix package поддерживает следующие опции при обращении к текущему состоянию профиля или для проверки доступности пакетов:

--search=regexp
-s regexp

Вывести список пакетов, чьи имена или описания содержат выражение regexp с учётом регистра, упорядоченные по соответствию. Печать всех метаданных соответствующих пакетов в формате recutils (see GNU recutils databases in GNU recutils manual).

Это позволяет извлекать заданые поля, используя команду recsel, например:

$ guix package -s malloc | recsel -p name,version,relevance
name: jemalloc
version: 4.5.0
relevance: 6

name: glibc
version: 2.25
relevance: 1

name: libgc
version: 7.6.0
relevance: 1

Также для отображения имён всех доступных пакетов под лицензией GNU LGPL версии 3:

$ guix package -s "" | recsel -p name -e 'license ~ "LGPL 3"'
name: elfutils

name: gmp
…

Также можно уточнить поиск, используя несколько флагов -s в команде guix package или несколько аргументов в guix search. Например, следующая команда возвращает список настольных игр (используя синоним guix search на этот раз):

$ guix search '\<board\>' game | recsel -p name
name: gnubg
…

При пропуске -s game мы получим пакеты программного обеспечения, которые работают с печатными платами (boards); удалив угловые скобки рядом с board, получим пакеты, которые также работают с клавиатурами (keyboards).

А теперь более запутанный пример. Следующая команда ищет библиотеки криптографии, фильтрует библиотеки Haskel, Perl, Python и Ruby и печатает имена и краткие описания найденных пакетов:

$ guix search crypto library | \
    recsel -e '! (name ~ "^(ghc|perl|python|ruby)")' -p name,synopsis

См. See Selection Expressions in GNU recutils manual для подробной информации о регуларяных выражениях selection expressions для recsel -e.

--show=package

Показать детали пакета package из списка доступных пакетов в формате recutils (see GNU recutils databases in GNU recutils manual).

$ guix package --show=guile | recsel -p name,version
name: guile
version: 3.0.5

name: guile
version: 3.0.2

name: guile
version: 2.2.7
…

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

$ guix show guile@3.0.5 | recsel -p name,version
name: guile
version: 3.0.5
--list-installed[=regexp]
-I [regexp]

Вывести текущий список установленных пакетов в заданном профиле, отобразив самый последний установленный пакет последним. Если задано regexp, будут выведены только пакеты, чьи имена содержат regexp.

Для каждого установленного пакета выводит следующие элементы, разделенные табуляцией (tab): имя пакета, строка версии, частью какого пакета является установленный пакет (например, out вывода по умолчанию включает include его заголовки т.д.), а также путь этого пакета на складе.

--list-available[=regexp]
-A [regexp]

Вывести список пакетов, доступных на текущий момент в дистрибутиве данной системы (see Дистрибутив GNU). Если задано regexp, выводит только установленные пакеты, чьё имя содержит regexp.

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

--list-generations[=pattern]
-l [pattern]

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

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

Если используется pattern, команда выводит только соответствующие поколения. Правильные паттерны содержат:

--delete-generations[=pattern]
-d [pattern]

Если pattern пропущен, удалит все поголения, кроме текущего.

Эта команда принимает такие же паттерны, как --list-generations. Если pattern задан, удалит соответствующие поколения. Если паттерн pattern задаёт срок, выбираются поколения старше срока. Например, --delete-generations=1m удалит поколения, которые старше одного месяца.

Если текущее поколение попадает под условия паттерна, оно не будет удалено. А также нулевое поокление никогда не удаляется.

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

--export-manifest

Напишите в стандартный вывод манифест, подходящий для --manifest, соответствующий выбранному профилю (-ам).

Эта опция предназначена для того, чтобы помочь вам перейти из “императивного” режима работы—запустив guix install, guix upgrade и т.д.—в декларативный режим, который предлагает --manifest.

Имейте в виду, что полученный манифест приблизительно соответствует тому, что на самом деле содержится в вашем профиле; например, в зависимости от того, как был создан ваш профиль, он может относиться к пакетам или версиям пакетов, которые не совсем то, что вы указали.

Имейте в виду, что манифест является чисто символическим: он содержит только имена пакетов и, возможно, версии, и их значение со временем меняется. Если вы хотите “привязать” каналы к ревизиям, которые использовались для создания профиля (ов), см. --export-channels ниже.

%default-channels

Вывести на стандартный вывод список каналов, используемых выбранным профилем (-ями), в формате, подходящем для guix pull --channels или guix time-machine --channels (see Каналы).

Вместе с --export-manifest этот параметр предоставляет информацию, позволяющую копировать текущий профиль (see Копирование Guix).

Однако обратите внимание, что выходные данные этой команды приблизительно используются для создания этого профиля. В частности, один профиль мог быть построен из нескольких различных версий одного и того же канала. В этом случае --export-manifest выбирает последнюю версию и записывает список других ревизий в комментарий. Если вам действительно нужно выбрать пакеты из разных ревизий канала, вы можете использовать подчиненные элементы в своем манифесте для этого (see Младшие версии).

Если вы хотите перейти от “императивной” модели к полностью декларативной модели, состоящей из файла манифеста и файла каналов, закрепляющего точную желаемые версии каналов, то --export-manifest хорошая отправная точка.

Наконец, так как guix package может запускать процессы сборки, она поддерживает все привычные опции сборки (see Стандартные параметры сборки). Она также поддерживает опции трансформации пакетов, как --with-source (see Параметры преобразования пакета). Однако, отметим, что трансформации пакетов теряются после обновлений; чтобы сохранить трансформации при обновлениях, нужно определить собственный вариант пакета в модуле Guile и добавить его в GUIX_PACKAGE_PATH (see Описание пакетов).


Next: , Previous: , Up: Управление пакетами   [Contents][Index]

6.3 Подстановки

Guix поддерживает прозрачную развёртку исходников/бинарников, это означает возможность сборки пакетов локально или скачивания собранных элементов с сервера, или и то и другое. Мы называем собранные элементы подстановками (substitutes) — это подстановки результатов локальных сборок. Часто скасивание подстановки намного быстрее, чем сборка пакетов локально.

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


Next: , Up: Подстановки   [Contents][Index]

6.3.1 Official Substitute Servers

ci.guix.gnu.org and bordeaux.guix.gnu.org are both front-ends to official build farms that build packages from Guix continuously for some architectures, and make them available as substitutes. These are the default source of substitutes; which can be overridden by passing the --substitute-urls option either to guix-daemon (see guix-daemon --substitute-urls) or to client tools such as guix package (see client --substitute-urls option).

URL подстановок могут быть либо HTTP, либо HTTPS. Рекомендуется HTTPS, так как такая связь шифруется; и наоборот, использование HTTP делает связь видимой для подслушивающих, и они могут использовать собранную информацию, чтобы определить, например, что ваша система не имеет патчей, покрывающих уязвимости безопасности.

Substitutes from the official build farms are enabled by default when using Guix System (see Дистрибутив GNU). However, they are disabled by default when using Guix on a foreign distribution, unless you have explicitly enabled them via one of the recommended installation steps (see Установка). The following paragraphs describe how to enable or disable substitutes for the official build farm; the same procedure can also be used to enable substitutes for any other substitute server.


Next: , Previous: , Up: Подстановки   [Contents][Index]

6.3.2 Авторизация сервера подстановок

To allow Guix to download substitutes from ci.guix.gnu.org, bordeaux.guix.gnu.org or a mirror, you must add the relevant public key to the access control list (ACL) of archive imports, using the guix archive command (see Вызов guix archive). Doing so implies that you trust the substitute server to not be compromised and to serve genuine substitutes.

Примечание: If you are using Guix System, you can skip this section: Guix System authorizes substitutes from ci.guix.gnu.org and bordeaux.guix.gnu.org by default.

The public keys for each of the project maintained substitute servers are installed along with Guix, in prefix/share/guix/, where prefix is the installation prefix of Guix. If you installed Guix from source, make sure you checked the GPG signature of guix-887a5fd.tar.gz, which contains this public key file. Then, you can run something like this:

# guix archive --authorize < prefix/share/guix/ci.guix.gnu.org.pub
# guix archive --authorize < prefix/share/guix/bordeaux.guix.gnu.org.pub

Когда это сделано, вывод команды guix build должен измениться с примерно такого:

$ guix build emacs --dry-run
The following derivations would be built:
   /gnu/store/yr7bnx8xwcayd6j95r2clmkdl1qh688w-emacs-24.3.drv
   /gnu/store/x8qsh1hlhgjx6cwsjyvybnfv2i37z23w-dbus-1.6.4.tar.gz.drv
   /gnu/store/1ixwp12fl950d15h2cj11c73733jay0z-alsa-lib-1.0.27.1.tar.bz2.drv
   /gnu/store/nlma1pw0p603fpfiqy7kn4zm105r5dmw-util-linux-2.21.drv
…

на примерно следующий:

$ guix build emacs --dry-run
112.3 MB would be downloaded:
   /gnu/store/pk3n22lbq6ydamyymqkkz7i69wiwjiwi-emacs-24.3
   /gnu/store/2ygn4ncnhrpr61rssa6z0d9x22si0va3-libjpeg-8d
   /gnu/store/71yz6lgx4dazma9dwn2mcjxaah9w77jq-cairo-1.12.16
   /gnu/store/7zdhgp0n1518lvfn8mb96sxqfmvqrl7v-libxrender-0.9.7
…

The text changed from “The following derivations would be built” to “112.3 MB would be downloaded”. This indicates that substitutes from the configured substitute servers are usable and will be downloaded, when possible, for future builds.

Механизм подстановок может быть отключен глобально путём запуска guix-daemon с --no-substitutes (see Вызов guix-daemon). Также он может отключиться временно путём указания опции --no-substitutes в guix package, guix build и других инструментах командной строки.


Next: , Previous: , Up: Подстановки   [Contents][Index]

6.3.3 Получение заменителей с других серверов

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

Вы можете дать Guix список URL-адресов серверов с заменителями, и он проверит их в указанном порядке. Вам также необходимо явно авторизовать открытые ключи серверов с заменителями, чтобы Guix принял заменители, которые они подписывают.

В системе Guix это достигается путем изменения конфигурации службы guix. Поскольку служба guix является частью списков служб по умолчанию, %base-services и %desktop-services, вы можете использовать modify-services для изменения ее конфигурации и добавьте нужные URL-адреса и заменить ключи (see modify-services).

В качестве примера предположим, что вы хотите получить заменители из guix.example.org и авторизовать ключ этого сервера в дополнение к ci.guix.gnu.org и bordeaux.guix.gnu.org. Полученная конфигурация операционной системы будет выглядеть примерно так:

(operating-system
  ;; …
  (services
    ;; Assume we're starting from '%desktop-services'.  Replace it
    ;; with the list of services you're actually using.
    (modify-services %desktop-services
      (guix-service-type config =>
                        (guix-configuration
                          (inherit config)
                          (substitute-urls
                            (append (list "https://guix.example.org")
                                    %default-substitute-urls))
                          (authorized-keys
                            (append (list (local-file "./key.pub"))
                                    %default-authorized-guix-keys)))))))

Предполагается, что файл key.pub содержит ключ подписи guix.example.org. После внесения этого изменения в файл конфигурации вашей операционной системы (например, /etc/config.scm) вы можете перенастроить и перезапустить службу guix-daemon или перезагрузиться, чтобы изменения вступили в силу:

$ sudo guix system reconfigure /etc/config.scm
$ sudo herd restart guix-daemon

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

  1. Отредактируйте файл конфигурации службы для guix-daemon; когда исользуете systemd, это обычно /etc/systemd/system/guix-daemon.service. Добавьте параметр --substitute-urls команды guix-daemon при вызове в командной строке и перечислите интересующие URL-адреса (see guix-daemon --substitute-urls):
    … --substitute-urls='https://guix.example.org https://ci.guix.gnu.org https://bordeaux.guix.gnu.org'
    
  2. Перезапустите демон. Пример для systemd:
    systemctl daemon-reload
    systemctl restart guix-daemon.service
    
  3. Авторизуйте ключ нового сервера (see Вызов guix archive):
    # guix archive --authorize < master-public-key.txt
    

    Опять же, это предполагает key.pub, содержащий открытый ключ, который guix.example.org использует для подписи замененителей.

Now you’re all set! Substitutes will be preferably taken from https://guix.example.org, using ci.guix.gnu.org then bordeaux.guix.gnu.org as fallback options. Of course you can list as many substitute servers as you like, with the caveat that substitute lookup can be slowed down if too many servers need to be contacted.

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


Next: , Previous: , Up: Подстановки   [Contents][Index]

6.3.4 Аутентификация подстановок

Guix определяет и вызывает ошибку, если происходит попытка использовать поддельную подстановку. А также он игнорирует подстановки, которые не подписаны, или те, которые не подписаны ни одним ключом из списка ACL.

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

--substitute-urls="https://a.example.org https://b.example.org"

Если ACL содержит только ключ для b.example.org, и если вдруг a.example.org предоставляет идентичные подстановки, тогда Guix будет скачивать подстановки из a.example.org, потому что он идёт первым в списке и может рассматриваться как зеркало b.example.org. На практике независимые машины сборки обычно производят одинаковые бинарники благодаря воспроизводимым сборкам (смотрите ниже).

При использовании HTTPS, сертификат X.509 сервера не проверяется (другими словами, сервер не проходит аутентификацию), супротив тому, что HTTPS-клиенты, как веб-браузеры, обычно делают это. Это потому, что Guix аутентифицирует саму информацию подстановки, как это описано выше, что собственно и представляет для нас интерес (в то время, как сертификаты X.509 относятся к аутентификации связок между доменными именами и публичными ключами).


Next: , Previous: , Up: Подстановки   [Contents][Index]

6.3.5 Настройки proxy

Подстановки скачиваются через HTTP или HTTPS. Можно установить переменную окружения http_proxy в окружении guix-daemon, чтобы она учитывалась при скачивании. Отметим, что значение http_proxy в окружении, в котором запускаются guix build, guix package и другие клиентские команды совершенно не даёт эффекта.


Next: , Previous: , Up: Подстановки   [Contents][Index]

6.3.6 Ошибки при подстановке

Даже когда подстановка для деривации доступна, иногда попытка подстановки завершается неудачно. Это может происходить по разным причинам: сервер подстановок может быть отключен, подстановка могла быть недавно удалена, связь может прерываться и т.д.

Когда подстановки включены, и подстановка для деривации доступна, но попытка подстановки завершается с ошибкой, Guix будет пытаться собрать деривацию локально в зависимости от того, задана или нет опция --fallback (see common build option --fallback). То есть, если --fallback пропущена, тогда локальная сборка не будет выполняться, а деривация будет рассматриваться как неудачная. Однако, если --fallback задана, тогда Guix попытается собрать деривацию локально, и успех или неудача деривации будет зависеть от успешной или неудачной процедуры локальной сборки. Отметим, что когда подстановки отключены или нет доступных подстановок для деривации, локальная сборка всегда будет исполняться, вне зависимости от установки опции --fallback.

Чтобы узнать,. сколько подстановок доступны в данный момент, можно попробовать запустить команду guix weather (see Запуск guix weather). Эта команда предоставляет статистику подстановок, предоставляемых сервером.


Previous: , Up: Подстановки   [Contents][Index]

6.3.7 Касательно проверенных бинарников

Today, each individual’s control over their own computing is at the mercy of institutions, corporations, and groups with enough power and determination to subvert the computing infrastructure and exploit its weaknesses. While using substitutes can be convenient, we encourage users to also build on their own, or even run their own build farm, such that the project run substitute servers are less of an interesting target. One way to help is by publishing the software you build using guix publish so that others have one more choice of server to download substitutes from (see Запуск guix publish).

Guix определяет цель максимизировать воспроизводимость сборок (see Особенности). В большинстве случаев независимые сборки заданного пакета или деривации должны давать результаты, идентичные до бита. То есть, благодаря ряду независимых сборок пакета мы можем улучшить чистоту наших систем. Команда guix challenge должна помочь пользователям оценить серверы подстановок, а разработчикам - помочь выявить недетерминистические сборки пакетов (see Запуск guix challenge). Подобным образом опция --check команды guix build даёт возможность пользователям проверить, яляются ли установленные ранее подстановки подлинными, выполнив их локальную сборку (see guix build --check).

Мы хотим, чтобы Guix в будущем поддерживал публикации и запросы бинарников от/для пользователей в формате равноправного обмена (peer-to-peer). Если вы желаете обсудить этот проект, присоединяйтесь к нам guix-devel@gnu.org.


Next: , Previous: , Up: Управление пакетами   [Contents][Index]

6.4 Пакеты со множественным выходом

Часто пакеты, определённые в Guix, имеют один выход, это значит, что исходный пакет даёт только одну директорию на складе. При запуске guix package -i glibc это устанавливает результат по умолчанию; результат по умолчанию называется выходом, но его имя может пропускаться, как показано в этой команде. В этом частном случае результат по умолчанию для glibc содержит все файлы заголовков C, разделяемые библиотеки, статические библиотеки, документацию Info и другие поставляемые файлы.

Часто более приемлемым будет разделить различные типы файлов, поставляемых одним исходным пакетом, на отдельные выходы (результаты). Например, библиотека GLib C, используемая GTK+ и связанными с ним пакетами, устанавливает более 20Мб связанной документации в виде страниц HTML. Чтобы экономить место, пользователи, которым это не нужно, документацию можно выделить в отдельный выход, называемый doc. Чтобы установить основной выход GLib, который содерит всё, кроме документации, можно запустить:

guix install glib

Команда для установки её документации:

guix install glib:doc

Некоторые пакеты устанавливают программы с различными “отпечатками зависимостей”. Например, пакет WordNet устанавливает и инструменты командной строки, и графический интерфейс (GUI). Первое зависит только от библиотеки C, а последнее зависит от Tcl/Tk и библиотек X. В таком случае мы оставляем инструменты командной строки в качестве результата по умолчанию, в то время как GUI поставляется как отдельный выход. Это экономит место для пользователей, которым не нужен GUI. Команда guix size может помочь выявить такие ситуации (see Запуск guix size). guix graph также полезна (see Запуск guix graph).

Есть несколько таких пакетов со множественным выходом в дистрибутиве GNU. Другие традиционные имена выходов включают lib - для библиотек и иногда файлов заголовков, bin - для самих программ, debug - для отладочной информации (see Установка файлов отладки). Выходы пакетов представлены в третьей колонке вывода guix package --list-available (see Вызов guix package).


Next: , Previous: , Up: Управление пакетами   [Contents][Index]

6.5 Вызов guix gc

Пакеты, которые установлены, но не используются, могут быть очищены как мусор (garbage-collected). Команда guix gc позволяет пользователям непосредственно запустить сборщик мусора и восстановить место в директории /gnu/store. Это единственный способ удалить файлы из /gnu/store — удаление файлов вручную может поломать её безвозвратно!

Сборщик мусора имеет набор известных корней (roots): любой файл в /gnu/store, доступный из корня, рассматривается как живой (live) и не может быть удалён; любой другой файл рассматривается как мёртвый (dead) и может быть удалён. Набор корней сборщика мусора (сокращённо "GC roots") содержит профили пользователей по умолчанию; по умолчанию символические ссылки в /var/guix/gcroots представляют эти корни сборщика мусора. Новые корни могут добавляться, например, командой guix build --root (see Запуск guix build). Команда guix gc --list-roots отображает их.

Перед запуском guix gc --collect-garbage для освобождения места часто бывает полезно удалить старые поколения из пользовательских профилей; так старые пакеты, относящиеся к этим поколениям, будут удалены. Это можно сделать, запустив guix package --delete-generations (see Вызов guix package).

Мы рекомендуем запускать сборщик мусора периодически, или когда вы хотите освободить место на диске. Например, чтобы гарантировать, что по меньшей мере 5 Гб будет доступно на вашем диске, просто запустите:

guix gc -F 5G

Хорошо бы запускать это как неинтерактивную периодическую задачу (see Запланированное исполнения задач, чтобы узнать, как добавить такую задачу). Запуск guix gc без аргументов соберёт столько мусора, сколько возможно, но это часто не удобно: можно обнаружить, что придётся заново собирать или скачивать программы, "убитые" сборщиком мусора, хотя они необходимы для сборки другого софта, например, это касается инструментов компилятора.

Команда guix gc предоставляет три способа взаимодействия: может использоваться для сборки мусора (garbage-collect) любых мёртвых файлов (по умолчанию), для удаления конкретных файлов (опция --delete), для вывода информации сборщика мусора, а также для более изощрённых запросов. Опции сборщика мусора:

--collect-garbage[=min]
-C [min]

Собрать мусор, то есть недоступные файлы в /gnu/store и поддиректориях. Это операция по умолчанию, если не заданы опции.

Если задана min, остановиться, когда min байт собрано. min может быть числом байт или может содержать единицу измерения в суффиксе, как например, MiB для мебибайт и GB гигабайт (see size specifications in GNU Coreutils).

Если min пропущено, собрать весь мусор.

--free-space=free
-F free

Собирать мусор, пока не станет доступно free места в /gnu/store, если возможно; free описывает дисковое пространство, как 500MiB, как это описанов выше.

Когда free или более места стало свободно в /gnu/store, ничего не делать и немедленно выйти.

--delete-generations[=duration]
-d [duration]

Before starting the garbage collection process, delete all the generations older than duration, for all the user profiles and home environment generations; when run as root, this applies to all the profiles of all the users.

Например, следующая команда удаляет все поколения всех ваших профилей, которые старше 2 месцев (кроме текущего поколения), а затем запускается процесс освобождения мместа, пока по меньшей мере 10 GiB не станет доступно:

guix gc -d 2m -F 10G
--delete
-D

Попытаться удалить все файлы и директории склада, приведённые в аргументах. Это завершается с ошибкой, если какие-либо файлы не присутствуют на складе, или если они ещё живы (live).

--list-failures

Вывести список элементов склада, которые относятся к кешированным неудачным сборкам.

Это ничего не выводит, если демон не был запущен с опцией --cache-failures (see --cache-failures).

--list-roots

Вывести список корней сборщика мусора (GC roots), которыми владеет пользователь; при запуске от root, выводит список всех корней сборщика мусора.

--list-busy

Составляет список элементов хранилица, исользуемых запущенными в данное время процессами. Эти элементы считаются корнями GC: они не могут быть удалены.

--clear-failures

Удалить заданные элементы склада из кеша неудачных сборок.

Опять же эта опция имеет смысл, если демон запущен с --cache-failures. В противном случае это не имеет эффекта.

--list-dead

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

--list-live

Вывести список живых файлов и директорий склада.

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

--references
--referrers

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

--requisites
-R

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

См. See Запуск guix size для информации об инструменте профилирования конвейера для элемента. См. See Запуск guix graph для информации об инструменте визуализации графа связей.

--derivers

Вернуть деривацию(-ии), производящие данные элементы склада (see Деривации).

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

guix gc --derivers `guix package -I ^emacs$ | cut -f4`

возвращает файл(ы) .drv, которые произвели пакет emacs, установленный в вашем профиле.

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

Наконец, следующие опции позволяют проверить целостность склада и контролировать использование диска.

--verify[=options]

Проверить целостность склада.

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

Опции options, если они указаны, должны представлять собой список, разделённый запятыми, содержащий одно или более значений contents и repair.

Если задано --verify=contents, демон вычисляет хеш содержимого каждого элемента склада и сравнивает с его хешем в базе данных. Несовпадения хеша отображаются в отчёте как повреждение данных. Так как она проходит все файлы склада, эта команда может занять много времени, особенно в системах с медленным диском.

Использование --verify=repair или --verify=contents,repair указывает демону предпринять попытку восстановить разрушенные элементы склада, выбирая подстановки для них (see Подстановки). Так как восстановление не атомарное, и поэтому потенциально опасно, оно доступно только системному администратору. Малозатратная альтернатива в случае, если вы знаете точно, какие элементы склада испорчены, — это guix build --repair (see Запуск guix build).

--optimize

Оптимизировать склад с помощью жёстких ссылок на идентичные файлы — это дедупликация.

Демон выполняет дедупликацию после каждой успешной сборки или импорта архива, если конечно оно не было запущено с --disable-deduplication (see --disable-deduplication). Так что эта опция особенно важна, если демон запущено с --disable-deduplication.


Next: , Previous: , Up: Управление пакетами   [Contents][Index]

6.6 Вызов guix pull

Пакеты, которые были установлены или обновлены до последней версии, доступные в дистрибутиве, доступны и на вашей локальной машине. Для обновления этого дистрибутива инструментами Guix нужно запустить guix pull: команда скачивает последние исходные коды Guix, описания пакетов и разворачивает их. Исходный код скачивается из репозитория Git, репозитория GNU Guix по умолчанию, хотя это можно поменять.

В частности, guix pull загружает код из channel (see Каналы), указанного одним из следующих способов, в следующем порядке:

  1. опция --channels;
  2. пользовательский файл ~/.config/guix/channels.scm;
  3. общесистемный файл /etc/guix/channels.scm file;
  4. встроенные по умолчанию каналы определены в переменной %default-channels.

После выполнения этой команды guix package будет использовать пакеты и те их версии, которые имеются в только что полученной копии Guix. Эта последняя версия будет источником также всех команд Guix, модулей Scheme. Из этого обновления станет доступен набор команд guix.

Любой пользователь может обновить свою копию Guix, используя guix pull, эффект коснётся только пользователя, который запустил guix pull. Например, если пользователь root запускает guix pull, это не имеет эффекта на версию Guix, которую видит alice sees, и наоборот.

Результат запуска guix pull — это профиль profile, доступный в ~/.config/guix/current, содержащий последний Guix. Так что обязательно добавьте этот адрес первым в пути поиска, чтобы использовать последнюю версию, а также для руководства Info (see Документация):

export PATH="$HOME/.config/guix/current/bin:$PATH"
export INFOPATH="$HOME/.config/guix/current/share/info:$INFOPATH"

Опция --list-generations или -l выводит список последних поколений, поставленных guix pull, вместе с деталями об их происхождении:

$ guix pull -l
Generation 1	Jun 10 2018 00:18:18
  guix 65956ad
    repository URL: https://git.savannah.gnu.org/git/guix.git
    branch: origin/master
    commit: 65956ad3526ba09e1f7a40722c96c6ef7c0936fe

Generation 2	Jun 11 2018 11:02:49
  guix e0cc7f6
    repository URL: https://git.savannah.gnu.org/git/guix.git
    branch: origin/master
    commit: e0cc7f669bec22c37481dd03a7941c7d11a64f1d

Generation 3	Jun 13 2018 23:31:07	(current)
  guix 844cc1c
    repository URL: https://git.savannah.gnu.org/git/guix.git
    branch: origin/master
    commit: 844cc1c8f394f03b404c5bb3aee086922373490c

Смотрите See guix describe, для информации о других способах получить информацию о текущем статусе Guix.

Этот профиль ~/.config/guix/current работает, как любой другой профиль, созданный guix package (see Вызов guix package). Так что можно вывести список поколений, откатиться до предыдущего поколения, то есть до предыдущего Guix, и так далее:

$ guix package -p ~/.config/guix/current --roll-back
switched from generation 3 to 2
$ guix package -p ~/.config/guix/current --delete-generations=1
deleting /var/guix/profiles/per-user/charlie/current-guix-1-link

Вы также можете использовать guix package (see Вызов guix package), чтобы управлять профилем, называя его явно:

$ guix package -p ~/.config/guix/current --roll-back
switched from generation 3 to 2
$ guix package -p ~/.config/guix/current --delete-generations=1
deleting /var/guix/profiles/per-user/charlie/current-guix-1-link

Команда guix pull обычно вызывается без аргументов, но поддерживает следующие опции:

--url=url
--commit=commit
--branch=branch

Скачать код канала guix из указанного url, относящийся к обозначенному коммиту commit (корректный ID коммита Git, представленный в виде шестнадцатеричной строки), или ветке branch.

Эти опции внедрены для удобства, но также можно задать конфигурационный файл ~/.config/guix/channels.scm или использовать опцию --channels (смотрите ниже).

--channels=file
-C file

Считать список каналов из файла file вместо ~/.config/guix/channels.scm. file должен содержать код Scheme, который определяет список объектов "канал". См. See Каналы для подробной информации.

--news
-N

Display news written by channel authors for their users for changes made since the previous generation (see Writing Channel News). When --details is passed, additionally display new and upgraded packages.

You can view that information for previous generations with guix pull -l.

--list-generations[=pattern]
-l [pattern]

Вывести список всех поколений ~/.config/guix/current или, если предоставлен паттерн pattern, подмножество поколений, которые соответствуют pattern. Синтаксис pattern — такой же, как у guix package --list-generations (see Вызов guix package).

By default, this prints information about the channels used in each revision as well as the corresponding news entries. If you pass --details, it will also print the list of packages added and upgraded in each generation compared to the previous one.

--details

Instruct --list-generations or --news to display more information about the differences between subsequent generations—see above.

--roll-back

Откатиться до предыдущего поколения профиля, то есть отменить последнюю транзакцию.

--switch-generation=pattern
-S pattern

Переключиться на определённое поколение, опрделённое pattern.

pattern может быть либо номером поколения или числом с префиксом "+" или "-". Последнее означает сменить вперёд/назад на обозначенное число поколений. Например, если вы хотите вернуться к последнему поколению после --roll-back, используйте --switch-generation=+1.

--delete-generations[=pattern]
-d [pattern]

Если pattern пропущен, удалит все поголения, кроме текущего.

Эта команда принимает такие же паттерны, как --list-generations. Если pattern задан, удалит соответствующие поколения. Если паттерн pattern задаёт срок, выбираются поколения старше срока. Например, --delete-generations=1m удалит поколения, которые старше одного месяца.

Если текущее поколение попадает под условия паттерна, оно не будет удалено. А также нулевое поокление никогда не удаляется.

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

См. See Вызов guix describe, чтобы узнать, как вывести информацию только о текущем поколении.

--profile=profile
-p profile

Использовать профиль profile вместо ~/.config/guix/current.

--dry-run
-n

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

--allow-downgrades

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

По умолчанию guix pull защищает от так называемых “атак на более раннюю версию”, когда репозиторий Git данного канала будет сброшен до более ранней или несвязанной версии, что может привести к установке более старых, известных уязвимых версий пакетов.

Примечание: Прежде чем использовать --allow-downgrades, убедитесь, что вы понимаете его последствия для безопасности.

--disable-authentication

Разрешить загрузку канала без его аутентификации.

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

Примечание: Прежде чем использовать --disable-authentication, убедитесь, что вы понимаете его последствия для безопасности.

--system=system
-s system

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

--bootstrap

Использовать бутстрап Guile для сорки последнего Guix. Эта опция полезна только для разработчиков.

Механизм каналов channel позволяет указать guix pull, из какого репозитория или ветки скачивать, а также какие дополнительные репозитории должны использоваться для развёртки. См. See Каналы для подробной информации.

В добавок guix pull поддерживает все стандартные опции сборки (see Стандартные параметры сборки).


Next: , Previous: , Up: Управление пакетами   [Contents][Index]

6.7 Запуск guix time-machine

Команда guix time-machine предоставляет доступ к другим версиям Guix, например, для установки более старых версий пакетов или для воспроизведения вычислений в идентичной среде. Версия используемого Guix определяется коммитом или файлом описания канала, созданным guix describe (see Вызов guix describe).

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

guix time-machine options… -- command arg

где command и arg… передаются без изменений в команду guix указанной ревизии. options, которые определяют эту ревизию, такие же, как и для guix pull (see Запуск guix pull):

--url=url
--commit=commit
--branch=branch

Скачать код канала guix из указанного url, относящийся к обозначенному коммиту commit (корректный ID коммита Git, представленный в виде шестнадцатеричной строки), или ветке branch.

--channels=file
-C file

Считать список каналов из файла file вместо ~/.config/guix/channels.scm. file должен содержать код Scheme, который определяет список объектов "канал". См. See Каналы для подробной информации.

Что касается guix pull, то отсутствие каких-либо опций означает, что будет использоваться последний коммит в основной ветке. Команда

guix time-machine -- build hello

таким образом, мы соберем пакет hello, как определено в основной ветке, которая, как правило, является более новой версией Guix, чем вы установили. Путешествие во времени работает в обоих направлениях!

Если указанные пакеты ещё не собраны, guix archive автоматически соберёт их. Процесс сборки может контролироваться обычными опциями сборки (see Стандартные параметры сборки).


Next: , Previous: , Up: Управление пакетами   [Contents][Index]

6.8 Младшие версии

Примечание: Функциональность, описанная здесь, — это обзор технологии версии 887a5fd. Интерфейс может меняться.

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

Технически работа с ранними версиями — это в целом отдельный процесс Guix, связанный с главным процессом Guix через REPL (see Запуск guix repl). Модуль (guix inferior) позволяет запускать ранние версии и взаимодействовать с ними. Он также предоставляет высокоуровневый интерфейс для обзора и управления пакетами, которые поставляет ранняя версия — ранние версии пакетов.

When combined with channels (see Каналы), inferiors provide a simple way to interact with a separate revision of Guix. For example, let’s assume you want to install in your profile the current guile package, along with the guile-json as it existed in an older revision of Guix—perhaps because the newer guile-json has an incompatible API and you want to run your code against the old API. To do that, you could write a manifest for use by guix package --manifest (see Writing Manifests); in that manifest, you would create an inferior for that old Guix revision you care about, and you would look up the guile-json package in the inferior:

(use-modules (guix inferior) (guix channels)
             (srfi srfi-1))   ;for 'first'

(define channels
  ;; This is the old revision from which we want to
  ;; extract guile-json.
  (list (channel
         (name 'guix)
         (url "https://git.savannah.gnu.org/git/guix.git")
         (commit
          "65956ad3526ba09e1f7a40722c96c6ef7c0936fe"))))

(define inferior
  ;; An inferior representing the above revision.
  (inferior-for-channels channels))

;; Now create a manifest with the current "guile" package
;; and the old "guile-json" package.
(packages->manifest
 (list (first (lookup-inferior-packages inferior "guile-json"))
       (specification->package "guile")))

Далее запуск guix package --manifest может вызвать сборку канала, который вы обозначили ранее, и в результате это задействует раннюю версию. Последовательные запуски будут быстрее, потому что ревизия Guix будет кеширована.

Модуль (guix inferior) предоставляет следующие процедуры для работы с ранними версиями:

Процедура Scheme: inferior-for-channels channels [#:cache-directory] [#:ttl] Возвращает раннюю версию для списка каналов

channels. Использует кеш в cache-directory, где компоненты могут восстанавливаться через ttl секунд. Эта процедура открывает новое соединение с демоном сборки.

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

Процедура Scheme: open-inferior directory [#:command "bin/guix"] Открывает раннюю версию Guix в directory,

запустив repl directory/command или эквивалент. Возвращает #f, если ранняя версия не может быть запущена.

Процедуры, приведённые ниже, обеспечивают работу и управление ранними версиями пакетов.

Процедура Scheme: inferior-packages inferior

Возвращает список пакетов, относящихся к ранней версии inferior.

Процедура Scheme: lookup-inferior-packages inferior name [version] Возвращает сортированный список пакетов ранней версии

inferior, содержащих имя name, поздняя версия - вначале. Если версия version задана, возвращает только пакеты с номером версии, начинающейся с version.

Процедура Scheme: inferior-package? obj

Возвращает true, если объект obj — это пакет ранней версии.

Процедура Scheme: inferior-package-name package
Процедура Scheme: inferior-package-version package
Процедура Scheme: inferior-package-synopsis package
Процедура Scheme: inferior-package-description package
Процедура Scheme: inferior-package-home-page package
Процедура Scheme: inferior-package-location package
Процедура Scheme: inferior-package-inputs package
Процедура Scheme: inferior-package-native-inputs package
Процедура Scheme: inferior-package-propagated-inputs package
Процедура Scheme: inferior-package-transitive-propagated-inputs package
Процедура Scheme: inferior-package-native-search-paths package
Процедура Scheme: inferior-package-transitive-native-search-paths package
Процедура Scheme: inferior-package-search-paths package

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

Пакеты ранних версий могут использоваться прозрачно, как любой другой пакет или объект типа файл в выражении G-expressions (see G-Expressions). Они также прозрачно используются в процедуре packages->manifest, которая обычно используется в манифестах (see the --manifest option of guix package). Так можно вставлять пакет ранней версии в принципе куда угодно, как если вставлять обычный пакет: в манифесты, в поле packages вашего объявления operating-system и т.д.


Next: , Previous: , Up: Управление пакетами   [Contents][Index]

6.9 Вызов guix describe

Часто может возникать вопрос: "Какую ревизию Guix я использую?" - Или: "Какие каналы я использую?" Это полезна информация во многих ситуациях: если вы хотите повторить окружение на другой машине или в другом пользовательском аккаунте, если вы хотите составить отчёт об ошибке, чтобы определить, какие изменения в канале, который вы используете, вызвали ошибку, или если вы хотите записать состояние вашей системы в целях воспроизводимости. Команда guix describe отвечает на эти вопросы.

В случае запуска после guix pull команда guix describe отображает канал(ы), из которых производилась сборка, включая URL и репозиториев и ID коммитов (see Каналы):

$ guix describe
Generation 10	Sep 03 2018 17:32:44	(current)
  guix e0fa68c
    repository URL: https://git.savannah.gnu.org/git/guix.git
    branch: master
    commit: e0fa68c7718fffd33d81af415279d6ddb518f727

Если вы знакомы с системой контроля версиями Git, эта команда по сути похожа на git describe; выход тот же, что в guix pull --list-generations, но ограничен текущим поколением (see the --list-generations option). Так как ID коммита Git выше ссылается однозначно на снимок Guix, эта информация — всё, что нужно для описания используемой ревизии Guix и повторения её.

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

$ guix describe -f channels
(list (channel
        (name 'guix)
        (url "https://git.savannah.gnu.org/git/guix.git")
        (commit
          "e0fa68c7718fffd33d81af415279d6ddb518f727")))
        (introduction
           (make-channel-introduction
             "9edb3f66fd807b096b48283debdcddccfea34bad"
             (openpgp-fingerprint
               "BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA")))))

Можно сохранить это в файл и подать на вход guix pull -C на любой другой машине или через время, чтобы инициализировать эту конкретную ревизию Guix (see the -C option). Теперь, когда можно развернуть подобную ревизию Guix, вы можете также полностью повторить программное окружение. Мы скромно полагаем, это чудесно. Надеемся, вам это тоже понравится!

Подробнее об опциях, поддерживаемых guix describe:

--format=format
-f format

Произвести вывод в указанном формате format, одном из:

human

произвести вывод для чтения человеком;

каналы

произвести список спецификаций каналов, который может использоваться в guix pull -C или вставлен в файл ~/.config/guix/channels.scm (see Запуск guix pull);

channels-sans-intro

как channels, но без поля Introduction; используйте его для создания спецификации канала, подходящей для Guix версии 1.1.0 или более ранней. Поле Introduction связано с аутентификацией канала (see Channel Authentication) и не поддерживается этими более ранними версиями;

json

произвести список спецификаций каналов в формате JSON;

recutils

произвести список спецификаций каналов в формате Recutils.

--list-roots

Вывести доступные форматы для --format опции.

--profile=profile
-p profile

Вывести информацию о профиле profile.


Previous: , Up: Управление пакетами   [Contents][Index]

6.10 Вызов guix archive

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

Примечание: Если вы ищете способ производить архивы в формате, который подходит для инструментов, отличных от Guix, смотрите see Запуск guix pack.

Чтобы экспортировать файлы склада в архив в стандартный вывод, выполните:

guix archive --export options specifications...

Спецификации specifications могут быть либо именами файлов или пакетами, как для команде guix package (see Вызов guix package). Например, следующая команда создаёт архив, содержащий выход gui пакета git и главный выход emacs:

guix archive --export git:gui /gnu/store/...-emacs-24.3 > great.nar

Если указанные пакеты ещё не собраны, guix archive автоматически соберёт их. Процесс сборки может контролироваться обычными опциями сборки (see Стандартные параметры сборки).

Чтобы передать пакет emacs на машину, соединённую по SSH, нужно следующее:

guix archive --export -r emacs | ssh the-machine guix archive --import

Точно также для передачи всего профиля пользователя из одной машины на другую, выполните:

guix archive --export -r $(readlink -f ~/.guix-profile) | \
  ssh the-machine guix archive --import

Однако заметим, что в обоих примерах, передаются весь emacs и профиль вместе с их зависимости (ввиду -r), не учитывая, что доступно на складе целевой машины. Опция --missing помогает определить отсутствующие элементы на целевом складе. Команда guix copy упрощает и оптимизирует весь этот процесс, так что в данном случае она решает проблему (see Запуск guix copy).

Каждый элемент храниища написан в normalized archive или nar формате (описано ниже), и вывод guix archive --export (и ввод guix archive --import) есть nar bundle.

Формат nar по духу сравним с tar, но с отличиями, которые делают его более подходящим для наших целей. Во-первых, вместо записи всех метаданных Unix для каждого файла, в формате nar упоминается только тип файла (обычный, каталог или символическая ссылка); Разрешения Unix и владелец/группа отклонены. Во-вторых, порядок, в котором хранятся записи каталога, всегда следует порядку имен файлов в соответствии с порядком сопоставления C локали. Это делает создание архивов полностью детерминированным.

Формат пакета nar - это, по сути, конкатенация нуля или более nars вместе с метаданными для каждого элемента store, который содержит: имя файла, ссылки, соответствующую derivation и цифровую подпись.

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

Основные опции:

--export

Экспортировать указанные файлы хранилища или пакеты (смотрите ниже). Писать результирующий архив в стандартный вывод.

Зависимости не включаются в выход, если не задана опция --recursive.

-r
--recursive

При сочетании с --export это указывает guix archive включать в архив зависимости обозначенных элементов. Так результирующий архив будет "сам в себе": содержит полный конвейер экспортированных элементов склада.

--import

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

--missing

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

--generate-key[=parameters]

Генерировать новую ключ-пару для демона. Это необходимо получить перед тем, как экспортировать архивы опцией --export. Отметим, что эта операция обычно занимает время, так как необходимо собрать много энтропии для ключ-пары.

Сгенерированная ключ-пара обычно сохраняется под /etc/guix, в файлы signing-key.pub (публичный ключ) и signing-key.sec (прватный ключ, который должен оставаться в секрете). Если параметры parameters пропущены, генерируется ключ ECDSA, используя кривую Ed25519, или для Libgcrypt версии ранее 1.6.0 — это 4096-битный ключ RSA. Альтернативно в параметрах parameters можно указать genkey, соответствующие Libgcrypt (see gcry_pk_genkey in The Libgcrypt Reference Manual).

--authorize

Авторизовать импорт, подписанный публичным ключом, поступивший на стандартный ввод. Публичный ключ должен быть в формате s-expression, то есть в таком же формате, как файл signing-key.pub.

Список авторизованных ключей хранится в файле /etc/guix/acl, доступном для редактирования человеком. Файл содержит s-expression расширенного формата, и он структурирован в виде списка контроля доступа в Simple Public-Key Infrastructure (SPKI).

--extract=directory
-x directory

Читать архив, представляющий один элемент, в качестве поставленного серверами подстановки (see Подстановки) и извлечь его в директорию directory. Это низкоуровневая операция, необходимая только в очень редких случаях, смотрите ниже.

Например, следующая команда распаковывает подстановку Emacs, поставленную ci.guix.gnu.org в /tmp/emacs:

$ wget -O - \
  https://ci.guix.gnu.org/nar/gzip/…-emacs-24.5 \
  | gunzip | guix archive -x /tmp/emacs

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

Основная цель этой операции — упростить просмотр содержимого архива, происходящего, возможно, из недоверенных серверов подстановок.

--list
-t

Читать архив, представляющий один элемент, в качестве поставленного серверами подстановки (see Подстановки) и распечатайте список файлов, которые он содержит, как в этом примере:

$ wget -O - \
  https://ci.guix.gnu.org/nar/lzip/…-emacs-26.3 \
  | lzip -d | guix archive -t

Next: , Previous: , Up: Top   [Contents][Index]

7 Каналы

Guix и его коллекция пакетов можно обновить запуском guix pull (see Запуск guix pull). По умолчанию guix pull скачивает и разворачивает Guix из официального репозитория GNU Guix. Это может быть изменено определением каналов channels в файле ~/.config/guix/channels.scm. Канал обозначает URL или ветку репозитория Git для разворачивания. Также guix pull может быть настроена для скачивания из одного или более каналов. Другими словами, каналы могут использоваться для настройки и для расширения Guix, как это будет показано ниже.


Next: , Up: Каналы   [Contents][Index]

7.1 Указание дополнительных каналов

Чтобы использовать канал, напишите ~/.config/guix/channels.scm, чтобы обозначить guix pull скачивать оттуда в дополнение к каналу(-ам) Guix по умолчанию:

;; Add my personal packages to those Guix provides.
(cons (channel
        (name 'my-personal-packages)
        (url "https://example.org/personal-packages.git"))
      %default-channels)

Заметим, что сниппет выше (всегда!) код Scheme; мы используем cons для добавления канала в список каналов, то есть в переменную %default-channels (see cons and lists in GNU Guile Reference Manual). Если этот файл написан, guix pull производит сборку не только Guix, но и пакетных модулей из вашего репозитория. В результате в ~/.config/guix/current содержится объединение Guix и ваших собственных пакетных модулей:

$ guix describe
Generation 19	Aug 27 2018 16:20:48
  guix d894ab8
    repository URL: https://git.savannah.gnu.org/git/guix.git
    branch: master
    commit: d894ab8e9bfabcefa6c49d9ba2e834dd5a73a300
  variant-packages dd3df5e
    repository URL: https://example.org/variant-packages.git
    branch: master
    commit: dd3df5e2c8818760a8fc0bd699e55d3b69fef2bb

The output of guix describe above shows that we’re now running Generation 19 and that it includes both Guix and packages from the variant-personal-packages channel (see Вызов guix describe).


Next: , Previous: , Up: Каналы   [Contents][Index]

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

Канал, названный guix, обозначает, откуда должен скачиваться сам Guix (его инструменты командной строки и коллекция пакетов). Например, предположим вы хотите обновиться из вашей собственной копии репозитория Guix на example.org, а именно из ветки super-hacks, тогда можно написать в ~/.config/guix/channels.scm следующую спецификацию:

;; Tell 'guix pull' to use my own repo.
(list (channel
        (name 'guix)
        (url "https://example.org/my-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 (see Аутентификация канала).


Next: , Previous: , Up: Каналы   [Contents][Index]

7.3 Копирование Guix

The guix describe command shows precisely which commits were used to build the instance of Guix we’re using (see Вызов guix describe). We can replicate this instance on another machine or at a different point in time by providing a channel specification “pinned” to these commits that looks like this:

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

To obtain this pinned channel specification, the easiest way is to run guix describe and to save its output in the channels format in a file, like so:

guix describe -f channels > channels.scm

The resulting channels.scm file can be passed to the -C option of guix pull (see Запуск guix pull) or guix time-machine (see Вызов guix time-machine), as in this example:

guix time-machine -C channels.scm -- shell python -- python3

Given the channels.scm file, the command above will always fetch the exact same Guix instance, then use that instance to run the exact same Python (see Запуск guix shell). On any machine, at any time, it ends up running the exact same binaries, bit for bit.

Pinned channels address a problem similar to “lock files” as implemented by some deployment tools—they let you pin and reproduce a set of packages. In the case of Guix though, you are effectively pinning the entire package set as defined at the given channel commits; in fact, you are pinning all of Guix, including its core modules and command-line tools. You’re also getting strong guarantees that you are, indeed, obtaining the exact same software.

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


Next: , Previous: , Up: Каналы   [Contents][Index]

7.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 канала из надежного источника, так как это основа вашего доверия.

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


Next: , Previous: , Up: Каналы   [Contents][Index]

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

При запуске guix pull Guix сначала скомпилирует определения каждого доступного пакета. Это тяжелая операция, для которой могут быть доступны заменители (see Подстановки). Следующий фрагмент в channels.scm гарантирует, что guix pull использует последний коммит с доступными заменами для определений пакетов: это делается путем запроса к серверу непрерывной интеграции по адресу https://ci.guix.gnu.org.

(use-package-modules guile emacs)

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

Учтите, что это не означает, что все пакеты, которые вы установите после запуска guix pull, будут иметь доступные заменители. Это только гарантирует, что guix pull не будет пытаться скомпилировать определения пакетов. Это особенно полезно при использовании машин с ограниченными ресурсами.


Next: , Previous: , Up: Каналы   [Contents][Index]

7.6 Создание канала

Можно также задать дополнительные каналы для выборки оттуда. Ну, например, у вас ряд собственных вариантов пакетов или собственные пакеты, которые вы считаете не особо важным для отправки в проект Guix, но хотите, чтобы эти пакеты были доступны вам в командной строке прозрачно, без дополнительных действий. Вначале можно написать модули, содержащие определения этих пакетов (see Пакетные модули), затем разместить их в репозитории Git, и тогда вы или кто-либо ещё сможете использовать их в качестве дополнтельного канала для получения пакетов. Красиво, да?

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

Вы предупреждены! Обозначив это, мы верим, что внешние каналы — это способ для вас проявлять свою свободу и вместе с тем расширять коллекцию пакетов Guix и делиться улучшениями, что является основными догматами свободного программного обеспечения. Пожалуйста, свяжитесь с нами по e-mail guix-devel@gnu.org, если вы хотите обсудить это.

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

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


Next: , Previous: , Up: Каналы   [Contents][Index]

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

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

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

Next: , Previous: , Up: Каналы   [Contents][Index]

7.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"))))

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

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


Next: , Previous: , Up: Каналы   [Contents][Index]

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

Как мы видели выше, Guix гарантирует, что исходный код, который он получает из каналов, поступает от авторизованных разработчиков. Как автор канала, вам необходимо указать список авторизованных разработчиков в файле .guix-authorizations в репозитории Git канала. Правило аутентификации простое: каждый коммит должен быть подписан ключом, указанным в файле .guix-authorizations его родительского коммита(ов) 11 файл .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 introductions answer these questions by describing the first commit of a channel that should be authenticated. The first time a channel is fetched with guix pull or guix time-machine, the command looks up the introductory commit and verifies that it is signed by the specified OpenPGP key. From then on, it authenticates commits according to the rule above. Authentication fails if the target commit is neither a descendant nor an ancestor of the introductory commit.

Кроме того, ваш канал должен предоставлять все ключи 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 в репозиторий канала. Сделайте это в подписанном коммите (see Доступ к коммитам, чтобы узнать, как подписывать коммиты Git)
  3. Рекламируйте channel introduction, например, на веб-странице вашего канала. Channel introduction, как мы видели выше, - это пара коммит/ключ, то есть коммит, который представляет .guix-authorizations, и отпечаток OpenPGP, использованный для его подписи.

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

guix git authenticate commit signer

где commit и signer являются вашим channel introduction. See Запуск guix git authenticate, подробнее.

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


Next: , Previous: , Up: Каналы   [Contents][Index]

7.10 Основной URL

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

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

Это позволяет guix pull определять, pull’ит ли он код из зеркала канала; в этом случае он предупреждает пользователя о том, что зеркало может быть устаревшим, и отображает основной URL-адрес. Таким образом, пользователей нельзя обмануть, заставив их получить код с устаревшего зеркала, которое не получает обновлений безопасности.

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


Previous: , Up: Каналы   [Contents][Index]

7.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 разметку (see Overview in GNU Texinfo). И заголовок, и тело являются списком языковых тегов/кортежей сообщений, что позволяет комманде guix pull отображать новости на языке, соответствующем языку пользователя.

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

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

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


Next: , Previous: , Up: Top   [Contents][Index]

8 Разработка

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

The guix shell command provides a convenient way to set up one-off software environments, be it for development purposes or to run a command without installing it in your profile. The guix pack command allows you to create application bundles that can be easily distributed to users who do not run Guix.


Next: , Up: Разработка   [Contents][Index]

8.1 Вызов guix shell

The purpose of guix shell is to make it easy to create one-off software environments, without changing one’s profile. It is typically used to create development environments; it is also a convenient way to run applications without “polluting” your profile.

Примечание: The guix shell command was recently introduced to supersede guix environment (see Запуск guix environment). If you are familiar with guix environment, you will notice that it is similar but also—we hope!—more convenient.

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

guix shell [options] [package…]

The following example creates an environment containing Python and NumPy, building or downloading any missing package, and runs the python3 command in that environment:

guix shell python python-numpy -- python3

Development environments can be created as in the example below, which spawns an interactive shell containing all the dependencies and environment variables needed to work on Inkscape:

guix shell --development inkscape

Exiting the shell places the user back in the original environment before guix shell was invoked. The next garbage collection (see Вызов guix gc) may clean up packages that were installed in the environment and that are no longer used outside of it.

As an added convenience, guix shell will try to do what you mean when it is invoked interactively without any other arguments as in:

guix shell

If it finds a manifest.scm in the current working directory or any of its parents, it uses this manifest as though it was given via --manifest. Likewise, if it finds a guix.scm in the same directories, it uses it to build a development profile as though both --development and --file were present. In either case, the file will only be loaded if the directory it resides in is listed in ~/.config/guix/shell-authorized-directories. This provides an easy way to define, share, and enter development environments.

By default, the shell session or command runs in an augmented environment, where the new packages are added to search path environment variables such as PATH. You can, instead, choose to create an isolated environment containing nothing but the packages you asked for. Passing the --pure option clears environment variable definitions found in the parent environment12; passing --container goes one step further by spawning a container isolated from the rest of the system:

guix shell --container emacs gcc-toolchain

The command above spawns an interactive shell in a container where nothing but emacs, gcc-toolchain, and their dependencies is available. The container lacks network access and shares no files other than the current working directory with the surrounding environment. This is useful to prevent access to system-wide resources such as /usr/bin on foreign distros.

This --container option can also prove useful if you wish to run a security-sensitive application, such as a web browser, in an isolated environment. For example, the command below launches Ungoogled-Chromium in an isolated environment, this time sharing network access with the host and preserving its DISPLAY environment variable, but without even sharing the current directory:

guix shell --container --network --no-cwd ungoogled-chromium \
  --preserve='^DISPLAY$' -- chromium

guix shell определяет переменную GUIX_ENVIRONMENT в оболочке, которую создаёт; её значением является имя файла профиля этого окружения. Это позволяет пользователям, скажем, определить специфичные значения окружений разработки в .bashrc (see Bash Startup Files in The GNU Bash Reference Manual):

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

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

$ ls "$GUIX_ENVIRONMENT/bin"

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

--check

Set up the environment and check whether the shell would clobber environment variables. It’s a good idea to use this option the first time you run guix shell for an interactive session to make sure your setup is correct.

For example, if the shell modifies the PATH environment variable, report it since you would get a different environment than what you asked for.

Such problems usually indicate that the shell startup files are unexpectedly modifying those environment variables. For example, if you are using Bash, make sure that environment variables are set or modified in ~/.bash_profile and not in ~/.bashrc—the former is sourced only by log-in shells. See Bash Startup Files in The GNU Bash Reference Manual, for details on Bash start-up files.

--development
-D

Cause guix shell to include in the environment the dependencies of the following package rather than the package itself. This can be combined with other packages. For instance, the command below starts an interactive shell containing the build-time dependencies of GNU Guile, plus Autoconf, Automake, and Libtool:

guix shell -D guile autoconf automake libtool
--expression=expr
-e expr

Создать окружение для пакета или списка пакетов, которые соответствуют выражению expr.

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

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

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

Запуск:

guix shell -e '(@ (gnu) %base-packages)'

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

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

guix shell -e '(list (@ (gnu packages bash) bash) "include")'

See package->development-manifest, for information on how to write a manifest for the development environment of a package.

--file=file
-f file

Create an environment containing the package or list of packages that the code within file evaluates to.

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

(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 (modify-inputs (package-native-inputs gdb)
                   (prepend autoconf-2.64 automake texinfo))))

With the file above, you can enter a development environment for GDB by running:

guix shell -D -f gdb-devel.scm
--manifest=file
-m file

Создать окружение для пакетов, содержащихся в объекте манифеста, возвращаемого кодом Scheme в файле file.

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

See Writing Manifests, for information on how to write a manifest. See --export-manifest below on how to obtain a first manifest.

--export-manifest

Write to standard output a manifest suitable for --manifest corresponding to given command-line options.

This is a way to “convert” command-line arguments into a manifest. For example, imagine you are tired of typing long lines and would like to get a manifest equivalent to this command line:

guix shell -D guile git emacs emacs-geiser emacs-geiser-guile

Just add --export-manifest to the command line above:

guix shell --export-manifest \
  -D guile git emacs emacs-geiser emacs-geiser-guile

... and you get a manifest along these lines:

(concatenate-manifests
  (list (specifications->manifest
          (list "git"
                "emacs"
                "emacs-geiser"
                "emacs-geiser-guile"))
        (package->development-manifest
          (specification->package "guile"))))

You can store it into a file, say manifest.scm, and from there pass it to guix shell or indeed pretty much any guix command:

guix shell -m manifest.scm

Voilà, you’ve converted a long command line into a manifest! That conversion process honors package transformation options (see Параметры преобразования пакета) so it should be lossless.

--profile=profile
-p profile

Create an environment containing the packages installed in profile. Use guix package (see Вызов guix package) to create and manage profiles.

--pure

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

--preserve=regexp
-E regexp

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

guix shell --pure --preserve=^SLURM openmpi … \
  -- mpirun …

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

--search-paths

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

--system=system
-s system

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

--container
-C

Запустить command в изолированном контейнере. Текущая рабочая директория за пределами контейнера отображается внутри контейнера. В дополнение, если это не переопределено опцией --user, тогда настраивается фиктивная домашняя директория, которая совпадает с домашней директорией текущего пользователя, а также соответствующий файл /etc/passwd.

Порождаемый процесс снаружи предстаёт как запущенный от текущего пользователя. Внутри контейнера он имеет такие же UID и GID, что и текущий пользователь, если не обозначена --user (смотрите ниже).

--network
-N

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

--link-profile
-P

Связать профиль окружения контейнера с ~/.guix-profile внутри контейнера. Это эквивалент запуска команды ln -s $GUIX_ENVIRONMENT ~/.guix-profile внутри контейнера. Связывание завершится ошибкой и отменит создание окружения, если директория уже существует, что, конечно, будет происходить, если guix shell вызвана в домашней директории пользователя.

Определённые пакеты сконфигурированы, чтобы смотреть конфигурационные файлы и данные в ~/.guix-profile;13 --link-profile позволяет этим программам вести себя ожидаемо внутри окружения.

--user=user
-u user

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

В дополнение, любой разделяемый или расширяемый путь (смотрите --share и --expose соответственно), чьи цели находятся в домашней директории пользователя, будут отображены соответственно в /home/USER; это включает автоматическое отображение текущей рабочей директории.

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

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

--no-cwd

Для контейнеров стандартным поведением является разделение текущего рабочего каталога с изолированным контейнером и немедленное переключение на этот каталог в контейнере. Если это нежелательно, --no-cwd приведет к автоматическому доступу к текущему рабочему каталогу not, который изменится на домашний каталог пользователя в контейнере. Смотрите также --user.

--expose=source[=target]
--share=source[=target]

Расширить файловую систему контейнера источником source из хостящей системы в качестве файловой системы только для чтения с целью target внутри контейнера. Если цель target не задана, источник source используется как целевая точка монтирования в контейнере.

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

guix shell --container --expose=$HOME=/exchange guile -- guile
--rebuild-cache

In most cases, guix shell caches the environment so that subsequent uses are instantaneous. Least-recently used cache entries are periodically removed. The cache is also invalidated, when using --file or --manifest, anytime the corresponding file is modified.

The --rebuild-cache forces the cached environment to be refreshed. This is useful when using --file or --manifest and the guix.scm or manifest.scm file has external dependencies, or if its behavior depends, say, on environment variables.

--root=file
-r file

Создать символическую ссылку file на профиль этого окружения и зарегистрировать её как корень сборщика мусора.

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

When this option is omitted, guix shell caches profiles so that subsequent uses of the same environment are instantaneous—this is comparable to using --root except that guix shell takes care of periodically removing the least-recently used garbage collector roots.

In some cases, guix shell does not cache profiles—e.g., if transformation options such as --with-latest are used. In those cases, the environment is protected from garbage collection only for the duration of the guix shell session. This means that next time you recreate the same environment, you could have to rebuild or re-download packages.

See Вызов guix gc, for more on GC roots.

guix shell также поддерживает все обычные опции сборки, которые поддерживает команда guix build (see Стандартные параметры сборки), а также опции трансформации пакета (see Параметры преобразования пакета).


Next: , Previous: , Up: Разработка   [Contents][Index]

8.2 Вызов guix environment

The purpose of guix environment is to assist in creating development environments.

Deprecation warning: The guix environment command is deprecated in favor of guix shell, which performs similar functions but is more convenient to use. See Запуск guix shell.

Being deprecated, guix environment is slated for eventual removal, but the Guix project is committed to keeping it until May 1st, 2023. Please get in touch with us at guix-devel@gnu.org if you would like to discuss it.

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

guix environment options package

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

guix environment guile

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

Выход из окружения Guix аналогичен выходу из оболочки и возвращает пользователя в старое окружение до вызова guix environment. Следующая сборка мусора (see Вызов guix gc) очистит пакеты, которые были установлены в окружении и больше не используются за ее пределами.

guix environment определяет переменную GUIX_ENVIRONMENT в оболочке, которую создаёт; её значением является имя файла профиля этого окружения. Это позволяет пользователям, скажем, определить специфичные значения окружений разработки в .bashrc (see Bash Startup Files in The GNU Bash Reference Manual):

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

In other situations, it is more convenient to specify the list of packages needed in the environment. For example, the following command runs python from an environment containing Python 3 and NumPy:

guix environment --ad-hoc python-numpy python -- python3

Более того, возможно, вам потребуются зависимости пакета, а также некоторые дополнительные пакеты, которые не являются зависимостями процесса сборки или процесса исполнения (работы), но важны при разработке. Для этого и указан флаш --ad-hoc. Пакеты, обозначенные до --ad-hoc интерпретируются как пакеты, чьи зависимости будут добавлены в окружение. Пакеты, которые обозначены после --ad-hoc, интерпретируются как пакеты, которые будут добавлены в окружение непосредственно. Например, следующая команда создаёт окружение разработки Guix, которая в дополнение включает Git и strace:

guix environment guix --ad-hoc git strace

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

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

Примечание: Опция --container требует Linux-libre 3.19 или новее.

Другой типичный вариант использования контейнеров - запуск приложений, чувствительных к безопасности, таких как веб-браузер. Чтобы запустить Eolie, мы должны предоставить доступ к некоторым файлам и каталогам; мы используем nss-certs и предоставляем /etc /ssl /certs/ для аутентификации HTTPS; наконец, мы сохраняем переменную среды DISPLAY, поскольку контейнерные графические приложения не будут отображаться без нее.

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

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

--check

Set up the environment and check whether the shell would clobber environment variables. See --check, for more info.

--root=file
-r file

Создать символическую ссылку file на профиль этого окружения и зарегистрировать её как корень сборщика мусора.

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

Если эта опция пропущена, окружеие защищено от сборщика мусора только на время сессии guix environment. Это означает, что в следующий раз, когда вы создадите такое же окружение, вам потребуется пересобирать и скачивать пакеты заново. See Вызов 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 может содержать определение (see Описание пакетов):

(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 (modify-inputs (package-native-inputs gdb)
                   (prepend autoconf-2.64 automake texinfo))))
--manifest=file
-m file

Создать окружение для пакетов, содержащихся в объекте манифеста, возвращаемого кодом Scheme в файле file.

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

See guix shell --export-manifest, for information on how to “convert” command-line options into a manifest.

--ad-hoc

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

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

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

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

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

Эта опция может сочетаться с поведением по умолчанию guix environment. Пакеты, которые появляются до --ad-hoc интерпретируются как пакеты, чьи зависимости будут добавлены в окружение (поведение по умолчанию). Пакеты, которые появляются после этой опции, интерпретируются как пакеты, которые будут добавлены в окружение непосредственно.

--profile=profile
-p profile

Create an environment containing the packages installed in profile. Use guix package (see Вызов guix package) to create and manage profiles.

--pure

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

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

Запустить command в изолированном контейнере. Текущая рабочая директория за пределами контейнера отображается внутри контейнера. В дополнение, если это не переопределено опцией --user, тогда настраивается фиктивная домашняя директория, которая совпадает с домашней директорией текущего пользователя, а также соответствующий файл /etc/passwd.

Порождаемый процесс снаружи предстаёт как запущенный от текущего пользователя. Внутри контейнера он имеет такие же UID и GID, что и текущий пользователь, если не обозначена --user (смотрите ниже).

--network
-N

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

--link-profile
-P

Связать профиль окружения контейнера с ~/.guix-profile внутри контейнера. Это эквивалент запуска команды ln -s $GUIX_ENVIRONMENT ~/.guix-profile внутри контейнера. Связывание завершится ошибкой и отменит создание окружения, если директория уже существует, что, конечно, будет происходить, если guix environment вызвана в домашней директории пользователя.

Определённые пакеты сконфигурированы, чтобы смотреть конфигурационные файлы и данные в ~/.guix-profile;15 --link-profile позволяет этим программам вести себя ожидаемо внутри окружения.

--user=user
-u user

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

В дополнение, любой разделяемый или расширяемый путь (смотрите --share и --expose соответственно), чьи цели находятся в домашней директории пользователя, будут отображены соответственно в /home/USER; это включает автоматическое отображение текущей рабочей директории.

# 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

Для контейнеров стандартным поведением является разделение текущего рабочего каталога с изолированным контейнером и немедленное переключение на этот каталог в контейнере. Если это нежелательно, --no-cwd приведет к автоматическому доступу к текущему рабочему каталогу not, который изменится на домашний каталог пользователя в контейнере. Смотрите также --user.

--expose=source[=target]
--share=source[=target]

Расширить файловую систему контейнера источником source из хостящей системы в качестве файловой системы только для чтения с целью target внутри контейнера. Если цель target не задана, источник source используется как целевая точка монтирования в контейнере.

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

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

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


Next: , Previous: , Up: Разработка   [Contents][Index]

8.3 Вызов guix pack

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

Примечание: Если вы ищете способ обмена бинарниками между машинами, работающими с Guix, see Запуск guix copy, Запуск guix publish и Вызов 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 (see Бинарная установка).

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

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

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

Что если получатель вашего пакета не имеет привилегий root на своей машине, и поэтому не может распаковать его в корне файловой системы? В таком случае вам стоит использовать опцию --relocatable (смотрите ниже). Эта опция производит перемещаемые бинарники, в том плане, что они могут размещаться где угодно в иерархии файловой системы: в примере выше пользователи могут распаковать ваш архив в свои домашние директории и напрямую запустить ./opt/gnu/bin/guile.

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

guix pack -f docker guile emacs geiser

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

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

Результатом будет архив, который можно передать команде docker load. Смотрите документацию Docker для подробной информации.

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

guix pack -f squashfs guile emacs geiser

Результатом будет образ файловой системы SquashFS, который может непосредственно монтироваться как образ, содержащий контейнер файловой системы, с помощью контейнерного окружения Singularity, используя команды типа singularity shell или singularity exec.

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

--format=format
-f format

Произвести пакет в указанном формате format.

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

tarball

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

docker

Это производит архив, соответствующий спецификации образа Docker.

squashfs

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

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

guix pack -f squashfs guile emacs geiser

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

deb

This produces a Debian archive (a package with the ‘.deb’ file extension) containing all the specified binaries and symbolic links, that can be installed on top of any dpkg-based GNU(/Linux) distribution. Advanced options can be revealed via the --help-deb-format option. They allow embedding control files for more fine-grained control, such as activating specific triggers or providing a maintainer configure script to run arbitrary setup code upon installation.

guix pack -f deb -C xz -S /usr/bin/hello=bin/hello hello

Примечание: Because archives produced with guix pack contain a collection of store items and because each dpkg package must not have conflicting files, in practice that means you likely won’t be able to install more than one such archive on a given system.

Внимание: dpkg will assume ownership of any files contained in the pack that it does not know about. It is unwise to install Guix-produced ‘.deb’ files on a system where /gnu/store is shared by other software, such as a Guix installation or other, non-deb packs.

--relocatable
-R

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

Когда эта опция передается один раз, конечные двоичные файлы требуют поддержки user namespaces в ядре Linux; при передаче дважды16, 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 дважды. В этом случае двоичные файлы будут пытаться использовать пространство имен пользователей и возвращаться к другому механизму выполнения, если пространства имен пользователей не поддерживаются. Поддерживаются следующие механизмы выполнения:

по умолчанию

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

форматирование кода

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

user

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

chroot

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

chroot

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

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

--commit=commit

Используйте command в качестве точки входа конечного пакета, если формат пакета поддерживает это — в настоящее время docker и squashfs (Singularity) поддерживают это. command должна относиться к профилю, содержащемуся в пакете.

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

guix pack -f docker guile emacs geiser

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

docker load -i pack.tar.gz
docker run image-id
--expression=expr
-e expr

Процедура, при выполнении которой возвращается пакет.

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

--manifest=file
-m file

Использовать пакеты, содержащиеся в объекте манифеста, возвращенном кодом Scheme в file. Эта опция может быть указана несколько раз, и в этом случае манифесты объединяются.

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

See Writing Manifests, for information on how to write a manifest. See guix shell --export-manifest, for information on how to “convert” command-line options into a manifest.

--system=system
-s system

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

--target=triplet

Cross-сборка для triplet, который должен быть допустимым GNU triplet, например \ "aarch64-linux-gnu\" (see GNU configuration triplets in Autoconf).

--compression=tool
-C tool

Архивировать логи сборки методом type. Это один из: gzip, bzip2 или none.

--symlink=spec
-S spec

Добавить в пакет символические ссылки, указанные в spec. Эта опция может быть указана несколько раз.

spec имеет вид source=target, где source - это символическая ссылка, которая будет создана, а target - это цель символьной ссылки.

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

--save-provenance

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

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

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

--root=file
-r file

Создать символическую ссылку file на профиль этого окружения и зарегистрировать её как корень сборщика мусора.

--localstatedir
--profile-name=name

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

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

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

--derivation
-d

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

--bootstrap

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

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


Next: , Previous: , Up: Разработка   [Contents][Index]

8.4 Тулчейн GCC

Guix предлагает индивидуальные пакеты компиляторов, как например, gcc. Но если вам необходим полный набор инструментов (тулчейн) для компиляции и линковки исходного кода, тогда то, что вам действительно нужно, — это пакет gcc-toolchain. Этот пакет предоставляет полный тулчейн GCC для разработки C/C++, включая сам GCC, библиотеку GNU C (заголовки и бинарники, а также отладочные символы в выходе debug), Binutils и набор линковщика.

Цель оболочки — проверять опции -L и -l, направленные линковщику, и соответствующие аргументы -rpath, и вызывать соответствующий линковщик с этим новым набором аргументов. Вы можете указать оболочке отклонять линковку с библиотеками, находящимися не на складе, установив переменную окружения GUIX_LD_WRAPPER_ALLOW_IMPURITIES в значение no.

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


Previous: , Up: Разработка   [Contents][Index]

8.5 Вызов guix package

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

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

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

guix environment options package

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

--extract=directory
-x directory

Открыть репозиторий Git в directory вместо текущего каталога.

--expression=expr
-F free

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

--stats

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

--search=regexp

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

--install-from-file=file

По умолчанию любой коммит, родительский коммит которого не содержит файла .guix-authorizations, считается недостоверным. Напротив, эта опция учитывает авторизацию в file для любого коммита, в котором отсутствует .guix-authorizations. Формат file такой же, как у .guix-authorizations (see .guix-authorizations format).


Next: , Previous: , Up: Top   [Contents][Index]

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

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

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

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

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


Next: , Up: Программный интерфейс   [Contents][Index]

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

С точки зрения программирования, определения пакетов дистрибутива GNU предоставляются модулями Guile в пространстве имен (gnu packages …) 17 (see Guile modules in GNU Guile Reference Manual)). Например, модуль (gnu packages emacs) экспортирует переменную с именем emacs, которая привязана к <package> объекту (see Описание пакетов).

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

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

  1. Добавить каталог, содержащий модули вашего пакета, в пути поиска с помощью флага -L команды guix package и другие команды (see Стандартные параметры сборки) или указать переменную окружения GUIX_PACKAGE_PATH, описанную ниже.
  2. Определить канал и настроить guix pull так, чтобы он учитывал его. Канал - это, по сути, репозиторий Git, содержащий модули пакетов. See Каналы, чтобы узнать больше о том, как определять и использовать каналы.

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

Environment Variable: GUIX_PACKAGE_PATH

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

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


Next: , Previous: , Up: Программный интерфейс   [Contents][Index]

9.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 (list 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 (see Scheme records in GNU Guile Reference Manual). Этот объект пакета можно проверить с помощью процедур из модуля (guix packages); например, (package-name hello) возвращает—сюрприз!—"hello".

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

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

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

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

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

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

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

Процедура Scheme: package-derivation store package [system]

Возвращает the <derivation> объект package для system (see Деривации).

package должен быть допустимым объектом <package>, а system должен быть строкой, обозначающей тип системы—например, "x86_64-linux" для системы GNU на базе x86_64 Linux. store должен быть подключен к демону, который работает с хранилищем (see Хранилище).

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

Процедура Scheme: package-cross-derivation store package target [system] Возвращает <derivation>

объект package cross-собранный из system в target.

target должен быть допустимым GNU triplet’ом, обозначающим желамое оборудование и операционную систему, например "aarch64-linux-gnu" (see Specifying Target Triplets in Autoconf).

Когда у вас есть определения пакетов, вы можете легко определить варианты этих пакетов. См. See Defining Package Variants, чтобы узнать об этом подробнее.


Next: , Up: Описание пакетов   [Contents][Index]

9.2.1 package Ссылка

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

Тип данных: package

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

name

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

версия

The version of the package, as a string. See Номера версий, for guidelines.

источник

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

система сборки

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

arguments (default: '())

The arguments that should be passed to the build system (see Системы сборки). This is a list, typically containing sequential keyword-value pairs, as in this example:

(package
  (name "example")
  ;; several fields omitted
  (arguments
    (list #:tests? #f                     ;skip tests
          #:make-flags #~'("VERBOSE=1")   ;pass flags to 'make'
          #:configure-flags #~'("--enable-frobbing"))))

The exact set of supported keywords depends on the build system (see Системы сборки), but you will find that almost all of them honor #:configure-flags, #:make-flags, #:tests?, and #:phases. The #:phases keyword in particular lets you modify the set of build phases for your package (see Фазы сборки).

inputs (default: '())
native-inputs (default: '())
propagated-inputs (default: '())

These fields list dependencies of the package. Each element of these lists is either a package, origin, or other “file-like object” (see G-Expressions); to specify the output of that file-like object that should be used, pass a two-element list where the second element is the output (see Пакеты со множественным выходом, for more on package outputs). For example, the list below specifies three inputs:

(list libffi libunistring
      `(,glib "bin"))      ;the "bin" output of GLib

In the example above, the "out" output of libffi and libunistring is used.

Compatibility Note: Until version 1.3.0, input lists were a list of tuples, where each tuple has a label for the input (a string) as its first element, a package, origin, or derivation as its second element, and optionally the name of the output thereof that should be used, which defaults to "out". For example, the list below is equivalent to the one above, but using the old input style:

;; Old input style (deprecated).
`(("libffi" ,libffi)
  ("libunistring" ,libunistring)
  ("glib:bin" ,glib "bin"))  ;the "bin" output of GLib

This style is now deprecated; it is still supported but support will be removed in a future version. It should not be used for new package definitions. See Invoking guix style, on how to migrate to the new style.

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

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

Наконец, propagated-inputs похоже на inputs, но указанные пакеты будут автоматически установлены в профили (see the role of profiles in Guix) вместе с пакетом, которому они принадлежат (see guix package, 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"))

Список выходных имен пакета. See Пакеты со множественным выходом, для типичного использования дополнительных выходов.

native-search-paths (default: '())
search-paths (по умолчанию: '())

A list of search-path-specification objects describing search-path environment variables honored by the package. See Search Paths, for more on search path specifications.

As for inputs, the distinction between native-search-paths and search-paths only matters when cross-compiling. In a cross-compilation context, native-search-paths applies exclusively to native inputs whereas search-paths applies only to host inputs.

Packages such as cross-compilers care about target inputs—for instance, our (modified) GCC cross-compiler has CROSS_C_INCLUDE_PATH in search-paths, which allows it to pick .h files for the target system and not those of native inputs. For the majority of packages though, only native-search-paths makes sense.

replacement (по умолчанию: #f)

Это должен быть либо #f, либо объект пакета, который будет использоваться как замена для этого пакета. See grafts, чтобы узнать подробности.

синопсис

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

описание

A more elaborate description of the package, as a string in Texinfo syntax.

лицензия

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

главная страница

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

port (default: 22)

Список систем, поддерживаемых пакетом, в виде строк вида architecture-kernel, например "x86_64-linux".

location (по умолчанию: исходное местоположение формы package)

Исходное расположение пакета. Это полезно переопределить при наследовании от другого пакета, и в этом случае это поле не корректируется автоматически.

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)
                     (list this-package)
                     '())))

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

The following helper procedures are provided to help deal with package inputs.

Scheme Procedure: lookup-package-input package name
Scheme Procedure: lookup-package-native-input package name
Scheme Procedure: lookup-package-propagated-input package name
Scheme Procedure: lookup-package-direct-input package name

Look up name among package’s inputs (or native, propagated, or direct inputs). Return it if found, #f otherwise.

name is the name of a package depended on. Here’s how you might use it:

(use-modules (guix packages) (gnu packages base))

(lookup-package-direct-input coreutils "gmp")
 #<package gmp@6.2.1 …>

In this example we obtain the gmp package that is among the direct inputs of coreutils.

Sometimes you will want to obtain the list of inputs needed to develop a package—all the inputs that are visible when the package is compiled. This is what the package-development-inputs procedure returns.

Scheme Procedure: package-development-inputs package [system] [#:target #f] Return the list of inputs required by

package for development purposes on system. When target is true, return the inputs needed to cross-compile package from system to triplet, where triplet is a triplet such as "aarch64-linux-gnu".

Note that the result includes both explicit inputs and implicit inputs—inputs automatically added by the build system (see Системы сборки). Let us take the hello package to illustrate that:

(use-modules (gnu packages base) (guix packages))

hello
 #<package hello@2.10 gnu/packages/base.scm:79 7f585d4f6790>

(package-direct-inputs hello)
 ()

(package-development-inputs hello)
 (("source" ) ("tar" #<package tar@1.32 …>) )

In this example, package-direct-inputs returns the empty list, because hello has zero explicit dependencies. Conversely, package-development-inputs includes inputs implicitly added by gnu-build-system that are required to build hello: tar, gzip, GCC, libc, Bash, and more. To visualize it, guix graph hello would show you explicit inputs, whereas guix graph -t bag hello would include implicit inputs (see Запуск guix graph).

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

Процедура Scheme: inferior-package-location package

Вернуть вариант 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 вместо значений по умолчанию. Системы сборки, чтобы узнать больше о системах сборки.


Previous: , Up: Описание пакетов   [Contents][Index]

9.2.2 origin Справка

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

Тип данных: origin

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

uri

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

метод

Монадическая процедура, обрабатывающая данный URI. Процедура должна принимать по крайней мере три аргумента: значение поля uri, а также алгоритм хеширования и значение хеш-функции, указанные в поле hash. Она должна возвращать элемент store или derivation в store монаде (see Устройство склада); большинство методов возвращают derivation с фиксированным выводом (see Деривации).

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

sha256

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

hash

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

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

file-name (по умолчанию: #f)

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

patches (по умолчанию: '())

Список имен файлов, источников или объектов подобных файлами (see file-like objects), указывающих на исправления, которые будут применены к источнику.

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

snippet (по умолчанию: #f)

G-выражение (see 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, или может быть байтовым вектором.

Следующие зависимости необязательны:

(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: lookup-inferior-packages inferior name [name] [#:executable? #f] Возвращает derivation с фиксированным выводом,

которая извлекает данные из url (строка или список строк, обозначающих альтернативные URL-адреса), который, как ожидается, будет иметь хэш hash типа hash-algo (символ). По умолчанию имя файла - это базовое имя URL-адреса; при желании name может указывать другое имя файла. Если executable? истинно, загруженный файл будет исполняемым.

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

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

Аналогичным образом, модуль (guix git-download) определяет метод источника git-download, который извлекает данные из репозитория управления версиями Git, и тип данных git-reference для описания репозиторий и ревизия для загрузки.

Scheme Procedure: mixed-text-file name text

Вернуть derivation с фиксированным выводом, которая выбирает объект ref, <git-reference>. Ожидается, что на выходе будет рекурсивный хеш hash типа hash-algo (символ). Использовать name в качестве имени файла или общее имя, если #f.

Тип данных: build-machine

Управление конфигурацией операционной системы.

url

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

commit

This string denotes either the commit to fetch (a hexadecimal string), or the tag to fetch. You can also use a “short” commit ID or a git describe style identifier such as v1.0.1-10-g58d7909c97.

features (default: '())

Это логическое значение (boolean) указывает, нужно ли рекурсивно получать подмодули Git.

Пример ниже обозначает тег 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"))

Для репозиториев Mercurial, модуль (guix hg-download) определяет метод hg-fetch и тип данных hg-reference для поддержки системы контроля версий Mercurial.

Scheme Procedure: mixed-text-file name text

Вернуть derivation с фиксированным выводом, которая выбирает объект ref, <git-reference>. Ожидается, что на выходе будет рекурсивный хеш hash типа hash-algo (символ). Использовать name в качестве имени файла или общее имя, если #f.


Next: , Previous: , Up: Программный интерфейс   [Contents][Index]

9.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 (see Параметры преобразования пакета). This section describes how to define package variants in code. This can be useful in “manifests” (see Writing Manifests) and in your own package collection (see Создание канала), among others!

Как обсуждалось ранее, пакеты—это объекты первого класса на языке Scheme. Модуль (guix packages) предоставляет конструкцию package для определения новых объектов пакета (see ссылка на пакет). Самый простой способ определить вариант пакета—использовать ключевое слово inherit вместе с package. Это позволяет вам наследовать от определения пакета, переопределяя нужные поля.

Например, учитывая переменную hello, которая содержит определение для текущей версии GNU Hello, вот как вы могли бы определить вариант для версии 2.2 (выпущенной в 2006 году, это винтаж!):

(use-modules (gnu packages guile))  ;for 'guile-json'

(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"))))))

Приведенный выше пример соответствует тому, что делает опция преобразования пакета --with-source. По сути, hello-2.2 сохраняет все поля hello, кроме version и source, которые переопределяется. Обратите внимание, что исходная переменная hello все еще присутствует в модуле (gnu packages base) без изменений. Когда вы определяете собственный пакет таким образом, вы на самом деле добавляете новое определение пакета; оригинал остается доступным.

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

(use-modules (gnu packages gdb))   ;for 'gdb'

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

The modify-inputs form above removes the "guile" package from the inputs field of gdb. The modify-inputs macro is a helper that can prove useful anytime you want to remove, add, or replace package inputs.

Scheme Syntax: modify-inputs inputs clauses

Modify the given package inputs, as returned by package-inputs & co., according to the given clauses. Each clause must have one of the following forms:

(delete name…)

Delete from the inputs packages with the given names (strings).

(append package…)

Add packages to the end of the input list.

(prepend package…)

Add packages to the front of the input list.

The example below removes the GMP and ACL inputs of Coreutils and adds libcap to the back of the input list:

(modify-inputs (package-inputs coreutils)
  (delete "gmp" "acl")
  (append libcap))

The example below replaces the guile package from the inputs of guile-redis with guile-2.2:

(modify-inputs (package-inputs guile-redis)
  (replace "guile" guile-2.2))

The last type of clause is prepend, to add inputs to the front of the list.

В некоторых случаях вам может быть полезно написать функции (“процедуры” Scheme), которые возвращают пакет на основе некоторых параметров. Например, рассмотрим библиотеку luasocket для языка программирования Lua. Мы хотим создать пакеты luasocket для основных версий Lua. Один из способов сделать это—определить процедуру, которая принимает пакет Lua и возвращает зависящий от него пакет luasocket:

(define (make-lua-socket name lua)
  ;; Return a luasocket package built with LUA.
  (package
    (name name)
    (version "3.0")
    ;; several fields omitted
    (inputs (list 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))

Здесь мы определили пакеты lua5.1-socket и lua5.2-socket, вызвав make-lua-socket с разными аргументами. См. See Procedures in GNU Guile Reference Manual, для получения дополнительной информации о процедурах. Наличие общедоступных определений верхнего уровня для этих двух пакетов означает, что на них можно ссылаться из командной строки (see Пакетные модули).

Это довольно простые варианты пакета. Для удобства модуль (guix transformations) предоставляет высокоуровневый интерфейс, который напрямую сопоставляется с более сложными параметрами преобразования пакетов (see Параметры преобразования пакета):

Процедура Scheme: open-inferior directory Возвращает процедуру, которая при передаче объекта для сборки (пакета,

производной и т. д.), применяет преобразования, указанные в opts, и возвращает результирующие объекты. opts должен быть списком пар символ/строка, например:

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

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

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

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

Вывод должен быть таким:

(use-package-modules guile emacs)

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

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

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

Перезапись графа зависимостей для замены пакетов в графе реализуется процедурой package-input-rewriting в (guix packages).

Процедура 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 (see --with-input).

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

Процедура Scheme: inferior-package-inputs package

Возвращает процедуру, которая для данного пакета применяет заданные 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: inferior-package-location package

Вернуть процедуру, которая для данного пакета применяет proc ко всем зависимым пакетам и возвращает полученный пакет. Процедура останавливает рекурсию, когда cut? возвращает истину для данного пакета. Когда deep? истинно, proc также применяется к неявным входным данным.


Next: , Previous: , Up: Программный интерфейс   [Contents][Index]

9.4 Writing Manifests

guix commands let you specify package lists on the command line. This is convenient, but as the command line becomes longer and less trivial, it quickly becomes more convenient to have that package list in what we call a manifest. A manifest is some sort of a “bill of materials” that defines a package set. You would typically come up with a code snippet that builds the manifest, store it in a file, say manifest.scm, and then pass that file to the -m (or --manifest) option that many guix commands support. For example, here’s what a manifest for a simple package set might look like:

;; Manifest for three packages.
(specifications->manifest '("gcc-toolchain" "make" "git"))

Once you have that manifest, you can pass it, for example, to guix package to install just those three packages to your profile (see -m option of guix package):

guix package -m manifest.scm

... or you can pass it to guix shell (see -m option of guix shell) to spawn an ephemeral environment:

guix shell -m manifest.scm

... or you can pass it to guix pack in pretty much the same way (see -m option of guix pack). You can store the manifest under version control, share it with others so they can easily get set up, etc.

But how do you write your first manifest? To get started, maybe you’ll want to write a manifest that mirrors what you already have in a profile. Rather than start from a blank page, guix package can generate a manifest for you (see guix package --export-manifest):

# Write to 'manifest.scm' a manifest corresponding to the
# default profile, ~/.guix-profile.
guix package --export-manifest > manifest.scm

Or maybe you’ll want to “translate” command-line arguments into a manifest. In that case, guix shell can help (see guix shell --export-manifest):

# Write a manifest for the packages specified on the command line.
guix shell --export-manifest gcc-toolchain make git > manifest.scm

In both cases, the --export-manifest option tries hard to generate a faithful manifest; in particular, it takes package transformation options into account (see Параметры преобразования пакета).

Примечание: Manifests are symbolic: they refer to packages of the channels currently in use (see Каналы). In the example above, gcc-toolchain might refer to version 11 today, but it might refer to version 13 two years from now.

If you want to “pin” your software environment to specific package versions and variants, you need an additional piece of information: the list of channel revisions in use, as returned by guix describe. See Копирование Guix, for more information.

Once you’ve obtained your first manifest, perhaps you’ll want to customize it. Since your manifest is code, you now have access to all the Guix programming interfaces!

Let’s assume you want a manifest to deploy a custom variant of GDB, the GNU Debugger, that does not depend on Guile, together with another package. Building on the example seen in the previous section (see Defining Package Variants), you can write a manifest along these lines:

(use-modules (guix packages)
             (gnu packages gdb)               ;for 'gdb'
             (gnu packages version-control))  ;for 'git'

;; Define a variant of GDB without a dependency on Guile.
(define gdb-sans-guile
  (package
    (inherit gdb)
    (inputs (modify-inputs (package-inputs gdb)
              (delete "guile")))))

;; Return a manifest containing that one package plus Git.
(packages->manifest (list gdb-sans-guile git))

Note that in this example, the manifest directly refers to the gdb and git variables, which are bound to a package object (see ссылка на пакет), instead of calling specifications->manifest to look up packages by name as we did before. The use-modules form at the top lets us access the core package interface (see Описание пакетов) and the modules that define gdb and git (see Пакетные модули). Seamlessly, we’re weaving all this together—the possibilities are endless, unleash your creativity!

The data type for manifests as well as supporting procedures are defined in the (guix profiles) module, which is automatically available to code passed to -m. The reference follows.

Data Type: manifest

Data type representing a manifest.

It currently has one field:

entries

This must be a list of manifest-entry records—see below.

Data Type: manifest-entry

Data type representing a manifest entry. A manifest entry contains essential metadata: a name and version string, the object (usually a package) for that entry, the desired output (see Пакеты со множественным выходом), and a number of optional pieces of information detailed below.

Most of the time, you won’t build a manifest entry directly; instead, you will pass a package to package->manifest-entry, described below. In some unusual cases though, you might want to create manifest entries for things that are not packages, as in this example:

;; Manually build a single manifest entry for a non-package object.
(let ((hello (program-file "hello" #~(display "Hi!"))))
  (manifest-entry
    (name "foo")
    (version "42")
    (item
     (computed-file "hello-directory"
                     #~(let ((bin (string-append #$output "/bin")))
                         (mkdir #$output) (mkdir bin)
                          (symlink #$hello
                                   (string-append bin "/hello")))))))

The available fields are the following:

name
версия

Name and version string for this entry.

item

A package or other file-like object (see file-like objects).

output (default: "out")

Output of item to use, in case item has multiple outputs (see Пакеты со множественным выходом).

dependencies (default: '())

List of manifest entries this entry depends on. When building a profile, dependencies are added to the profile.

Typically, the propagated inputs of a package (see propagated-inputs) end up having a corresponding manifest entry in among the dependencies of the package’s own manifest entry.

search-paths (по умолчанию: '())

The list of search path specifications honored by this entry (see Search Paths).

properties (default: '())

List of symbol/value pairs. When building a profile, those properties get serialized.

This can be used to piggyback additional metadata—e.g., the transformations applied to a package (see Параметры преобразования пакета).

parent (default: (delay #f))

A promise pointing to the “parent” manifest entry.

This is used as a hint to provide context when reporting an error related to a manifest entry coming from a dependencies field.

Scheme Procedure: concatenate-manifests lst

Concatenate the manifests listed in lst and return the resulting manifest.

Scheme Procedure: package->manifest-entry package [output] [#:properties] Return a manifest entry for the output

of package package, where output defaults to "out", and with the given properties. By default properties is the empty list or, if one or more package transformations were applied to package, it is an association list representing those transformations, suitable as an argument to options->transformation (see options->transformation).

The code snippet below builds a manifest with an entry for the default output and the send-email output of the git package:

(use-modules (gnu packages version-control))

(manifest (list (package->manifest-entry git)
                (package->manifest-entry git "send-email")))
Scheme Procedure: packages->manifest packages

Return a list of manifest entries, one for each item listed in packages. Elements of packages can be either package objects or package/string tuples denoting a specific output of a package.

Using this procedure, the manifest above may be rewritten more concisely:

(use-modules (gnu packages version-control))

(packages->manifest (list git `(,git "send-email")))
Scheme Procedure: package->development-manifest package [system] [#:target] Return a manifest for the development inputs

of package for system, optionally when cross-compiling to target. Development inputs include both explicit and implicit inputs of package.

Like the -D option of guix shell (see guix shell -D), the resulting manifest describes the environment in which one can develop package. For example, suppose you’re willing to set up a development environment for Inkscape, with the addition of Git for version control; you can describe that “bill of materials” with the following manifest:

(use-modules (gnu packages inkscape)          ;for 'inkscape'
             (gnu packages version-control))  ;for 'git'

(concatenate-manifests
 (list (package->development-manifest inkscape)
       (packages->manifest (list git))))

In this example, the development manifest that package->development-manifest returns includes the compiler (GCC), the many supporting libraries (Boost, GLib, GTK, etc.), and a couple of additional development tools—these are the dependencies guix show inkscape lists.

Last, the (gnu packages) module provides higher-level facilities to build manifests. In particular, it lets you look up packages by name—see below.

Scheme Procedure: specifications->manifest specs

Given specs, a list of specifications such as "emacs@25.2" or "guile:debug", return a manifest. Specs have the format that command-line tools such as guix install and guix package understand (see Вызов guix package).

As an example, it lets you rewrite the Git manifest that we saw earlier like this:

(specifications->manifest '("git" "git:send-email"))

Notice that we do not need to worry about use-modules, importing the right set of modules, and referring to the right variables. Instead, we directly refer to packages in the same way as on the command line, which can often be more convenient.


Next: , Previous: , Up: Программный интерфейс   [Contents][Index]

9.5 Системы сборки

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

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

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

Системы сборки принимают необязательный список из arguments. В определениях пакетов они передаются через поле arguments (see Описание пакетов). Обычно это аргументы ключевого слова (see keyword arguments in Guile in GNU Guile Reference Manual). Значение этих аргументов обычно оценивается в build stratum—то есть процессом Guile, запущенным демоном (see Деривации).

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

Scheme Variable: gnu-build-system

gnu-build-system представляет систему сборки GNU и ее варианты (see configuration and makefile conventions in GNU Coding Standards).

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

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

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

build phases

Считать список каналов из файла file вместо ~/.config/guix/channels.scm. file должен содержать код Scheme, который определяет список объектов "канал". См. See Каналы для подробной информации.

Конфигурирование системы

Это список флагов (строк), переданных в сценарий (script) configure. См. See Описание пакетов.

#:make-flags

Этот список строк содержит флаги, передаваемые в качестве аргументов для вызовов make на этапах build, check и install.

#:out-of-source?

Это логическое значение, #f по умолчанию, указывает, следует ли запускать сборки в каталоге сборки отдельно от исходников.

Когда это значение истинно, на этапе configure создается отдельный каталог сборки, происходит переход в этот каталог и оттуда запускается сценарий configure. Это полезно для пакетов, которым это необходимо, таких как 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 (see --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. See the validate-runpath phase, for details.

#: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 (see Подстановки).

--references
--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 (see Запуск 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.

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

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

Параметр #:main-class можно использовать с минимальным файлом сборки ant для указания основного класса результирующего jar-файла. Это делает файл jar исполняемым. Параметр #:test-include можно использовать для указания списка запускаемых тестов junit. По умолчанию это (list "**/*Test.java"). #:test-exclude можно использовать для отключения некоторых тестов. По умолчанию это (list "**/Abstract*.java"), потому что абстрактные классы не могут быть запущены как тесты.

Параметр #: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

Эти переменные, экспортированные (guix build-system asdf), реализуют процедуры сборки для пакетов Common Lisp с использованием “ASDF”. ASDF - это средство определения системы для программ и библиотек Common Lisp.

Система asdf-build-system/source устанавливает пакеты в исходной форме и может быть загружена с использованием любой распространенной реализации Lisp через ASDF. Другие, такие как asdf-build-system/sbcl, устанавливают двоичные системы в формате, понятном конкретной реализации. Эти системы сборки также могут использоваться для создания исполняемых программ или образов lisp, которые содержат набор предварительно загруженных пакетов.

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

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

Для создания исполняемых программ и образов можно использовать процедуры сборки build-program и build-image. Их следует вызывать в фазе сборки после фазы create-symlinks, чтобы только что созданную систему можно было использовать в полученном образе. build-program требует, чтобы список выражений Common Lisp был передан в качестве аргумента #:entry-program.

Если система не определена в собственном файле .asd с тем же именем, тогда следует использовать параметр #:asd-file, чтобы указать, в каком файле определена система. Кроме того, если пакет определяет систему для своих тестов в отдельном файле, он будет загружен перед запуском тестов, если он указан параметром #:test-asd-file. Если он не установлен, будут попробованы файлы <system>-tests.asd, <system>-test.asd, tests.asd и test.asd, если они есть.

Если по какой-то причине пакет должен быть назван иначе, чем это предлагается в соглашениях об именах, можно использовать параметр #:asd-system-name для указания имени системы.

Scheme Variable: cargo-build-system

Эта переменная экспортируется (guix build-system cargo). Она поддерживает сборку пакетов с использованием Cargo, инструмента сборки языка программирования Rust.

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

Обычные cargo зависимости должны быть добавлены к определению пакета через параметр #:cargo-inputs в виде списка пар имени и спецификации, где спецификацией может быть определение пакета или источника. Обратите внимание, что в спецификации должен быть указан путь к сжатому архиву, который содержит файл Cargo.toml в своем корне, иначе он будет проигнорирован. Точно так же dev-зависимости cargo должны быть добавлены в определение пакета с помощью параметра #:cargo-development-inputs.

На этапе configure эта система сборки собирет любые исходные данные, указанные в параметрах #:cargo-inputs и #:cargo-development-inputs, доступными для cargo. Она также удалит файл Cargo.lock, который будет воссоздан cargo на этапе build. На этапе install устанавливаются двоичные файлы, определенные crate.

Scheme переменная: cmake-build-system

This variable is exported by (guix build-system chicken). It builds CHICKEN Scheme 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.

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

(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 необязательны.

Примеры:

Scheme Variable: clojure-build-system

Эта переменная экспортируется (guix build-system clojure). Она реализует простую процедуру сборки пакетов Clojure с использованием простого старого 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.

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

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

Scheme переменная: dune-build-system

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

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

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

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

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

Scheme variable: elm-build-system

This variable is exported by (guix build-system elm). It implements a build procedure for Elm packages similar to ‘elm install’.

The build system adds an Elm compiler package to the set of inputs. The default compiler package (currently elm-sans-reactor) can be overridden using the #:elm argument. Additionally, Elm packages needed by the build system itself are added as implicit inputs if they are not already present: to suppress this behavior, use the #:implicit-elm-package-inputs? argument, which is primarily useful for bootstrapping.

The "dependencies" and "test-dependencies" in an Elm package’s elm.json file correspond to propagated-inputs and inputs, respectively.

Elm requires a particular structure for package names: see Elm Packages for more details, including utilities provided by (guix build-system elm).

There are currently a few noteworthy limitations to elm-build-system:

Scheme переменная: go-build-system

Эта переменная экспортируется (guix build-system go). Онf реализует процедуру сборки пакетов Go с использованием стандартного механизмов сборки Go.

Ожидается, что пользователь предоставит значение для ключа #:import-path и, в некоторых случаях, #:unpack-path. import path соответствует пути к файловой системе, ожидаемому сценариями сборки пакета и любыми ссылочными пакетами, и обеспечивает уникальный способ ссылки на Go пакет. Обычно он основан на комбинации удаленного URI исходного кода пакета и иерархической структуры файловой системы. В некоторых случаях вам нужно будет распаковать исходный код пакета в другую структуру каталогов, отличную от той, которая указана в пути импорта, и в таких случаях следует использовать #:unpack-path.

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

Packages can be cross-built, and if a specific architecture or operating system is desired then the keywords #:goarch and #:goos can be used to force the package to be built for that architecture and operating system. The combinations known to Go can be found in their documentation.

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+. Это достигается путем включения программ в сценарии запуска, которые соответствующим образом устанавливают переменные среды 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 в GLib скомпилированы. Компиляция выполняется программой glib-compile-schemas. Она предоставляется пакетом glib:bin, который автоматически импортируется системой сборки. Пакет glib, предоставляющий glib-compile-schemas, можно указать с помощью параметра #:glib.

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

Scheme переменная: guile-build-system

Эта система сборки предназначена для пакетов Guile, которые состоят исключительно из кода Scheme и настолько скудны, что у них даже нет make-файла, не говоря уже о сценарии configure. Она компилирует Scheme код с помощью guild compile (see Compilation in GNU Guile Reference Manual) и устанавливает файлы .scm и .go в нужное место. Она также устанавливает документацию.

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

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

Scheme переменная: julia-build-system

Эта переменная экспортируется в (guix build-system julia). Она реализует процедуру сборки, используемую пакетами julia, которая по сути аналогична запуску ‘julia -e 'используя Pkg; Pkg.add(package)'’ в среде, где JULIA_LOAD_PATH содержит пути ко всем входным данным пакета Julia. Тесты запускаются с Pkg.test.

The Julia package name and uuid is read from the file Project.toml. These values can be overridden by passing the argument #:julia-package-name (which must be correctly capitalized) or #:julia-package-uuid.

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 (see Фазы сборки) 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 Project.toml yet, will require this file to be created, too. It is internally done if the arguments #:julia-package-name and #:julia-package-uuid are provided.

Scheme Variable: ant-build-system

Эта переменная экспортируется в (guix build-system maven). Она реализует процедуру сборки пакетов Maven. 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 переменная: minetest-mod-build-system

This variable is exported by (guix build-system minetest). It implements a build procedure for Minetest mods, which consists of copying Lua code, images and other resources to the location Minetest searches for mods. The build system also minimises PNG images and verifies that Minetest can load the mod without errors.

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, которая заключается в выборе правильного набора команд для запуска для каждого пакета. Пакеты OCaml могут ожидать выполнения множества различных команд. Эта система сборки попробует некоторые из них.

Если в пакете есть файл setup.ml на верхнем уровне, он будет запускать ocaml setup.ml -configure, ocaml setup.ml -build и ocaml setup.ml -install. Система сборки предполагает, что этот файл был сгенерирован OASIS, и позаботится об установке префикса и включении тестов, если они не отключены. Вы можете передать флаги конфигурации и сборки с помощью #: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/….

For packages that install stand-alone Python programs under bin/, it takes care of wrapping these programs so that their GUIX_PYTHONPATH environment variable points to all the Python libraries they depend on.

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

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

If a "python" output is available, the package is installed into it instead of the default "out" output. This is useful for packages that include a Python package as only a part of the software, and thus want to combine the phases of python-build-system with another build system. Python bindings are a common usecase.

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: r-build-system

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

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, которая, по сути, немного больше, чем запуск ‘R CMD INSTALL --library=/gnu/store/…’ в среде, где R_LIBS_SITE содержит пути ко всем входам пакета R. Тесты запускаются после установки с использованием R-функции tools::testInstalledPackage.

Scheme переменная: rakudo-build-system

Эта переменная экспортируется (guix build-system rakudo). Которая реализует систем сборки, используемую Rakudo для Perl6 пакетов. Она устанавливает: пакет в /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 Variable: rebar-build-system

This variable is exported by (guix build-system rebar). It implements a build procedure around rebar3, a build system for programs written in the Erlang language.

It adds both rebar3 and the erlang to the set of inputs. Different packages can be specified with the #:rebar and #:erlang parameters, respectively.

This build system is based on gnu-build-system, but with the following phases changed:

unpack

This phase, after unpacking the source like the gnu-build-system does, checks for a file contents.tar.gz at the top-level of the source. If this file exists, it will be unpacked, too. This eases handling of package hosted at https://hex.pm/, the Erlang and Elixir package repository.

bootstrap
configure

There are no bootstrap and configure phase because erlang packages typically don’t need to be configured.

build

This phase runs rebar3 compile with the flags listed in #:rebar-flags.

check

Unless #:tests? #f is passed, this phase runs rebar3 eunit, or some other target specified with #:test-target, with the flags listed in #:rebar-flags,

установка

This installs the files created in the default profile, or some other profile specified with #:install-profile.

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 (see Packages in The GNU Emacs Manual).

Сначала она создает файл 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 в качестве своей системы сборки.

It adds both Meson and Ninja to the set of inputs, and they can be changed with the parameters #:meson and #:ninja if needed.

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

configure

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

build

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

check

The phase runs ‘meson test’ with a base set of options that cannot be overridden. This base set of options can be extended via the #:test-options argument, for example to select or skip a specific test suite.

установка

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

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

fix-runpath

This phase ensures that all binaries can find the libraries they need. It searches for required libraries in subdirectories of the package being built, and adds those to RUNPATH where needed. It also removes references to libraries left over from the build phase by meson, such as test dependencies, that aren’t actually required for the program to run.

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, которая реализует аппроксимацию команды npm install, за которой следует команда npm test.

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

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

Scheme переменная: trivial-build-system

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

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

Scheme Variable: channel-build-system

This variable is exported by (guix build-system channel).

This build system is meant primarily for internal use. A package using this build system must have a channel specification as its source field (see Каналы); alternatively, its source can be a directory name, in which case an additional #:commit argument must be supplied to specify the commit being built (a hexadecimal string).

The resulting package is a Guix instance of the given channel, similar to how guix time-machine would build it.


Next: , Previous: , Up: Программный интерфейс   [Contents][Index]

9.6 Фазы сборки

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

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:

set-paths

Define search path environment variables for all the input packages, including PATH (see Search Paths).

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, если они доступны (see Установка файлов отладки).

validate-runpath

Validate the RUNPATH of ELF binaries, unless #:validate-runpath? is false (see Системы сборки).

This validation step consists in making sure that all the shared libraries needed by an ELF binary, 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. See -rpath in The GNU Linker, for more information on RUNPATH.

Как обсуждалось в предыдущем разделе, эти системы сборки предоставляют стандартный список фаз. Для gnu-build-system стандартные фазы включают фазу unpack для распаковки архива исходного кода, фазу configure для запуска ./configure, build фаза для запуска make и (среди прочего) фазу install для запуска make install; see Системы сборки, чтобы получить более подробное представление об этих фазах. Точно так же cmake-build-system наследует эти фазы, но его фаза configure запускает cmake вместо ./configure. Другие системы сборки, такие как python-build-system, имеют совершенно другой список стандартных фаз. Весь этот код выполняется на build side: он выполняется, когда вы фактически собираете пакет, в отдельном процессе сборки, порожденном демоном сборки (see Вызов guix-daemon).

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

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

;; 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 определяется как список пар символ/процедура (see Pairs in GNU Guile Reference Manual). Первая пара связывает процедуру unpack с символом unpack—именем; вторая пара аналогичным образом определяет фазу configure и так далее. При сборке пакета, который использует gnu-build-system со списком фаз по умолчанию, эти фазы выполняются последовательно. Вы можете увидеть название каждой фазы, запущенной и завершенной, в журнале сборки пакетов, которые вы собираете.

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

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

Список фаз, используемых для конкретного пакета, можно изменить с помощью параметра #:phase системы сборки. Изменение набора фаз сборки сводится к созданию нового списка фаз на основе списка %standard-phase, описанного выше. Это можно сделать с помощью стандартных процедур списков, таких как alist-delete (see SRFI-1 Association Lists in GNU Guile Reference Manual); однако это удобнее делать с помощью modify-phase (see 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")))))))))))

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

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


Next: , Previous: , Up: Программный интерфейс   [Contents][Index]

9.7 Build Utilities

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

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

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

(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).

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

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

Процедура Scheme: sane-service-type

Проверить целостность склада.

Scheme Procedure: file-union name files

Возвращает true, если объект obj — это пакет ранней версии.

Scheme Procedure: file-union name files

Удалиnm /gnu/store и хэш из file, имени файла в store. Результатом обычно является строка "package-version".

Процедура Scheme: inferior-package-version package

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

9.7.2 Файловые системы

Процедуры, приведённые ниже, обеспечивают работу и управление ранними версиями пакетов.

Scheme Procedure: directory-union name things

Вернуть #t, если dir существует и является каталогом.

Scheme Procedure: file-union name files

Вернуть #t, если file существует и исполняемый файл.

Scheme Procedure: file-union name files

Вернуть #t, если file является символической ссылкой (также известной как “символическая ссылка”).

Scheme Procedure: file-union name files
Scheme Procedure: file-union name files
Scheme Procedure: file-union name files

Вернуть #t, если file является, соответственно, файлом ELF, архивом ar (например, статической библиотекой .a) или файлом gzip.

Процедура Scheme: inferior-package-inputs package

Если file является файлом gzip, сбросить его timestamp (как в случае gzip --no-name) и вернуть истину. В противном случае вернуть #f. Когда keep-mtime? истинна, сохранить время модификации file.

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

Следующие процедуры и макросы помогают создавать, изменять и удалять файлы. Они обеспечивают функциональность, сопоставимую с такими обычными утилитами оболочки, как mkdir -p, cp -r, rm -r и sed. Они дополняют обширный, но низкоуровневый интерфейс файловой системы Guile (see POSIX in GNU Guile Reference Manual).

Scheme Syntax: let-system system body

Запустить body с directory в качестве текущего каталога процесса.

По сути, этот макрос изменяет текущий каталог на directory перед вычислением body, используя chdir (see Processes in GNU Guile Reference Manual). Она возвращается в исходный каталог, когда остается динамический extent body, будь то через возврат нормальной процедуры или через нелокальный выход, такой как исключение.

Процедура Scheme: inferior-packages inferior

Создать каталог dir и всех его предков.

Процедура Scheme: open-inferior directory Создать каталог, если он не существует, и скопировать туда file

под тем же именем.

Scheme Procedure: file-union name files

Сделать file доступным для записи его владельцу.

Scheme Procedure: lookup-inferior-packages inferior name [#:log (current-output-port)] [#:follow-symlinks? #f]  [#:copy-file

copy-file] [#:keep-mtime? #f] [#:keep-permissions? #t] Copy source directory to destination. Follow symlinks if follow-symlinks? is true; otherwise, just preserve them. Call copy-file to copy regular files. When keep-mtime? is true, keep the modification time of the files in source on those of destination. When keep-permissions? is true, preserve file permissions. Write verbose output to the log port.

Процедура Scheme: open-inferior directory [#:follow-mounts? #f] dir рекурсивно, как rm -rf, без

использования символических ссылок. Также не следовать точкам монтирования, если follow-mounts? не истинна. Сообщать об ошибках, но игнорировать их.

Scheme Syntax: let-system system body

((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" letters end)))

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

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

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

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

9.7.4 Файловые системы

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

Процедура Scheme: inferior-package? obj

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

Процедура Scheme: lookup-inferior-packages inferior name [#: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: inferior-packages inferior

Вернуть полное имя файла для program, как в $PATH, или #f, если program не найдена.

Scheme Procedure: search-input-file inputs name
Scheme Procedure: search-input-directory inputs name

Return the complete file name for name as found in inputs; search-input-file searches for a regular file and search-input-directory searches for a directory. If name could not be found, an exception is raised.

Here, inputs must be an association list like inputs and native-inputs as available to build phases (see Фазы сборки).

Here is a (simplified) example of how search-input-file is used in a build phase of the wireguard-tools package:

(add-after 'install 'wrap-wg-quick
  (lambda* (#:key inputs outputs #:allow-other-keys)
    (let ((coreutils (string-append (assoc-ref inputs "coreutils")
                                    "/bin")))
      (wrap-program (search-input-file outputs "bin/wg-quick")
        #:sh (search-input-file inputs "bin/bash")
        `("PATH" ":" prefix ,(list coreutils))))))

9.7.5 Program Invocation

You’ll find handy procedures to spawn processes in this module, essentially convenient wrappers around Guile’s system* (see system* in GNU Guile Reference Manual).

Scheme Procedure: invoke program args

Invoke program with the given args. Raise an &invoke-error exception if the exit code is non-zero; otherwise return #t.

The advantage compared to system* is that you do not need to check the return value. This reduces boilerplate in shell-script-like snippets for instance in package build phases.

Scheme Procedure: invoke-error? c

Return true if c is an &invoke-error condition.

Scheme Procedure: invoke-error-program c
Scheme Procedure: invoke-error-arguments c
Scheme Procedure: invoke-error-exit-status c
Scheme Procedure: invoke-error-term-signal c
Scheme Procedure: invoke-error-stop-signal c

Access specific fields of c, an &invoke-error condition.

Scheme Procedure: report-invoke-error c [port]

Report to port (by default the current error port) about c, an &invoke-error condition, in a human-friendly way.

Typical usage would look like this:

(use-modules (srfi srfi-34) ;for 'guard'
             (guix build utils))

(guard (c ((invoke-error? c)
           (report-invoke-error c)))
  (invoke "date" "--imaginary-option"))

-| command "date" "--imaginary-option" failed with status 1
Scheme Procedure: invoke/quiet program args

Invoke program with args and capture program’s standard output and standard error. If program succeeds, print nothing and return the unspecified value; otherwise, raise a &message error condition that includes the status code and the output of program.

Here’s an example:

(use-modules (srfi srfi-34) ;for 'guard'
             (srfi srfi-35) ;for 'message-condition?'
             (guix build utils))

(guard (c ((message-condition? c)
           (display (condition-message c))))
  (invoke/quiet "date")  ;all is fine
  (invoke/quiet "date" "--imaginary-option"))

-| 'date --imaginary-option' exited with status 1; output follows:

    date: unrecognized option '--imaginary-option'
    Try 'date --help' for more information.

9.7.6 Фазы сборки

(guix build utils) также содержит инструменты для управления фазами сборки, которые используются системами сборки (see Системы сборки). Фазы сборки представлены в виде ассоциативных списков или “alists” (see Association Lists in GNU Guile Reference Manual), где каждый ключ представляет собой символ, обозначающий фазу, а связанное значение представляет собой процедуру (see Фазы сборки).

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

Scheme Syntax: let-system system body

Изменить 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 и игнорирует дополнительные аргументы ключевого слова (see Optional Arguments in GNU Guile Reference Manual, 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")))))))

В приведенном ниже примере фазы изменяются двумя способами: стандартная фаза 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)))))

9.7.7 Wrappers

It is not unusual for a command to require certain environment variables to be set for proper functioning, typically search paths (see Search Paths). Failing to do that, the command might fail to find files or other commands it relies on, or it might pick the “wrong” ones—depending on the environment in which it runs. Examples include:

For a package writer, the goal is to make sure commands always work the same rather than depend on some external settings. One way to achieve that is to wrap commands in a thin script that sets those environment variables, thereby ensuring that those run-time dependencies are always found. The wrapper would be used to set PATH, GUILE_LOAD_PATH, or QT_PLUGIN_PATH in the examples above.

To ease that task, the (guix build utils) module provides a couple of helpers to wrap commands.

Scheme Procedure: wrap-program program [#:sh sh] [#:rest variables] Make a wrapper for program.

variables should look like this:

'(variable delimiter position list-of-directories)

where delimiter is optional. : will be used if delimiter is not given.

For example, this call:

(wrap-program "foo"
              '("PATH" ":" = ("/gnu/.../bar/bin"))
              '("CERT_PATH" suffix ("/gnu/.../baz/certs"
                                    "/qux/certs")))

will copy foo to .foo-real and create the file foo with the following contents:

#!location/of/bin/bash
export PATH="/gnu/.../bar/bin"
export CERT_PATH="$CERT_PATH${CERT_PATH:+:}/gnu/.../baz/certs:/qux/certs"
exec -a $0 location/of/.foo-real "$@"

If program has previously been wrapped by wrap-program, the wrapper is extended with definitions for variables. If it is not, sh will be used as the interpreter.

Scheme Procedure: wrap-script program [#:guile guile] [#:rest variables] Wrap the script program

such that variables are set first. The format of variables is the same as in the wrap-program procedure. This procedure differs from wrap-program in that it does not create a separate shell script. Instead, program is modified directly by prepending a Guile script, which is interpreted as a comment in the script’s language.

Special encoding comments as supported by Python are recreated on the second line.

Note that this procedure can only be used once per file as Guile scripts are not supported.


Next: , Previous: , Up: Программный интерфейс   [Contents][Index]

9.8 Search Paths

Many programs and libraries look for input data in a search path, a list of directories: shells like Bash look for executables in the command search path, a C compiler looks for .h files in its header search path, the Python interpreter looks for .py files in its search path, the spell checker has a search path for dictionaries, and so on.

Search paths can usually be defined or overridden via environment variables (see Environment Variables in The GNU C Library Reference Manual). For example, the search paths mentioned above can be changed by defining the PATH, C_INCLUDE_PATH, PYTHONPATH (or GUIX_PYTHONPATH), and DICPATH environment variables—you know, all these something-PATH variables that you need to get right or things “won’t be found”.

You may have noticed from the command line that Guix “knows” which search path environment variables should be defined, and how. When you install packages in your default profile, the file ~/.guix-profile/etc/profile is created, which you can “source” from the shell to set those variables. Likewise, if you ask guix shell to create an environment containing Python and NumPy, a Python library, and if you pass it the --search-paths option, it will tell you about PATH and GUIX_PYTHONPATH (see Запуск guix shell):

$ guix shell python python-numpy --pure --search-paths
export PATH="/gnu/store/…-profile/bin"
export GUIX_PYTHONPATH="/gnu/store/…-profile/lib/python3.9/site-packages"

When you omit --search-paths, it defines these environment variables right away, such that Python can readily find NumPy:

$ guix shell python python-numpy -- python3
Python 3.9.6 (default, Jan  1 1970, 00:00:01)
[GCC 10.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> numpy.version.version
'1.20.3'

For this to work, the definition of the python package declares the search path it cares about and its associated environment variable, GUIX_PYTHONPATH. It looks like this:

(package
  (name "python")
  (version "3.9.9")
  ;; some fields omitted...
  (native-search-paths
   (list (search-path-specification
          (variable "GUIX_PYTHONPATH")
          (files (list "lib/python/3.9/site-packages"))))))

What this native-search-paths field says is that, when the python package is used, the GUIX_PYTHONPATH environment variable must be defined to include all the lib/python/3.9/site-packages sub-directories encountered in its environment. (The native- bit means that, if we are in a cross-compilation environment, only native inputs may be added to the search path; see search-paths.) In the NumPy example above, the profile where python appears contains exactly one such sub-directory, and GUIX_PYTHONPATH is set to that. When there are several lib/python/3.9/site-packages—this is the case in package build environments—they are all added to GUIX_PYTHONPATH, separated by colons (:).

Примечание: Notice that GUIX_PYTHONPATH is specified as part of the definition of the python package, and not as part of that of python-numpy. This is because this environment variable “belongs” to Python, not NumPy: Python actually reads the value of that variable and honors it.

Corollary: if you create a profile that does not contain python, GUIX_PYTHONPATH will not be defined, even if it contains packages that provide .py files:

$ guix shell python-numpy --search-paths --pure
export PATH="/gnu/store/…-profile/bin"

This makes a lot of sense if we look at this profile in isolation: no software in this profile would read GUIX_PYTHONPATH.

Of course, there are many variations on that theme: some packages honor more than one search path, some use separators other than colon, some accumulate several directories in their search path, and so on. A more complex example is the search path of libxml2: the value of the XML_CATALOG_FILES environment variable is space-separated, it must contain a list of catalog.xml files (not directories), which are to be found in xml sub-directories—nothing less. The search path specification looks like this:

(package
  (name "libxml2")
  ;; some fields omitted
  (native-search-paths
   (list (search-path-specification
          (variable "XML_CATALOG_FILES")
          (separator " ")
          (files '("xml"))
          (file-pattern "^catalog\\.xml$")
          (file-type 'regular)))))

Worry not, search path specifications are usually not this tricky.

The (guix search-paths) module defines the data type of search path specifications and a number of helper procedures. Below is the reference of search path specifications.

Data Type: search-path-specification

The data type for search path specifications.

variable

The name of the environment variable for this search path (a string).

files

The list of sub-directories (strings) that should be added to the search path.

separator (default: ":")

The string used to separate search path components.

As a special case, a separator value of #f specifies a “single-component search path”—in other words, a search path that cannot contain more than one element. This is useful in some cases, such as the SSL_CERT_DIR variable (honored by OpenSSL, cURL, and a few other packages) or the ASPELL_DICT_DIR variable (honored by the GNU Aspell spell checker), both of which must point to a single directory.

file-type (default: 'directory)

The type of file being matched—'directory or 'regular, though it can be any symbol returned by stat:type (see stat in GNU Guile Reference Manual).

In the libxml2 example above, we would match regular files; in the Python example, we would match directories.

file-pattern (default: #f)

This must be either #f or a regular expression specifying files to be matched within the sub-directories specified by the files field.

Again, the libxml2 example shows a situation where this is needed.

Some search paths are not tied by a single package but to many packages. To reduce duplications, some of them are pre-defined in (guix search-paths).

Scheme Variable: $SSL_CERT_DIR
Scheme Variable: $SSL_CERT_FILE

These two search paths indicate where X.509 certificates can be found (see Сертификаты X.509).

These pre-defined search paths can be used as in the following example:

(package
  (name "curl")
  ;; some fields omitted ...
  (native-search-paths (list $SSL_CERT_DIR $SSL_CERT_FILE)))

How do you turn search path specifications on one hand and a bunch of directories on the other hand in a set of environment variable definitions? That’s the job of evaluate-search-paths.

Scheme Procedure: evaluate-search-paths search-paths directories [getenv] Evaluate search-paths, a list of

search-path specifications, for directories, a list of directory names, and return a list of specification/value pairs. Use getenv to determine the current settings and report only settings not already effective.

The (guix profiles) provides a higher-level helper procedure, load-profile, that sets the environment variables of a profile.


Next: , Previous: , Up: Программный интерфейс   [Contents][Index]

9.9 Хранилище

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

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

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

See guix gc --verify, для получения информации о том, как проверить целостность 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-соединения (see --listen).

ssh

Эти URI позволяют подключаться к удаленному демону через SSH. Для этой функции требуется Guile-SSH (see Требования) и рабочий guile binary файл в PATH на конечном компьютере. Он поддерживает открытый ключ и аутентификацию GSSAPI. Типичный URL-адрес может выглядеть так:

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

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

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

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

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: lookup-inferior-packages inferior name [mode] Собрать derivations, список объектов <derivation>,

имен файлов .drv или пар derivation/output, используя указанный mode(build-mode normal) по умолчанию.

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

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


Next: , Previous: , Up: Программный интерфейс   [Contents][Index]

9.10 Деривации

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

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

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

Outputs of derivations—то есть результаты сборки—имеют множество references, в соответствии с указаниями RPC references или команды guix gc --references (see Вызов 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 и должна быть собрана локально (see Установка демона разгрузки). Это справедливо для небольших derivation’ов, когда затраты на передачу данных перевешивают выгоды.

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

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. Для получения дополнительной информации, see 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 => …>

Next: , Previous: , Up: Программный интерфейс   [Contents][Index]

9.11 Устройство склада

Все процедуры, которые работают с 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 можно даже опустить, поскольку она будет выполняться неявно, как мы увидим позже (see 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

Note that the (guix monad-repl) module extends the Guile REPL with new “commands” to make it easier to deal with monadic procedures: run-in-store, and enter-store-monad (see Using Guix Interactively). The former is used to “run” a single monadic value through the 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.

Other meta-commands are available at the REPL, such as ,build to build a file-like object (see Using Guix Interactively).

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

Scheme Syntax: with-monad monad body ...

Evaluate any >>= or return forms in body as being in monad.

Scheme Syntax: return val

Возвращает монадическое значение, инкапсулирующее val.

Scheme Syntax: >>= mval mproc ...

Bind monadic value mval, passing its “contents” to monadic procedures mproc20. 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 (see Local Bindings in GNU Guile Reference Manual).

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 (see Описание пакетов).


Next: , Previous: , Up: Программный интерфейс   [Contents][Index]

9.12 G-Expressions

So we have “derivations”, which represent a sequence of build actions to be performed to produce an item in the store (see Деривации). These build actions are performed when asking the daemon to actually build the derivations; they are run by the daemon in a container (see Вызов 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 code21: 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 (see Фазы сборки).

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 (see quasiquote in GNU Guile Reference Manual). However, there are major differences:

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 image)))
  (gexp->derivation "something-with-vms"
                    #~(begin
                        (use-modules (guix build utils)
                                     (gnu build image))
                        )))

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 (see Пакеты со множественным выходом).

#+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 th