Manual de referência do GNU Guix

Próximo: , Acima: (dir)   [Conteúdo][Índice]

GNU Guix

Esse documento descreve Guix versão 4b5f040, uma ferramenta de gerenciamento de pacotes funcional escrita para o sistema GNU.

Este manual também está disponível em inglês (veja GNU Guix Reference Manual), chinês simplificado (veja GNU Guix参考手册), francês (veja Manuel de référence de GNU Guix), alemão (veja Referenzhandbuch zu GNU Guix), espanhol (veja Manual de referencia de GNU Guix) e russo (veja Руководство GNU Guix). Se você quiser traduzi-lo para seu idioma nativo, considere participar do Weblate (veja Traduzindo o Guix).

Sumário


Próximo: , Anterior: , Acima: GNU Guix   [Conteúdo][Índice]

1 Introdução

GNU Guix1 é uma ferramenta de gerenciamento de pacotes e distribuição do sistema GNU. O Guix facilita a instalação, a atualização ou a remoção de pacotes de software, a reversão para um conjunto de pacotes anterior, a compilação de pacotes a partir do código-fonte e geralmente ajuda na criação e manutenção de ambientes de software.

Você pode instalar o GNU Guix sobre um sistema GNU/Linux existente, onde ele complementa as ferramentas disponíveis sem interferência (veja Instalação) ou você pode usá-lo como uma distribuição de sistema operacional independente, Guix System2. Veja Distribuição GNU.


1.1 Gerenciando software do jeito do Guix

O Guix fornece uma interface de gerenciamento de pacotes de linha de comando (veja Gerenciamento de pacote), ferramentas para ajudar no desenvolvimento de software (veja Desenvolvimento), utilitários de linha de comando para uso mais avançado (veja Utilitários), bem como interfaces de programação Scheme (veja Interface de programação). O build daemon é responsável por compilar pacotes em nome dos usuários (veja Configurando o daemon) e por baixar binários pré-compilados de fontes autorizados (veja Substitutos).

Guix inclui definições de pacotes para muitos pacotes GNU e não-GNU, todos os quais respeitam a liberdade de computação do usuário. É extensível: os usuários podem escrever suas próprias definições de pacotes (veja Definindo pacotes) e disponibilizá-los como módulos de pacotes independentes (veja Módulos de pacote). Também é personalizável: os usuários podem derivar definições de pacotes especializados das existentes, incluindo da linha de comando (veja Opções de transformação de pacote).

Nos bastidores, a Guix implementa a disciplina gerenciamento de pacotes funcional pioneira da Nix (veja Agradecimentos). No Guix, o processo de compilação e instalação de pacotes é visto como uma função, no sentido matemático. Essa função recebe entradas, como scripts de compilação, um compilador e bibliotecas, e retorna um pacote instalado. Como uma função pura, seu resultado depende apenas de suas entradas – por exemplo, não pode fazer referência a um software ou scripts que não foram explicitamente passados como entradas. Uma função de compilação sempre produz o mesmo resultado ao passar por um determinado conjunto de entradas. Não pode alterar o ambiente do sistema em execução de qualquer forma; por exemplo, ele não pode criar, modificar ou excluir arquivos fora de seus diretórios de compilação e instalação. Isto é conseguido através da execução de processos de compilação em ambientes isolados (ou containers), onde somente suas entradas explícitas são visíveis.

O resultado das funções de compilação do pacote é mantido (cached) no sistema de arquivos, em um diretório especial chamado armazém (veja O armazém). Cada pacote é instalado em um diretório próprio no armazém – por padrão, em /gnu/store. O nome do diretório contém um hash de todas as entradas usadas para compilar esse pacote; Assim, a alteração uma entrada gera um nome de diretório diferente.

Essa abordagem é a fundação para os principais recursos do Guix: suporte para atualização transacional de pacotes e reversão, instalação por usuário e coleta de lixo de pacotes (veja Recursos).


1.2 Distribuição GNU

O Guix vem com uma distribuição do sistema GNU que consiste inteiramente de software livre3. A distribuição pode ser instalada por conta própria (veja Instalação do sistema), mas também é possível instalar o Guix como um gerenciador de pacotes em cima de um sistema GNU/Linux instalado (veja Instalação). Quando precisamos distinguir entre os dois, nos referimos à distribuição independente como Guix System.

A distribuição fornece pacotes GNU principais, como GNU libc, GCC e Binutils, além de muitos aplicativos GNU e não GNU. A lista completa de pacotes disponíveis pode ser acessada online ou executando guix package (veja Invocando guix package):

guix package --list-available

Nosso objetivo é fornecer uma distribuição prática e 100% de software livre, baseada em Linux e outras variantes do GNU, com foco na promoção e forte integração de componentes do GNU e ênfase em programas e ferramentas que ajudam os usuários a exercer essa liberdade.

Os pacotes estão atualmente disponíveis nas seguintes plataformas:

x86_64-linux

Arquitetura Intel/AMD x86_64, kernel Linux-Libre.

i686-linux

Arquitetura Intel de 32 bits (IA32), kernel Linux-Libre.

armhf-linux

Arquitetura ARMv7-A com hard float, Thumb-2 e NEON, usando a interface binária de aplicativos EABI hard-float (ABI) e o kernel Linux-Libre.

aarch64-linux

Processadores ARMv8-A little-endian de 64 bits, kernel Linux-Libre.

i586-gnu

GNU/Hurd sobre a arquitetura Intel de 32 bits (IA32).

Esta configuração é experimental e está em desenvolvimento. A maneira mais fácil de você tentar é configurando uma instância de hurd-vm-service-type na sua máquina GNU/Linux (veja hurd-vm-service-type). Veja Contribuindo, sobre como ajudar!

x86_64-gnu

GNU/Hurd on the x86_64 Intel/AMD 64-bit architecture.

This configuration is even more experimental and under heavy upstream development.

mips64el-linux (sem suporte)

processadores little-endian MIPS de 64 bits, especificamente a série Loongson, n32 ABI e kernel Linux-Libre. Esta configuração não é mais totalmente suportada; em particular, não há trabalho em andamento para garantir que esta arquitetura ainda funcione. Caso alguém decida que deseja reviver esta arquitetura, o código ainda estará disponível.

powerpc-linux (sem suporte)

processadores PowerPC big-endian de 32 bits, especificamente o PowerPC G4 com suporte AltiVec e kernel Linux-Libre. Esta configuração não é totalmente suportada e não há trabalho em andamento para garantir que esta arquitetura funcione.

powerpc64le-linux

processadores little-endian 64 bits Power ISA, kernel Linux-Libre. Isso inclui sistemas POWER9 como o placa-mãe RYF Talos II. Esta plataforma está disponível como uma "prévia de tecnologia": embora seja suportada, substitutos ainda não estão disponíveis na fazenda de construção (veja Substitutos), e alguns pacotes podem falhar na construção (veja Rastreando Bugs e Mudanças). Dito isso, a comunidade Guix está trabalhando ativamente para melhorar esse suporte, e agora é um ótimo momento para experimentá-lo e se envolver!

riscv64-linux

processadores little-endian RISC-V de 64 bits, especificamente RV64GC, e kernel Linux-Libre. Esta plataforma está disponível como uma "prévia de tecnologia": embora seja suportada, substitutos ainda não estão disponíveis na build farm (veja Substitutos), e alguns pacotes podem falhar na compilação (veja Rastreando Bugs e Mudanças). Dito isto, a comunidade Guix está trabalhando ativamente para melhorar este suporte, e agora é um ótimo momento para experimentá-lo e se envolver!

Com o Guix System, você declara todos os aspectos da configuração do sistema operacional, e o Guix cuida de instanciar a configuração de maneira transacional, reproduzível e sem estado (veja Configuração do sistema). O Guix System usa o kernel Linux-libre, o sistema de inicialização Shepherd (veja Introduction em The GNU Shepherd Manual), os conhecidos utilitários do GNU e cadeia de ferramentas, bem como o ambiente gráfico ou os serviços de sistema do sua escolha.

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

Para obter informações sobre como portar para outras arquiteturas ou kernels, veja Portando para uma nova plataforma.

A construção desta distribuição é um esforço cooperativo e você está convidado a participar! Veja Contribuindo, para obter informações sobre como você pode ajudar.


Próximo: , Anterior: , Acima: GNU Guix   [Conteúdo][Índice]

2 Instalação

Você pode instalar a ferramenta de gerenciamento de pacotes Guix sobre um sistema GNU/Linux ou GNU/Hurd existente4, conhecido como distro estrangeiro. Se, em vez disso, você quiser instalar a distribuição completa e autônoma do sistema GNU, Guix System, veja Instalação do sistema. Esta seção se preocupa apenas com a instalação do Guix em uma distro estrangeira.

Importante: Esta seção se aplica somente a sistemas sem Guix. Segui-la para instalações Guix existentes sobrescreverá arquivos importantes do sistema.

Quando instalado sobre uma distro alheia. GNU Guix complementa as ferramentas disponíveis sem interferência. Seus dados residem exclusivamente em dois diretórios, geralmente /gnu/store e /var/guix; outros arquivos no seu sistema, como /etc, são deixados intactos.

Uma vez instalado, o Guix pode ser atualizado executando guix pull (veja Invocando guix pull).


2.1 Instalação de binários

This section describes how to install Guix from a self-contained tarball providing binaries for Guix and for all its dependencies. This is often quicker than installing from source, described later (veja Compilando do git).

Importante: Esta seção se aplica somente a sistemas sem Guix. Segui-la para instalações Guix existentes sobrescreverá arquivos importantes do sistema.

Algumas distribuições GNU/Linux, como Debian, Ubuntu e openSUSE fornecem Guix por meio de seus próprios gerenciadores de pacotes. A versão do Guix pode ser mais antiga que 4b5f040, mas você pode atualizá-la depois executando ‘guix pull’.

Aconselhamos os administradores de sistema que instalam o Guix, tanto a partir do script de instalação quanto por meio do gerenciador de pacotes nativo de sua distribuição estrangeira, a também ler e seguir regularmente os avisos de segurança, conforme mostrado pelo guix pull.

Para Debian ou derivados como Ubuntu ou Trisquel, chame:

sudo apt install guix

Da mesma forma, no openSUSE:

sudo zypper install guix

Se você estiver executando o Parabola, depois de habilitar o repositório pcr (Parabola Community Repo), você pode instalar o Guix com:

sudo pacman -S guix

O projeto Guix também fornece um script de shell, guix-install.sh, que automatiza o processo de instalação binária sem o uso de um gerenciador de pacotes de distro estrangeiro5. O uso de guix-install.sh requer Bash, GnuPG, GNU tar, wget e Xz.

The script guides you through the following:

  • Baixando e extraindo o tarball binário
  • Setting up the build daemon
  • Disponibilizando o comando ‘guix’ para usuários não root
  • Configuring substitute servers

Como root, execute:

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

O script para instalar o Guix também está empacotado no Parabola (no repositório pcr). Você pode instalá-lo e executá-lo com:

sudo pacman -S guix-installer
sudo guix-install.sh

Nota: Por padrão, guix-install.sh configurará o Guix para baixar binários de pacotes pré-construídos, chamados substitutes (veja Substitutos), das fazendas de construção do projeto. Se você escolher não permitir isso, o Guix construirá tudo a partir da fonte, tornando cada instalação e atualização muito cara. Veja Confiança em binários para uma discussão sobre por que você pode querer construir pacotes a partir da fonte.

Para usar substitutos de bordeaux.guix.gnu.org, ci.guix.gnu.org ou um espelho, você deve autorizá-los. Por exemplo,

# guix archive --authorize < \
     ~root/.config/guix/current/share/guix/bordeaux.guix.gnu.org.pub
# guix archive --authorize < \
     ~root/.config/guix/current/share/guix/ci.guix.gnu.org.pub

Quando terminar de instalar o Guix, veja Configuração de aplicativo para configurações extras que você pode precisar e Começando para seus primeiros passos!

Nota: O tarball da instalação binária pode ser (re)produzido e verificado simplesmente executando o seguinte comando na árvore de código-fonte do Guix:

make guix-binary.sistema.tar.xz

... que, por sua vez, executa:

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

Veja Invocando guix pack, para mais informações sobre essa ferramenta útil.

Caso você queira desinstalar o Guix, execute o mesmo script com o sinalizador --uninstall:

./guix-install.sh --uninstall

Com --uninstall, o script exclui irreversivelmente todos os arquivos Guix, configuração e serviços.


2.2 Configurando o daemon

Durante a instalação, o build daemon que deve estar em execução para usar o Guix já foi configurado e você pode executar comandos guix no seu programa de terminal, veja Começando:

guix build hello

Se isso ocorrer sem erros, sinta-se à vontade para pular esta seção. Você deve continuar com a seção seguinte, Configuração de aplicativo.

No entanto, agora seria um bom momento para substituir versões desatualizadas do daemon, ajustá-lo, executar compilações em outras máquinas (veja Usando o recurso de descarregamento) ou iniciá-lo manualmente em ambientes especiais como “chroots” (veja Acessando um sistema existente via chroot) ou WSL (não necessário para imagens WSL criadas com Guix, veja wsl2-image-type). Se você quiser saber mais ou otimizar seu sistema, vale a pena ler esta seção.

Operações como compilar um pacote ou executar o coletor de lixo são todas executadas por um processo especializado, o build daemon, em nome dos clientes. Apenas o daemon pode acessar o armazém e seu banco de dados associado. Assim, qualquer operação que manipule o armazém passa pelo daemon. Por exemplo, ferramentas de linha de comando como guix package e guix build se comunicam com o daemon (via chamadas de procedimento remoto) para instruir o que fazer.

As seções a seguir explicam como preparar o ambiente do daemon de compilação. Veja Substitutos para informações sobre como permitir que o daemon baixe binários pré-compilados.


2.2.1 Configuração do ambiente de compilação

Em uma configuração multiusuário padrão, o Guix e seu daemon – o programa guix-daemon – são instalados pelo administrador do sistema; /gnu/store é de propriedade de root e guix-daemon é executado como root. Usuários desprivilegiados podem usar ferramentas Guix para criar pacotes ou acessar o armazém, e o daemon fará isso em seu nome, garantindo que o armazém seja mantido em um estado consistente e permitindo que pacotes construídos sejam compartilhados entre os usuários.

Quando guix-daemon é executado como root, você pode não querer que os próprios processos de compilação de pacotes também sejam executados como root, por razões óbvias de segurança. Para evitar isso, um conjunto especial de usuários de compilação deve ser criado para uso pelos processos de construção iniciados pelo daemon. Esses usuários de compilação não precisam ter um shell e um diretório pessoal: eles serão usados apenas quando o daemon der um privilégio root nos processos de compilação. Ter vários desses usuários permite que o daemon ative processos de compilação distintos sob UIDs separados, o que garante que eles não interfiram uns com os outros - um recurso essencial, pois as compilações são consideradas funções puras (veja Introdução).

Em um sistema GNU/Linux, um conjunto de usuários de construção pode ser criado assim (usando a sintaxe Bash e os comandos 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

O número de usuários de compilação determina quantos trabalhos de compilação podem ser executados em paralelo, conforme especificado pela opção --max-jobs (veja --max-jobs). Para usar guix system vm e comandos relacionados, você pode precisar adicionar os usuários de compilação ao grupo kvm para que eles possam acessar /dev/kvm, usando -G guixbuild,kvm em vez de -G guixbuild (veja Invoking guix system).

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

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

Dessa forma, o daemon inicia os processos de compilação em um chroot, sob um dos usuários guixbuilder. No GNU/Linux, por padrão, o ambiente chroot contém nada além de:

  • um diretório /dev mínimo, criado principalmente independentemente do /dev do hospedeiro7;
  • o diretório /proc; mostra apenas os processos do contêiner desde que um espaço de nome PID separado é usado;
  • /etc/passwd com uma entrada para o usuário atual e uma entrada para o usuário nobody;
  • /etc/group com uma entrada para o grupo de usuários;
  • /etc/hosts com uma entrada que mapeia localhost para 127.0.0.1;
  • um diretório /tmp com permissão de escrita.

O chroot não contém um diretório /home, e a variável de ambiente HOME é definida como o inexistente /homeless-shelter. Isso ajuda a destacar usos inapropriados de HOME nos scripts de construção de pacotes.

Tudo isso geralmente é suficiente para garantir que os detalhes do ambiente não influenciem os processos de construção. Em alguns casos excepcionais em que mais controle é necessário — normalmente sobre a data, kernel ou CPU — você pode recorrer a uma máquina de construção virtual (veja máquinas de construção virtual).

Você pode influenciar o diretório onde o daemon armazena árvores de build via a variável de ambiente TMPDIR. No entanto, a árvore de build dentro do chroot é sempre chamada /tmp/guix-build-name.drv-0, onde name é o nome da derivação—por exemplo, coreutils-8.24. Dessa forma, o valor de TMPDIR não vaza dentro de ambientes de build, o que evita discrepâncias em casos em que os processos de build capturam o nome de sua árvore de build.

O daemon também respeita as variáveis de ambiente http_proxy e https_proxy para downloads HTTP e HTTPS que ele realiza, seja para derivações de saída fixa (veja Derivações) ou para substitutos (veja Substitutos).

Se você estiver instalando o Guix como um usuário sem privilégios, ainda é possível executar guix-daemon desde que você passe --disable-chroot. No entanto, os processos de construção não serão isolados uns dos outros, e nem do resto do sistema. Assim, os processos de construção podem interferir uns nos outros, e podem acessar programas, bibliotecas e outros arquivos disponíveis no sistema — tornando muito mais difícil visualizá-los como funções puras.


2.2.2 Usando o recurso de descarregamento

Quando desejado, o daemon de compilação pode offload compilações de derivação para outras máquinas executando Guix, usando o offload build hook8. Quando esse recurso é habilitado, uma lista de máquinas de compilação especificadas pelo usuário é lida de /etc/guix/machines.scm; toda vez que uma compilação é solicitada, por exemplo via guix build, o daemon tenta descarregá-la para uma das máquinas que satisfazem as restrições da derivação, em particular seus tipos de sistema — por exemplo, x86_64-linux. Uma única máquina pode ter vários tipos de sistema, seja porque sua arquitetura o suporta nativamente, via emulação (veja Transparent Emulation with QEMU), ou ambos. Os pré-requisitos ausentes para a compilação são copiados por SSH para a máquina de destino, que então prossegue com a compilação; em caso de sucesso, a(s) saída(s) da compilação são copiadas de volta para a máquina inicial. O recurso de offload vem com um agendador básico que tenta selecionar a melhor máquina. A melhor máquina é escolhida entre as máquinas disponíveis com base em critérios como:

  1. A disponibilidade de um slot de build. Uma máquina de build pode ter tantos slots de build (conexões) quanto o valor do campo parallel-builds do seu objeto build-machine.
  2. Sua velocidade relativa, conforme definida pelo campo speed do seu objeto build-machine.
  3. Sua carga. A carga normalizada da máquina deve ser menor que um valor limite, configurável por meio do campo overload-threshold de seu objeto build-machine.
  4. Disponibilidade de espaço em disco. Mais de 100 MiB devem estar disponíveis.

O arquivo /etc/guix/machines.scm geralmente se parece com isso:

(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")

        ;; Lembre-se de que 'guix offload' é gerado por
        ;; 'guix-daemon' como root.
        (private-key "/root/.ssh/identity-for-guix")))

No exemplo acima, especificamos uma lista de duas máquinas de compilação, uma para as arquiteturas x86_64 e i686 e uma para a arquitetura aarch64.

De fato, esse arquivo é – não surpreendentemente! – um arquivo de Scheme que é avaliado quando o hook offload é iniciado. Seu valor de retorno deve ser uma lista de objetos de build-machine. Embora este exemplo mostre uma lista fixa de máquinas de compilação, pode-se imaginar, digamos, usando DNS-SD para retornar uma lista de possíveis máquinas de compilação descobertas na rede local (veja Guile-Avahi em Using Avahi in Guile Scheme Programs). O tipo de dados de build-machine está detalhado abaixo.

Tipo de dados: build-machine

Esse tipo de dados representa máquinas de compilação nas quais o daemon pode descarregar compilações. Os campos importantes são:

name

O nome de host da máquina remota.

systems

O sistema digita os tipos que a máquina remota suporta, por exemplo, (list "x86_64-linux" "i686-linux").

user

The user account on the remote machine to use when connecting over SSH. Note that the SSH key pair must not be passphrase-protected, to allow non-interactive logins.

host-key

Essa deve ser a SSH chave pública do host da máquina no formato OpenSSH. Isso é usado para autenticar a máquina quando nos conectamos a ela. É uma string longa que se parece com isso:

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

Se a máquina estiver executando o daemon OpenSSH, sshd, a chave do host poderá ser encontrada em um arquivo como /etc/ssh/ssh_host_ed25519_key.pub.

Se a máquina estiver executando o daemon SSH do GNU lsh, lshd, a chave do host estará em /etc/lsh/host-key.pub ou em um arquivo semelhante. Ele pode ser convertido para o formato OpenSSH usando o lsh-export-key (veja Converting keys em LSH Manual):

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

Vários campos opcionais podem ser especificados:

port (padrão: 22)

O número da porta para o servidor SSH na máquina.

private-key (padrão: ~root/.ssh/id_rsa)

O arquivo de chave privada SSH a ser usado ao conectar-se à máquina, no formato OpenSSH. Esta chave não deve ser protegida com uma senha.

Observe que o valor padrão é a chave privada da usuário root. Verifique se ele existe se você usar o padrão.

compression (padrão: "zlib@openssh.com,zlib")
compression-level (padrão: 3)

Os métodos de compactação no nível SSH e o nível de compactação solicitado.

Observe que o descarregamento depende da compactação SSH para reduzir o uso da largura de banda ao transferir arquivos de e para máquinas de compilação.

daemon-socket (padrão: "/var/guix/daemon-socket/socket")

O nome do arquivo do soquete do domínio Unix guix-daemon está escutando nessa máquina.

overload-threshold (default: 0.8)

O limite de carga acima do qual uma máquina de offload potencial é desconsiderada pelo agendador de offload. O valor traduz aproximadamente o uso total do processador da máquina de build, variando de 0,0 (0%) a 1,0 (100%). Ele também pode ser desabilitado definindo overload-threshold para #f.

parallel-builds (padrão: 1)

O número de compilações que podem ser executadas paralelamente na máquina.

speed (padrão: 1.0)

Um “fator de velocidade relativo”. O agendador de descarregamento tenderá a preferir máquinas com um fator de velocidade mais alto.

features (padrão: '())

Uma lista de strgins que denotam recursos específicos suportados pela máquina. Um exemplo é "kvm" para máquinas que possuem os módulos KVM Linux e o suporte de hardware correspondente. As derivações podem solicitar recursos pelo nome e serão agendadas nas máquinas de compilação correspondentes.

Nota: No Guix System, em vez de gerenciar /etc/guix/machines.scm de forma independente, você pode escolher especificar máquinas de compilação diretamente na declaração operating-system, no campo build-machines de guix-configuration. Veja campo build-machines de guix-configuration.

O comando guix deve estar no caminho de pesquisa nas máquinas de compilação. Você pode verificar se este é o caso executando:

ssh build-machine guix repl --version

Há uma última coisa a fazer quando o machines.scm está em vigor. Como explicado acima, ao descarregar, os arquivos são transferidos entre os armazéns das máquinas. Para que isso funcione, primeiro você precisa gerar um par de chaves em cada máquina para permitir que o daemon exporte arquivos assinados de arquivos do armazém (veja Invocando guix archive):

# guix archive --generate-key

Nota: Este par de chaves não está relacionado ao par de chaves SSH mencionado anteriormente na descrição do tipo de dados build-machine.

Cada máquina de construção deve autorizar a chave da máquina principal para que ela aceite itens do armazém que recebe do mestre:

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

Da mesma forma, a máquina principal deve autorizar a chave de cada máquina de compilação.

Todo esse barulho com as chaves está aqui para expressar relações de confiança mútua de pares entre a máquina mestre e as de compilação. Concretamente, quando o mestre recebe arquivos de uma máquina de compilação (e vice-versa), seu daemon de compilação pode garantir que eles sejam genuínos, não tenham sido violados e que sejam assinados por uma chave autorizada.

Para testar se sua configuração está operacional, execute este comando no nó principal:

# guix offload test

Isso tentará se conectar a cada uma das máquinas de compilação especificadas em /etc/guix/machines.scm, certificar-se de que o Guix esteja disponível em cada máquina, tentará exportar para a máquina e importar dela e relatará qualquer erro no processo.

Se você quiser testar um arquivo de máquina diferente, basta especificá-lo na linha de comando:

# guix offload test machines-qualif.scm

Por fim, você pode testar o subconjunto das máquinas cujo nome corresponde a uma expressão regular como esta:

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

Para exibir o carregamento atual de todos os hosts de compilação, execute este comando no nó principal:

# guix offload status

2.2.3 Suporte a SELinux

O Guix inclui um arquivo de políticas do SELinux em etc/guix-daemon.cil que pode ser instalado em um sistema em que o SELinux está ativado, para rotular os arquivos do Guix e especificar o comportamento esperado do daemon. Como o Guix System não fornece uma política básica do SELinux, a política do daemon não pode ser usada no Guix System.

2.2.3.1 Instalando a política do SELinux

Nota: O script de instalação binária guix-install.sh se oferece para executar as etapas abaixo para você (veja Instalação de binários).

Para instalar a política, execute esse comando como root:

semodule -i /var/guix/profiles/per-user/root/current-guix/share/selinux/guix-daemon.cil

Então, como root, renomeie o sistema de arquivos, possivelmente depois de torná-lo gravável:

mount -o remount,rw /gnu/store
restorecon -R /gnu /var/guix

Neste ponto, você pode iniciar ou reiniciar guix-daemon; em uma distribuição que usa systemd como seu gerenciador de serviços, você pode fazer isso com:

systemctl restart guix-daemon

Depois que a política é instalada, o sistema de arquivos foi rotulado novamente e o daemon foi reiniciado, ele deve estar em execução no contexto guix_daemon_t. Você pode confirmar isso com o seguinte comando:

ps -Zax | grep guix-daemon

Monitore os arquivos de log do SELinux enquanto executa um comando como guix build hello para se convencer de que o SELinux permite todas as operações necessárias.

2.2.3.2 Limitações

Esta política não é perfeita. Aqui está uma lista de limitações ou peculiaridades que devem ser consideradas ao implementar a política SELinux fornecida para o daemon Guix.

  1. guix_daemon_socket_t isn’t actually used. None of the socket operations involve contexts that have anything to do with guix_daemon_socket_t. It doesn’t hurt to have this unused label, but it would be preferable to define socket rules for only this label.
  2. guix gc não pode acessar links arbitrários para perfis. Por design, o rótulo do arquivo do destino de uma ligação simbólica é independente do rótulo do arquivo do próprio link. Embora todos os perfis em $localstatedir estejam rotulados, as ligações para esses perfis herdam o rótulo do diretório em que estão. Para as ligações no diretório pessoal do usuário, será user_home_t. Mas, para ligações do diretório pessoal do usuário root, ou /tmp, ou do diretório de trabalho do servidor HTTP etc., isso não funcionará. guix gc seria impedido de ler e seguir essas ligações.
  3. O recurso do daemon de escutar conexões TCP pode não funcionar mais. Isso pode exigir regras extras, porque o SELinux trata os soquetes de rede de maneira diferente dos arquivos.
  4. Atualmente, todos os arquivos com um nome correspondente à expressão regular /gnu/store/.+-(guix-.+|profile)/bin/guix-daemon recebem o rótulo guix_daemon_exec_t; isso significa que qualquer arquivo com esse nome em qualquer perfil poderá ser executado no domínio de guix_daemon_t. Isto não é o ideal. Um invasor pode criar um pacote que forneça esse executável e convencer um usuário a instalar e executá-lo, o que o eleva ao domínio de guix_daemon_t. Nesse ponto, o SELinux não poderia impedir o acesso a arquivos permitidos para processos nesse domínio.

    Você precisará renomear o diretório store após todas as atualizações para guix-daemon, como após executar guix pull. Supondo que o store esteja em /gnu, você pode fazer isso com restorecon -vR /gnu, ou por outros meios fornecidos pelo seu sistema operacional.

    Poderíamos gerar uma política muito mais restritiva no momento da instalação, para que apenas o nome do arquivo exato do executável guix-daemon atualmente instalado seja rotulado com guix_daemon_exec_t, em vez de usar um amplo expressão regular. A desvantagem é que o root precisaria instalar ou atualizar a política no momento da instalação sempre que o pacote Guix que fornece o executável guix-daemon em execução efetiva for atualizado.


2.3 Invocando guix-daemon

O programa guix-daemon implementa todas as funcionalidades para acessar o armazém. Isso inclui iniciar processos de compilação, executar o coletor de lixo, consultar a disponibilidade de um resultado da compilação etc. É normalmente executado como root, assim:

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

Este daemon também pode ser iniciado seguindo o protocolo de “ativação de soquete” do systemd (veja make-systemd-constructor em The GNU Shepherd Manual).

Para detalhes sobre como configurá-lo, veja Configurando o daemon.

Por padrão, guix-daemon inicia processos de compilação sob diferentes UIDs, obtidos do grupo de compilação especificado com --build-users-group. Além disso, cada processo de compilação é executado em um ambiente chroot que contém apenas o subconjunto do armazém do qual o processo de compilação depende, conforme especificado por sua derivação (veja derivação), mais um conjunto de diretórios de sistema específicos. Por padrão, o último contém /dev e /dev/pts. Além disso, no GNU/Linux, o ambiente de compilação é um container: além de ter sua própria árvore de sistema de arquivos, ele tem um espaço de nome de montagem separado, seu próprio espaço de nome PID, espaço de nome de rede, etc. Isso ajuda a obter compilações reproduzíveis (veja Recursos).

Quando o daemon executa uma compilação em nome do usuário, ele cria um diretório de compilação em /tmp ou no diretório especificado por sua variável de ambiente TMPDIR. Esse diretório é compartilhado com o contêiner durante a compilação, embora dentro do contêiner, a árvore de compilação seja sempre chamada de /tmp/guix-build-name.drv-0.

O diretório de compilação é excluído automaticamente após a conclusão, a menos que a compilação falhe e o cliente tenha especificado --keep-failed (veja --keep-failed).

O daemon escuta conexões e gera um subprocesso para cada sessão iniciada por um cliente (um dos subcomandos guix). O comando guix processes permite que você tenha uma visão geral da atividade no seu sistema visualizando cada uma das sessões e clientes ativos. Veja Invocando guix processes, para mais informações.

As seguintes opções de linha de comando são suportadas:

--build-users-group=grupo

Obtém os usuários do grupo para executar os processos de compilação (veja usuários de compilação).

--no-substitutes

Não use substitutos para compilar produtos. Ou seja, sempre crie coisas localmente, em vez de permitir downloads de binários pré-compilados (veja Substitutos).

Quando o daemon é executado com --no-substitutes, os clientes ainda podem habilitar explicitamente a substituição por meio da chamada de procedimento remoto set-build-options (veja O armazém).

--substitute-urls=urls

Consider urls the default whitespace-separated list of substitute source URLs. When this option is omitted, ‘https://bordeaux.guix.gnu.org https://ci.guix.gnu.org’ is used.

Isso significa que os substitutos podem ser baixados de urls, desde que assinados por uma assinatura confiável (veja Substitutos).

Veja Obtendo substitutos de outros servidores, para mais informações sobre como configurar o daemon para obter substitutos de outros servidores.

--no-offload

Não use compilações de offload para outras máquinas (veja Usando o recurso de descarregamento). Ou seja, sempre compile as coisas localmente em vez de descarregar compilações para máquinas remotas.

--cache-failures

Armazena em cache as compilações que falharam. Por padrão, apenas compilações bem-sucedidas são armazenadas em cache.

Quando essa opção é usada, o guix gc --list-failures pode ser usado para consultar o conjunto de itens do armazém marcados como com falha; O guix gc --clear-failures remove os itens do armazém do conjunto de falhas em cache. Veja Invocando guix gc.

--cores=n
-c n

Usa n núcleos de CPU para compilar cada derivação; 0 significa todos disponíveis.

O valor padrão é 0, mas pode ser substituído pelos clientes, como a opção --cores de guix build (veja Invocando guix build).

O efeito é definir a variável de ambiente NIX_BUILD_CORES no processo de compilação, que pode então usá-la para explorar o paralelismo interno — por exemplo, executando make -j$NIX_BUILD_CORES.

--max-jobs=n
-M n

Permite no máximo n tarefas de compilação em paralelo. O valor padrão é 1. Definir como 0 significa que nenhuma compilação será executada localmente; em vez disso, o daemon descarregará as compilações (veja Usando o recurso de descarregamento) ou simplesmente falhará.

--max-silent-time=segundos

Quando o processo de compilação ou substituição permanecer em silêncio por mais de segundos, encerra-o e relata uma falha de compilação.

The default value is 3600 (one hour).

O valor especificado aqui pode ser substituído pelos clientes (veja --max-silent-time).

--timeout=segundos

Da mesma forma, quando o processo de compilação ou substituição durar mais que segundos, encerra-o e relata uma falha de compilação.

O valor padrão é 24 horas.

O valor especificado aqui pode ser substituído pelos clientes (veja --timeout).

--rounds=N

Compila cada derivação n vezes seguidas e gera um erro se os resultados consecutivos da compilação não forem idênticos bit a bit. Observe que essa configuração pode ser substituída por clientes como guix build (veja Invocando guix build).

Quando usado em conjunto com --keep-failed, uma saída de comparação é mantida no armazém, sob /gnu/store/…-check. Isso facilita procurar por diferenças entre os dois resultados.

--debug

Produz uma saída de depuração.

Isso é útil para depurar problemas de inicialização do daemon, mas pode ser substituído pelos clientes, por exemplo, a opção --verbosity de guix build (veja Invocando guix build).

--chroot-directory=dir

adiciona dir ao chroot de compilação.

Isso pode alterar o resultado dos processos de compilação – por exemplo, se eles usam dependências opcionais encontradas em dir quando estão disponíveis, e não o contrário. Por esse motivo, não é recomendável fazê-lo. Em vez disso, verifique se cada derivação declara todas as entradas necessárias.

--disable-chroot

Desabilita compilações em chroot.

O uso dessa opção não é recomendado, pois, novamente, isso permitiria que os processos de compilação obtivessem acesso a dependências não declaradas. Porém, é necessário quando o guix-daemon está sendo executado em uma conta de usuário sem privilégios.

--log-compression=tipo

Compacta logs de compilação de aconrdo com tipo, que pode ser um entre gzip, bzip2 e none.

A menos que --lose-logs seja usado, todos os logs de build são mantidos em localstatedir. Para economizar espaço, o daemon os compacta automaticamente com gzip por padrão.

--discover[=yes|no]

Se deve descobrir servidores substitutos na rede local usando mDNS e DNS-SD.

Este recurso ainda é experimental. No entanto, aqui estão algumas considerações.

  1. Pode ser mais rápido/menos caro do que buscar em servidores remotos;
  2. Não há riscos de segurança, apenas substitutos genuínos serão usados (veja Autenticação de substituto);
  3. Um invasor anunciando guix publish na sua LAN não pode fornecer binários maliciosos, mas pode descobrir qual software você está instalando;
  4. Os servidores podem servir substitutos via HTTP, sem criptografia, para que qualquer pessoa na LAN possa ver qual software você está instalando.

Também é possível habilitar ou desabilitar a descoberta de servidor substituto em tempo de execução executando:

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

Desabilita “deduplicação” automática de arquivos no armazém.

Por padrão, os arquivos adicionados ao armazém são automaticamente “deduplicados”: se um arquivo recém-adicionado for idêntico a outro encontrado no armazém, o daemon tornará o novo arquivo um link físico para o outro arquivo. Isso pode reduzir notavelmente o uso do disco, às custas de um leve aumento na carga de entrada/saída no final de um processo de criação. Esta opção desativa essa otimização.

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

Diz se o coletor de lixo (GC) deve manter as saídas de derivações vivas.

Quando definido como yes, o GC manterá as saídas de qualquer derivação ativa disponível no armazém—os arquivos .drv. O padrão é no, o que significa que as saídas de derivação são mantidas somente se forem acessíveis a partir de uma raiz do GC. Veja Invocando guix gc, para mais informações sobre raízes do GC.

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

Diz se o coletor de lixo (GC) deve manter as derivações correspondentes às saídas vivas.

Quando definido como yes, como é o caso por padrão, o GC mantém derivações—ou seja, arquivos .drv—desde que pelo menos uma de suas saídas esteja ativa. Isso permite que os usuários acompanhem as origens dos itens em seu armazém. Defini-lo como no economiza um pouco de espaço em disco.

Dessa forma, definir --gc-keep-derivations como yes faz com que a vivacidade flua das saídas para as derivações, e definir --gc-keep-outputs como yes faz com que a vivacidade flua das derivações para as saídas. Quando ambos são definidos como yes, o efeito é manter todos os pré-requisitos de compilação (as fontes, o compilador, as bibliotecas e outras ferramentas de tempo de compilação) de objetos ativos no armazém, independentemente de esses pré-requisitos serem acessíveis a partir de uma raiz GC. Isso é conveniente para desenvolvedores, pois economiza reconstruções ou downloads.

--impersonate-linux-2.6

Em sistemas baseados em Linux, personifique o Linux 2.6. Isso significa que a chamada de sistema uname do kernel relatará 2.6 como o número da versão.

Isso pode ser útil para criar programas que (geralmente de forma errada) dependem do número da versão do kernel.

--lose-logs

Não mantenha logs de build. Por padrão, eles são mantidos em localstatedir/guix/log.

--system=sistema

Assuma sistema como o tipo de sistema atual. Por padrão, é o par arquitetura/kernel encontrado no momento da configuração, como x86_64-linux.

--listen=endpoint

Ouça conexões em endpoint. endpoint é interpretado como o nome do arquivo de um soquete de domínio Unix se ele começar com / (sinal de barra). Caso contrário, endpoint é interpretado como um nome de host ou nome de host e porta para ouvir. Aqui estão alguns exemplos:

--listen=/gnu/var/daemon

Ouça conexões no soquete de domínio Unix /gnu/var/daemon, criando-o se necessário.

--listen=localhost

Ouça as conexões TCP na interface de rede correspondente a localhost, na porta 44146.

--listen=128.0.0.42:1234

Ouça as conexões TCP na interface de rede correspondente ao 128.0.0.42, na porta 1234.

Esta opção pode ser repetida várias vezes, nesse caso guix-daemon aceita conexões em todos os endpoints especificados. Os usuários podem informar aos comandos do cliente a qual endpoint se conectar definindo a variável de ambiente GUIX_DAEMON_SOCKET (veja GUIX_DAEMON_SOCKET).

Nota: O protocolo daemon é unauthenticated and unencrypted. Usar --listen=host é adequado em redes locais, como clusters, onde apenas nós confiáveis podem se conectar ao daemon de compilação. Em outros casos em que o acesso remoto ao daemon é necessário, recomendamos usar soquetes de domínio Unix junto com SSH.

Quando --listen é omitido, guix-daemon escuta conexões no soquete de domínio Unix localizado em localstatedir/guix/daemon-socket/socket.


2.4 Configuração de aplicativo

Ao usar Guix sobre uma distribuição GNU/Linux que não seja um Guix System — uma chamada distro alheia — algumas etapas adicionais são necessárias para colocar tudo no seu lugar. Aqui estão algumas delas.

2.4.1 Localidades

Pacotes instalados via Guix não usarão os dados de localidade do sistema host. Em vez disso, você deve primeiro instalar um dos pacotes de localidade disponíveis com Guix e então definir a variável de ambiente GUIX_LOCPATH:

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

Observe que o pacote glibc-locales contém dados para todos os locais suportados pela GNU libc e pesa cerca de 930 MiB9. Se você precisar apenas de alguns locais, poderá definir seu pacote de locais personalizados por meio do procedimento make-glibc-utf8-locales do módulo (gnu packages base). O exemplo a seguir define um pacote contendo os vários locais UTF-8 canadenses conhecidos pela GNU libc, que pesa cerca de 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"))

A variável GUIX_LOCPATH desempenha um papel similar a LOCPATH (veja LOCPATH em The GNU C Library Reference Manual). Há duas diferenças importantes, no entanto:

  1. GUIX_LOCPATH é honrado apenas pela libc no Guix, e não pela libc fornecida por distros estrangeiras. Assim, usar GUIX_LOCPATH permite que você tenha certeza de que os programas da distro estrangeira não acabarão carregando dados de localidade incompatíveis.
  2. libc sufixa cada entrada de GUIX_LOCPATH com /X.Y, onde X.Y é a versão libc—por exemplo, 2.22. Isso significa que, caso seu perfil Guix contenha uma mistura de programas vinculados a diferentes versões libc, cada versão libc tentará carregar apenas dados de localidade no formato correto.

Isso é importante porque o formato de dados de localidade usado por diferentes versões da libc pode ser incompatível.

2.4.2 Name Service Switch

Ao usar o Guix em uma distro alheia, nós recomendamos fortemente que o sistema use o daemon de cache de serviço de nomes da biblioteca C do GNU, nscd, que deve ouvir no soquete /var/run/nscd/socket. Caso não faça isso, os aplicativos instalados com Guix podem falhar em procurar nomes de máquina e contas de usuário, ou até mesmo travar. Os próximos parágrafos explicam o porquê.

A biblioteca GNU C implementa um name service switch (NSS), que é um mecanismo extensível para “pesquisas de nomes” em geral: resolução de nomes de host, contas de usuários e muito mais (veja Name Service Switch em The GNU C Library Reference Manual).

Sendo extensível, o NSS suporta plugins, que fornecem novas implementações de pesquisa de nomes: por exemplo, o plugin nss-mdns permite a resolução de nomes de host .local, o plugin nis permite a pesquisa de contas de usuários usando o Network information service (NIS), e assim por diante. Esses "serviços de pesquisa” extras são configurados em todo o sistema em /etc/nsswitch.conf, e todos os programas em execução no sistema honram essas configurações (veja NSS Configuration File em The GNU C Reference Manual).

Quando eles realizam uma pesquisa de nome — por exemplo chamando a função getaddrinfo em C — os aplicativos primeiro tentam se conectar ao nscd; em caso de sucesso, o nscd realiza pesquisas de nome em seu nome. Se o nscd não estiver em execução, eles realizam a pesquisa de nome sozinhos, carregando os serviços de pesquisa de nome em seu próprio espaço de endereço e executando-o. Esses serviços de pesquisa de nome — os arquivos libnss_*.so — são dlopen’d, mas podem vir da biblioteca C do sistema host, em vez da biblioteca C à qual o aplicativo está vinculado (a biblioteca C vem do Guix).

E é aqui que está o problema: se seu aplicativo estiver vinculado à biblioteca C do Guix (por exemplo, glibc 2.24) e tentar carregar plugins NSS de outra biblioteca C (por exemplo, libnss_mdns.so para glibc 2.22), ele provavelmente travará ou terá suas pesquisas de nome falhando inesperadamente.

Executar nscd no sistema, entre outras vantagens, elimina esse problema de incompatibilidade binária porque esses arquivos libnss_*.so são carregados no processo nscd, não nos próprios aplicativos.

Note that nscd is no longer provided on some GNU/Linux distros, such as Arch Linux (as of Dec. 2024). nsncd can be used as a drop-in-replacement. See the nsncd repository and this blog post for more information.

2.4.3 Fontes X11

A maioria dos aplicativos gráficos usa o Fontconfig para localizar e carregar fontes e executar renderização do lado do cliente X11. O pacote fontconfig no Guix procura fontes em $HOME/.guix-profile por padrão. Assim, para permitir que aplicativos gráficos instalados com o Guix exibam fontes, você precisa instalar fontes com o Guix também. Pacotes de fontes essenciais incluem font-ghostscript, font-dejavu e font-gnu-freefont.

Depois de instalar ou remover fontes, ou quando notar que um aplicativo não encontra fontes, talvez seja necessário instalar o Fontconfig e forçar uma atualização do cache de fontes executando:

guix install fontconfig
fc-cache -rv

Para exibir texto escrito em chinês, japonês ou coreano em aplicativos gráficos, considere instalar font-adobe-source-han-sans ou font-wqy-zenhei. O primeiro tem várias saídas, uma por família de idiomas (veja Pacotes com múltiplas saídas). Por exemplo, o comando a seguir instala fontes para idiomas chineses:

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

Programas mais antigos como xterm não usam Fontconfig e, em vez disso, dependem da renderização de fontes do lado do servidor. Tais programas exigem a especificação de um nome completo de uma fonte usando XLFD (X Logical Font Description), como este:

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

Para poder usar esses nomes completos para as fontes TrueType instaladas no seu perfil Guix, você precisa estender o caminho da fonte do servidor X:

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

Depois disso, você pode executar xlsfonts (do pacote xlsfonts) para garantir que suas fontes TrueType estejam listadas lá.

2.4.4 Certificados X.509

O pacote nss-certs fornece certificados X.509, que permitem que programas autentiquem servidores Web acessados por HTTPS.

Ao usar uma Guix em uma distro alheia, você pode instalar esse pacote e definir as variáveis de ambiente relevantes de forma que os pacotes saibam onde procurar por certificados. Veja Certificados X.509, para informações detalhadas.

2.4.5 Pacotes Emacs

Quando você instala pacotes do Emacs com o Guix, os arquivos Elisp são colocados no diretório share/emacs/site-lisp/ do perfil no qual eles são instalados. As bibliotecas Elisp são disponibilizadas para o Emacs por meio da variável de ambiente EMACSLOADPATH, que é definida ao instalar o próprio Emacs.

Além disso, as definições de autoload são avaliadas automaticamente na inicialização do Emacs, pelo procedimento específico do Guix guix-emacs-autoload-packages. Este procedimento pode ser invocado interativamente para que pacotes Emacs recém-instalados sejam descobertos, sem precisar reiniciar o Emacs. Se, por algum motivo, você quiser evitar o carregamento automático dos pacotes Emacs instalados com o Guix, você pode fazer isso executando o Emacs com a opção --no-site-file (veja Init File em The GNU Emacs Manual).

Nota: A maioria das variantes do Emacs agora são capazes de fazer compilação nativa. A abordagem adotada pelo Guix Emacs, no entanto, difere muito da abordagem adotada pelo upstream.

O Upstream Emacs compila pacotes just-in-time e normalmente coloca arquivos de objetos compartilhados em uma pasta especial dentro do seu user-emacs-directory. Esses objetos compartilhados dentro da referida pasta são organizados em uma hierarquia plana, e seus nomes de arquivo contêm dois hashes para verificar o nome do arquivo original e o conteúdo do código-fonte.

O Guix Emacs, por outro lado, prefere compilar pacotes antes do tempo. Objetos compartilhados retêm muito do nome do arquivo original e nenhum hashe é adicionado para verificar o nome do arquivo original ou o conteúdo do arquivo. Crucialmente, isso permite que o Guix Emacs e os pacotes construídos contra ele sejam enxertados (veja enxertos), mas, ao mesmo tempo, o Guix Emacs não tem a verificação baseada em hash do código-fonte embutido no Emacs upstream. Como esse esquema de nomenclatura é trivial de explorar, desabilitamos a compilação just-in-time.

Observe ainda que emacs-minimal—o Emacs padrão para construir pacotes—foi configurado sem compilação nativa. Para compilar nativamente seus pacotes emacs antes do tempo, use uma transformação como --with-input=emacs-minimal=emacs.


2.5 Atualizando o Guix

Para atualizar o Guix, execute:

guix pull

Veja Invocando guix pull, para maiores informações.

Em uma distribuição estrangeira, você pode atualizar o daemon de compilação executando:

sudo -i guix pull

seguido por (supondo que sua distribuição use a ferramenta de gerenciamento de serviço systemd):

systemctl restart guix-daemon.service

No sistema Guix, a atualização do daemon é obtida reconfigurando o sistema (veja guix system reconfigure).


Próximo: , Anterior: , Acima: GNU Guix   [Conteúdo][Índice]

3 Instalação do sistema

Esta seção explica como instalar o Guix System em uma máquina. Guix, como gerenciador de pacotes, também pode ser instalado sobre um sistema GNU/Linux em execução, veja Instalação.


3.1 Limitações

Consideramos que o Guix System está pronto para uma ampla gama de casos de uso de "desktop” e servidores. As garantias de confiabilidade que ele fornece – atualizações e reversões transacionais, reprodutibilidade – tornam-no uma base sólida.

Cada vez mais serviços de sistema são fornecidos (veja Serviços).

No entanto, antes de prosseguir com a instalação, esteja ciente de que alguns serviços dos quais você depende ainda podem estar faltando na versão 4b5f040.

Mais do que um aviso de isenção de responsabilidade, este é um convite para relatar problemas (e histórias de sucesso!) e se juntar a nós para melhorá-los. Veja Contribuindo, para mais informações.


3.2 Considerações de Hardware

GNU Guix se concentra em respeitar a liberdade computacional do usuário. Ele é construído em torno do kernel Linux-libre, o que significa que apenas o hardware para o qual existem drivers e firmware de software livre é suportado. Hoje em dia, uma ampla gama de hardware disponível no mercado é suportada no GNU/Linux-libre – de teclados a placas gráficas, scanners e controladores Ethernet. Infelizmente, ainda existem áreas onde os fornecedores de hardware negam aos usuários o controle sobre sua própria computação, e tal hardware não é suportado no Guix System.

Uma das principais áreas onde faltam drivers ou firmware gratuitos são os dispositivos WiFi. Os dispositivos WiFi que funcionam incluem aqueles que usam chips Atheros (AR9271 e AR7010), que corresponde ao driver ath9k Linux-libre, e aqueles que usam chips Broadcom/AirForce (BCM43xx com Wireless-Core Revisão 5), que corresponde a o driver livre Linux b43-open. Existe firmware livre para ambos e está disponível imediatamente no Guix System, como parte do %base-firmware (veja firmware).

O instalador avisa você antecipadamente se detectar dispositivos que não funcionam devido à falta de firmware ou drivers gratuitos.

A Free Software Foundation administra Respects Your Freedom (RYF), um programa de certificação para produtos de hardware que respeitem sua liberdade e privacidade e garantam que você tenha controle sobre seu dispositivo. Recomendamos que você verifique a lista de dispositivos certificados RYF.

Outro recurso útil é o site H-Node. Ele contém um catálogo de dispositivos de hardware com informações sobre seu suporte no GNU/Linux.


3.3 Instalação em um pendrive e em DVD

Uma imagem de instalação ISO-9660 que pode ser gravada em um pendrive ou gravada em um DVD pode ser baixada em ‘https://ftp.gnu.org/gnu/guix/guix-system-install-4b5f040.x86_64-linux.iso’, onde você pode substituir x86_64-linux por um dos seguintes:

x86_64-linux

para um sistema GNU/Linux em CPUs de 64 bits compatíveis com Intel/AMD;

i686-linux

para um sistema GNU/Linux de 32 bits em CPUs compatíveis com Intel.

Certifique-se de baixar o arquivo .sig associado e verificar a autenticidade da imagem em relação a ele, seguindo estas linhas:

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

Se esse comando falhar porque você não possui a chave pública requerida, execute este comando para importá-lo:

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

e execute novamente o comando gpg --verify.

Observe que um aviso como "Esta chave não está certificada com uma assinatura confiável!” é normal.

Esta imagem contém as ferramentas necessárias para uma instalação. Ele deve ser copiado como está para um pendrive ou DVD grande o suficiente.

Copiando para um pendrive

Insira um pendrive de 1 GiB ou mais em sua máquina e determine o nome do dispositivo. Supondo que o pendrive seja conhecido como /dev/sdX, copie a imagem com:

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

O acesso a /dev/sdX geralmente requer privilégios de root.

Gravando em um DVD

Insira um DVD virgem em sua máquina e determine o nome do dispositivo. Supondo que a unidade de DVD seja conhecida como /dev/srX, copie a imagem com:

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

O acesso a /dev/srX geralmente requer privilégios de root.

Inicializando

Feito isso, você poderá reiniciar o sistema e inicializar a partir do pendrive ou DVD. O último geralmente requer que você entre no menu de inicialização do BIOS ou UEFI, onde você pode optar por inicializar a partir do pendrive. Para inicializar a partir do Libreboot, mude para o modo de comando pressionando a tecla c e digite search_grub usb.

Infelizmente, em algumas máquinas, o meio de instalação não pode ser inicializado corretamente e você só verá uma tela preta após a inicialização, mesmo depois de esperar dez minutos. Isto pode indicar que sua máquina não consegue executar o Sistema Guix; talvez você queira instalar o Guix em uma distribuição estrangeira (veja Instalação de binários). Mas não desista ainda; uma possível solução alternativa é pressionar a tecla e no menu de inicialização do GRUB e anexar nomodeset à linha de inicialização do Linux. Às vezes, o problema da tela preta também pode ser resolvido conectando um monitor diferente.

Veja Instalando Guix em uma Máquina Virtual, se, em vez disso, você quiser instalar o Guix System em uma máquina virtual (VM).


3.4 Preparando para instalação

Depois de inicializar, você pode usar o instalador gráfico guiado, o que facilita o início (veja Instalação gráfica guiada). Alternativamente, se você já está familiarizado com GNU/Linux e deseja mais controle do que o instalador gráfico oferece, você pode escolher o processo de instalação "manual” (veja Instalação manual).

O instalador gráfico está disponível em TTY1. Você pode obter shells root em TTYs 3 a 6 pressionando ctrl-alt-f3, ctrl-alt-f4, etc. TTY2 mostra esta documentação e você pode acessá-la com ctrl-alt -f2. A documentação pode ser navegada usando os comandos do leitor de informações (veja Stand-alone GNU Info). O sistema de instalação executa o daemon do mouse GPM, que permite selecionar texto com o botão esquerdo do mouse e colá-lo com o botão do meio.

Nota: A instalação requer acesso à Internet para que quaisquer dependências ausentes na configuração do sistema possam ser baixadas. Consulte a seção "Rede" abaixo.


3.5 Instalação gráfica guiada

O instalador gráfico é uma interface de usuário baseada em texto. Ele guiará você, com caixas de diálogo, pelas etapas necessárias para instalar o GNU Guix System.

As primeiras caixas de diálogo permitem que você configure o sistema conforme você o utiliza durante a instalação: você pode escolher o idioma, o layout do teclado e configurar a rede que será usada durante a instalação. A imagem abaixo mostra a caixa de diálogo de rede.

configuração de rede com o instalador
gráfico

As etapas posteriores permitem particionar seu disco rígido, conforme mostrado na imagem abaixo, escolher se deseja ou não usar sistemas de arquivos criptografados, inserir o nome do host e a senha root e criar uma conta adicional, entre outras coisas.

particionando com o instalador
gráfico

Observe que, a qualquer momento, o instalador permite sair da etapa de instalação atual e retomar uma etapa anterior, conforme imagem abaixo.

retomando o processo de instalação

Quando terminar, o instalador produz uma configuração do sistema operacional e a exibe (veja Usando o sistema de configuração). Nesse ponto você pode clicar em "OK” e a instalação continuará. Se tiver sucesso, você pode reiniciar no novo sistema e aproveitar. Veja Após a instalação do sistema, para saber o que vem a seguir!


3.6 Instalação manual

Esta seção descreve como você instalaria "manualmente” o GNU Guix System em sua máquina. Esta opção requer familiaridade com GNU/Linux, com o shell e com ferramentas de administração comuns. Se você acha que isso não é para você, considere usar o instalador gráfico guiado (veja Instalação gráfica guiada).

O sistema de instalação fornece shells root nos TTYs 3 a 6; pressione ctrl-alt-f3, ctrl-alt-f4 e assim por diante para alcançá-los. Inclui muitas ferramentas comuns necessárias para instalar o sistema, mas também é um sistema Guix completo. Isso significa que você pode instalar pacotes adicionais, caso precise, usando guix package (veja Invocando guix package).


3.6.1 Layout de teclado, rede e particionamento

Antes de instalar o sistema, você pode querer ajustar o layout do teclado, configurar a rede e particionar o disco rígido de destino. Esta seção irá guiá-lo através disso.

3.6.1.1 Disposição do teclado

A imagem de instalação usa o layout de teclado qwerty dos EUA. Se quiser alterá-lo, você pode usar o comando loadkeys. Por exemplo, o comando a seguir seleciona o layout do teclado Dvorak:

loadkeys dvorak

Consulte os arquivos em /run/current-system/profile/share/keymaps para obter uma lista de layouts de teclado disponíveis. Execute man loadkeys para obter mais informações.

3.6.1.2 Rede

Execute o seguinte comando para ver como são chamadas suas interfaces de rede:

ifconfig -a

… ou, usando o comando ip específico do GNU/Linux:

ip address

As interfaces com fio têm um nome que começa com ‘e’; por exemplo, a interface correspondente ao primeiro controlador Ethernet integrado é chamada ‘eno1’. As interfaces sem fio têm um nome que começa com ‘w’, como ‘w1p2s0’.

Conexão cabeada

Para configurar uma rede com fio execute o seguinte comando, substituindo interface pelo nome da interface com fio que você deseja usar.

ifconfig interface up

… ou, usando o comando ip específico do GNU/Linux:

ip link set interface up
Conexão sem fio

Para configurar a rede sem fio, você pode criar um arquivo de configuração para a ferramenta de configuração wpa_supplicant (sua localização não é importante) usando um dos editores de texto disponíveis, como nano:

nano wpa_supplicant.conf

Como exemplo, a sub-rotina a seguir pode ir para este arquivo e funcionará para muitas redes sem fio, desde que você forneça o SSID e a senha reais da rede à qual está se conectando:

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

Inicie o serviço sem fio e execute-o em segundo plano com o seguinte comando (substitua interface pelo nome da interface de rede que deseja usar):

wpa_supplicant -c wpa_supplicant.conf -i interface -B

Execute man wpa_supplicant para obter mais informações.

Neste ponto, você precisa adquirir um endereço IP. Em uma rede onde os endereços IP são atribuídos automaticamente via DHCP, você pode executar:

dhclient -v interface

Tente executar ping em um servidor para ver se a rede está funcionando:

ping -c 3 gnu.org

Configurar o acesso à rede é quase sempre um requisito porque a imagem não contém todos os softwares e ferramentas que podem ser necessários.

Se você precisar de acesso HTTP e HTTPS para passar por um proxy, execute o seguinte comando:

herd set-http-proxy guix-daemon URL

onde URL é a URL do proxy, por exemplo http://example.org:8118.

Se desejar, você pode continuar a instalação remotamente iniciando um servidor SSH:

herd start ssh-daemon

Certifique-se de definir uma senha com passwd ou configurar a autenticação de chave pública OpenSSH antes de efetuar login.

3.6.1.3 Particionamento de disco

A menos que isso já tenha sido feito, o próximo passo é particionar e então formatar a(s) partição(ões) de destino.

A imagem de instalação inclui várias ferramentas de particionamento, incluindo Parted (veja Overview em GNU Parted User Manual), fdisk e cfdisk. Execute-a e configure seu disco com o layout de partição que você deseja:

cfdisk

Se o seu disco usa o formato GUID Partition Table (GPT) e você planeja instalar o GRUB baseado em BIOS (que é o padrão), certifique-se de que uma partição de inicialização do BIOS esteja disponível (veja BIOS installation em manual do GNU GRUB).

Se você preferir usar o GRUB baseado em EFI, uma partição de sistema EFI (ESP) FAT32 EFI System Partition é necessária. Essa partição pode ser montada em /boot/efi, por exemplo, e deve ter o sinalizador esp definido. Por exemplo, para parted:

parted /dev/sda set 1 esp on

Nota: Não tem certeza se deve usar o GRUB baseado em EFI ou BIOS? Se o diretório /sys/firmware/efi existir na imagem de instalação, então você provavelmente deve executar uma instalação EFI, usando grub-efi-bootloader. Caso contrário, você deve usar o GRUB baseado em BIOS, conhecido como grub-bootloader. Veja Configuração do carregador de inicialização, para mais informações sobre bootloaders.

Depois de terminar de particionar o disco rígido de destino, você precisa criar um sistema de arquivos na(s) partição(ões) relevante(s)10. Para o ESP, se você tiver um e presumindo que seja /dev/sda1, execute:

mkfs.fat -F32 /dev/sda1

Para o sistema de arquivos raiz, ext4 é o formato mais amplamente usado. Outros sistemas de arquivos, como Btrfs, suportam compressão, que é relatada como um bom complemento para a desduplicação de arquivos que o daemon executa independentemente do sistema de arquivos (veja deduplication).

De preferência, atribua um rótulo aos sistemas de arquivos para que você possa se referir a eles de forma fácil e confiável nas declarações file-system (veja Sistemas de arquivos). Isso normalmente é feito usando a opção -L de mkfs.ext4 e comandos relacionados. Então, assumindo que a partição raiz de destino esteja em /dev/sda2, um sistema de arquivos com o rótulo my-root pode ser criado com:

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

Se você estiver planejando criptografar a partição raiz, você pode usar os utilitários Cryptsetup/LUKS para fazer isso (veja man cryptsetup para mais informações).

Supondo que você queira armazenar a partição raiz em /dev/sda2, a sequência de comandos para formatá-la como uma partição LUKS seria algo como isto:

cryptsetup luksFormat /dev/sda2
cryptsetup open /dev/sda2 my-partition
mkfs.ext4 -L my-root /dev/mapper/my-partition

Feito isso, monte o sistema de arquivos de destino em /mnt com um comando como (novamente, assumindo que my-root é o rótulo do sistema de arquivos raiz):

mount LABEL=my-root /mnt

Monte também quaisquer outros sistemas de arquivos que você gostaria de usar no sistema de destino em relação a este caminho. Se você optou por /boot/efi como um ponto de montagem EFI, por exemplo, monte-o em /mnt/boot/efi agora para que ele seja encontrado por guix system init depois.

Por fim, se você planeja usar uma ou mais partições swap (veja Espaço de troca (swap)), certifique-se de inicializá-las com mkswap. Supondo que você tenha uma partição swap em /dev/sda3, você executaria:

mkswap /dev/sda3
swapon /dev/sda3

Alternativamente, você pode usar um arquivo de swap. Por exemplo, supondo que no novo sistema você queira usar o arquivo /swapfile como um arquivo de swap, você executaria 11:

# Este é 10 GiB de espaço de swap. Ajuste "count" para alterar o tamanho.
dd if=/dev/zero of=/mnt/swapfile bs=1MiB count=10240
# Por segurança, torne o arquivo legível e gravável somente pelo root.
chmod 600 /mnt/swapfile
mkswap /mnt/swapfile
swapon /mnt/swapfile

Observe que se você criptografou a partição raiz e criou um arquivo de swap em seu sistema de arquivos, conforme descrito acima, a criptografia também protegerá o arquivo de swap, assim como qualquer outro arquivo naquele sistema de arquivos.


3.6.2 Prosseguindo com a instalação

Com as partições de destino prontas e a raiz de destino montada em /mnt, estamos prontos para começar. Primeiro, execute:

herd start cow-store /mnt

Isso torna /gnu/store copy-on-write, de modo que os pacotes adicionados a ele durante a fase de instalação são gravados no disco de destino em /mnt em vez de mantidos na memória. Isso é necessário porque a primeira fase do comando guix system init (veja abaixo) envolve downloads ou compilações para /gnu/store que, inicialmente, é um sistema de arquivos na memória.

Em seguida, você precisa editar um arquivo e fornecer a declaração do sistema operacional a ser instalado. Para isso, o sistema de instalação vem com três editores de texto. Recomendamos o GNU nano (veja GNU nano Manual), que suporta realce de sintaxe e correspondência de parênteses; outros editores incluem mg (um clone do Emacs) e nvi (um clone do editor original BSD vi). Recomendamos fortemente armazenar esse arquivo no sistema de arquivos raiz de destino, digamos, como /mnt/etc/config.scm. Se isso não for feito, você perderá seu arquivo de configuração depois de reinicializar o sistema recém-instalado.

Veja Usando o sistema de configuração, para uma visão geral do arquivo de configuração. As configurações de exemplo discutidas nessa seção estão disponíveis em /etc/configuration na imagem de instalação. Assim, para começar com uma configuração de sistema fornecendo um servidor de exibição gráfica (um sistema “desktop”), você pode executar algo como estas linhas:

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

Você deve prestar atenção ao que seu arquivo de configuração contém e, em particular:

  • Certifique-se de que o formulário bootloader-configuration se refere aos alvos nos quais você deseja instalar o GRUB. Ele deve mencionar grub-bootloader se você estiver instalando o GRUB da maneira legada, ou grub-efi-bootloader para sistemas UEFI mais novos. Para sistemas legados, o campo targets contém os nomes dos dispositivos, como (list "/dev/sda"); para sistemas UEFI, ele nomeia os caminhos para partições EFI montadas, como (list "/boot/efi"); certifique-se de que os caminhos estejam montados no momento e que uma entrada file-system esteja especificada em sua configuração.
  • Certifique-se de que os rótulos do seu sistema de arquivos correspondam ao valor dos respectivos campos device na sua configuração file-system, supondo que sua configuração file-system use o procedimento file-system-label no seu campo device.
  • Se houver partições criptografadas ou RAID, certifique-se de adicionar um campo mapped-devices para descrevê-las (veja Dispositivos mapeados).

Depois de terminar de preparar o arquivo de configuração, o novo sistema deve ser inicializado (lembre-se de que o sistema de arquivos raiz de destino é montado em /mnt):

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

Isso copia todos os arquivos necessários e instala o GRUB em /dev/sdX, a menos que você passe a opção --no-bootloader. Para mais informações, veja Invoking guix system. Este comando pode disparar downloads ou compilações de pacotes ausentes, o que pode levar algum tempo.

Após a conclusão desse comando – e esperamos que com sucesso! – você pode executar o comando reboot e inicializar no novo sistema. A senha root no novo sistema está inicialmente vazia; as senhas de outros usuários precisam ser inicializadas executando o comando passwd como root, a menos que sua configuração especifique o contrário (veja senhas de contas de usuário). Veja Após a instalação do sistema, para o que vem a seguir!


3.7 Após a instalação do sistema

Success, you’ve now booted into Guix System! Login to the system using the non-root user that you created during installation. You can upgrade the system whenever you want by running:

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

Isso cria uma nova geração sistema com os pacotes e serviços mais recentes.

Agora, veja Começando, junte-se a nós no #guix na rede IRC Libera.Chat ou no guix-devel@gnu.org para compartilhar sua experiência!


3.8 Instalando Guix em uma Máquina Virtual

Se você deseja instalar o Guix System em uma máquina virtual (VM) ou em um servidor virtual privado (VPS) em vez de na sua máquina favorita, esta seção é para você.

Para inicializar uma VM QEMU para instalar o Guix System em uma imagem de disco, siga estas etapas:

  1. Primeiro, recupere e descompacte a imagem de instalação do sistema Guix conforme descrito anteriormente (veja Instalação em um pendrive e em DVD).
  2. Crie uma imagem de disco que irá conter o sistema instalado. Para criar uma imagem de disco formatada em qcow2, use o comando qemu-img:
    qemu-img create -f qcow2 guix-system.img 50G
    

    O arquivo resultante será muito menor que 50 GB (normalmente menos de 1 MB), mas aumentará à medida que o dispositivo de armazenamento virtualizado for preenchido.

  3. Boot the USB installation image in a 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,readonly=on,file=guix-system-install-4b5f040.sistema.iso
    

    -enable-kvm é opcional, mas melhora significativamente o desempenho, veja Usando o Guix em uma Máquina Virtual.

  4. Agora você está como root na VM, prossiga com o processo de instalação. Veja Preparando para instalação e siga as instruções.

Quando a instalação estiver concluída, você pode inicializar o sistema que está na sua imagem guix-system.img. Veja Usando o Guix em uma Máquina Virtual, para saber como fazer isso.


3.9 Compilando a imagem de instalação

A imagem de instalação descrita acima foi criada usando o comando guix system, especificamente:

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

Dê uma olhada em gnu/system/install.scm na árvore de origem e veja também Invoking guix system para mais informações sobre a imagem de instalação.

3.10 Construindo a imagem de instalação para placas ARM

Muitas placas ARM exigem uma variante específica do bootloader U-Boot.

Se você criar uma imagem de disco e o bootloader não estiver disponível de outra forma (em outra unidade de inicialização, etc.), é aconselhável criar uma imagem que inclua o bootloader, especificamente:

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

A20-OLinuXino-Lime2 é o nome do quadro. Se você especificar um quadro inválido, uma lista de quadros possíveis será mostrada.


4 Começando

Presumivelmente, você chegou a esta seção porque instalou o Guix sobre outra distribuição (veja Instalação) ou instalou o Guix System autônomo (veja Instalação do sistema). É hora de começar a usar o Guix e esta seção tem como objetivo ajudar você a fazer isso e dar uma ideia de como é.

Guix é sobre instalar software, então provavelmente a primeira coisa que você vai querer fazer é realmente procurar por software. Digamos que você esteja procurando por um editor de texto, você pode executar:

guix search text editor

Este comando mostra a você um número de pacotes correspondentes, cada vez mostrando o nome do pacote, versão, uma descrição e informações adicionais. Depois de descobrir qual você quer usar, digamos Emacs (ah ha!), você pode prosseguir e instalá-lo (execute este comando como um usuário regular, não precisa de privilégios de root!):

guix install emacs

Você instalou seu primeiro pacote, parabéns! O pacote agora está visível no seu perfil padrão, $HOME/.guix-profile—um perfil é um diretório que contém pacotes instalados. No processo, você provavelmente notou que o Guix baixou binários pré-compilados; ou, se você escolheu explicitamente não usar binários pré-compilados, então provavelmente o Guix ainda está compilando software (veja Substitutos, para mais informações).

A menos que você esteja usando o Guix System, o comando guix install deve ter mostrado esta dica:

dica: Considere definir as variáveis de ambiente necessárias executando:

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

Alternativamente, consulte `guix package --search-paths -p "$HOME/.guix-profile"'.

De fato, agora você deve informar ao seu shell onde emacs e outros programas instalados com Guix podem ser encontrados. Colar as duas linhas acima fará exatamente isso: adicionará $HOME/.guix-profile/bin—que é onde o pacote instalado está—à variável de ambiente PATH. Você pode colar essas duas linhas no seu shell para que elas entrem em vigor imediatamente, mas o mais importante é adicioná-las a ~/.bash_profile (ou arquivo equivalente se você não usar Bash) para que as variáveis de ambiente sejam definidas na próxima vez que você gerar um shell. Você só precisa fazer isso uma vez e outras variáveis de ambiente de caminhos de busca serão cuidadas de forma semelhante—por exemplo, se você eventualmente instalar python e bibliotecas Python, GUIX_PYTHONPATH será definido.

Você pode continuar instalando pacotes à vontade. Para listar os pacotes instalados, execute:

guix package --list-installed

Para remover um pacote, você executaria, sem surpresa, guix remove. Um recurso diferenciador é a capacidade de reverter qualquer operação que você fez—instalação, remoção, atualização—simplesmente digitando:

guix package --roll-back

Isso ocorre porque cada operação é, na verdade, uma transação que cria uma nova geração. Essas gerações e a diferença entre elas podem ser exibidas executando:

guix package --list-generations

Agora você conhece os conceitos básicos de gerenciamento de pacotes!

Indo além: Veja Gerenciamento de pacote, para mais informações sobre gerenciamento de pacotes. Você pode gostar do gerenciamento de pacotes declarativo com guix package --manifest, gerenciar perfis separados com --profile, excluir gerações antigas, coletar lixo e outros recursos interessantes que serão úteis à medida que você se familiarizar com o Guix. Se você for um desenvolvedor, veja Desenvolvimento para ferramentas adicionais. E se estiver curioso, veja Recursos, para dar uma olhada nos bastidores.

Você também pode gerenciar a configuração de todo o seu ambiente pessoal — seus "arquivos dot” de usuário, serviços e pacotes — usando o Guix Home. Veja Home Configuration, para saber mais sobre isso!

Depois de instalar um conjunto de pacotes, você vai querer atualizá-los periodicamente para a versão mais recente e melhor. Para fazer isso, você primeiro vai puxar a revisão mais recente do Guix e sua coleção de pacotes:

guix pull

O resultado final é um novo comando guix, em ~/.config/guix/current/bin. A menos que você esteja no Guix System, na primeira vez que você executar guix pull, certifique-se de seguir a dica que o comando imprime e, similar ao que vimos acima, cole estas duas linhas no seu terminal e .bash_profile:

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

Você também deve instruir seu shell a apontar para este novo guix:

hash guix

Neste ponto, você está executando um Guix novinho em folha. Você pode então prosseguir e realmente atualizar todos os pacotes que você instalou anteriormente:

guix upgrade

Ao executar este comando, você verá que os binários são baixados (ou talvez alguns pacotes são construídos) e, eventualmente, você acaba com os pacotes atualizados. Se um desses pacotes atualizados não for do seu agrado, lembre-se de que você sempre pode reverter!

Você pode exibir a revisão exata do Guix que está usando atualmente executando:

guix describe

As informações exibidas são tudo o que é necessário para reproduzir exatamente o mesmo Guix, seja em um momento diferente ou em uma máquina diferente.

Indo além: Veja Invocando guix pull, para mais informações. Veja Canais, sobre como especificar canais adicionais para extrair pacotes, como replicar Guix e muito mais. Você também pode achar time-machine útil (veja Invocando guix time-machine).

Se você instalou o Guix System, uma das primeiras coisas que você vai querer fazer é atualizar seu sistema. Depois de executar guix pull para obter o Guix mais recente, você pode atualizar o sistema assim:

sudo guix system reconfigure /etc/config.scm

Após a conclusão, o sistema executa as versões mais recentes de seus pacotes de software. Assim como para pacotes, você sempre pode reverter para uma geração anterior de todo o sistema. Veja Começando, para aprender como gerenciar seu sistema.

Agora você sabe o suficiente para começar!

Recursos: O restante deste manual fornece uma referência para todas as coisas do Guix. Aqui estão alguns recursos adicionais que você pode achar úteis:

  • Veja O Livro de Receitas do GNU Guix, para uma lista de receitas no estilo "como fazer" para uma variedade de aplicações.
  • O GNU Guix Reference Card lista em duas páginas a maioria dos comandos e opções que você precisará.
  • O site contém vídeos instrucionais que abordam tópicos como o uso diário do Guix, como obter ajuda e como se tornar um colaborador.
  • Veja Documentação, para aprender como acessar a documentação no seu computador.

Esperamos que você goste do Guix tanto quanto a comunidade gosta de criá-lo!


Próximo: , Anterior: , Acima: GNU Guix   [Conteúdo][Índice]

5 Gerenciamento de pacote

O propósito do GNU Guix é permitir que os usuários instalem, atualizem e removam facilmente pacotes de software, sem precisar saber sobre seus procedimentos de construção ou dependências. O Guix também vai além desse conjunto óbvio de recursos.

Este capítulo descreve os principais recursos do Guix, bem como as ferramentas de gerenciamento de pacotes que ele fornece. Junto com a interface de linha de comando descrita abaixo (veja guix package), você também pode usar a interface Emacs-Guix (veja The Emacs-Guix Reference Manual), após instalar o pacote emacs-guix (execute o comando M-x guix-help para começar com ele):

guix install emacs-guix

5.1 Recursos

Aqui presumimos que você já deu os primeiros passos com o Guix (veja Começando) e gostaria de ter uma visão geral do que está acontecendo nos bastidores.

Ao usar o Guix, cada pacote acaba no armazém de pacotes, em seu próprio diretório — algo que lembra /gnu/store/xxx-package-1.2, onde xxx é uma string base32.

Em vez de se referir a esses diretórios, os usuários têm seu próprio perfil, que aponta para os pacotes que eles realmente querem usar. Esses perfis são armazenados dentro do diretório pessoal de cada usuário, em $HOME/.guix-profile.

Por exemplo, alice instala o GCC 4.7.2. Como resultado, /home/alice/.guix-profile/bin/gcc aponta para /gnu/store/…-gcc-4.7.2/bin/gcc. Agora, na mesma máquina, bob já tinha instalado o GCC 4.8.0. O perfil de bob simplesmente continua a apontar para /gnu/store/…-gcc-4.8.0/bin/gcc—ou seja, ambas as versões do GCC coexistem no mesmo sistema sem nenhuma interferência.

O comando guix package é a ferramenta central para gerenciar pacotes (veja Invocando guix package). Ele opera nos perfis por usuário e pode ser usado com privilégios normais de usuário.

O comando fornece as operações óbvias de instalação, remoção e atualização. Cada invocação é, na verdade, uma transação: ou a operação especificada é bem-sucedida ou nada acontece. Portanto, se o processo guix package for encerrado durante a transação, ou se ocorrer uma queda de energia durante a transação, o perfil do usuário permanecerá em seu estado anterior e continuará utilizável.

Além disso, qualquer transação de pacote pode ser revertida. Então, se, por exemplo, uma atualização instalar uma nova versão de um pacote que acabe tendo um bug sério, os usuários podem reverter para a instância anterior de seu perfil, que era conhecida por funcionar bem. Da mesma forma, a configuração global do sistema no Guix está sujeita a atualizações transacionais e roll-back (veja Começando).

Todos os pacotes no repositório de pacotes podem ser garbage-collected. O Guix pode determinar quais pacotes ainda são referenciados por perfis de usuário e remover aqueles que comprovadamente não são mais referenciados (veja Invocando guix gc). Os usuários também podem remover explicitamente gerações antigas de seus perfis para que os pacotes aos quais eles se referem possam ser coletados.

Guix adota uma abordagem puramente funcional para gerenciamento de pacotes, conforme descrito na introdução (veja Introdução). Cada nome de diretório de pacote /gnu/store contém um hash de todas as entradas que foram usadas para construir aquele pacote—compilador, bibliotecas, scripts de construção, etc. Essa correspondência direta permite que os usuários tenham certeza de que uma determinada instalação de pacote corresponde ao estado atual de sua distribuição. Também ajuda a maximizar a reprodutibilidade da construção: graças aos ambientes de construção isolados que são usados, uma determinada construção provavelmente produzirá arquivos de bits idênticos quando executada em máquinas diferentes (veja container).

Essa base permite que o Guix suporte transparent binary/source deployment. Quando um binário pré-construído para um item /gnu/store está disponível em uma fonte externa—um substituto, o Guix apenas o baixa e descompacta; caso contrário, ele constrói o pacote a partir da fonte, localmente (veja Substitutos). Como os resultados da construção são geralmente reproduzíveis bit a bit, os usuários não precisam confiar em servidores que fornecem substitutos: eles podem forçar uma construção local e desafiar os provedores (veja Invocando guix challenge).

O controle sobre o ambiente de construção é um recurso que também é útil para desenvolvedores. O comando guix shell permite que os desenvolvedores de um pacote configurem rapidamente o ambiente de desenvolvimento correto para seu pacote, sem ter que instalar manualmente as dependências do pacote em seu perfil (veja Invocando guix shell).

Todo o Guix e suas definições de pacote são controlados por versão, e guix pull permite que você "viaje no tempo” no histórico do próprio Guix (veja Invocando guix pull). Isso torna possível replicar uma instância do Guix em uma máquina diferente ou em um ponto posterior no tempo, o que por sua vez permite que você replique ambientes de software completos, enquanto retém o rastreamento de procedência preciso do software.


Próximo: , Anterior: , Acima: Gerenciamento de pacote   [Conteúdo][Índice]

5.2 Invocando guix package

O comando guix package é a ferramenta que permite aos usuários instalar, atualizar e remover pacotes, bem como reverter para configurações anteriores. Essas operações funcionam no perfil de um usuário—um diretório de pacotes instalados. Cada usuário tem um perfil padrão em $HOME/.guix-profile. O comando opera apenas no próprio perfil do usuário e funciona com privilégios de usuário normais (veja Recursos). Sua sintaxe é:

guix package opções

Principalmente, opções especifica as operações a serem executadas durante a transação. Após a conclusão, um novo perfil é criado, mas as gerações anteriores do perfil permanecem disponíveis, caso o usuário queira reverter.

Por exemplo, para remover lua e instalar guile e guile-cairo em uma única transação:

guix package -r lua -i guile guile-cairo

Para sua conveniência, também fornecemos os seguintes aliases:

  • guix search é um alias para guix package -s,
  • guix install é um alias para guix package -i,
  • guix remove é um alias para guix package -r,
  • guix upgrade é um alias para guix package -u,
  • e guix show é um alias para guix package --show=.

Esses aliases são menos expressivos que guix package e oferecem menos opções, então em alguns casos você provavelmente desejará usar guix package diretamente.

guix package também suporta uma abordagem declarativa em que o usuário especifica o conjunto exato de pacotes que estarão disponíveis e passa a ele via a opção --manifest (veja --manifest).

Para cada usuário, uma ligação simbólica para o perfil padrão do usuário é criado automaticamente em $HOME/.guix-profile. Esta ligação simbólico sempre aponta para a geração atual do perfil padrão do usuário. Assim, os usuários podem adicionar $HOME/.guix-profile/bin à sua variável de ambiente PATH e assim por diante. Se você não estiver usando o sistema Guix, considere adicionar as seguintes linhas ao seu ~/.bash_profile (veja Bash Startup Files em Manual de referência do GNU Bash) para que os shells recém-gerados obtenham todos as definições corretas de variáveis de ambiente:

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

Em uma configuração multiusuário, os perfis de usuário são armazenados em um local registrado como raiz do coletor de lixo, para o qual $HOME/.guix-profile aponta (veja Invocando guix gc). Esse diretório geralmente é localstatedir/guix/profiles/per-user/usuário, onde localstatedir é o valor passado para configure como -- localstatedir e usuário é o nome do usuário. O diretório per-user é criado quando guix-daemon é iniciado, e o subdiretório usuário é criado por guix package.

As seguintes opções podem ser usadas:

--install=pacote
-i pacote

Instale os pacotes especificados.

Cada pacote pode especificar um nome de pacote simples como guile, opcionalmente seguido por uma arroba e número de versão, como guile@3.0.7 ou simplesmente guile@3.0. Neste último caso, a versão mais recente prefixada por 3.0 é selecionada.

Se nenhum número de versão for especificado, a versão mais recente disponível será selecionada. Além disso, tal especificação pacote pode conter dois pontos, seguido pelo nome de uma das saídas do pacote, como em gcc:doc ou binutils@2.22:lib (veja Pacotes com múltiplas saídas).

Pacotes com um nome correspondente (e opcionalmente versão) são procurados entre os módulos de distribuição GNU (veja Módulos de pacote).

Alternativamente, um pacote pode especificar diretamente um nome de arquivo de armazém como /gnu/store/...-guile-3.0.7, conforme produzido por, por exemplo, guix build.

Às vezes, os pacotes têm propagated-inputs: são dependências que são instaladas automaticamente junto com o pacote necessário (veja propagated-inputs em package objetos, para obter informações sobre entradas propagadas em definições de pacote).

Um exemplo é a biblioteca GNU MPC: seus arquivos de cabeçalho C referem-se aos da biblioteca GNU MPFR, que por sua vez se refere aos da biblioteca GMP. Assim, ao instalar o MPC, as bibliotecas MPFR e GMP também são instaladas no perfil; a remoção do MPC também remove o MPFR e o GMP — a menos que eles também tenham sido explicitamente instalados pelo usuário.

Além disso, os pacotes às vezes dependem da definição de variáveis de ambiente para seus caminhos de pesquisa (veja a explicação de --search-paths abaixo). Quaisquer definições de variáveis ambientais ausentes ou possivelmente incorretas são relatadas aqui.

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

Instale o pacote avaliado por exp.

exp deve ser uma expressão de Scheme avaliada como um objeto <package>. Esta opção é particularmente útil para desambiguar variantes de um pacote com o mesmo nome, com expressões como (@(gnu packages commencement) guile-final).

Observe que esta opção instala a primeira saída do pacote especificado, o que pode ser insuficiente quando for necessária uma saída específica de um pacote de múltiplas saídas.

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

Instale o pacote avaliado pelo código em arquivo.

Por exemplo, arquivo pode conter uma definição como esta (veja Definindo pacotes):

(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+))

Os desenvolvedores podem achar útil incluir um arquivo guix.scm na raiz da árvore de origem do projeto que pode ser usado para testar instantâneos de desenvolvimento e criar ambientes de desenvolvimento reproduzíveis (veja Invocando guix shell).

O arquivo também pode conter uma representação JSON de uma ou mais definições de pacote. Executar guix package -f em hello.json com o seguinte conteúdo resultaria na instalação do pacote greeter após construir myhello:

[
  {
    "name": "myhello",
    "version": "2.10",
    "source": "mirror://gnu/hello/hello-2.10.tar.gz",
    "build-system": "gnu",
    "arguments": {
      "tests?": false
    },
    "home-page": "https://www.gnu.org/software/hello/",
    "synopsis": "Hello, GNU world: An example GNU package",
    "description": "GNU Hello prints a greeting.",
    "license": "GPL-3.0+",
    "native-inputs": ["gettext"]
  },
  {
    "name": "greeter",
    "version": "1.0",
    "source": "mirror://gnu/hello/hello-2.10.tar.gz",
    "build-system": "gnu",
    "arguments": {
      "test-target": "foo",
      "parallel-build?": false
    },
    "home-page": "https://example.com/",
    "synopsis": "Greeter using GNU Hello",
    "description": "This is a wrapper around GNU Hello.",
    "license": "GPL-3.0+",
    "inputs": ["myhello", "hello"]
  }
]
--remove=pacote
-r pacote

Remova os pacotes especificados.

Quanto a --install, cada pacote pode especificar um número de versão e/ou nome de saída além do nome do pacote. Por exemplo, ‘-r glibc:debug’ removeria a saída de glibc.

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

Atualize todos os pacotes instalados. Se um ou mais regexps forem especificados, atualize apenas os pacotes instalados cujo nome corresponda a um regexp. Veja também a opção --do-not-upgrade abaixo.

Note que isso atualiza o pacote para a versão mais recente dos pacotes encontrados na distribuição atualmente instalada. Para atualizar sua distribuição, você deve executar regularmente guix pull (veja Invocando guix pull).

Ao atualizar, as transformações de pacote que foram aplicadas originalmente ao criar o perfil são automaticamente reaplicadas (veja Opções de transformação de pacote). Por exemplo, suponha que você instalou o Emacs pela ponta do seu branch de desenvolvimento com:

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

Na próxima vez que você executar guix upgrade, o Guix puxará novamente a ponta do branch de desenvolvimento do Emacs e compilará emacs-next a partir desse checkout.

Observe que opções de transformação como --with-branch e --with-source dependem do estado externo; cabe a você garantir que elas funcionem conforme o esperado. Você também pode descartar transformações que se aplicam a um pacote executando:

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

Quando usado junto com a opção --upgrade, não atualize nenhum pacote cujo nome corresponda a um regexp. Por exemplo, para atualizar todos os pacotes no perfil atual, exceto aqueles que contêm a substring "emacs”:

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

Crie uma nova geração do perfil a partir do objeto manifest retornado pelo código Scheme em arquivo. Esta opção pode ser repetida várias vezes, em cujo caso os manifestos são concatenados.

Isso permite que você declarando o conteúdo do perfil em vez de construí-lo por meio de uma sequência de --install e comandos similares. A vantagem é que arquivo pode ser colocado sob controle de versão, copiado para máquinas diferentes para reproduzir o mesmo perfil, e assim por diante.

arquivo deve retornar um objeto manifest, que é aproximadamente uma lista de pacotes:

(use-package-modules guile emacs)

(packages->manifest
 (list emacs
       guile-2.0
       ;; Usa uma saída de pacote específica.
       (list guile-2.0 "debug")))

Veja Escrevendo manifestos, para obter informações sobre como escrever um manifesto. Veja --export-manifest, para aprender como obter um arquivo de manifesto de um perfil existente.

--roll-back

Reverta para a geração anterior do perfil, ou seja, desfaça a última transação.

Quando combinado com opções como --install, a reversão ocorre antes de qualquer outra ação.

Ao reverter da primeira geração que realmente contém pacotes instalados, o perfil é feito para apontar para a geração zero, que não contém arquivos além de seus próprios metadados.

Após ter revertido, instalar, remover ou atualizar pacotes sobrescreve gerações futuras anteriores. Assim, o histórico das gerações em um perfil é sempre linear.

--switch-generation=padrão
-S padrão

Mude para uma geração específica definida por padrão.

padrão pode ser um número de geração ou um número prefixado com "+” ou "-”. O último significa: mover para frente/para trás por um número especificado de gerações. Por exemplo, se você quiser retornar para a última geração após --roll-back, use --switch-generation=+1.

A diferença entre --roll-back e --switch-generation=-1 é que --switch-generation não fará uma geração zero, então se uma geração especificada não existir, a geração atual não será alterada.

--search-paths[=tipo]

Relata definições de variáveis de ambiente, na sintaxe Bash, que podem ser necessárias para usar o conjunto de pacotes instalados. Essas variáveis de ambiente são usadas para especificar caminhos de busca para arquivos usados por alguns dos pacotes instalados.

Por exemplo, o GCC precisa que as variáveis de ambiente CPATH e LIBRARY_PATH sejam definidas para que ele possa procurar cabeçalhos e bibliotecas no perfil do usuário (veja Environment Variables em Usando o GNU Compiler Collection (GCC)). Se o GCC e, digamos, a biblioteca C estiverem instalados no perfil, então --search-paths sugerirá definir essas variáveis como perfil/include e perfil/lib, respectivamente (veja Caminhos de pesquisa, para obter informações sobre especificações de caminho de pesquisa associadas a pacotes.)

O caso de uso típico é definir essas variáveis de ambiente no shell:

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

tipo pode ser um dos seguintes: exact, prefix ou suffix, o que significa que as definições de variáveis de ambiente retornadas serão configurações exatas ou prefixos ou sufixos do valor atual dessas variáveis. Quando omitido, tipo assume como padrão exact.

Esta opção também pode ser usada para calcular os caminhos de busca combinados de vários perfis. Considere este exemplo:

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

O último comando acima relata sobre a variável GUILE_LOAD_PATH, embora, considerados individualmente, nem foo nem bar levariam a essa recomendação.

--profile=perfil
-p perfil

Use perfil em vez do perfil padrão do usuário.

perfil deve ser o nome de um arquivo que será criado após a conclusão. Concretamente, perfil será uma mera ligação simbólica ("symlink”) apontanda para o perfil real onde os pacotes estão instalados:

$ guix install hello -p ~/code/my-profile
…
$ ~/code/my-profile/bin/hello
Olá, mundo!

Tudo o que é preciso para se livrar do perfil é remover este link simbólico e seus irmãos que apontam para gerações específicas:

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

Liste todos os perfis dos usuários:

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

Ao executar como root, liste todos os perfis de todos os usuários.

--allow-collisions

Permitir pacotes de colisão no novo perfil. Use por sua conta e risco!

Por padrão, guix package relata como um erro collisions no perfil. Colisões acontecem quando duas ou mais versões ou variantes diferentes de um determinado pacote acabam no perfil.

--bootstrap

Use o bootstrap Guile para construir o perfil. Esta opção é útil somente para desenvolvedores de distribuição.

Além dessas ações, guix package suporta as seguintes opções para consultar o estado atual de um perfil ou a disponibilidade de pacotes:

--search=regexp
-s regexp

Liste os pacotes disponíveis cujo nome, sinopse ou descrição correspondem a regexp (sem distinção entre maiúsculas e minúsculas), classificados por relevância. Imprima todos os metadados dos pacotes correspondentes no formato recutils (veja bancos de dados GNU recutils em manual GNU recutils).

Isso permite que campos específicos sejam extraídos usando o comando recsel, por exemplo:

$ 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

Da mesma forma, para mostrar o nome de todos os pacotes disponíveis sob os termos da GNU LGPL versão 3:

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

name: gmp
…

Também é possível refinar os resultados da pesquisa usando vários sinalizadores -s para guix package, ou vários argumentos para guix search. Por exemplo, o comando a seguir retorna uma lista de jogos de tabuleiro (desta vez usando o alias guix search):

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

Se omitissemos -s game, também teríamos pacotes de software que lidam com placas de circuito impresso; remover os colchetes angulares em torno de board adicionaria ainda mais pacotes relacionados a teclados.

E agora um exemplo mais elaborado. O comando a seguir procura bibliotecas criptográficas, filtra as bibliotecas Haskell, Perl, Python e Ruby e imprime o nome e a sinopse dos pacotes correspondentes:

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

Veja Selection Expressions em manual GNU recutils, para obter mais informações sobre expressões de seleção para recsel -e.

--show=pacote

Exibe detalhes sobre pacote, retirados da lista de pacotes disponíveis, no formato recutils (veja GNU Recutils Databases em 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
…

Você também pode especificar o nome completo de um pacote para obter detalhes apenas sobre uma versão específica dele (desta vez usando o alias guix show):

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

Lista os pacotes instalados mais recentemente no perfil especificado, com os pacotes instalados mais recentemente mostrados por último. Quando regexp for especificado, liste apenas os pacotes instalados cujo nome corresponda a regexp.

Para cada pacote instalado, imprima os seguintes itens, separados por tabulações: o nome do pacote, sua string de versão e a parte do pacote que está instalada (por exemplo, out para a saída predefinida, include para os seus cabeçalhos, etc.) e o caminho deste pacote no armazém.

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

Lista de pacotes atualmente disponíveis na distribuição para este sistema (veja Distribuição GNU). Quando regexp for especificado, liste apenas os pacotes disponíveis cujo nome corresponda a regexp.

Para cada pacote, imprima os seguintes itens separados por tabulações: seu nome, sua string de versão, as partes do pacote (veja Pacotes com múltiplas saídas) e o local de origem de sua definição.

--list-generations[=padrão]
-l [padrão]

Retorne uma lista de gerações junto com suas datas de criação; para cada geração, exiba os pacotes instalados, com os pacotes instalados mais recentemente mostrados por último. Observe que a geração zero nunca é mostrada.

Para cada pacote instalado, mostre os seguintes itens, separados por tabulações: o nome de um pacote, sua string de versão, a parte do pacote que está instalada (veja Pacotes com múltiplas saídas) e a localização deste pacote em o armazém.

Quando padrão é usado, o comando retorna apenas gerações correspondentes. Os padrões válidos incluem:

  • Inteiros e números inteiros separados por vírgula. Ambos os padrões denotam números de geração. Por exemplo, --list-generations=1 retorna o primeiro.

    E --list-generations=1,8,2 gera três gerações na ordem especificada. Não são permitidos espaços nem vírgulas finais.

  • Intervalos. --list-generations=2..9 mostra o gerações especificadas e tudo mais. Observe que o início de um intervalo deve ser menor que o seu final.

    Também é possível omitir o ponto final. Por exemplo, --list-generations=2.. retorna todas as gerações começando pela segunda.

  • Duração. Você também pode visitar os últimos N dias, semanas, ou meses passando um número inteiro junto com a primeira letra da duração. Por exemplo, --list-generations=20d lista gerações com até 20 dias.
--delete-generations[=padrão]
-d [padrão]

Quando padrão for omitido, exclua todas as gerações, exceto a atual.

Este comando aceita os mesmos padrões de --list-Generations. Quando pattern for especificado, exclua as gerações correspondentes. Quando padrão especifica uma duração, as gerações mais antigas que a duração especificada correspondem. Por exemplo, --delete-generations=1m exclui gerações com mais de um mês.

Se a geração atual corresponder, ela será não excluída. Além disso, a geração zero nunca é excluída.

Observe que a exclusão de gerações impede a reversão para elas. Conseqüentemente, este comando deve ser usado com cuidado.

--export-manifest

Escreva na saída padrão um manifesto adequado para --manifest correspondente ao(s) perfil(s) selecionado(s).

Esta opção destina-se a ajudá-lo a migrar do modo operacional "imperativo” — executando guix install, guix upgrade, etc.—para o modo declarativo que --manifest ofertas.

Observe que o manifesto resultante aproxima o que seu perfil realmente contém; por exemplo, dependendo de como seu perfil foi criado, ele pode se referir a pacotes ou versões de pacotes que não são exatamente o que você especificou.

Tenha em mente que um manifesto é puramente simbólico: ele contém apenas nomes de pacotes e possivelmente versões, e seu significado varia com o tempo. Se você quiser “fixar” canais nas revisões que foram usadas para construir o(s) perfil(es), veja --export-channels abaixo.

--export-channels

Escreva na saída padrão a lista de canais usados pelo(s) perfil(s) selecionado(s), em um formato adequado para guix pull --channels ou guix time-machine --channels (veja Canais) . .

Juntamente com --export-manifest, esta opção fornece informações que permitem replicar o perfil atual (veja Replicando Guix).

No entanto, observe que a saída deste comando aproxima o que foi realmente usado para construir este perfil. Em particular, um único perfil pode ter sido construído a partir de diversas revisões diferentes do mesmo canal. Nesse caso, --export-manifest escolhe a última e escreve a lista de outras revisões em um comentário. Se você realmente precisa escolher pacotes de análises de canais diferentes, você pode usar inferiores em seu manifesto para fazer isso (veja Inferiores).

Juntamente com --export-manifest, este é um bom ponto de partida se você estiver disposto a migrar do modelo "imperativo" para o modelo totalmente declarativo que consiste em um arquivo de manifesto junto com um arquivo de canais fixando o canal exato revisão(ões) que você deseja.

Finalmente, como guix package pode realmente iniciar processos de construção, ele suporta todas as opções de construção comuns (veja Opções de compilação comuns). Ele também oferece suporte a opções de transformação de pacotes, como --with-source, e as preserva em atualizações (veja Opções de transformação de pacote).


5.3 Substitutos

Guix suporta implantação transparente de origem/binário, o que significa que ele pode construir coisas localmente ou baixar itens pré-construídos de um servidor, ou ambos. Chamamos esses itens pré-construídos de substitutos—eles são substitutos para resultados de construção local. Em muitos casos, baixar um substituto é muito mais rápido do que construir coisas localmente.

Substitutos podem ser qualquer coisa resultante de uma construção de derivação (veja Derivações). Claro, no caso comum, eles são binários de pacotes pré-construídos, mas tarballs de origem, por exemplo, que também resultam de construções de derivação, podem estar disponíveis como substitutos.


5.3.1 Official Substitute Servers

bordeaux.guix.gnu.org e ci.guix.gnu.org são ambos front-ends para farms de build oficiais que constroem pacotes do Guix continuamente para algumas arquiteturas e os disponibilizam como substitutos. Essas são a fonte padrão de substitutos; que podem ser substituídos passando a opção --substitute-urls para guix-daemon (veja guix-daemon --substitute-urls) ou para ferramentas de cliente como guix package (veja client --substitute-urls option).

URLs substitutos podem ser HTTP ou HTTPS. HTTPS é recomendado porque as comunicações são criptografadas; por outro lado, usar HTTP torna todas as comunicações visíveis para um bisbilhoteiro, que pode usar as informações coletadas para determinar, por exemplo, se seu sistema tem vulnerabilidades de segurança não corrigidas.

Substitutos das build farms oficiais são habilitados por padrão ao usar o Guix System (veja Distribuição GNU). No entanto, eles são desabilitados por padrão ao usar o Guix em uma distribuição estrangeira, a menos que você os tenha habilitado explicitamente por meio de uma das etapas de instalação recomendadas (veja Instalação). Os parágrafos a seguir descrevem como habilitar ou desabilitar substitutos para a build farm oficial; o mesmo procedimento também pode ser usado para habilitar substitutos para qualquer outro servidor substituto.


5.3.2 Autorização de servidor substituto

Para permitir que o Guix baixe substitutos de bordeaux.guix.gnu.org, ci.guix.gnu.org ou um espelho, você deve adicionar a chave pública relevante à lista de controle de acesso (ACL) de importações de arquivo, usando o comando guix archive (veja Invocando guix archive). Fazer isso implica que você confia que o servidor substituto não será comprometido e servirá substitutos genuínos.

Nota: Se você estiver usando o Guix System, pode pular esta seção: O Guix System autoriza substitutos de bordeaux.guix.gnu.org e ci.guix.gnu.org por padrão.

As chaves públicas para cada um dos servidores substitutos mantidos pelo projeto são instaladas junto com o Guix, em prefix/share/guix/, onde prefix é o prefixo de instalação do Guix. Se você instalou o Guix a partir da fonte, certifique-se de verificar a assinatura GPG de guix-4b5f040.tar.gz, que contém este arquivo de chave pública. Então, você pode executar algo como isto:

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

Uma vez que isso esteja pronto, a saída de um comando como guix build deve mudar de algo como:

$ guix build emacs --dry-run
A seguinte derivações seriam compiladas:
   /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
…

para algo como:

$ guix build emacs --dry-run
112.3 MB seriam baixados:
   /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
…

O texto mudou de "As seguintes derivações seriam construídas” para "112,3 MB seriam baixados”. Isso indica que os substitutos dos servidores substitutos configurados são utilizáveis e serão baixados, quando possível, para construções futuras.

O mecanismo de substituição pode ser desabilitado globalmente executando guix-daemon com --no-substitutes (veja Invocando guix-daemon). Ele também pode ser desabilitado temporariamente passando a opção --no-substitutes para guix package, guix build e outras ferramentas de linha de comando.


5.3.3 Obtendo substitutos de outros servidores

Guix pode procurar e buscar substitutos de vários servidores. Isso é útil quando você está usando pacotes de canais adicionais para os quais o servidor oficial não tem substitutos, mas outro servidor os fornece. Outra situação em que isso é útil é quando você prefere baixar do servidor substituto da sua organização, recorrendo ao servidor oficial apenas como um fallback ou descartando-o completamente.

Você pode dar ao Guix uma lista de URLs de servidores substitutos e ele irá verificá-los na ordem especificada. Você também precisa autorizar explicitamente as chaves públicas dos servidores substitutos para instruir o Guix a aceitar os substitutos que eles assinam.

No Guix System, isso é obtido modificando a configuração do serviço guix. Como o serviço guix faz parte das listas padrão de serviços, %base-services e %desktop-services, você pode usar modify-services para alterar sua configuração e adicionar as URLs e chaves substitutas que você deseja (veja modify-services).

Como exemplo, suponha que você queira buscar substitutos de guix.example.org e autorizar a chave de assinatura desse servidor, além do padrão bordeaux.guix.gnu.org e ci.guix.gnu.org. A configuração do sistema operacional resultante será algo como:

(operating-system
 ;; …
 (services
  ;; Suponha que estamos começando com '%desktop-services'. Substitua-o
  ;; pela lista de serviços que você está realmente usando.
  (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)))))))

Isso pressupõe que o arquivo key.pub contém a chave de assinatura de guix.example.org. Com essa alteração em vigor no arquivo de configuração do seu sistema operacional (digamos /etc/config.scm), você pode reconfigurar e reiniciar o serviço guix-daemon ou reinicializar para que as alterações entrem em vigor:

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

Se você estiver executando o Guix em uma "distribuição estrangeira”, você deve seguir os seguintes passos para obter substitutos de servidores adicionais:

  1. Edite o arquivo de configuração de serviço para guix-daemon; ao usar systemd, normalmente é /etc/systemd/system/guix-daemon.service. Adicione a opção --substitute-urls na linha de comando guix-daemon e liste as URLs de interesse (veja guix-daemon --substitute-urls):
    … --substitute-urls='https://guix.example.org https://bordeaux.guix.gnu.org https://ci.guix.gnu.org'
    
  2. Reinicie o daemon. Para systemd, é assim:
    systemctl daemon-reload
    systemctl restart guix-daemon.service
    
  3. Autorize a chave do novo servidor (veja Invocando guix archive):
    guix archive --authorize < key.pub
    

    Novamente, isso pressupõe que key.pub contém a chave pública que guix.example.org usa para assinar substitutos.

Agora você está pronto! Os substitutos serão preferencialmente retirados de https://guix.example.org, usando bordeaux.guix.gnu.org e então ci.guix.gnu.org como opções de fallback. Claro que você pode listar quantos servidores substitutos quiser, com a ressalva de que a pesquisa de substitutos pode ser desacelerada se muitos servidores precisarem ser contatados.

Troubleshooting: Para diagnosticar problemas, você pode executar guix weather. Por exemplo, executando:

guix weather coreutils

não apenas informa qual dos servidores atualmente configurados tem substitutos para o pacote coreutils, mas também informa se um desses servidores não está autorizado. Veja Invocando guix weather, para mais informações.

Observe que também há situações em que é possível adicionar a URL de um servidor substituto sem autorizar sua chave. Veja Autenticação de substituto, para entender esse ponto.


5.3.4 Autenticação de substituto

Guix detecta e gera um erro ao tentar usar um substituto que foi adulterado. Da mesma forma, ele ignora substitutos que não são assinados, ou que não são assinados por uma das chaves listadas na ACL.

Há uma exceção, no entanto: se um servidor não autorizado fornecer substitutos que sejam bit-for-bit idênticos aos fornecidos por um servidor autorizado, então o servidor não autorizado se torna elegível para downloads. Por exemplo, suponha que escolhemos dois servidores substitutos com esta opção:

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

Se a ACL contiver apenas a chave para ‘b.example.org’, e se ‘a.example.org’ servir os substitutos exatamente os mesmos, então o Guix baixará os substitutos de ‘a.example.org’ porque ele vem primeiro na lista e pode ser considerado um espelho de ‘b.example.org’. Na prática, máquinas de construção independentes geralmente produzem os mesmos binários, graças às construções reproduzíveis em bits (veja abaixo).

Ao usar HTTPS, o certificado X.509 do servidor é não validado (em outras palavras, o servidor não é autenticado), ao contrário do que os clientes HTTPS, como navegadores da Web, geralmente fazem. Isso ocorre porque o Guix autentica as próprias informações substitutas, conforme explicado acima, que é o que nos importa (enquanto os certificados X.509 são sobre autenticação de ligações entre nomes de domínio e chaves públicas).


5.3.5 Configurações de proxy

Os substitutos são baixados por HTTP ou HTTPS. As variáveis de ambiente http_proxy e https_proxy podem ser definidas no ambiente de guix-daemon e são honradas para downloads de substitutos. Observe que o valor dessas variáveis de ambiente no ambiente onde guix build, guix package e outros comandos de cliente são executados não tem absolutamente nenhum efeito.


5.3.6 Falha na substituição

Mesmo quando um substituto para uma derivação estiver disponível, às vezes a tentativa de substituição falhará. Isso pode acontecer por vários motivos: o servidor substituto pode estar offline, o servidor substituto pode ter sido excluído recentemente, a conexão pode ter sido interrompida, etc.

Quando os substitutos estão habilitados e um substituto para uma derivação está disponível, mas a tentativa de substituição falha, o Guix tentará construir a derivação localmente dependendo se --fallback foi fornecido ou não (veja opção de compilação comum --fallback). Especificamente, se --fallback for omitido, nenhuma construção local será executada e a derivação será considerada como tendo falhado. No entanto, se --fallback for fornecido, o Guix tentará construir a derivação localmente, e o sucesso ou fracasso da derivação dependerá do sucesso ou fracasso da construção local. Observe que quando os substitutos estão desabilitados ou nenhum substituto está disponível para a derivação em questão, uma construção local sempre será executada, independentemente de --fallback ter sido fornecido ou não.

Para ter uma ideia de quantos substitutos estão disponíveis no momento, você pode tentar executar o comando guix weather (veja Invocando guix weather). Este comando fornece estatísticas sobre os substitutos fornecidos por um servidor.


5.3.7 Confiança em binários

Hoje, o controlo de cada indivíduo sobre a sua própria computação está à mercê de instituições, empresas e grupos com poder e determinação suficientes para subverter a infra-estrutura informática e explorar as suas fraquezas. Embora o uso de substitutos possa ser conveniente, encorajamos os usuários a também construírem por conta própria, ou até mesmo executarem seu próprio build farm, de modo que os servidores substitutos executados pelo projeto sejam um alvo menos interessante. Uma maneira de ajudar é publicando o software que você constrói usando guix publish para que outros tenham mais uma opção de servidor para baixar substitutos (veja Invocando guix publish).

Guix has the foundations to maximize build reproducibility (veja Recursos). In most cases, independent builds of a given package or derivation should yield bit-identical results. Thus, through a diverse set of independent package builds, we can strengthen the integrity of our systems. The guix challenge command aims to help users assess substitute servers, and to assist developers in finding out about non-deterministic package builds (veja Invocando guix challenge). Similarly, the --check option of guix build allows users to check whether previously-installed substitutes are genuine by rebuilding them locally (veja guix build --check). To force a full rebuild of a package (ignoring security updates via grafts (veja Atualizações de segurança), if any grafts exist—which is not always the case), use --check together with --no-grafts (veja --no-grafts). Because grafts are built as their own derivation, if the package you want to rebuild is subject to being grafted, merely using --check will only rebuild the grafting derivation, and not actually recompile the package.

No futuro, queremos que o Guix tenha suporte para publicação e recuperação de binários de/para outros usuários, de forma peer-to-peer. Se você gostaria de discutir este projeto, entre em contato conosco em guix-devel@gnu.org.


5.4 Pacotes com múltiplas saídas

Frequentemente, os pacotes definidos no Guix têm uma única saída — ou seja, o pacote fonte leva a exatamente um diretório no armazém. Ao executar guix install glibc, instala-se a saída padrão do pacote GNU libc; A saída padrão é chamada out, mas seu nome pode ser omitido conforme mostrado neste comando. Neste caso específico, a saída padrão de glibc contém todos os arquivos de cabeçalho C, bibliotecas compartilhadas, bibliotecas estáticas, documentação de informações e outros arquivos de suporte.

Às vezes é mais apropriado separar os vários tipos de arquivos produzidos a partir de um único pacote fonte em saídas separadas. Por exemplo, a biblioteca GLib C (usada pelo GTK+ e pacotes relacionados) instala mais de 20 MiB de documentação de referência como páginas HTML. Para economizar espaço para usuários que não precisam, a documentação vai para uma saída separada, chamada doc. Para instalar a saída principal do GLib, que contém tudo menos a documentação, seria executado:

guix install glib

O comando para instalar sua documentação é:

guix install glib:doc

Embora a sintaxe de dois pontos funcione para especificação de linha de comando de saídas de pacotes, ela não funcionará ao usar uma variável de pacote no código do Scheme. Por exemplo, para adicionar a documentação do glib aos pacotes instalados globalmente de um operating-system (veja operating-system Reference), uma lista de dois itens, sendo o primeiro a variável de pacote e o segundo o nome da saída a ser selecionada (uma string), devem ser usados:

(use-modules (gnu packages glib))
;; glib-with-documentation é o símbolo de Guile para o pacote glib
(operating-system
 ...
 (packages
  (append
   (list (list glib-with-documentation "doc"))
         %base-packages)))

Alguns pacotes instalam programas com diferentes "pegadas de dependência”. Por exemplo, o pacote WordNet instala ferramentas de linha de comando e interfaces gráficas de usuário (GUIs). Os primeiros dependem exclusivamente da biblioteca C, enquanto os últimos dependem apenas do Tcl/Tk e das bibliotecas X subjacentes. Nesse caso, deixamos as ferramentas de linha de comando na saída padrão, enquanto as GUIs ficam em uma saída separada. Isso permite que usuários que não precisam de GUIs economizem espaço. O comando guix size pode ajudar a descobrir tais situações (veja Invocando guix size). guix graph também pode ser útil (veja Invocando guix graph).

Existem vários desses pacotes de múltiplas saídas na distribuição GNU. Outros nomes de saída convencionais incluem lib para bibliotecas e possivelmente arquivos de cabeçalho, bin para programas independentes e debug para informações de depuração (veja Instalando arquivos de depuração). A saída de um pacote está listada na terceira coluna da saída de guix package --list-available (veja Invocando guix package).


5.5 Invocando guix locate

Há tantos softwares gratuitos por aí que, mais cedo ou mais tarde, você precisará procurar por pacotes. O comando guix search que vimos antes (veja Invocando guix package) permite pesquisar por palavras-chave:

guix search video editor

Às vezes, você deseja descobrir qual pacote fornece um determinado arquivo, e é aí que entra guix locate. Veja como você pode encontrar o comando ls:

$ guix locate ls
coreutils@9.1       /gnu/store/…-coreutils-9.1/bin/ls

É claro que o comando funciona para qualquer arquivo, não apenas para comandos:

$ guix locate unistr.h
icu4c@71.1          /gnu/store/…/include/unicode/unistr.h
libunistring@1.0    /gnu/store/…/include/unistr.h

Você também pode especificar padrões de globo com curingas. Por exemplo, aqui está como você procuraria pacotes que fornecem arquivos .service:

$ guix locate -g '*.service'
man-db@2.11.1        …/lib/systemd/system/man-db.service
wpa-supplicant@2.10  …/system-services/fi.w1.wpa_supplicant1.service

O comando guix locate depende de um banco de dados que mapeia nomes de arquivos para nomes de pacotes. Por padrão, ele cria automaticamente esse banco de dados, caso ele ainda não exista, percorrendo os pacotes disponíveis localmente, o que pode levar alguns minutos (dependendo do tamanho do seu armazém e da velocidade do seu dispositivo de armazenamento).

Nota: Por enquanto, guix locate constrói seu banco de dados baseado em conhecimento puramente local – o que significa que você não encontrará pacotes que nunca chegaram ao sue armazém. Eventualmente, ele suportará o download de um banco de dados pré-construído para que você possa encontrar mais pacotes.

Por padrão, guix locate primeiro tenta procurar um banco de dados de todo o sistema, geralmente em /var/cache/guix/locate; Se não existir ou for muito antigo, ele retornará ao banco de dados por usuário, por padrão em ~/.cache/guix/locate. Em um sistema multiusuário, os administradores podem querer atualizar periodicamente o banco de dados de todo o sistema para que todos os usuários possam se beneficiar dele, por exemplo, configurando package-database-service-type (veja package-database-service-type).

A sintaxe geral é:

guix locate [opções…] arquivo

... onde arquivo é o nome de um arquivo a ser pesquisado (especificamente, o "nome base" do arquivo: arquivos cujos diretórios pais são chamados arquivo não são correspondidos).

As opções disponíveis são as seguintes:

--glob
-g

Interprete arquivo… como padrões de globo—padrões que podem incluir caracteres curinga, como ‘*.scm’ para denotar todos os arquivos que terminam em ‘.scm’.

--stats

Exibir estatísticas do banco de dados.

--update
-u

Atualize o banco de dados dos arquivos.

Por padrão, o banco de dados é atualizado automaticamente quando é muito antigo.

--clear

Limpe o banco de dados e preencha-o novamente.

Esta opção permite começar de novo, garantindo que os dados antigos sejam removidos do banco de dados, o que também evita ter um banco de dados em constante crescimento. Por padrão, guix locate faz isso automaticamente periodicamente, embora com pouca frequência.

--database=arquivo

Use arquivo como banco de dados, criando-o se necessário.

Por padrão, guix locate escolhe o banco de dados em ~/.cache/guix ou /var/cache/guix, o que for mais recente.

--method=método
-m método

Use método para selecionar o conjunto de pacotes a serem indexados. Os valores possíveis são:

manifests

Este é o método padrão: ele funciona percorrendo perfis na máquina e gravando os pacotes que encontra – pacotes instalados por você ou por outros usuários da máquina, direta ou indiretamente. É rápido mas você pode perder outros pacotes disponíveis no armazém mas não referenciados por nenhum perfil.

store

Este é um método mais lento, porém mais exaustivo: verifica entre todos os pacotes existentes aqueles que estão disponíveis no armazém e os registra.


5.6 Invocando guix gc

Pacotes instalados mas não usados podem ser garbage-collected. O comando guix gc permite que os usuários executem explicitamente o coletor de lixo para recuperar espaço do diretório /gnu/store. É a maneira única de remover arquivos de /gnu/store — remover arquivos ou diretórios manualmente pode quebrá-los sem possibilidade de reparo!

O coletor de lixo possui um conjunto de raizes conhecidos: qualquer arquivo em /gnu/store acessível a partir de uma raiz é considerado live e não pode ser excluído; Qualquer outro arquivo é considerado dead e pode ser excluído. O conjunto de raízes do coletor de lixo (abreviadamente “Raízes GC”) inclui perfis de usuário padrão; por padrão, as ligações simbólicas em /var/guix/gcroots representam essas raízes do GC. Novas raízes de GC podem ser adicionadas com guix build --root, por exemplo (veja Invocando guix build). O comando guix gc --list-roots os lista.

Antes de executar guix gc --collect-garbage para liberar espaço, geralmente é útil remover gerações antigas dos perfis de usuário; dessa forma, compilações de pacotes antigos referenciadas por essas gerações podem ser recuperadas. Isso é conseguido executando guix package --delete-generations (veja Invocando guix package).

Nossa recomendação é executar uma coleta de lixo periodicamente ou quando houver pouco espaço em disco. Por exemplo, para garantir que pelo menos 5 GB estejam disponíveis no disco, basta executar:

guix gc -F 5G

É perfeitamente seguro executar como um trabalho periódico não interativo (veja Execução de trabalho agendado, para saber como configurar tal trabalho). Executar guix gc sem argumentos coletará o máximo de lixo possível, mas isso geralmente é inconveniente: você pode ter que reconstruir ou baixar novamente um software que está "morto" do ponto de vista do GC, mas que é necessário para construir outras peças de software - por exemplo, a cadeia de ferramentas do compilador.

O comando guix gc tem três modos de operação: pode ser usado para coletar o lixo de quaisquer arquivos mortos (o padrão), para excluir arquivos específicos (a opção --delete), para imprimir lixo- informações do coletor ou para consultas mais avançadas. As opções de coleta de lixo são as seguintes:

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

Colete lixo, ou seja, arquivos e subdiretórios /gnu/store inacessíveis. Esta é a operação padrão quando nenhuma opção é especificada.

Quando min for fornecido, pare quando min bytes forem coletados. min pode ser um número de bytes ou pode incluir uma unidade como sufixo, como MiB para mebibytes e GB para gigabytes (veja especificações de tamanho em GNU Coreutils).

Quando min for omitido, colete todo o lixo.

--free-space=free
-F free

Colete o lixo até que o espaço free esteja disponível em /gnu/store, se possível; free denota espaço de armazenamento, como 500MiB, conforme descrito acima.

Quando free ou mais já estiver disponível em /gnu/store, não faça nada e saia imediatamente.

--delete-generations[=duração]
-d [duração]

Antes de iniciar o processo de coleta de lixo, exclua todas as gerações anteriores a duração, para todos os perfis de usuário e gerações do ambiente pessoal. Quando executado como root, isso se aplica a todos os perfis de todos os usuários.

Por exemplo, este comando exclui todas as gerações de todos os seus perfis com mais de 2 meses (exceto as gerações atuais) e depois libera espaço até que pelo menos 10 GiB estejam disponíveis:

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

Tentativa de excluir todos os arquivos e diretórios de armazém especificados como argumentos. Isso falhará se alguns dos arquivos não estiverem no armazém ou se ainda estiverem ativos.

--list-failures

Listar itens de armazém correspondentes a falhas de compilação em cache.

Isso não imprime nada, a menos que o daemon tenha sido iniciado com --cache-failures (veja --cache-failures).

--list-roots

Listar as raízes do GC de propriedade do usuário; quando executado como root, listar todas as raízes do GC.

--list-busy

Listar itens de armazém em uso por processos em execução no momento. Esses itens de armazém são efetivamente considerados raízes GC: eles não podem ser excluídos.

--clear-failures

Remova os itens de armazém especificados do cache de compilação com falha.

Novamente, essa opção só faz sentido quando o daemon é iniciado com --cache-failures. Caso contrário, não faz nada.

--list-dead

Exibe a lista de arquivos e diretórios mortos ainda presentes no armazém, ou seja, arquivos e diretórios que não podem mais ser acessados de nenhuma raiz.

--list-live

Exibe a lista de arquivos e diretórios do armazém ativa.

Além disso, as referências entre arquivos de armazém existentes podem ser consultadas:

--references
--referrers

Listar as referências (respectivamente, os referenciadores) dos arquivos de armazém fornecidos como argumentos.

--requisites
-R

Liste os requisitos dos arquivos de armazém passados como argumentos. Os requisitos incluem os próprios arquivos de armazém, suas referências e as referências destes, recursivamente. Em outras palavras, a lista retornada é o fechamento transitivo dos arquivos de armazém.

Veja Invocando guix size, para uma ferramenta para criar o perfil do tamanho do fechamento de um elemento. Veja Invocando guix graph, para uma ferramenta para visualizar o grafo de referências.

--derivers

Retorna a(s) derivação(ões) que levam aos itens de armazém fornecidos (veja Derivações).

Por exemplo, este comando:

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

retorna o(s) arquivo(s) .drv que levam ao pacote emacs instalado no seu perfil.

Note que pode haver zero arquivos .drv correspondentes, por exemplo porque esses arquivos foram coletados como lixo. Também pode haver mais de um .drv correspondente devido a derivações de saída fixa.

Por fim, as seguintes opções permitem que você verifique a integridade do armazém e controle o uso do disco.

--verify[=opções]

Verifique a integridade do armazém.

Por padrão, certifique-se de que todos os itens de armazém marcados como válidos no banco de dados do daemon realmente existam em /gnu/store.

Quando fornecido, opções deve ser uma lista separada por vírgulas contendo um ou mais de contents e repair.

Ao passar --verify=contents, o daemon calcula o hash de conteúdo de cada item do armazém e o compara com seu hash no banco de dados. Incompatibilidades de hash são relatadas como corrupções de dados. Como ele percorre todos os arquivos no armazém, esse comando pode levar muito tempo, especialmente em sistemas com uma unidade de disco lenta.

Usar --verify=repair ou --verify=contents,repair faz com que o daemon tente reparar itens corrompidos do armazém buscando substitutos para eles (veja Substitutos). Como o reparo não é atômico e, portanto, potencialmente perigoso, ele está disponível apenas para o administrador do sistema. Uma alternativa leve, quando você sabe exatamente quais itens no armazém estão corrompidos, é guix build --repair (veja Invocando guix build).

--optimize

Otimize o armazém vinculando fisicamente arquivos idênticos — isso é deduplication.

O daemon executa a desduplicação após cada importação bem-sucedida de build ou archive, a menos que tenha sido iniciado com --disable-deduplication (veja --disable-deduplication). Portanto, essa opção é útil principalmente quando o daemon estava em execução com --disable-deduplication.

--vacuum-database

Guix usa um banco de dados sqlite para manter o controle dos itens no armazém (veja O armazém). Com o tempo, é possível que o banco de dados cresça muito e se torne fragmentado. Como resultado, pode-se desejar limpar o espaço liberado e juntar as páginas parcialmente usadas no banco de dados deixadas para trás por pacotes removidos ou após executar o coletor de lixo. Executar sudo guix gc --vacuum-database bloqueará o banco de dados e VACUUM o store, desfragmentando o banco de dados e expurgando as páginas liberadas, desbloqueando o banco de dados quando terminar.


5.7 Invocando guix pull

Os pacotes são instalados ou atualizados para a versão mais recente disponível na distribuição atualmente disponível na sua máquina local. Para atualizar essa distribuição, junto com as ferramentas Guix, você deve executar guix pull: o comando baixa o código-fonte Guix mais recente e as descrições dos pacotes, e os implementa. O código-fonte é baixado de um repositório Git, por padrão o repositório oficial GNU Guix, embora isso possa ser personalizado. guix pull garante que o código que ele baixa é autêntico, verificando se os commits são assinados pelos desenvolvedores Guix.

Especificamente, guix pull baixa o código dos canais (veja Canais) especificados por um dos seguintes, nesta ordem:

  1. a opção --channels;
  2. o arquivo ~/.config/guix/channels.scm do usuário, a menos que -q seja passado;
  3. o arquivo /etc/guix/channels.scm de todo o sistema, a menos que -q seja passado (no sistema Guix, este arquivo pode ser declarado na configuração do sistema operacional, veja campo channels de guix-configuration);
  4. os canais padrão integrados especificados na variável %default-channels.

Após a conclusão, guix package usará pacotes e versões de pacotes desta cópia recém-recuperada do Guix. Não apenas isso, mas todos os comandos Guix e módulos Scheme também serão retirados dessa versão mais recente. Novos subcomandos guix adicionados pela atualização também se tornam disponíveis.

Qualquer usuário pode atualizar sua cópia do Guix usando guix pull, e o efeito é limitado ao usuário que executou guix pull. Por exemplo, quando o usuário root executa guix pull, isso não tem efeito na versão do Guix que o usuário alice vê, e vice-versa.

O resultado da execução de guix pull é um perfil disponível em ~/.config/guix/current contendo o Guix mais recente.

A opção --list-generations ou -l lista gerações anteriores produzidas por guix pull, juntamente com detalhes sobre sua procedência:

$ guix pull -l
Geração 1	10 jun 2018 00:18:18
  guix 65956ad
    URL do repositório: https://git.savannah.gnu.org/git/guix.git
    ramo: origin/master
    commit: 65956ad3526ba09e1f7a40722c96c6ef7c0936fe

Geração 2	11 jun 2018 11:02:49
  guix e0cc7f6
    URL do repositório: https://git.savannah.gnu.org/git/guix.git
    ramo: origin/master
    commit: e0cc7f669bec22c37481dd03a7941c7d11a64f1d

Geração 3	13 jun 2018 23:31:07	(atual)
  guix 844cc1c
    URL do repositório: https://git.savannah.gnu.org/git/guix.git
    ramo: origin/master
    commit: 844cc1c8f394f03b404c5bb3aee086922373490c

Veja guix describe, para outras maneiras de descrever o status atual do Guix.

Este perfil ~/.config/guix/current funciona exatamente como os perfis criados por guix package (veja Invocando guix package). Ou seja, você pode listar gerações, reverter para a geração anterior — ou seja, o Guix anterior — e assim por diante:

$ guix pull --roll-back
trocado da geração 3 para 2
$ guix pull --delete-generations=1
excluindo /var/guix/profiles/per-user/charlie/current-guix-1-link

Você também pode usar guix package (veja Invocando guix package) para gerenciar o perfil nomeando-o explicitamente:

$ guix package -p ~/.config/guix/current --roll-back
trocado da geração 3 para 2
$ guix package -p ~/.config/guix/current --delete-generations=1
excluindo /var/guix/profiles/per-user/charlie/current-guix-1-link

O comando guix pull geralmente é invocado sem argumentos, mas suporta as seguintes opções:

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

Baixe o código para o canal guix do url especificado, no commit fornecido (um ID de commit Git válido representado como uma string hexadecimal ou o nome de uma tag) ou ramo.

Essas opções são fornecidas para sua conveniência, mas você também pode especificar sua configuração no arquivo ~/.config/guix/channels.scm ou usando a opção --channels (veja abaixo).

--channels=arquivo
-C arquivo

Leia a lista de canais de arquivo em vez de ~/.config/guix/channels.scm ou /etc/guix/channels.scm. arquivo deve conter código Scheme que avalia uma lista de objetos de canal. Veja Canais, para mais informações.

--no-channel-files
-q

Inibir o carregamento dos arquivos de canal do usuário e do sistema, ~/.config/guix/channels.scm e /etc/guix/channels.scm.

--news
-N

Exibir notícias escritas por autores de canais para seus usuários para alterações feitas desde a geração anterior (veja Escrevendo Notícias de Canal). Quando --details é passado, exibir adicionalmente pacotes novos e atualizados.

Você pode visualizar essas informações de gerações anteriores com guix pull -l.

--list-generations[=padrão]
-l [padrão]

Liste todas as gerações de ~/.config/guix/current ou, se padrão for fornecido, o subconjunto de gerações que correspondem a padrão. A sintaxe de padrão é a mesma de guix package --list-generations (veja Invocando guix package).

Por padrão, isso imprime informações sobre os canais usados em cada revisão, bem como as entradas de notícias correspondentes. Se você passar --details, ele também imprimirá a lista de pacotes adicionados e atualizados em cada geração em comparação com a anterior.

--details

Instrua --list-generations ou --news para exibir mais informações sobre as diferenças entre gerações subsequentes — veja acima.

--roll-back

Reverta para a geração anterior de ~/.config/guix/current—ou seja, desfaça a última transação.

--switch-generation=padrão
-S padrão

Mude para uma geração específica definida por padrão.

padrão pode ser um número de geração ou um número prefixado com "+” ou "-”. O último significa: mover para frente/para trás por um número especificado de gerações. Por exemplo, se você quiser retornar para a última geração após --roll-back, use --switch-generation=+1.

--delete-generations[=padrão]
-d [padrão]

Quando padrão for omitido, exclua todas as gerações, exceto a atual.

Este comando aceita os mesmos padrões de --list-Generations. Quando pattern for especificado, exclua as gerações correspondentes. Quando padrão especifica uma duração, as gerações mais antigas que a duração especificada correspondem. Por exemplo, --delete-generations=1m exclui gerações com mais de um mês.

Se a geração atual corresponder, ela não será excluída.

Observe que a exclusão de gerações impede a reversão para elas. Conseqüentemente, este comando deve ser usado com cuidado.

Veja Invocando guix describe, para uma maneira de exibir informações somente sobre a geração atual.

--profile=perfil
-p perfil

Use perfil em vez de ~/.config/guix/current.

--dry-run
-n

Mostre quais commits de canal seriam usados e o que seria construído ou substituído, mas não faça isso de fato.

--allow-downgrades

Permitir extrair revisões de canais mais antigas ou não relacionadas às que estão em uso atualmente.

Por padrão, guix pull protege contra os chamados "ataques de downgrade”, nos quais o repositório Git de um canal seria redefinido para uma revisão anterior ou não relacionada a si mesmo, potencialmente levando você a instalar versões mais antigas e conhecidas de pacotes de software.

Nota: Certifique-se de entender as implicações de segurança antes de usar --allow-downgrades.

--disable-authentication

Permitir extrair código de canal sem autenticá-lo.

Por padrão, guix pull autentica o código baixado de canais verificando se seus commits são assinados por desenvolvedores autorizados e gera um erro se esse não for o caso. Esta opção o instrui a não executar nenhuma verificação desse tipo.

Nota: Certifique-se de entender as implicações de segurança antes de usar --disable-authentication.

--no-check-certificate

Do not validate the X.509 certificates of HTTPS servers.

When using this option, you have absolutely no guarantee that you are communicating with the authentic server responsible for the given URL. Unless the channel is authenticated, this makes you vulnerable to “man-in-the-middle” attacks.

--system=sistema
-s sistema

Tente compilar para sistema—por exemplo, i686-linux—em vez do tipo de sistema do host de compilação.

--bootstrap

Use o bootstrap Guile para construir o Guix mais recente. Esta opção é útil somente para desenvolvedores Guix.

O mecanismo dos canais permite que você instrua guix pull de qual repositório e branch extrair, bem como repositórios adicionais contendo módulos de pacote que devem ser implantados. Veja Canais, para mais informações.

Além disso, guix pull suporta todas as opções de compilação comuns (veja Opções de compilação comuns).


5.8 Invocando guix time-machine

O comando guix time-machine fornece acesso a outras revisões do Guix, por exemplo, para instalar versões mais antigas de pacotes ou para reproduzir uma computação em um ambiente idêntico. A revisão do Guix a ser usada é definida por um commit ou por um arquivo de descrição de canal criado por guix describe (veja Invocando guix describe).

Vamos supor que você queira viajar para aqueles dias de novembro de 2020, quando a versão 1.2.0 do Guix foi lançada e, uma vez lá, executar o guile daquela época:

guix time-machine --commit=v1.2.0 -- \
  environment -C --ad-hoc guile -- guile

O comando acima busca Guix 1.2.0 (e possivelmente outros canais especificados pelos seus arquivos de configuração channels.scm — veja abaixo) e executa seu comando guix environment para gerar um ambiente em um contêiner executando guile (guix environment foi desde então subsumido por guix shell; veja Invocando guix shell). É como dirigir um DeLorean12! A primeira invocação de guix time-machine pode ser cara: pode ser necessário baixar ou até mesmo construir um grande número de pacotes; o resultado é armazenado em cache e os comandos subsequentes direcionados ao mesmo commit são quase instantâneos.

Quanto ao guix pull, na ausência de quaisquer opções, o time-machine busca os últimos commits dos canais especificados em ~/.config/guix/channels.scm, /etc/guix/channels.scm, ou os canais padrão; a opção -q permite que você ignore esses arquivos de configuração. O comando:

guix time-machine -q -- build hello

construirá então o pacote hello conforme definido no branch principal do Guix, sem nenhum canal adicional, que é em geral uma revisão mais nova do Guix do que a que você instalou. A viagem no tempo funciona em ambas as direções!

Nota: O histórico do Guix é imutável e guix time-machine fornece exatamente o mesmo software que eles estão em uma revisão específica do Guix. Naturalmente, nenhuma correção de segurança é fornecida para versões antigas do Guix ou seus canais. Um uso descuidado do guix time-machine abre a porta para vulnerabilidades de segurança. Veja --allow-downgrades.

guix time-machine gera um erro ao tentar viajar para commits mais antigos que "v0.16.0" (commit ‘4a0b87f0’), datados de Dez. 2018. Este é um dos commits mais antigos que oferecem suporte ao mecanismo de canal que torna a "viagem no tempo" possível.

Nota: Embora seja tecnicamente possível viajar para um commit tão antigo, a facilidade para fazê-lo dependerá em grande parte da disponibilidade de substitutos binários. Ao viajar para um passado distante, alguns pacotes podem não ser mais facilmente construídos a partir da fonte. Um exemplo são as versões antigas do OpenSSL cujos testes falhavam após uma certa data. Esse problema em particular pode ser contornado executando uma máquina de construção virtual com seu relógio ajustado para a hora certa (veja Máquinas de Construção Virtual).

A sintaxe geral é:

guix time-machine opções… -- comando arg

onde comando e arg… são passados sem modificações para o comando guix da revisão especificada. As opções que definem esta revisão são as mesmas que para guix pull (veja Invocando guix pull):

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

Use o canal guix do url especificado, no commit fornecido (um ID de commit Git válido representado como uma string hexadecimal ou o nome de uma tag) ou ramo.

--channels=arquivo
-C arquivo

Leia a lista de canais de arquivo. arquivo deve conter código Scheme que avalia uma lista de objetos de canal. Veja Canais para mais informações.

--no-channel-files
-q

Inibir o carregamento dos arquivos de canal do usuário e do sistema, ~/.config/guix/channels.scm e /etc/guix/channels.scm.

Portanto, guix time-machine -q é equivalente ao seguinte comando Bash, usando a sintaxe "substituição de processo" (veja Process Substitution em Manual de referência do GNU Bash):

guix time-machine -C <(echo %default-channels) …

Observe que guix time-machine pode acionar compilações de canais e suas dependências, e elas são controladas pelas opções de compilação padrão (veja Opções de compilação comuns).

Se guix time-machine for executado sem nenhum comando, ele imprime o nome do arquivo do perfil que seria usado para executar o comando. Isso às vezes é útil se você precisa obter o nome do arquivo de armazém do perfil — por exemplo, quando você quer guix copy ele.


5.9 Inferiores

Nota: A funcionalidade descrita aqui é uma “prévia de tecnologia” da versão 4b5f040. Como tal, a interface está sujeita a alterações.

Às vezes, você pode precisar misturar pacotes da revisão do Guix que você está executando atualmente com pacotes disponíveis em uma revisão diferente do Guix. Os inferiores do Guix permite que você consiga isso compondo diferentes revisões do Guix de maneiras arbitrárias.

Tecnicamente, um “inferior” é essencialmente um processo Guix separado conectado ao seu processo Guix principal por meio de um REPL (veja Invocando guix repl). O módulo (guix inferior) permite que você crie inferiores e se comunique com eles. Ele também fornece uma interface de alto nível para navegar e manipular os pacotes que um inferior fornece—pacotes inferiores.

Quando combinados com canais (veja Canais), os inferiores fornecem uma maneira simples de interagir com uma revisão separada do Guix. Por exemplo, vamos supor que você queira instalar em seu perfil o pacote guile atual, junto com o guile-json como ele existia em uma revisão mais antiga do Guix—talvez porque o mais novo guile-json tenha uma API incompatível e você queira executar seu código contra a API antiga. Para fazer isso, você pode escrever um manifesto para uso por guix package --manifest (veja Escrevendo manifestos); nesse manifesto, você criaria um inferior para aquela revisão antiga do Guix que você se importa, e você procuraria o pacote guile-json no inferior:

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

(define canais
  ;; Esta é a revisão antiga da qual queremos
  ;; extrair guile-json.
  (list (channel
         (name 'guix)
         (url "https://git.savannah.gnu.org/git/guix.git")
         (commit
          "65956ad3526ba09e1f7a40722c96c6ef7c0936fe"))))

(define inferior
  ;; Um inferior representando a revisão acima.
  (inferior-for-channels canais))

;; Agora crie um manifesto com o pacote "guile" atual
;; e o antigo pacote "guile-json".
(packages->manifest
 (list (first (lookup-inferior-packages inferior "guile-json"))
       (specification->package "guile")))

Na primeira execução, guix package --manifest pode ter que construir o canal que você especificou antes de poder criar o inferior; execuções subsequentes serão muito mais rápidas porque a revisão do Guix será armazenada em cache.

O módulo (guix inferior) fornece os seguintes procedimentos para abrir um inferior:

Procedimento: inferior-for-channels canais [#:cache-directory] [#:ttl]

Retorna um inferior para canais, uma lista de canais. Use o cache em cache-directory, onde as entradas podem ser recuperadas após ttl segundos. Este procedimento abre uma nova conexão com o daemon de construção.

Como efeito colateral, esse procedimento pode criar ou substituir binários para canais, o que pode levar tempo.

Procedimento: open-inferior diretório [#:command "bin/guix"]

Abra o Guix inferior em diretório, executando o comando diretório/command repl ou equivalente. Retorne #f se o inferior não puder ser iniciado.

Os procedimentos listados abaixo permitem que você obtenha e manipule pacotes inferiores.

Procedimento: inferior-packages inferior

Retorna a lista de pacotes conhecidos por inferior.

Procedimento: lookup-inferior-packages inferior nome [versão]

Retorna a lista ordenada de pacotes inferiores que correspondem a nome em inferior, com os números de versão mais altos primeiro. Se versão for true, retorna apenas pacotes com um número de versão prefixado por versão.

Procedimento: inferior-package? obj

Retorna verdadeiro se obj for um pacote inferior.

Procedimento: inferior-package-name pacote
Procedimento: inferior-package-version pacote
Procedimento: inferior-package-synopsis pacote
Procedimento: inferior-package-description pacote
Procedimento: inferior-package-home-page pacote
Procedimento: inferior-package-location pacote
Procedimento: inferior-package-inputs pacote
Procedimento: inferior-package-native-inputs pacote
Procedimento: inferior-package-propagated-inputs pacote
Procedimento: inferior-package-transitive-propagated-inputs pacote
Procedimento: inferior-package-native-search-paths pacote
Procedimento: inferior-package-transitive-native-search-paths pacote
Procedimento: inferior-package-search-paths pacote

Esses procedimentos são a contrapartida dos acessadores de registro de pacote (veja Referência do package). A maioria deles funciona consultando o inferior de onde pacote vem, então o inferior ainda deve estar ativo quando você chamar esses procedimentos.

Pacotes inferiores podem ser usados transparentemente como qualquer outro pacote ou objeto tipo arquivo em expressões-G (veja Expressões-G). Eles também são manipulados transparentemente pelo procedimento packages->manifest, que é comumente usado em manifestos (veja a opção --manifest de guix package). Assim, você pode inserir um pacote inferior praticamente em qualquer lugar em que inseriria um pacote regular: em manifestos, no campo packages da sua declaração operating-system e assim por diante.


5.10 Invocando guix describe

Frequentemente você pode querer responder perguntas como: “Qual revisão do Guix estou usando?” ou “Quais canais estou usando?” Essas são informações úteis em muitas situações: se você quiser replicar um ambiente em uma máquina ou conta de usuário diferente, se quiser relatar um bug ou determinar qual alteração nos canais que você está usando o causou, ou se quiser registrar o estado do seu sistema para fins de reprodutibilidade. O comando guix describe responde a essas perguntas.

Quando executado a partir de um guix obtido com guix pull, guix describe exibe o(s) canal(ais) dos quais foi criado, incluindo a URL do repositório e os IDs de confirmação (veja Canais):

$ guix describe
Geração 10	03 set 2018 17:32:44	(atual)
  guix e0fa68c
    URL do repositório: https://git.savannah.gnu.org/git/guix.git
    ramo: master
    commit: e0fa68c7718fffd33d81af415279d6ddb518f727

Se você estiver familiarizado com o sistema de controle de versão do Git, isso é similar em espírito a git describe; a saída também é similar à de guix pull --list-generations, mas limitada à geração atual (veja a opção --list-generations). Como o ID de commit do Git mostrado acima se refere inequivocamente a um snapshot do Guix, essa informação é tudo o que é preciso para descrever a revisão do Guix que você está usando e também para replicá-la.

Para facilitar a replicação do Guix, guix describe também pode ser solicitado a retornar uma lista de canais em vez da descrição legível acima:

$ 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")))))

Você pode salvar isso em um arquivo e alimentá-lo com guix pull -C em alguma outra máquina ou em um momento posterior, o que instanciará esta revisão exata do Guix (veja a opção -C). A partir daí, já que você consegue implementar a mesma revisão do Guix, você pode muito bem replicar um ambiente de software completo. Humildemente achamos isso incrível, e esperamos que você goste também!

Os detalhes das opções suportadas por guix describe são os seguintes:

--format=formato
-f formato

Produza saída no formato especificado, um dos seguintes:

human

produzir resultados legíveis por humanos;

channels

produz uma lista de especificações de canal que podem ser passadas para guix pull -C ou instaladas como ~/.config/guix/channels.scm (veja Invocando guix pull);

channels-sans-intro

como channels, mas omita o campo introduction; use-o para produzir uma especificação de canal adequada para a versão 1.1.0 do Guix ou anterior — o campo introduction tem a ver com autenticação de canal (veja Autenticação de canal) e não é suportado por essas versões mais antigas;

json

produzir uma lista de especificações de canal no formato JSON;

recutils

produzir uma lista de especificações de canais no formato Recutils.

--list-formats

Exibir formatos disponíveis para a opção --format.

--profile=perfil
-p perfil

Exibir informações sobre perfil.


5.11 Invocando guix archive

O comando guix archive permite que os usuários exportem arquivos do armazém para um único arquivamento e depois importem eles em uma máquina que execute o Guix. Em particular, ele permite que os arquivos do armazém sejam transferidos de uma máquina para o store em outra máquina.

Nota: Se você estiver procurando uma maneira de produzir arquivamentos em um formato adequado para outras ferramentas além do Guix, veja Invocando guix pack.

Para exportar arquivos de armazém como um arquivamento para saída padrão, execute:

guix archive --export opções especificações...

especificações pode ser nomes de arquivos de armazém ou especificações de pacotes, como para guix package (veja Invocando guix package). Por exemplo, o comando a seguir cria um arquivo contendo a saída gui do pacote git e a saída principal de emacs:

guix archive --export git:gui /gnu/store/...-emacs-24.3 > great.nar

Se os pacotes especificados ainda não foram construídos, guix archive os constrói automaticamente. O processo de construção pode ser controlado com as opções comuns de construção (veja Opções de compilação comuns).

Para transferir o pacote emacs para uma máquina conectada via SSH, execute:

guix archive --export -r emacs | ssh a-máquina guix archive --import

Da mesma forma, um perfil de usuário completo pode ser transferido de uma máquina para outra assim:

guix archive --export -r $(readlink -f ~/.guix-profile) | \
  ssh a-máquina guix archive --import

No entanto, observe que, em ambos os exemplos, todos os emacs e o perfil, bem como todas as suas dependências são transferidos (devido a -r), independentemente do que já esteja disponível no armazém na máquina de destino. A opção --missing pode ajudar a descobrir quais itens estão faltando no armazém de destino. O comando guix copy simplifica e otimiza todo esse processo, então é provavelmente isso que você deve usar neste caso (veja Invocando guix copy).

Cada item do armazém é escrito no formato arquivamento normalizado ou nar (descrito abaixo), e a saída de guix archive --export (e entrada de guix archive --import) é uma embalagem nar.

O formato nar é comparável em espírito ao ‘tar’, mas com diferenças que o tornam mais apropriado para nossos propósitos. Primeiro, em vez de registrar todos os metadados Unix para cada arquivo, o formato nar menciona apenas o tipo de arquivo (regular, diretório ou ligação simbólica); permissões Unix e proprietário/grupo são descartados. Segundo, a ordem em que as entradas de diretório são armazenadas sempre segue a ordem dos nomes de arquivo de acordo com a ordem de agrupamento de localidade C. Isso torna a produção de arquivo totalmente determinística.

O formato da embalagem nar é essencialmente a concatenação de zero ou mais nars junto com metadados para cada item de armazém que ele contém: seu nome de arquivo, referências, derivação correspondente e uma assinatura digital.

Ao exportar, o daemon assina digitalmente o conteúdo do arquivamento, e essa assinatura digital é anexada. Ao importar, o daemon verifica a assinatura e rejeita a importação em caso de uma assinatura inválida ou se a chave de assinatura não for autorizada.

As principais opções são:

--export

Exporte os arquivos de armazém ou pacotes especificados (veja abaixo). Grave o arquivo resultante na saída padrão.

Dependências não são incluídas na saída, a menos que --recursive seja passado.

-r
--recursive

Quando combinado com --export, isso instrui guix archive a incluir dependências dos itens fornecidos no arquivo. Assim, o arquivo resultante é autocontido: ele contém o fechamento dos itens exportados do armazém.

--import

Leia um arquivo da entrada padrão e importe os arquivos listados nele para o armazém. Aborte se o arquivo tiver uma assinatura digital inválida ou se for assinado por uma chave pública que não esteja entre as chaves autorizadas (veja --authorize abaixo).

--missing

Leia uma lista de nomes de arquivos do armazém da entrada padrão, um por linha, e escreva na saída padrão o subconjunto desses arquivos que faltam no armazém.

--generate-key[=parâmetros]

Gere um novo par de chaves para o daemon. Este é um pré-requisito antes que os arquivos possam ser exportados com --export. Esta operação é geralmente instantânea, mas pode levar algum tempo se o pool de entropia do sistema precisar ser recarregado. No Guix System, guix-service-type cuida da geração deste par de chaves na primeira inicialização.

O par de chaves gerado é normalmente armazenado em /etc/guix, em signing-key.pub (chave pública) e signing-key.sec (chave privada, que deve ser mantida em segredo). Quando parâmetros é omitido, uma chave ECDSA usando a curva Ed25519 é gerada ou, para versões do Libgcrypt anteriores a 1.6.0, é uma chave RSA de 4096 bits. Como alternativa, parâmetros pode especificar parâmetros genkey adequados para Libgcrypt (veja gcry_pk_genkey em Manual de referência do Libgcrypt).

--authorize

Autorize importações assinadas pela chave pública passada na entrada padrão. A chave pública deve estar em “s-expression advanced format”—i.e., o mesmo formato do arquivo signing-key.pub.

A lista de chaves autorizadas é mantida no arquivo editável por humanos /etc/guix/acl. O arquivo contém “advanced-format s-expressions” e é estruturado como uma lista de controle de acesso no Simple Public-Key Infrastructure (SPKI).

--extract=diretório
-x diretório

Leia um arquivo de item único conforme servido por servidores substitutos (veja Substitutos) e extraia-o para diretório. Esta é uma operação de baixo nível necessária apenas em casos de uso muito restritos; veja abaixo.

Por exemplo, o comando a seguir extrai o substituto para o Emacs servido por bordeaux.guix.gnu.org para /tmp/emacs:

$ wget -O - \
  https://bordeaux.guix.gnu.org/nar/gzip/…-emacs-24.5 \
  | gunzip | guix archive -x /tmp/emacs

Arquivamentos de item único são diferentes de arquivamentos de itens múltiplos produzidos por guix archive --export; eles contêm um único item de armazém e não incorporam uma assinatura. Portanto, essa operação não faz nenhuma verificação de assinatura e sua saída deve ser considerada insegura.

O objetivo principal desta operação é facilitar a inspeção de conteúdos de arquivamento provenientes de servidores substitutos possivelmente não confiáveis (veja Invocando guix challenge).

--list
-t

Leia um arquivamento de item único servido por servidores substitutos (veja Substitutos) e exiba a lista de arquivos que ele contém, como neste exemplo:

$ wget -O - \
  https://bordeaux.guix.gnu.org/nar/lzip/…-emacs-26.3 \
  | lzip -d | guix archive -t

6 Canais

Guix e sua coleção de pacotes são atualizados executando guix pull. Por padrão, guix pull baixa e implementa o próprio Guix do repositório oficial GNU Guix. Isso pode ser personalizado fornecendo um arquivo especificando o conjunto de canais para extrair de (veja Invocando guix pull). Um canal especifica a URL e a ramificação de um repositório Git a ser implantado, e guix pull pode ser instruído a extrair de um ou mais canais. Em outras palavras, os canais podem ser usados para personalizar e estender o Guix, como veremos abaixo. O Guix é capaz de levar em conta preocupações de segurança e lidar com atualizações autenticadas.


6.1 Especificando canais adicionais

Você pode especificar canais adicionais para puxar. Para usar um canal, escreva ~/.config/guix/channels.scm para instruir guix pull para puxar dele além do(s) canal(ais) Guix padrão:

;; Adicione pacotes variantes aos fornecidos pelo Guix.
(cons (channel
        (name 'variant-packages)
        (url "https://example.org/variant-packages.git"))
      %default-channels)

Note que o snippet acima é (como sempre!) código do Scheme; usamos cons para adicionar um canal à lista de canais aos quais a variável %default-channels está vinculada (veja cons and lists em GNU Guile Reference Manual). Com esse arquivo no lugar, guix pull compila não apenas o Guix, mas também os módulos do pacote do seu próprio repositório. O resultado em ~/.config/guix/current é a união do Guix com seus próprios módulos do pacote:

$ guix describe
Geração 19	27 ago 2018 16:20:48
  guix d894ab8
    URL do repositório: https://git.savannah.gnu.org/git/guix.git
    ramo: master
    commit: d894ab8e9bfabcefa6c49d9ba2e834dd5a73a300
  variant-packages dd3df5e
    URL do repositório: https://example.org/variant-packages.git
    ramo: master
    commit: dd3df5e2c8818760a8fc0bd699e55d3b69fef2bb

A saída do guix describe acima mostra que agora estamos executando o geração 19 e que ele inclui o Guix e os pacotes do canal variant-packages (veja Invocando guix describe).


6.2 Usando um canal Guix personalizado

O canal chamado guix especifica onde o próprio Guix—suas ferramentas de linha de comando, bem como sua coleção de pacotes—deve ser baixado. Por exemplo, suponha que você queira atualizar de outra cópia do repositório Guix em example.org, e especificamente o branch super-hacks, você pode escrever em ~/.config/guix/channels.scm esta especificação:

;; Diga ao 'guix pull' para usar outro repositório.
(list (channel
        (name 'guix)
        (url "https://example.org/another-guix.git")
        (branch "super-hacks")))

A partir daí, guix pull buscará o código do branch super-hacks do repositório em example.org. A preocupação com a autenticação é abordada abaixo (veja Autenticação de canal).

Note que você pode especificar um diretório local no campo url acima se o canal que você pretende usar residir em um sistema de arquivos local. No entanto, neste caso, guix verifica o diretório em busca de propriedade antes de qualquer processamento posterior. Isso significa que se o usuário não for o proprietário do diretório, mas quiser usá-lo como padrão, ele precisará defini-lo como um diretório seguro em seu arquivo de configuração global do git. Caso contrário, guix se recusará até mesmo a lê-lo. Supondo que seu diretório local de todo o sistema esteja em /src/guix.git, você criaria um arquivo de configuração do git em ~/.gitconfig com o seguinte conteúdo:

[safe]
        directory = /src/guix.git

Isso também se aplica ao usuário root, a menos que seja chamado com sudo pelo proprietário do diretório.


6.3 Replicando Guix

O comando guix describe mostra precisamente quais commits foram usados para construir a instância do Guix que estamos usando (veja Invocando guix describe). Podemos replicar essa instância em outra máquina ou em um ponto diferente no tempo fornecendo uma especificação de canal “fixada” a esses commits que se parece com isso:

;; Implantar commits específicos dos meus canais de interesse.
(list (channel
       (name 'guix)
       (url "https://git.savannah.gnu.org/git/guix.git")
       (commit "6298c3ffd9654d3231a6f25390b056483e8f407c"))
      (channel
       (name 'variant-packages)
       (url "https://example.org/variant-packages.git")
       (commit "dd3df5e2c8818760a8fc0bd699e55d3b69fef2bb")))

Para obter essa especificação de canal fixado, a maneira mais fácil é executar guix describe e salvar sua saída no formato channels em um arquivo, assim:

guix describe -f channels > channels.scm

O arquivo channels.scm resultante pode ser passado para a opção -C de guix pull (veja Invocando guix pull) ou guix time-machine (veja Invocando guix time-machine), como neste exemplo:

guix time-machine -C channels.scm -- shell python -- python3

Dado o arquivo channels.scm, o comando acima sempre buscará a exatamente a mesma instância Guix, então usará essa instância para executar exatamente o mesmo Python (veja Invocando guix shell). Em qualquer máquina, a qualquer momento, ele acaba executando exatamente os mesmos binários, bit por bit.

Os canais fixados abordam um problema semelhante a “arquivos de bloqueio” conforme implementado por algumas ferramentas de implantação — eles permitem que você fixe e reproduza um conjunto de pacotes. No caso do Guix, no entanto, você está efetivamente fixando o conjunto de pacotes inteiro conforme definido nos commits de canal fornecidos; na verdade, você está fixando todo o Guix, incluindo seus módulos principais e ferramentas de linha de comando. Você também está obtendo fortes garantias de que está, de fato, obtendo exatamente o mesmo software.

Isso lhe dá superpoderes, permitindo que você rastreie a procedência de artefatos binários com granularidade muito fina e reproduza ambientes de software à vontade — algum tipo de capacidade de “meta reprodutibilidade”, se preferir. Veja Inferiores, para outra maneira de aproveitar esses superpoderes.


Próximo: , Anterior: , Acima: Canais   [Conteúdo][Índice]

6.4 Customizing the System-Wide Guix

Se você estiver executando o Guix System ou construindo imagens de sistema com ele, talvez você queira personalizar o guix de todo o sistema que ele fornece—especificamente, /run/current-system/profile/bin/guix. Por exemplo, você pode querer fornecer canais adicionais ou fixar sua revisão.

Isso pode ser feito usando o procedimento guix-for-channels, que retorna um pacote para os canais fornecidos e o usa como parte da configuração do seu sistema operacional, como neste exemplo:

(use-modules (gnu packages package-management)
             (guix channels))

(define my-channels
  ;; Canais que devem estar disponíveis para
  ;; /run/current-system/profile/bin/guix.
  (append
   (list (channel
          (name 'guix-science)
          (url "https://github.com/guix-science/guix-science")
          (branch "master")))
   %default-channels))

(operating-system
  ;; …
  (services
    ;; Change the package used by 'guix-service-type'.
    (modify-services %base-services
      (guix-service-type
       config => (guix-configuration
                  (inherit config)
                  (channels my-channels)
                  (guix (guix-for-channels my-channels)))))))

O sistema operacional resultante terá os canais guix e guix-science visíveis por padrão. O campo channels de guix-configuration acima garante ainda mais que /etc/guix/channels.scm, que é usado por guix pull, especifica o mesmo conjunto de canais (veja campo channels de guix-configuration).

O módulo (gnu packages package-management) exporta o procedimento guix-for-channels, descrito abaixo.

Procedimento: guix-for-channels canais

Retorna um pacote correspondente a canais.

O resultado é um pacote “regular”, que pode ser usado em guix-configuration como mostrado acima ou em qualquer outro lugar que espere um pacote.


6.5 Autenticação de canal

Os comandos guix pull e guix time-machine autenticam o código recuperado dos canais: eles garantem que cada commit que é buscado seja assinado por um desenvolvedor autorizado. O objetivo é proteger contra modificações não autorizadas no canal que levariam os usuários a executar código malicioso.

Como usuário, você deve fornecer uma introdução de canal no seu arquivo de canais para que o Guix saiba como autenticar seu primeiro commit. Uma especificação de canal, incluindo sua introdução, parece algo como estas linhas:

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

A especificação acima mostra o nome e a URL do canal. A chamada para make-channel-introduction acima especifica que a autenticação deste canal começa no commit 6f0d8cc…, que é assinado pela chave OpenPGP com impressão digital CABB A931….

Para o canal principal, chamado guix, você obtém automaticamente essas informações da sua instalação Guix. Para outros canais, inclua a introdução do canal fornecida pelos autores do canal no seu arquivo channels.scm. Certifique-se de recuperar a introdução do canal de uma fonte confiável, pois essa é a raiz da sua confiança.

Se você está curioso sobre a mecânica de autenticação, continue lendo!


Próximo: , Anterior: , Acima: Canais   [Conteúdo][Índice]

6.6 Canais com substitutos

Ao executar guix pull, o Guix primeiro compilará as definições de cada pacote disponível. Esta é uma operação cara para a qual substitutos (veja Substitutos) podem estar disponíveis. O seguinte snippet em channels.scm garantirá que o guix pull use o commit mais recente com substitutos disponíveis para as definições de pacote: isso é feito consultando o servidor de integração contínua em https://ci.guix.gnu.org.

(use-modules (guix ci))

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

Note que isso não significa que todos os pacotes que você instalará após executar guix pull terão substitutos disponíveis. Isso apenas garante que guix pull não tentará compilar definições de pacotes. Isso é particularmente útil ao usar máquinas com recursos limitados.


6.7 Criando um canal

Digamos que você tenha um monte de variantes de pacotes personalizados ou pacotes pessoais que você acha que faria pouco sentido contribuir para o projeto Guix, mas gostaria de ter esses pacotes disponíveis de forma transparente para você na linha de comando. Ao criar um canal, você pode usar e publicar tal coleção de pacotes. Isso envolve as seguintes etapas:

  1. Um canal fica em um repositório Git, então o primeiro passo, ao criar um canal, é criar seu repositório:
    mkdir meu-canal
    cd meu-canal
    git init
    
  2. O próximo passo é criar arquivos contendo módulos de pacote (veja Módulos de pacote), cada um dos quais conterá uma ou mais definições de pacote (veja Definindo pacotes). Um canal pode fornecer coisas além de pacotes, como sistemas de compilação ou serviços; estamos usando pacotes, pois é o caso de uso mais comum.

    Por exemplo, Alice pode querer fornecer um módulo chamado (alice packages greetings) que fornecerá suas implementações favoritas de “hello world”. Para fazer isso, Alice criará um diretório correspondente ao nome desse módulo.

    mkdir -p alice/packages
    $EDITOR alice/packages/greetings.scm
    git add alice/packages/greetings.scm
    

    Você pode nomear seus módulos de pacote como quiser; a principal restrição a ter em mente é evitar conflitos de nomes com outras coleções de pacotes, e é por isso que nossa hipotética Alice sabiamente escolheu o namespace (alice packages …).

    Observe que você também pode colocar módulos em um subdiretório do repositório; veja Módulos de pacote em um subdiretório, para mais informações sobre isso.

  3. Com este primeiro módulo em funcionamento, o próximo passo é testar os pacotes que ele fornece. Isso pode ser feito com guix build, que precisa ser informado para procurar módulos no checkout do Git. Por exemplo, supondo que (alice packages greetings) forneça um pacote chamado hi-from-alice, Alice executará este comando do checkout do Git:
    guix build -L. hi-from-alice
    

    ... onde -L. adiciona o diretório atual ao caminho de carregamento do Guile (veja Load Paths em Manual de referência do GNU Guile).

  4. Pode levar algumas iterações para Alice obter definições de pacote satisfatórias. Eventualmente, Alice fará commit deste arquivo:
    git commit
    

    Como autor de um canal, considere agrupar material de autenticação com seu canal para que os usuários possam autenticá-lo. Veja Autenticação de canal e Especificando autorizações de canal para obter informações sobre como fazer isso.

  5. Para usar o canal de Alice, qualquer pessoa pode adicioná-lo ao seu arquivo de canal (veja Especificando canais adicionais) e executar guix pull (veja Invocando guix pull):
    $EDITOR ~/.config/guix/channels.scm
    guix pull
    

    Guix agora se comportará como se o diretório raiz do repositório Git daquele canal tivesse sido adicionado permanentemente ao caminho de carregamento do Guile. Neste exemplo, (alice packages greetings) será encontrado automaticamente pelo comando guix.

Voilà!

Aviso: Antes de publicar seu canal, gostaríamos de compartilhar algumas palavras de cautela:

  • Antes de publicar um canal, considere contribuir com suas definições de pacote para o Guix propriamente dito (veja Contribuindo). O Guix como um projeto é aberto a software livre de todos os tipos, e os pacotes no Guix propriamente dito estão prontamente disponíveis para todos os usuários do Guix e se beneficiam do processo de garantia de qualidade do projeto.
  • Módulos de pacote e definições de pacote são códigos Scheme que usam várias interfaces de programação (APIs). Nós, desenvolvedores Guix, nunca mudamos APIs gratuitamente, mas também não nos comprometemos a congelar APIs. Quando você mantém definições de pacote fora do Guix, consideramos que o fardo da compatibilidade é seu.
  • Corolário: se você estiver usando um canal externo e esse canal quebrar, reporte o problema aos autores do canal, não ao projeto Guix.

Você foi avisado! Dito isso, acreditamos que canais externos são uma maneira prática de exercer sua liberdade para aumentar a coleção de pacotes do Guix e compartilhar suas melhorias, que são princípios básicos do software livre. Por favor, envie um e-mail para guix-devel@gnu.org se você quiser discutir isso.


6.8 Módulos de pacote em um subdiretório

Como autor de canal, você pode querer manter seus módulos de canal em um subdiretório. Se seus módulos estiverem no subdiretório guix, você deve adicionar um arquivo de metadados .guix-channel que contenha:

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

Os módulos devem estar abaixo do diretório especificado, pois o diretório directory altera o load-path do Guile. Por exemplo, se .guix-channel tiver (directory "base"), então um módulo definido como (define-module (gnu packages fun)) deve estar localizado em base/gnu/packages/fun.scm.

Fazer isso permite que apenas partes de um repositório sejam usadas como um canal, pois o Guix espera módulos Guile válidos ao puxar. Por exemplo, os arquivos de configuração de máquina guix deploy não são módulos Guile válidos, e tratá-los como tal faria com que guix pull falhasse.


6.9 Declarando dependências de canal

Os autores de canais podem decidir aumentar uma coleção de pacotes fornecida por outros canais. Eles podem declarar que seu canal é dependente de outros canais em um arquivo de metadados .guix-channel, que deve ser colocado na raiz do repositório do canal.

O arquivo de metadados deve conter uma expressão S simples como esta:

(channel
 (version 0)
 (dependencies
  (channel
   (name algum-coleção)
   (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"))))

No exemplo acima, este canal é declarado para depender de dois outros canais, que serão buscados automaticamente. Os módulos fornecidos pelo canal serão compilados em um ambiente onde os módulos de todos esses canais declarados estão disponíveis.

Por uma questão de confiabilidade e manutenibilidade, você deve evitar dependências em canais que você não controla e deve tentar manter o número de dependências no mínimo.


6.10 Especificando autorizações de canal

Como vimos acima, o Guix garante que o código-fonte que ele extrai dos canais vem de desenvolvedores autorizados. Como autor de um canal, você precisa especificar a lista de desenvolvedores autorizados no arquivo .guix-authorizations no repositório Git do canal. A regra de autenticação é simples: cada commit deve ser assinado por uma chave listada no arquivo .guix-authorizations de seu(s) commit(s) pai(s)13 O arquivo .guix-authorizations se parece com isso:

;; Exemplo de arquivo '.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"))))

Cada impressão digital é seguida por pares chave/valor opcionais, como no exemplo acima. Atualmente, esses pares chave/valor são ignorados.

Esta regra de autenticação cria um problema do tipo "ovo e galinha": como autenticamos o primeiro commit? Relacionado a isso: como lidamos com canais cujo histórico de repositório contém commits não assinados e não tem .guix-authorizations? E como bifurcamos canais existentes?

As introduções de canal respondem a essas perguntas descrevendo o primeiro commit de um canal que deve ser autenticado. Na primeira vez que um canal é buscado com guix pull ou guix time-machine, o comando procura o commit introdutório e verifica se ele está assinado pela chave OpenPGP especificada. A partir daí, ele autentica os commits de acordo com a regra acima. A autenticação falha se o commit de destino não for descendente nem ancestral do commit introdutório.

Além disso, seu canal deve fornecer todas as chaves OpenPGP que já foram mencionadas em .guix-authorizations, armazenadas como arquivos .key, que podem ser binários ou “ASCII-armored”. Por padrão, esses arquivos .key são pesquisados no branch chamado keyring, mas você pode especificar um nome de branch diferente em .guix-channel assim:

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

Para resumir, como autor de um canal, há três coisas que você precisa fazer para permitir que os usuários autentiquem seu código:

  1. Exporte as chaves OpenPGP de contribuidores anteriores e atuais com gpg --export e armazene-as em arquivos .key, por padrão em uma ramificação chamada keyring (recomendamos torná-la uma ramificação órfã).
  2. Introduza um .guix-authorizations inicial no repositório do canal. Faça isso em um commit assinado (veja Confirmar acesso, para obter informações sobre como assinar commits do Git).
  3. Anuncie a introdução do canal, por exemplo, na página web do seu canal. A introdução do canal, como vimos acima, é o par commit/chave—i.e., o commit que introduziu .guix-authorizations, e a impressão digital do OpenPGP usada para assiná-lo.

Antes de enviar para seu repositório Git público, você pode executar guix git authenticate para verificar se você assinou todos os commits que está prestes a enviar com uma chave autorizada:

guix git authenticate commit signer

onde commit e signer são a introdução do seu canal. Veja Invocando guix git authenticate, para detalhes.

Publicar um canal assinado requer disciplina: qualquer erro, como um commit não assinado ou um commit assinado por uma chave não autorizada, impedirá que usuários puxem do seu canal — bem, esse é o ponto principal da autenticação! Preste atenção às mesclagens em particular: commits de mesclagem são considerados autênticos se e somente se forem assinados por uma chave presente no arquivo .guix-authorizations de ambos os ramos.


6.11 URL principal

Os autores do canal podem indicar a URL principal do repositório Git do canal no arquivo .guix-channel, assim:

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

Isso permite que guix pull determine se está puxando código de um espelho do canal; quando esse for o caso, ele avisa o usuário que o espelho pode estar obsoleto e exibe a URL primária. Dessa forma, os usuários não podem ser enganados para buscar código de um espelho obsoleto que não recebe atualizações de segurança.

Esse recurso só faz sentido para repositórios autenticados, como o canal oficial guix, para o qual guix pull garante que o código que ele recupera é autêntico.


Anterior: , Acima: Canais   [Conteúdo][Índice]

6.12 Escrevendo notícias do canal

Os autores do canal podem ocasionalmente querer comunicar aos seus usuários informações sobre mudanças importantes no canal. Você enviaria um e-mail para todos eles, mas isso não é conveniente.

Em vez disso, os canais podem fornecer um arquivo de notícias; quando os usuários do canal executam guix pull, esse arquivo de notícias é lido automaticamente e guix pull --news pode exibir os anúncios que correspondem aos novos commits que foram extraídos, se houver.

Para fazer isso, os autores do canal devem primeiro declarar o nome do arquivo de notícias em seu arquivo .guix-channel:

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

O arquivo de notícias em si, etc/news.txt neste exemplo, deve ser parecido com isto:

(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!"))))

Enquanto o arquivo de notícias estiver usando a sintaxe Scheme, evite nomeá-lo com uma extensão .scm ou então ele será pego ao construir o canal e gerará um erro, pois não é um módulo válido. Como alternativa, você pode mover o módulo do canal para um subdiretório e armazenar o arquivo de notícias em outro diretório.

O arquivo consiste em uma lista de entradas de notícias. Cada entrada é associada a um commit ou tag: ela descreve as alterações feitas neste commit, possivelmente em commits anteriores também. Os usuários veem as entradas somente na primeira vez que obtêm o commit ao qual a entrada se refere.

O campo title deve ser um resumo de uma linha, enquanto body pode ser arbitrariamente longo, e ambos podem conter marcação Texinfo (veja Overview em GNU Texinfo). Tanto o título quanto o corpo são uma lista de tuplas de tag/mensagem de idioma, o que permite que guix pull exiba notícias no idioma que corresponde à localidade do usuário.

Se você quiser traduzir notícias usando um fluxo de trabalho baseado em gettext, você pode extrair strings traduzíveis com xgettext (veja xgettext Invocation em GNU Gettext Utilities). Por exemplo, supondo que você escreva entradas de notícias em inglês primeiro, o comando abaixo cria um arquivo PO contendo as strings a serem traduzidas:

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

Para resumir, sim, você pode usar seu canal como um blog. Mas cuidado, isso é não é bem o que seus usuários podem esperar.


Próximo: , Anterior: , Acima: GNU Guix   [Conteúdo][Índice]

7 Desenvolvimento

Se você é um desenvolvedor de software, o Guix fornece ferramentas que você achará úteis, independentemente da linguagem em que estiver desenvolvendo. É sobre isso que este capítulo trata.

O comando guix shell fornece uma maneira conveniente de configurar ambientes de software únicos, seja para fins de desenvolvimento ou para executar um comando sem instalá-lo em seu perfil. O comando guix pack permite que você crie embalagens de aplicativos que podem ser facilmente distribuídas para usuários que não executam o Guix.


7.1 Invocando guix shell

O propósito do guix shell é facilitar a criação de ambientes de software únicos, sem alterar o perfil. Ele é normalmente usado para criar ambientes de desenvolvimento; também é uma maneira conveniente de executar aplicativos sem “poluir” seu perfil.

Nota: O comando guix shell foi introduzido recentemente para substituir guix environment (veja Invocando guix environment). Se você estiver familiarizado com guix environment, notará que ele é semelhante, mas também—esperamos!—mais conveniente.

A sintaxe geral é:

guix shell [opções] [pacote…]

Às vezes, uma sessão de shell interativa não é desejada. Um comando arbitrário pode ser invocado colocando o token -- para separar o comando do resto dos argumentos.

O exemplo a seguir cria um ambiente contendo Python e NumPy, compilando ou baixando qualquer pacote ausente e executa o comando python3 nesse ambiente:

guix shell python python-numpy -- python3

Note que é necessário incluir o pacote principal python neste comando, mesmo que ele já esteja instalado em seu ambiente. Isso é para que o ambiente shell saiba definir PYTHONPATH e outras variáveis relacionadas. O ambiente shell não pode verificar o ambiente instalado anteriormente, porque então seria não determinístico. Isso é verdade para a maioria das bibliotecas: seu pacote de linguagem correspondente deve ser incluído na invocação do shell.

Nota: guix shell também pode ser usado como um interpretador de script, também conhecido como shebang. Aqui está um exemplo de script Python autocontido fazendo uso desse recurso:

#!/usr/bin/env -S guix shell python python-numpy -- python3
import numpy
print("This is numpy", numpy.version.version)

Você pode passar qualquer opção guix shell, mas há uma ressalva: o kernel Linux tem um limite de 127 bytes no comprimento do shebang.

Ambientes de desenvolvimento podem ser criados como no exemplo abaixo, que gera um shell interativo contendo todas as dependências e variáveis de ambiente necessárias para trabalhar no Inkscape:

guix shell --development inkscape

Sair do shell coloca o usuário de volta no ambiente original antes de guix shell ser invocado. A próxima coleta de lixo (veja Invocando guix gc) pode limpar pacotes que foram instalados no ambiente e que não são mais usados fora dele.

Como uma conveniência adicional, guix shell tentará fazer o que você quer dizer quando for invocado interativamente sem nenhum outro argumento, como em:

guix shell

Se encontrar um manifest.scm no diretório de trabalho atual ou em qualquer um dos seus pais, ele usa esse manifesto como se tivesse sido fornecido via --manifest. Da mesma forma, se encontrar um guix.scm nos mesmos diretórios, ele o usa para construir um perfil de desenvolvimento como se --development e --file estivessem presentes. Em ambos os casos, o arquivo só será carregado se o diretório em que ele reside estiver listado em ~/.config/guix/shell-authorized-directories. Isso fornece uma maneira fácil de definir, compartilhar e entrar em ambientes de desenvolvimento.

Por padrão, a sessão ou comando do shell é executado em um ambiente aumentado, onde os novos pacotes são adicionados às variáveis de ambiente do caminho de pesquisa, como PATH. Em vez disso, você pode escolher criar um ambiente isolado contendo apenas os pacotes solicitados. Passar a opção --pure limpa as definições de variáveis de ambiente encontradas no ambiente pai14; passar --container vai um passo além ao gerar um contêiner isolado do resto do sistema:

guix shell --container emacs gcc-toolchain

O comando acima gera um shell interativo em um contêiner onde nada além de emacs, gcc-toolchain e suas dependências estão disponíveis. O contêiner não tem acesso à rede e não compartilha nenhum arquivo além do diretório de trabalho atual com o ambiente ao redor. Isso é útil para evitar acesso a recursos de todo o sistema, como /usr/bin em distros estrangeiras.

Esta opção --container também pode ser útil se você deseja executar um aplicativo sensível à segurança, como um navegador da web, em um ambiente isolado. Por exemplo, o comando abaixo inicia o Ungoogled-Chromium em um ambiente isolado, que:

  • compartilha o acesso à rede com o host
  • herda as variáveis de ambiente do host DISPLAY e XAUTHORITY
  • tem acesso aos registros de autenticação do host do XAUTHORITY file
  • não tem informações sobre o diretório atual do host
guix shell --container --network --no-cwd ungoogled-chromium \
  --preserve='^XAUTHORITY$' --expose="${XAUTHORITY}" \
  --preserve='^DISPLAY$' -- chromium

guix shell define a variável GUIX_ENVIRONMENT no shell que ele gera; seu valor é o nome do arquivo do perfil deste ambiente. Isso permite que os usuários, digamos, definam um prompt específico para ambientes de desenvolvimento em seu .bashrc (veja Bash Startup Files em Manual de referência do GNU Bash):

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

... ou para navegar pelo perfil:

$ ls "$GUIX_ENVIRONMENT/bin"

As opções disponíveis estão resumidas abaixo.

--check

Configure o ambiente e verifique se o shell sobrecarregaria as variáveis de ambiente. É uma boa ideia usar esta opção na primeira vez que você executar guix shell para uma sessão interativa para garantir que sua configuração esteja correta.

Por exemplo, se o shell modificar a variável de ambiente PATH, informe isso, pois você obterá um ambiente diferente do que solicitou.

Tais problemas geralmente indicam que os arquivos de inicialização do shell estão modificando inesperadamente essas variáveis de ambiente. Por exemplo, se você estiver usando Bash, certifique-se de que as variáveis de ambiente estejam definidas ou modificadas em ~/.bash_profile e não em ~/.bashrc—o primeiro é originado apenas por shells de login. Veja Bash Startup Files em Manual de referência do GNU Bash, para detalhes sobre os arquivos de inicialização do Bash.

--development
-D

Faça com que guix shell inclua no ambiente as dependências do pacote a seguir em vez do pacote em si. Isso pode ser combinado com outros pacotes. Por exemplo, o comando abaixo inicia um shell interativo contendo as dependências de tempo de compilação do GNU Guile, além do Autoconf, Automake e Libtool:

guix shell -D guile autoconf automake libtool
--expression=expr
-e expr

Crie um ambiente para o pacote ou lista de pacotes que expr avalia.

Por exemplo, executando:

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

inicia um shell com o ambiente para esta variante específica do pacote PETSc.

Rodando:

guix shell -e '(@ (gnu) %base-packages)'

inicia um shell com todos os pacotes do sistema base disponíveis.

Os comandos acima usam apenas a saída padrão dos pacotes fornecidos. Para selecionar outras saídas, duas tuplas de elementos podem ser especificadas:

guix shell -e '(list (@ (gnu packages bash) bash) "include")'

Veja package->development-manifest, para obter informações sobre como escrever um manifesto para o ambiente de desenvolvimento de um pacote.

--file=arquivo
-f arquivo

Crie um ambiente contendo o pacote ou lista de pacotes que o código dentro de arquivo avalia.

Por exemplo, arquivo pode conter uma definição como esta (veja Definindo pacotes):

(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.69 automake texinfo))))

Com o arquivo acima, você pode entrar em um ambiente de desenvolvimento para o GDB executando:

guix shell -D -f gdb-devel.scm
--manifest=arquivo
-m arquivo

Crie um ambiente para os pacotes contidos no objeto manifest retornado pelo código Scheme em arquivo. Esta opção pode ser repetida várias vezes, nesse caso os manifestos são concatenados.

Isso é semelhante à opção de mesmo nome em guix package (veja --manifest) e usa os mesmos arquivos de manifesto.

Veja Escrevendo manifestos, para informações sobre como escrever um manifesto. Veja --export-manifest abaixo sobre como obter um primeiro manifesto.

--export-manifest

Grave na saída padrão um manifesto adequado para --manifest correspondente às opções de linha de comando fornecidas.

Esta é uma maneira de “converter” argumentos de linha de comando em um manifesto. Por exemplo, imagine que você está cansado de digitar linhas longas e gostaria de obter um manifesto equivalente a esta linha de comando:

guix shell -D guile git emacs emacs-geiser emacs-geiser-guile

Basta adicionar --export-manifest à linha de comando acima:

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"))))

Você pode armazená-lo em um arquivo, digamos manifest.scm, e de lá passá-lo para guix shell ou praticamente qualquer comando guix:

guix shell -m manifest.scm

Voilà, você converteu uma longa linha de comando em um manifesto! Esse processo de conversão honra opções de transformação de pacote (veja Opções de transformação de pacote), então deve ser sem perdas.

--profile=perfil
-p perfil

Crie um ambiente contendo os pacotes instalados em perfil. Use guix package (veja Invocando guix package) para criar e gerenciar perfis.

--pure

Desconfigura variáveis de ambiente existentes ao construir o novo ambiente, exceto aquelas especificadas com --preserve (veja abaixo). Isso tem o efeito de criar um ambiente no qual os caminhos de pesquisa contêm apenas entradas de pacote.

--preserve=regexp
-E regexp

Quando usado junto com --pure, preserva as variáveis de ambiente que correspondem a regexp—em outras palavras, coloca-as em uma “lista branca” de variáveis de ambiente que devem ser preservadas. Esta opção pode ser repetida várias vezes.

guix shell --pure --preserve=^SLURM openmpi … \
  -- mpirun …

Este exemplo executa mpirun em um contexto onde as únicas variáveis de ambiente definidas são PATH, variáveis de ambiente cujo nome começa com ‘SLURM’, bem como as variáveis “preciosas” usuais (HOME, USER, etc.).

--search-paths

Exiba as definições de variáveis de ambiente que compõem o ambiente.

--system=sistema
-s sistema

Tente construir para sistema—por exemplo, i686-linux.

--container
-C

Execute comando dentro de um contêiner isolado. O diretório de trabalho atual fora do contêiner é mapeado dentro do contêiner. Além disso, a menos que substituído por --user, um diretório pessoal (home) fictício é criado que corresponde ao diretório pessoal do usuário atual, e /etc/passwd é configurado adequadamente.

O processo gerado é executado como o usuário atual fora do contêiner. Dentro do contêiner, ele tem o mesmo UID e GID que o usuário atual, a menos que --user seja passado (veja abaixo).

--network
-N

Para contêineres, compartilhe o namespace de rede com o sistema host. Os contêineres criados sem esse sinalizador têm acesso somente ao dispositivo de loopback.

--link-profile
-P

Para contêineres, vincule o perfil do ambiente a ~/.guix-profile dentro do contêiner e defina GUIX_ENVIRONMENT para isso. Isso é equivalente a tornar ~/.guix-profile uma ligação simbólica para o perfil real dentro do contêiner. A vinculação falhará e abortará o ambiente se o diretório já existir, o que certamente será o caso se guix shell foi invocado no diretório pessoal do usuário.

Certos pacotes são configurados para procurar em ~/.guix-profile por arquivos de configuração e dados;15 --link-profile permite que esses programas se comportem conforme o esperado no ambiente.

--user=usuário
-u usuário

Para contêineres, use o nome de usuário usuário no lugar do usuário atual. A entrada /etc/passwd gerada dentro do contêiner conterá o nome usuário, o diretório pessoal será /home/usuário e nenhum dado GECOS do usuário será copiado. Além disso, o UID e o GID dentro do contêiner são 1000. usuário não precisa existir no sistema.

Além disso, qualquer caminho compartilhado ou exposto (veja --share e --expose respectivamente) cujo destino esteja dentro do pessoal do usuário atual será remapeado em relação a /home/USUÁRIO; isso inclui o mapeamento automático do diretório de trabalho atual.

# 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

Embora isso limite o vazamento da identidade do usuário por meio de caminhos iniciais e de cada um dos campos do usuário, esse é apenas um componente útil de uma solução mais ampla de privacidade/anonimato — não uma solução em si.

--no-cwd

Para contêineres, o comportamento padrão é compartilhar o diretório de trabalho atual com o contêiner isolado e mudar imediatamente para esse diretório dentro do contêiner. Se isso for indesejável, --no-cwd fará com que o diretório de trabalho atual não seja compartilhado automaticamente e mudará para o diretório pessoal do usuário dentro do contêiner. Veja também --user.

--expose=fonte[=alvo]
--share=fonte[=alvo]

Para contêineres, --expose (resp. --share) expõe o sistema de arquivos fonte do sistema host como o sistema de arquivos somente leitura (resp. gravável) alvo dentro do contêiner. Se alvo não for especificado, fonte será usado como o ponto de montagem de destino no contêiner.

O exemplo abaixo gera um Guile REPL em um contêiner no qual o diretório pessoal do usuário é acessível somente para leitura por meio do diretório /exchange:

guix shell --container --expose=$HOME=/exchange guile -- guile
--symlink=spec
-S spec

Para contêineres, crie as ligações simbólicas especificadas por spec, conforme documentado em pack-symlink-option.

--emulate-fhs
-F

Quando usado com --container, emule uma configuração do FHS) dentro do contêiner, fornecendo /bin, /lib e outros diretórios e arquivos especificados pelo FHS.

Como Guix desvia da especificação FHS, esta opção configura o contêiner para imitar mais de perto o de outras distribuições GNU/Linux. Isto é útil para reproduzir outros ambientes de desenvolvimento, testar e usar programas que esperam que a especificação FHS seja seguida. Com esta opção, o contêiner incluirá uma versão do glibc que lerá /etc/ld.so.cache dentro do contêiner para o cache da biblioteca compartilhada (ao contrário do glibc no uso regular do Guix) e configurará os diretórios FHS esperados: /bin, /etc, /lib e /usr do perfil do contêiner.

--nesting
-W

Quando usado com --container, forneça Guix dentro do contêiner e organize para que ele possa interagir com o daemon de construção que roda fora do contêiner. Isso é útil se você quiser, dentro do seu contêiner isolado, criar outros contêineres, como nesta sessão de exemplo:

$ guix shell -CW coreutils
[env]$ guix shell -C guile -- guile -c '(display "olá!\n")'
olá!
[env]$ exit

A sessão acima inicia um contêiner com programas coreutils disponíveis em PATH. A partir daí, geramos guix shell para criar um contêiner aninhado que fornece nada além de Guile.

Outro exemplo é avaliar um arquivo guix.scm que não é confiável, conforme mostrado aqui:

guix shell -CW -- guix build -f guix.scm

O comando guix build executado acima só pode acessar o diretório atual.

Nos bastidores, a opção -W faz várias coisas:

  • mapeia o socket do daemon (por padrão, /var/guix/daemon-socket/socket) dentro do contêiner;
  • mapeia todo o armazém (por padrão /gnu/store) dentro do contêiner de forma que os itens do armazém disponibilizados por invocações aninhadas guix sejam visíveis;
  • adiciona o comando guix usado atualmente ao perfil no contêiner, de modo que guix describe retorne o mesmo estado dentro e fora do contêiner;
  • compartilha o cache (por padrão ~/.cache/guix) com o host, para acelerar operações como guix time-machine e guix shell.
--rebuild-cache

Na maioria dos casos, guix shell armazena em cache o ambiente para que os usos subsequentes sejam instantâneos. As entradas de cache menos usadas recentemente são removidas periodicamente. O cache também é invalidado, ao usar --file ou --manifest, sempre que o arquivo correspondente for modificado.

O --rebuild-cache força o ambiente em cache a ser atualizado. Isso é útil ao usar --file ou --manifest e o arquivo guix.scm ou manifest.scm tem dependências externas, ou se seu comportamento depende, digamos, de variáveis de ambiente.

--root=arquivo
-r arquivo

Crie arquivo como uma ligação simbólica para o perfil deste ambiente e registre-a como raiz do coletor de lixo.

Isso é útil se você deseja proteger seu ambiente da coleta de lixo, para torná-lo “persistente”.

Quando esta opção é omitida, guix shell armazena em cache os perfis para que os usos subsequentes do mesmo ambiente sejam instantâneos — isso é comparável ao uso de --root, exceto que guix shell cuida da remoção periódica das raízes do coletor de lixo menos usadas recentemente.

Em alguns casos, guix shell não armazena perfis em cache—por exemplo, se opções de transformação como --with-latest forem usadas. Nesses casos, o ambiente é protegido da coleta de lixo somente durante a sessão guix shell. Isso significa que na próxima vez que você recriar o mesmo ambiente, poderá ter que reconstruir ou baixar novamente os pacotes.

Veja Invocando guix pack, para mais sobre as raízes do coletor de lixo.

guix shell também suporta todas as opções de compilação comuns que guix build suporta (veja Opções de compilação comuns), bem como opções de transformação de pacotes (veja Opções de transformação de pacote).


7.2 Invocando guix environment

O objetivo do guix environment é auxiliar na criação de ambientes de desenvolvimento.

Aviso de descontinuação: O comando guix environment foi descontinuado em favor do guix shell, que executa funções semelhantes, mas é mais conveniente de usar. Veja Invocando guix shell.

Sendo obsoleto, o guix environment está programado para remoção futura, mas o projeto Guix está comprometido em mantê-lo até 1º de maio de 2023. Entre em contato conosco pelo e-mail guix-devel@gnu.org se quiser discutir o assunto.

A sintaxe geral é:

guix environment opções pacote

O exemplo a seguir gera uma nova configuração de shell para o desenvolvimento do GNU Guile:

guix environment guile

Se as dependências necessárias ainda não foram construídas, guix environment as constrói automaticamente. O ambiente do novo shell é uma versão aumentada do ambiente em que guix environment foi executado. Ele contém os caminhos de pesquisa necessários para construir o pacote fornecido adicionado às variáveis de ambiente existentes. Para criar um ambiente “puro”, no qual as variáveis de ambiente originais foram desconfiguradas, use a opção --pure16.

Sair de um ambiente Guix é o mesmo que sair do shell, e colocará o usuário de volta no ambiente antigo antes de guix environment ser invocado. A próxima coleta de lixo (veja Invocando guix gc) limpará os pacotes que foram instalados de dentro do ambiente e não são mais usados fora dele.

guix environment define a variável GUIX_ENVIRONMENT no shell que ele gera; seu valor é o nome do arquivo do perfil deste ambiente. Isso permite que os usuários, digamos, definam um prompt específico para ambientes de desenvolvimento em seu .bashrc (veja Bash Startup Files em Manual de referência do GNU Bash):

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

... ou para navegar pelo perfil:

$ ls "$GUIX_ENVIRONMENT/bin"

Além disso, mais de um pacote pode ser especificado, em cujo caso a união das entradas para os pacotes fornecidos é usada. Por exemplo, o comando abaixo gera um shell onde todas as dependências do Guile e do Emacs estão disponíveis:

guix environment guile emacs

Às vezes, uma sessão de shell interativa não é desejada. Um comando arbitrário pode ser invocado colocando o token -- para separar o comando do resto dos argumentos:

guix environment guile -- make -j4

Em outras situações, é mais conveniente especificar a lista de pacotes necessários no ambiente. Por exemplo, o comando a seguir executa python de um ambiente contendo Python 3 e NumPy:

guix environment --ad-hoc python-numpy python -- python3

Além disso, pode-se querer as dependências de um pacote e também alguns pacotes adicionais que não são dependências de tempo de construção ou tempo de execução, mas são úteis ao desenvolver, no entanto. Por causa disso, o sinalizador --ad-hoc é posicional. Pacotes que aparecem antes de --ad-hoc são interpretados como pacotes cujas dependências serão adicionadas ao ambiente. Pacotes que aparecem depois são interpretados como pacotes que serão adicionados ao ambiente diretamente. Por exemplo, o comando a seguir cria um ambiente de desenvolvimento Guix que inclui adicionalmente Git e strace:

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

Às vezes, é desejável isolar o ambiente o máximo possível, para máxima pureza e reprodutibilidade. Em particular, ao usar Guix em uma distribuição host que não seja Guix System, é desejável impedir o acesso a /usr/bin e outros recursos de todo o sistema do ambiente de desenvolvimento. Por exemplo, o comando a seguir gera um Guile REPL em um “contêiner” onde apenas o armazém e o diretório de trabalho atual são montados:

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

Nota: A opção --container requer Linux-libre 3.19 ou mais recente.

Outro caso de uso típico para contêineres é executar aplicativos sensíveis à segurança, como um navegador da web. Para executar o Eolie, precisamos expor e compartilhar alguns arquivos e diretórios; incluímos nss-certs e expomos /etc/ssl/certs/ para autenticação HTTPS; finalmente, preservamos a variável de ambiente DISPLAY, pois os aplicativos gráficos em contêiner não serão exibidos sem ela.

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

As opções disponíveis estão resumidas abaixo.

--check

Configure o ambiente e verifique se o shell sobrecarregaria as variáveis de ambiente. Veja --check, para mais informações.

--root=arquivo
-r arquivo

Crie arquivo como uma ligação simbólica para o perfil deste ambiente e registre-a como raiz do coletor de lixo.

Isso é útil se você deseja proteger seu ambiente da coleta de lixo, para torná-lo “persistente”.

Quando esta opção pe omitida, o ambiente é protegido da coleta de lixo apenas pela duração da sessão do guix environment. Isso significa que na próxima vez que você recriar o mesmo ambiente, você tpoderia ter que reconstruir ou refazer o download dos pacotes. Veja Invocando guix gc, para mais sobre GC roots.

--expression=expr
-e expr

Crie um ambiente para o pacote ou lista de pacotes que expr avalia.

Por exemplo, executando:

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

inicia um shell com o ambiente para esta variante específica do pacote PETSc.

Rodando:

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

inicia um shell com todos os pacotes do sistema base disponíveis.

Os comandos acima usam apenas a saída padrão dos pacotes fornecidos. Para selecionar outras saídas, duas tuplas de elementos podem ser especificadas:

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

Crie um ambiente para o pacote ou lista de pacotes que o código dentro de arquivo avalia.

Por exemplo, arquivo pode conter uma definição como esta (veja Definindo pacotes):

(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.69 automake texinfo))))
--manifest=arquivo
-m arquivo

Crie um ambiente para os pacotes contidos no objeto manifest retornado pelo código Scheme em arquivo. Esta opção pode ser repetida várias vezes, nesse caso os manifestos são concatenados.

Isso é semelhante à opção de mesmo nome em guix package (veja --manifest) e usa os mesmos arquivos de manifesto.

Veja guix shell --export-manifest, para obter informações sobre como “converter” opções de linha de comando em um manifesto.

--ad-hoc

Inclui todos os pacotes especificados no ambiente resultante, como se um pacote ad hoc fosse definido com eles como entradas. Esta opção é útil para criar rapidamente um ambiente sem ter que escrever uma expressão de pacote para conter as entradas desejadas.

Por exemplo, o comando:

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

executa guile em um ambiente onde Guile e Guile-SDL estão disponíveis.

Observe que este exemplo solicita implicitamente a saída padrão de guile e guile-sdl, mas é possível solicitar uma saída específica — por exemplo, glib:bin solicita a saída bin de glib (veja Pacotes com múltiplas saídas).

Esta opção pode ser composta com o comportamento padrão de guix environment. Pacotes que aparecem antes de --ad-hoc são interpretados como pacotes cujas dependências serão adicionadas ao ambiente, o comportamento padrão. Pacotes que aparecem depois são interpretados como pacotes que serão adicionados ao ambiente diretamente.

--profile=perfil
-p perfil

Crie um ambiente contendo os pacotes instalados em perfil. Use guix package (veja Invocando guix package) para criar e gerenciar perfis.

--pure

Desconfigura variáveis de ambiente existentes ao construir o novo ambiente, exceto aquelas especificadas com --preserve (veja abaixo). Isso tem o efeito de criar um ambiente no qual os caminhos de pesquisa contêm apenas entradas de pacote.

--preserve=regexp
-E regexp

Quando usado junto com --pure, preserva as variáveis de ambiente que correspondem a regexp—em outras palavras, coloca-as em uma “lista branca” de variáveis de ambiente que devem ser preservadas. Esta opção pode ser repetida várias vezes.

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

Este exemplo executa mpirun em um contexto onde as únicas variáveis de ambiente definidas são PATH, variáveis de ambiente cujo nome começa com ‘SLURM’, bem como as variáveis “preciosas” usuais (HOME, USER, etc.).

--search-paths

Exiba as definições de variáveis de ambiente que compõem o ambiente.

--system=sistema
-s sistema

Tente construir para sistema—por exemplo, i686-linux.

--container
-C

Execute comando dentro de um contêiner isolado. O diretório de trabalho atual fora do contêiner é mapeado dentro do contêiner. Além disso, a menos que substituído por --user, um diretório pessoal (home) fictício é criado que corresponde ao diretório pessoal do usuário atual, e /etc/passwd é configurado adequadamente.

O processo gerado é executado como o usuário atual fora do contêiner. Dentro do contêiner, ele tem o mesmo UID e GID que o usuário atual, a menos que --user seja passado (veja abaixo).

--network
-N

Para contêineres, compartilhe o namespace de rede com o sistema host. Os contêineres criados sem esse sinalizador têm acesso somente ao dispositivo de loopback.

--link-profile
-P

Para contêineres, vincule o perfil do ambiente a ~/.guix-profile dentro do contêiner e defina GUIX_ENVIRONMENT para isso. Isso é equivalente a tornar ~/.guix-profile uma ligação simbólica para o perfil real dentro do contêiner. A vinculação falhará e abortará o ambiente se o diretório já existir, o que certamente será o caso se guix environment foi invocado no diretório pessoal do usuário.

Certos pacotes são configurados para procurar em ~/.guix-profile por arquivos de configuração e dados;17 --link-profile permite que esses programas se comportem conforme o esperado no ambiente.

--user=usuário
-u usuário

Para contêineres, use o nome de usuário usuário no lugar do usuário atual. A entrada /etc/passwd gerada dentro do contêiner conterá o nome usuário, o diretório pessoal será /home/usuário e nenhum dado GECOS do usuário será copiado. Além disso, o UID e o GID dentro do contêiner são 1000. usuário não precisa existir no sistema.

Além disso, qualquer caminho compartilhado ou exposto (veja --share e --expose respectivamente) cujo destino esteja dentro do pessoal do usuário atual será remapeado em relação a /home/USUÁRIO; isso inclui o mapeamento automático do diretório de trabalho atual.

# 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

Embora isso limite o vazamento da identidade do usuário por meio de caminhos iniciais e de cada um dos campos do usuário, esse é apenas um componente útil de uma solução mais ampla de privacidade/anonimato — não uma solução em si.

--no-cwd

Para contêineres, o comportamento padrão é compartilhar o diretório de trabalho atual com o contêiner isolado e mudar imediatamente para esse diretório dentro do contêiner. Se isso for indesejável, --no-cwd fará com que o diretório de trabalho atual não seja compartilhado automaticamente e mudará para o diretório pessoal do usuário dentro do contêiner. Veja também --user.

--expose=fonte[=alvo]
--share=fonte[=alvo]

Para contêineres, --expose (resp. --share) expõe o sistema de arquivos fonte do sistema host como o sistema de arquivos somente leitura (resp. gravável) alvo dentro do contêiner. Se alvo não for especificado, fonte será usado como o ponto de montagem de destino no contêiner.

O exemplo abaixo gera um Guile REPL em um contêiner no qual o diretório pessoal do usuário é acessível somente para leitura por meio do diretório /exchange:

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

Para contêineres, emule uma configuração Filesystem Hierarchy Standard (FHS) dentro do contêiner, veja a especificação oficial. Como o Guix se desvia da especificação FHS, esta opção configura o contêiner para imitar mais de perto o de outras distribuições GNU/Linux. Isto é útil para reproduzir outros ambientes de desenvolvimento, testar e usar programas que esperam que a especificação FHS seja seguida. Com esta opção, o contêiner incluirá uma versão de glibc que lerá /etc/ld.so.cache dentro do contêiner para o cache da biblioteca compartilhada (ao contrário de glibc no uso regular do Guix) e configurará os diretórios FHS esperados: /bin, /etc, /lib e /usr do perfil do contêiner.

guix environment também oferece suporte a todas as opções de compilação comuns que guix build oferece suporte (veja Opções de compilação comuns), bem como opções de transformação de pacotes (veja Opções de transformação de pacote).


7.3 Invocando guix pack

Ocasionalmente você quer passar software para pessoas que não têm (ainda!) a sorte de usar Guix. Você diria para elas executarem guix package -i algo, mas isso não é possível neste caso. É aqui que guix pack entra.

Nota: Se você estiver procurando maneiras de trocar binários entre máquinas que já executam Guix, veja Invocando guix copy, Invocando guix publish e Invocando guix archive.

O comando guix pack cria uma embalagem de software encapsulado: ele cria um tarball ou algum outro arquivo contendo os binários do software em que você está interessado e todas as suas dependências. O arquivo resultante pode ser usado em qualquer máquina que não tenha Guix, e as pessoas podem executar exatamente os mesmos binários que você tem com Guix. A embalagem em si é criada de forma reproduzível em bits, para que qualquer um possa verificar se ela realmente contém os resultados da compilação que você pretende enviar.

Por exemplo, para criar uma embalagem contenda Guile, Emacs, Geiser e todas as suas dependências, você pode executar:

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

O resultado aqui é um tarball contendo um diretório /gnu/store com todos os pacotes relevantes. O tarball resultante contém um perfil com os três pacotes de interesse; o perfil é o mesmo que seria criado por guix package -i. É esse mecanismo que é usado para criar o próprio tarball binário autônomo do Guix (veja Instalação de binários).

Usuários desta embalagem teriam que executar /gnu/store/…-profile/bin/guile para executar o Guile, o que você pode achar inconveniente. Para contornar isso, você pode criar, digamos, uma ligação simbólica /opt/gnu/bin para o perfil:

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

Dessa forma, os usuários podem digitar /opt/gnu/bin/guile e aproveitar.

E se o destinatário do sua embalagem não tiver privilégios de root na máquina dele e, portanto, não puder descompactá-lo no sistema de arquivos raiz? Nesse caso, você vai querer usar a opção --relocatable (veja abaixo). Essa opção produz binários relocáveis, o que significa que eles podem ser colocados em qualquer lugar na hierarquia do sistema de arquivos: no exemplo acima, os usuários podem descompactar seu tarball no diretório pessoal deles e executar diretamente ./opt/gnu/bin/guile.

Como alternativa, você pode produzir uma embalagem no formato de imagem do Docker usando o seguinte comando:

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

O resultado é um tarball que pode ser passado para o comando docker load, seguido por docker run:

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

onde arquivo é a imagem retornada por guix pack, e guile-guile-readline é sua “image tag”. Veja documentação do Docker para mais informações.

Outra opção é produzir uma imagem SquashFS com o seguinte comando:

guix pack -f squashfs bash guile emacs emacs-geiser

O resultado é uma imagem do sistema de arquivos SquashFS que pode ser montada ou usada diretamente como uma imagem de contêiner do sistema de arquivos com o ambiente de execução do contêiner Singularity, usando comandos como singularity shell ou singularity exec.

Outro formato internamente baseado em SquashFS é o AppImage. Um arquivo de AppImage pode ser criado e executado sem qualquer provilégio especial:

file=$(guix pack -f appimage --entry-point=bin/guile guile)
$file --help

Várias opções de linha de comando permitem que você personalize sua embalagem:

--format=formato
-f formato

Produza uma embalagem no formato fornecido.

Os formatos disponíveis são:

tarball

Este é o formato padrão. Ele produz um tarball contendo todos os binários e ligações simbólicas especificados.

docker

Isso produz um tarball que segue o Docker Image Specification. Por padrão, o “nome do repositório” como aparece na saída do comando docker images é computado a partir de nomes de pacotes passados na linha de comando ou no arquivo manifesto. Como alternativa, o “nome do repositório” também pode ser configurado por meio da opção --image-tag. Consulte --help-docker-format para obter mais informações sobre essas opções avançadas.

squashfs

Isso produz uma imagem SquashFS contendo todos os binários e ligações simbólicas especificados, bem como pontos de montagem vazios para sistemas de arquivos virtuais como procfs.

Nota: Singularity requer que você forneça /bin/sh na imagem. Por esse motivo, guix pack -f squashfs sempre implica -S /bin=bin. Portanto, sua invocação guix pack deve sempre começar com algo como:

guix pack -f squashfs bash …

Se você esquecer o pacote bash (ou similar), singularity run e singularity exec falharão com uma mensagem inútil “nenhum arquivo ou diretório”.

deb

Isso produz um arquivo Debian (um pacote com a extensão de arquivo ‘.deb’) contendo todos os binários e ligações simbólicas especificados, que podem ser instalados em cima de qualquer distribuição GNU(/Linux) baseada em dpkg. Opções avançadas podem ser reveladas por meio da opção --help-deb-format. Elas permitem incorporar arquivos de controle para um controle mais refinado, como ativar gatilhos específicos ou fornecer um script de configuração do mantenedor para executar código de configuração arbitrário na instalação.

guix pack -f deb -C xz -S /usr/bin/hello=bin/hello hello

Nota: Como os arquivos produzidos com guix pack contêm uma coleção de itens de armazém e como cada pacote dpkg não deve ter arquivos conflitantes, na prática isso significa que você provavelmente não conseguirá instalar mais de um desses arquivos em um dado sistema. Você pode, no entanto, empacotar quantos pacotes Guix quiser em um desses arquivos.

Aviso: dpkg assumirá a propriedade de quaisquer arquivos contidos no pacote que ele não saiba. Não é sensato instalar arquivos ‘.deb’ produzidos pelo Guix em um sistema onde /gnu/store é compartilhado por outro software, como uma instalação do Guix ou outras embalagens não deb.

rpm

Isso produz um arquivo RPM (um pacote com a extensão de arquivo ‘.rpm’) contendo todos os binários e ligações simbólicas especificados, que podem ser instalados em cima de qualquer distribuição GNU/Linux baseada em RPM. O formato RPM incorpora somas de verificação para cada arquivo que ele contém, que o comando rpm usa para validar a integridade do arquivo.

Opções avançadas relacionadas a RPM são reveladas por meio da opção --help-rpm-format. Essas opções permitem incorporar scripts de mantenedor que podem ser executados antes ou depois da instalação do arquivo RPM, por exemplo.

O formato RPM suporta pacotes relocáveis por meio da opção --prefix do comando rpm, o que pode ser útil para instalar um pacote RPM em um prefixo específico.

guix pack -f rpm -R -C xz -S /usr/bin/hello=bin/hello hello
sudo rpm --install --prefix=/opt /gnu/store/...-hello.rpm

Nota: Ao contrário dos pacotes Debian, arquivos conflitantes, mas idênticos em pacotes RPM podem ser instalados simultaneamente, o que significa que vários pacotes RPM produzidos pelo guix pack geralmente podem ser instalados lado a lado sem nenhum problema.

Aviso: rpm assume a propriedade de quaisquer arquivos contidos no pacote, o que significa que ele removerá /gnu/store ao desinstalar um pacote RPM gerado pelo Guix, a menos que o pacote RPM tenha sido instalado com a opção --prefix do comando rpm. Não é sensato instalar pacotes ‘.rpm’ produzidos pelo Guix em um sistema onde /gnu/store é compartilhado por outro software, como uma instalação do Guix ou outras embalagens não rpm.

appimage

Isto produz um arquivo AppImage com a extensão ‘.AppImage’. Um AppImage é um volume SquashFS prefixado com uma execução que monta o sistema de arquivo SquashFS e executa o binário criado com o --entry-point. Isso resulta num arquivo auto-contido que agrupa o software e todos os requisitos num único arquivo. Quando o mesmo é executado, ele roda o software empacotado.

guix pack -f appimage --entry-point=bin/vlc vlc

A execução usada pelos AppImages invoca o comando fusermount3 para montar a imagem rapidamente. Se o comando está indiponível, o AppImage falha em executar, mas ele ainda pode ser iniciado com a opção --appimage-extract-and-run.

Aviso: Ao construir um AppImage, sempre passe a opção --relocatable (ou -R, ou a -RR) para ter certeza que a imagem pode ser usada em sistemas onde o Guix não está instalado. Um aviso é impresso quando esta opção não é usada.

guix pack -f appimage --entry-point=bin/hello --relocatable hello

Nota: The resulting AppImage does not conform to the complete standard as it currently does not contain a .DirIcon file. This does not impact functionality of the AppImage itself, but possibly that of software used to manage AppImages.

Nota: As the generated AppImage packages the complete dependency graph, it will be larger than comparable AppImage files found online, which depend on host system libraries.

--relocatable
-R

Produza binários relocáveis—ou seja, binários que podem ser colocados em qualquer lugar na hierarquia do sistema de arquivos e executados a partir daí.

Quando essa opção é passada uma vez, os binários resultantes requerem suporte para user namespaces no kernel Linux; quando passada duas vezes18, binários relocáveis recorrem a outras técnicas se os namespaces de usuário não estiverem disponíveis, e essencialmente funcionam em qualquer lugar—veja abaixo as implicações.

Por exemplo, se você criar uma embalagem contendo Bash com:

guix pack -RR -S /mybin=bin bash

... você pode copiar essa embalagem para uma máquina que não tenha Guix e, a partir do seu diretório pessoal, como um usuário normal, executar:

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

Nesse shell, se você digitar ls /gnu/store, você notará que /gnu/store aparece e contém todas as dependências de bash, mesmo que a máquina realmente não tenha /gnu/store completamente! Essa é provavelmente a maneira mais simples de implementar software construído pelo Guix em uma máquina não Guix.

Nota: Por padrão, binários relocáveis dependem do recurso user namespace do kernel Linux, que permite que usuários sem privilégios montem ou alterem a raiz (chroot). Versões antigas do Linux não o suportavam, e algumas distribuições GNU/Linux o desativam.

Para produzir binários relocáveis que funcionam mesmo na ausência de namespaces de usuário, passe --relocatable ou -R duas vezes. Nesse caso, os binários tentarão o suporte a namespaces de usuário e retornarão a outro mecanismo de execução se os namespaces de usuário não forem suportados. Os seguintes mecanismos de execução são suportados:

default

Experimente usar namespaces de usuário e retorne ao PRoot se eles não forem suportados (veja abaixo).

performance

Experimente usar namespaces de usuário e retorne ao Fakechroot se eles não forem suportados (veja abaixo).

userns

Execute o programa por meio de namespaces de usuário e aborte se eles não forem suportados.

proot

Execute através do PRoot. O programa PRoot fornece o suporte necessário para virtualização do sistema de arquivos. Ele consegue isso usando a chamada de sistema ptrace no programa em execução. Essa abordagem tem a vantagem de funcionar sem exigir suporte especial do kernel, mas incorre em sobrecarga de tempo de execução toda vez que uma chamada de sistema é feita.

fakechroot

Execute através do Fakechroot. Fakechroot virtualiza acessos ao sistema de arquivos interceptando chamadas para funções da biblioteca C, como open, stat, exec e assim por diante. Ao contrário do PRoot, ele incorre em muito pouca sobrecarga. No entanto, nem sempre funciona: por exemplo, alguns acessos ao sistema de arquivos feitos de dentro da biblioteca C não são interceptados, e acessos ao sistema de arquivos feitos via syscalls diretas também não são interceptados, levando a um comportamento errático.

Ao executar um programa encapsulado, você pode solicitar explicitamente um dos mecanismos de execução listados acima, definindo a variável de ambiente GUIX_EXECUTION_ENGINE adequadamente.

--entry-point=comando

Use command as the entry point of the resulting pack, if the pack format supports it—currently docker, appimage, and squashfs (Singularity) support it. command must be relative to the profile contained in the pack.

O ponto de entrada especifica o comando que ferramentas como docker run ou singularity run iniciam automaticamente por padrão. Por exemplo, você pode fazer:

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

A embalagem resultante pode ser facilmente carregado e docker run sem argumentos extras irá gerar bin/guile:

docker load -i pack.tar.gz
docker run image-id
--entry-point-argument=comando
-A comando

Use comando como um argumento para o ponto de entrada da embalagem resultante. Esta opção é válida somente em conjunto com --entry-point e pode aparecer várias vezes na linha de comando.

guix pack -f docker --entry-point=bin/guile --entry-point-argument="--help" guile
--max-layers=n

Especifica o número máximo de camadas de imagem do Docker permitidas ao criar uma imagem.

guix pack -f docker --max-layers=100 guile

Esta opção permite que você limite o número de camadas em uma imagem Docker. As imagens Docker são compostas de várias camadas, e cada camada adiciona ao tamanho geral e à complexidade da imagem. Ao definir um número máximo de camadas, você pode controlar os seguintes efeitos:

  • Uso do disco: Aumentar o número de camadas pode ajudar a otimizar o espaço em disco necessário para armazenar várias imagens criadas com um grafo de pacote semelhante.
  • Puxar: Ao transferir imagens entre diferentes nós ou sistemas, ter mais camadas pode reduzir o tempo necessário para puxar a imagem.
--expression=expr
-e expr

Considere o pacote que expr avalia.

Isso tem o mesmo propósito que a opção de mesmo nome em guix build (veja --expression em guix build).

--file=arquivo

Build a pack containing the package or other object the code within file evaluates to.

This has the same purpose as the same-named option in guix build (veja --file in guix build), but it has no shorthand, because -f already means --format.

--manifest=arquivo
-m arquivo

Use os pacotes contidos no objeto manifesto retornado pelo código Scheme em arquivo. Esta opção pode ser repetida várias vezes, nesse caso os manifestos são concatenados.

Isto tem um propósito similar à opção de mesmo nome em guix package (veja --manifest) e usa os mesmos arquivos de manifesto. Ele permite que você defina uma coleção de pacotes uma vez e use-a tanto para criar perfis quanto para criar arquivos para uso em máquinas que não tenham o Guix instalado. Note que você pode especificar ou um arquivo de manifesto ou uma lista de pacotes, mas não ambos.

Veja Escrevendo manifestos, para obter informações sobre como escrever um manifesto. Veja guix shell --export-manifest, para obter informações sobre como “converter” opções de linha de comando em um manifesto.

--system=sistema
-s sistema

Tente compilar para sistema—por exemplo, i686-linux—em vez do tipo de sistema do host de compilação.

--target=tripleto

Construção cruzada para tripleto, que deve ser um tripleto GNU válido, como "aarch64-linux-gnu" (veja (Autoconf)autoconf).

--compression=ferramenta
-C ferramenta

Compacte o tarball resultante usando ferramenta—um dos seguintes: gzip, zstd, bzip2, xz, lzip ou none para nenhuma compactação.

--symlink=spec
-S spec

Adicione os symlinks especificados por spec à embalagem. Esta opção pode aparecer várias vezes.

spec tem o formato fonte=alvo, onde fonte é a ligação simbólica que será criado e alvo é o destino da ligação simbólica.

Por exemplo, -S /opt/gnu/bin=bin cria uma ligação simbólica /opt/gnu/bin apontanda para o subdiretório bin do perfil.

--save-provenance

Salvar informações de procedência para os pacotes passados na linha de comando. As informações de procedência incluem a URL e o commit dos canais em uso (veja Canais).

As informações de procedência são salvas no arquivo /gnu/store/…-profile/manifest na embalagem, junto com os metadados usuais do pacote — o nome e a versão de cada pacote, suas entradas propagadas e assim por diante. São informações úteis para o destinatário da embalagem, que então sabe como a embalagem foi (supostamente) obtida.

Esta opção não é habilitada por padrão porque, assim como os timestamps, as informações de proveniência não contribuem em nada para o processo de construção. Em outras palavras, há uma infinidade de URLs de canais e IDs de commit que podem levar à mesma embalagem. Gravar esses metadados “silenciosos” na saída, portanto, potencialmente quebra a propriedade de reprodutibilidade bit a bit de origem para binário.

--root=arquivo
-r arquivo

Crie arquivo como uma ligação simbólica para a embalagem resultante e registre-a como uma raiz do coletor de lixo.

--localstatedir
--profile-name=nome

Inclua o “diretório de estado local”, /var/guix, na embalagem resultante, e principalmente o perfil /var/guix/profiles/per-user/root/nome — por padrão, nome é guix-profile, que corresponde a ~root/.guix-profile.

/var/guix contém o banco de dados do armazém (veja O armazém), bem como as raízes do coletor de lixo (veja Invocando guix gc). Fornecê-lo na embalagem significa que o armazém está “completo” e gerenciável pelo Guix; não fornecê-lo na embalagem significa que o armazém está “morto”: itens não podem ser adicionados a ele ou removidos dele após a extração da embalagem.

Um caso de uso para isso é o tarball binário independente do Guix (veja Instalação de binários).

--derivation
-d

Exiba o nome da derivação que constrói a embalagem.

--bootstrap

Use os binários bootstrap para construir a embalagem. Esta opção é útil somente para desenvolvedores do Guix.

Além disso, guix pack suporta todas as opções de compilação comuns (veja Opções de compilação comuns) e todas as opções de transformação de pacote (veja Opções de transformação de pacote).


7.4 A cadeia de ferramentas do GCC

Se você precisa de uma cadeia de ferramentas completa para compilar e vincular código-fonte C ou C++, use o pacote gcc-toolchain. Este pacote fornece uma cadeia de ferramentas GCC completa para desenvolvimento C/C++, incluindo o próprio GCC, a GNU C Library (cabeçalhos e binários, além de símbolos de depuração na saída debug), Binutils e um wrapper de vinculador.

O propósito do wrapper é inspecionar os switches -L e -l passados para o vinculador, adicionar argumentos -rpath correspondentes e invocar o vinculador real com esse novo conjunto de argumentos. Você pode instruir o wrapper a se recusar a vincular bibliotecas que não estejam no store definindo a variável de ambiente GUIX_LD_WRAPPER_ALLOW_IMPURITIES como no.

O pacote gfortran-toolchain fornece uma cadeia de ferramentas GCC completa para desenvolvimento Fortran. Para outras linguagens, use ‘guix search gcc toolchain’ (veja Invoking guix package).


7.5 Invocando guix git authenticate

O comando guix git authenticate autentica um checkout do Git seguindo a mesma regra dos canais (veja autenticação dos canais). Ou seja, a partir de um commit determinado, ele garante que todos os commits subsequentes sejam assinados por uma chave OpenPGP cuja impressão digital apareça no arquivo .guix-authorizations de seus commits pais.

Você achará esse comando útil se mantiver um canal. Mas, na verdade, esse mecanismo de autenticação é útil em um contexto mais amplo, então você pode querer usá-lo para repositórios Git que não tenham nada a ver com Guix.

A sintaxe geral é:

guix git authenticate commit signer [options…]

By default, this command authenticates the Git checkout in the current directory; it outputs nothing and exits with exit code zero on success and non-zero on failure. commit above denotes the first commit where authentication takes place, and signer is the OpenPGP fingerprint of public key used to sign commit. Together, they form a channel introduction (veja channel introduction). On your first successful run, the introduction is recorded in the .git/config file of your checkout, allowing you to omit them from subsequent invocations:

guix git authenticate [opções…]

Caso você tenha ramos que exijam introduções diferentes, você pode especificá-las diretamente em .git/config. Por exemplo, se o ramo chamado personal-fork tiver uma introdução diferente de outros ramos, você pode estender .git/config ao longo destas linhas:

[guix "authentication-personal-fork"]
	introduction-commit = cabba936fd807b096b48283debdcddccfea3900d
	introduction-signer = C0FF EECA BBA9 E6A8 0D1D  E643 A2A0 6DF2 A33A 54FA
	keyring = keyring

A primeira execução também tenta instalar ganchos pré-push e pós-mesclagem, de modo que guix git authenticate seja invocado assim que você executar git push, git pull e comandos relacionados; no entanto, ele não substitui ganchos preexistentes.

As opções de linha de comando descritas abaixo permitem que você ajuste o processo.

--repository=diretório
-r diretório

Abra o repositório Git em diretório em vez do diretório atual.

--keyring=referência
-k referência

Carregue o chaveiro OpenPGP de referência, a referência de uma ramificação como origin/keyring ou my-keyring. A ramificação deve conter chaves públicas OpenPGP em arquivos .key, em formato binário ou “ASCII-armored”. Por padrão, o chaveiro é carregado da ramificação chamada keyring.

--end=commit

Autentique revisões até commit.

--stats

Exibir estatísticas de assinatura de confirmação após a conclusão.

--cache-key=chave

Os commits autenticados anteriormente são armazenados em cache em um arquivo em ~/.cache/guix/authentication. Esta opção força o cache a ser armazenado no arquivo chave naquele diretório.

--historical-authorizations=arquivo

Por padrão, qualquer commit cujo(s) commit(s) pai(s) não tenha(m) o arquivo .guix-authorizations é considerado não autêntico. Em contraste, esta opção considera as autorizações em arquivo para qualquer commit que não tenha .guix-authorizations. O formato de arquivo é o mesmo que o de .guix-authorizations (veja formato .guix-authorizations).


Próximo: , Anterior: , Acima: GNU Guix   [Conteúdo][Índice]

8 Interface de programação

O GNU Guix fornece várias interfaces de programação Scheme (APIs) para definir, construir e consultar pacotes. A primeira interface permite que os usuários escrevam definições de pacotes de alto nível. Essas definições se referem a conceitos de empacotamento familiares, como o nome e a versão de um pacote, seu sistema de construção e suas dependências. Essas definições podem então ser transformadas em ações de construção concretas.

As ações de build são executadas pelo daemon Guix, em nome dos usuários. Em uma configuração padrão, o daemon tem acesso de gravação ao armazém—o diretório /gnu/store—enquanto os usuários não têm. A configuração recomendada também faz com que o daemon execute builds em chroots, sob usuários de compilação específicos, para minimizar a interferência com o resto do sistema.

APIs de nível inferior estão disponíveis para interagir com o daemon e o armazém. Para instruir o daemon a executar uma ação de compilação, os usuários na verdade fornecem a ele uma derivação. Uma derivação é uma representação de baixo nível das ações de compilação a serem tomadas e do ambiente no qual elas devem ocorrer — derivações são para definições de pacotes o que assembly é para programas C. O termo “derivação” vem do fato de que os resultados de compilação derivam deles.

Este capítulo descreve todas essas APIs, começando pelas definições de pacotes de alto nível. Veja Estrutura da árvore de origem, para uma visão geral mais geral do código-fonte.


8.1 Módulos de pacote

Do ponto de vista da programação, as definições de pacotes da distribuição GNU são fornecidas pelos módulos Guile no namespace (gnu packages …)19 (veja módulos Guile em Manual de Referência do GNU Guile). Por exemplo, o módulo (gnu packages emacs) exporta uma variável chamada emacs, que é vinculada a um objeto <package> (veja Definindo pacotes).

O namespace do módulo (gnu packages …) é automaticamente escaneado em busca de pacotes pelas ferramentas de linha de comando. Por exemplo, ao executar guix install emacs, todos os módulos (gnu packages …) são escaneados até que um que exporte um objeto de pacote cujo nome é emacs seja encontrado. Esse recurso de busca de pacotes é implementado no módulo (gnu packages).

Os usuários podem armazenar definições de pacotes em módulos com nomes diferentes — por exemplo, (my-packages emacs)20. Há duas maneiras de tornar essas definições de pacotes visíveis para as interfaces do usuário:

  1. Ao adicionar o diretório que contém os módulos do seu pacote ao caminho de pesquisa com o sinalizador -L do guix package e outros comandos (veja Opções de compilação comuns), ou definindo a variável de ambiente GUIX_PACKAGE_PATH descrita abaixo.
  2. Ao definir um canal e configurando guix pull para que ele puxe dele. Um canal é essencialmente um repositório Git contendo módulos de pacote. Veja Canais, para mais informações sobre como definir e usar canais.

GUIX_PACKAGE_PATH funciona de forma semelhante a outras variáveis de caminho de pesquisa:

Variável de ambiente: GUIX_PACKAGE_PATH

Esta é uma lista de diretórios separados por dois pontos para procurar módulos de pacotes adicionais. Os diretórios listados nesta variável têm precedência sobre os próprios módulos da distribuição.

A distribuição é totalmente bootstrapped e auto-contida: cada pacote é construído com base somente em outros pacotes na distribuição. A raiz deste grafo de dependência é um pequeno conjunto dos binários bootstrap, fornecido pelo módulo (gnu packages bootstrap). Para mais informações sobre bootstrapping, veja Inicializando.


8.2 Definindo pacotes

A interface de alto nível para definições de pacotes é implementada nos módulos (guix packages) e (guix build-system). Como exemplo, a definição de pacote, ou receita, para o pacote GNU Hello se parece com isto:

(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+)))

Sem ser um especialista em Scheme, o leitor pode ter adivinhado o significado dos vários campos aqui. Esta expressão vincula a variável hello a um objeto <package>, que é essencialmente um registro (veja Scheme records em Manual de Referência do GNU Guile). Este objeto de pacote pode ser inspecionado usando procedimentos encontrados no módulo (guix packages); por exemplo, (package-name hello) retorna—surpresa!—"hello".

Com sorte, você poderá importar parte ou toda a definição do pacote de seu interesse de outro repositório, usando o comando guix import (veja Invoking guix import).

No exemplo acima, hello é definido em um módulo próprio, (gnu packages hello). Tecnicamente, isso não é estritamente necessário, mas é conveniente fazê-lo: todos os pacotes definidos em módulos sob (gnu packages …) são automaticamente conhecidos pelas ferramentas de linha de comando (veja Módulos de pacote).

Há alguns pontos que vale a pena observar na definição do pacote acima:

  • O campo source do pacote é um objeto <origin> (veja Referência do origin, para a referência completa). Aqui, o método url-fetch de (guix download) é usado, o que significa que a fonte é um arquivo a ser baixado por FTP ou HTTP.

    O prefixo mirror://gnu instrui url-fetch a usar um dos espelhos GNU definidos em (guix download).

    O campo sha256 especifica o hash SHA256 esperado do arquivo que está sendo baixado. É obrigatório e permite que o Guix verifique a integridade do arquivo. O formulário (base32 …) introduz a representação base32 do hash. Você pode obter essas informações com guix download (veja Invocando guix download) e guix hash (veja Invocando guix hash).

    Quando necessário, o formulário origin também pode ter um campo patches listando os remendos a serem aplicados e um campo snippet fornecendo uma expressão Scheme para modificar o código-fonte.

  • O campo build-system especifica o procedimento para construir o pacote (veja Sistemas de compilação). Aqui, gnu-build-system representa o familiar GNU Build System, onde os pacotes podem ser configurados, construídos e instalados com a sequência de comando usual ./configure && make && make check && make install.

    Ao começar a empacotar software não trivial, você pode precisar de ferramentas para manipular essas fases de compilação, manipular arquivos e assim por diante. Veja Construir utilitários, para mais informações sobre isso.

  • O campo arguments especifica opções para o sistema de compilação (veja Sistemas de compilação). Aqui, ele é interpretado por gnu-build-system como uma solicitação executada configure com o sinalizador --enable-silent-rules.

    E quanto a esses caracteres de citação (')? Eles são sintaxe Scheme para introduzir uma lista literal; ' é sinônimo de quote. Às vezes, você também verá ` (uma crase, sinônimo de quasiquote) e , (uma vírgula, sinônimo de unquote). Veja quoting em Manual de referência do GNU Guile, para detalhes. Aqui, o valor do campo arguments é uma lista de argumentos passados para o sistema de construção mais adiante, como com apply (veja apply em Manual de referência do GNU Guile).

    A sequência hash-dois-pontos (#:) define um palavra-chave em Scheme (veja Keywords em Manual de referência do GNU Guile) e #:configure-flags é uma palavra-chave usada para passar um argumento de palavra-chave para o sistema de compilação (veja Coding With Keywords em Manual de referência do GNU Guile).

  • O campo inputs especifica entradas para o processo de construção—i.e., dependências de tempo de construção ou tempo de execução do pacote. Aqui, adicionamos uma entrada, uma referência à variável gawk; gawk é ele próprio vinculado a um objeto <package>.

    Note que GCC, Coreutils, Bash e outras ferramentas essenciais não precisam ser especificadas como entradas aqui. Em vez disso, gnu-build-system cuida de garantir que elas estejam presentes (veja Sistemas de compilação).

    No entanto, quaisquer outras dependências precisam ser especificadas no campo inputs. Qualquer dependência não especificada aqui simplesmente ficará indisponível para o processo de build, possivelmente levando a uma falha de build.

Veja Referência do package, para uma descrição completa dos campos possíveis.

Indo além: Intimidado pela linguagem Scheme ou curioso sobre ela? O Livro de receitas tem uma seção curta para começar que recapitula algumas das coisas mostradas acima e explica os fundamentos. Veja Um curso intensivo de Scheme em Livro de receitas do GNU Guix, para mais informações.

Uma vez que uma definição de pacote esteja pronta, o pacote pode ser realmente construído usando a ferramenta de linha de comando guix build (veja Invocando guix build), solucionando problemas de quaisquer falhas de construção que você encontrar (veja Depurando falhas de compilação). Você pode facilmente voltar para a definição do pacote usando o comando guix edit (veja Invocando guix edit). Veja Diretrizes de empacotamento, para mais informações sobre como testar definições de pacote, e Invocando guix lint, para informações sobre como verificar uma definição para conformidade de estilo. Por fim, veja Canais, para obter informações sobre como estender a distribuição adicionando suas próprias definições de pacote em um “canal”.

Por fim, a atualização da definição do pacote para uma nova versão upstream pode ser parcialmente automatizada pelo comando guix refresh (veja Invocando guix refresh).

Nos bastidores, uma derivação correspondente ao objeto <package> é primeiro computada pelo procedimento package-derivation. Essa derivação é armazenada em um arquivo .drv em /gnu/store. As ações de construção que ele prescreve podem então ser realizadas usando o procedimento build-derivations (veja O armazém).

Procedimento: package-derivation armazém pacote [sistema]

Retorne o objeto <derivation> de pacote para sistema (veja Derivações).

pacote deve ser um objeto <package> válido e sistema deve ser uma string que indique o tipo de sistema de destino — por exemplo, "x86_64-linux" para um sistema GNU baseado em Linux x86_64. armazém deve ser uma conexão com o daemon, que opera no armazém (veja O armazém).

Da mesma forma, é possível calcular uma derivação que crie um pacote para algum outro sistema:

Procedimento: package-cross-derivation armazém pacote alvo [sistema]

Retorne o objeto <derivation> de pacote criado de sistema para alvo.

alvo deve ser um tripleto GNU válido que indique o hardware e o sistema operacional de destino, como "aarch64-linux-gnu" (veja Specifying Target Triplets em Autoconf).

Depois de ter as definições dos pacotes, você pode definir facilmente variantes desses pacotes. Veja Definindo variantes de pacote, para mais informações sobre isso.


8.2.1 Referência do package

Esta seção resume todas as opções disponíveis nas declarações package (veja Definindo pacotes).

Tipo de dados: package

Este é o tipo de dado que representa uma receita de pacote.

name

The name of the package, as a string.

version

The version of the package, as a string. Veja Números de versão, for guidelines.

source

Um objeto que diz como o código-fonte do pacote deve ser adquirido. Na maioria das vezes, este é um objeto origin, que denota um arquivo obtido da Internet (veja Referência do origin). Também pode ser qualquer outro objeto “tipo arquivo”, como um local-file, que denota um arquivo do sistema de arquivos local (veja local-file).

build-system

O sistema de compilação que deve ser usado para compilar o pacote (veja Sistemas de compilação).

arguments (padrão: '())

Os argumentos que devem ser passados para o sistema de compilação (veja Sistemas de compilação). Esta é uma lista, normalmente contendo pares sequenciais de palavra-chave-valor, como neste exemplo:

(package
  (name "example")
  ;; several fields omitted
  (arguments
    (list #:tests? #f                     ;skip tests
          #:make-flags #~'("VERBOSE=1")   ;pass flags to 'make'
          #:configure-flags #~'("--enable-frobbing"))))

O conjunto exato de palavras-chave suportadas depende do sistema de compilação (veja Sistemas de compilação), mas você verá que quase todas elas honram #:configure-flags, #:make-flags, #:tests? e #:phases. A palavra-chave #:phases em particular permite que você modifique o conjunto de fases de compilação para seu pacote (veja Fases de construção).

O REPL tem comandos dedicados para inspecionar interativamente os valores de alguns desses argumentos, como um auxílio de depuração conveniente (veja Usando Guix interativamente).

Nota de compatibilidade: Até a versão 1.3.0, o campo arguments normalmente usaria quote (') ou quasiquote (`) e nenhuma expressão G, assim:

(package
  ;; several fields omitted
  (arguments   ;old-style quoted arguments
   '(#:tests? #f
     #:configure-flags '("--enable-frobbing"))))

Para converter esse estilo para o mostrado acima, você pode executar guix style -S arguments pacote (veja Invoking guix style).

inputs (padrão: '())
native-inputs (padrão: '())
propagated-inputs (padrão: '())

Esses campos listam dependências do pacote. Cada elemento dessas listas é um pacote, origem ou outro “objeto tipo arquivo” (veja Expressões-G); para especificar a saída desse objeto tipo arquivo que deve ser usado, passe uma lista de dois elementos onde o segundo elemento é a saída (veja Pacotes com múltiplas saídas, para mais informações sobre saídas de pacotes). Por exemplo, a lista abaixo especifica três entradas:

(list libffi libunistring
      `(,glib "bin"))      ;a saída "bin" de GLib

No exemplo acima, a saída "out" de libffi e libunistring é usada.

Nota de compatibilidade: Até a versão 1.3.0, as listas de entrada eram uma lista de tuplas, onde cada tupla tem um rótulo para a entrada (uma string) como seu primeiro elemento, um pacote, origem ou derivação como seu segundo elemento e, opcionalmente, o nome da saída que deve ser usada, cujo padrão é "out". Por exemplo, a lista abaixo é equivalente à acima, mas usando o antigo estilo de entrada:

;; Estilo de entrada antigo (obsoleto).
`(("libffi" ,libffi)
  ("libunistring" ,libunistring)
  ("glib:bin" ,glib "bin"))  ;a saída "bin" do GLib

Este estilo agora está obsoleto; ele ainda é suportado, mas o suporte será removido em uma versão futura. Ele não deve ser usado para novas definições de pacote. Veja Invoking guix style, sobre como migrar para o novo estilo.

A distinção entre native-inputs e inputs é necessária ao considerar a compilação cruzada. Ao compilar cruzadamente, as dependências listadas em inputs são construídas para a arquitetura target (alvo); inversamente, as dependências listadas em native-inputs são construídas para a arquitetura da máquina build.

native-inputs é normalmente usado para listar ferramentas necessárias no momento da compilação, mas não no momento da execução, como Autoconf, Automake, pkg-config, Gettext ou Bison. guix lint pode relatar prováveis erros nesta área (veja Invocando guix lint).

Por fim, propagated-inputs é semelhante a inputs, mas os pacotes especificados serão instalados automaticamente nos perfis (veja a função dos perfis no Guix) junto com o pacote ao qual pertencem (veja guix package, para obter informações sobre como guix package lida com entradas propagadas).

Por exemplo, isso é necessário ao empacotar uma biblioteca C/C++ que precisa de cabeçalhos de outra biblioteca para compilar, ou quando um arquivo pkg-config faz referência a outro por meio de seu campo Requires.

Outro exemplo em que propagated-inputs é útil é para linguagens que não têm um recurso para registrar o caminho de pesquisa em tempo de execução semelhante ao RUNPATH de arquivos ELF; isso inclui Guile, Python, Perl e mais. Ao empacotar bibliotecas escritas nessas linguagens, garanta que elas possam encontrar o código da biblioteca do qual dependem em tempo de execução listando as dependências em tempo de execução em propagated-inputs em vez de inputs.

outputs (padrão: '("out"))

A lista de nomes de saída do pacote. Veja Pacotes com múltiplas saídas, para usos típicos de saídas adicionais.

native-search-paths (padrão: '())
search-paths (padrão: '())

Uma lista de objetos search-path-specification descrevendo variáveis de ambiente do caminho de pesquisa respeitadas pelo pacote. Veja Caminhos de pesquisa, para mais informações sobre especificações do caminho de pesquisa.

Quanto às entradas, a distinção entre native-search-paths e search-paths só importa quando há compilação cruzada. Em um contexto de compilação cruzada, native-search-paths se aplica exclusivamente a entradas nativas, enquanto search-paths se aplica somente a entradas de host.

Pacotes como compiladores cruzados se importam com entradas de destino — por exemplo, nosso compilador cruzado GCC (modificado) tem CROSS_C_INCLUDE_PATH em search-paths, o que permite que ele escolha arquivos .h para o sistema de destino e não aqueles de entradas nativas. Para a maioria dos pacotes, porém, apenas native-search-paths faz sentido.

replacement (padrão: #f)

Deve ser #f ou um objeto de pacote que será usado como um substituição para este pacote. Veja enxertos, para detalhes.

synopsis

Uma descrição de uma linha do pacote.

description

Uma descrição mais elaborada do pacote, como uma string na sintaxe Texinfo.

license

A licença do pacote; um valor de (guix licenses), ou uma lista de tais valores.

home-page

A URL para a página inicial do pacote, como uma string.

supported-systems (padrão: %supported-systems)

A lista de sistemas suportados pelo pacote, como strings do formato arquitetura-kernel, por exemplo "x86_64-linux".

location (padrão: localização de origem do formulário package)

O local de origem do pacote. É útil sobrescrever isso ao herdar de outro pacote, em cujo caso esse campo não é corrigido automaticamente.

Macro: this-package

Quando usado no escopo lexical de uma definição de campo de pacote, esse identificador é resolvido para o pacote que está sendo definido.

O exemplo abaixo mostra como adicionar um pacote como uma entrada nativa de si mesmo durante a compilação cruzada:

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

  ;; Quando compilado de forma cruzada, Guile, por exemplo, depende de
  ;; uma versão nativa de si mesmo. Adicione aqui.
  (native-inputs (if (%current-target-system)
                     (list this-package)
                     '())))

É um erro fazer referência a this-package fora de uma definição de pacote.

Os seguintes procedimentos auxiliares são fornecidos para ajudar a lidar com entradas de pacotes.

Procedimento: lookup-package-input pacote nome
Procedimento: lookup-package-native-input pacote nome
Procedimento: lookup-package-propagated-input pacote nome
Procedimento: lookup-package-direct-input pacote nome

Procure nome entre as entradas de pacote (ou entradas nativas, propagadas ou diretas). Retorne-o se encontrado, #f caso contrário.

name is the name of a package or the file name of an origin 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 …>

Neste exemplo, obtemos o pacote gmp que está entre as entradas diretas de coreutils.

When looking up an origin, use the name that appears in the origin’s file-name field or its default file name—e.g., "foo-1.2.tar.gz".

Às vezes, você vai querer obter a lista de entradas necessárias para desenvolver um pacote—todas as entradas que são visíveis quando o pacote é compilado. É isso que o procedimento package-development-inputs retorna.

Procedimento: package-development-inputs pacote [sistema] [#:target #f]

Retorna a lista de entradas necessárias para pacote para fins de desenvolvimento em sistema. Quando target é verdadeiro, retorna as entradas necessárias para compilar cruzadamente pacote de sistema para o alvo target, onde target é um tripleto como "aarch64-linux-gnu".

Note que o resultado inclui entradas explícitas e entradas implícitas—entradas adicionadas automaticamente pelo sistema de construção (veja Sistemas de compilação). Vamos pegar o pacote hello para ilustrar isso:

(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 …>) )

Neste exemplo, package-direct-inputs retorna a lista vazia, porque hello tem zero dependências explícitas. Por outro lado, package-development-inputs inclui entradas adicionadas implicitamente por gnu-build-system que são necessárias para construir hello: tar, gzip, GCC, libc, Bash e mais. Para visualizá-lo, guix graph hello mostraria entradas explícitas, enquanto guix graph -t bag hello incluiria entradas implícitas (veja Invocando guix graph).

Como os pacotes são objetos Scheme regulares que capturam um grafo de dependência completo e procedimentos de construção associados, geralmente é útil escrever procedimentos que pegam um pacote e retornam uma versão modificada dele de acordo com alguns parâmetros. Abaixo estão alguns exemplos.

Procedimento: package-with-c-toolchain pacote cadeia

Retorna uma variante de pacote que usa cadeia de ferramentas em vez da cadeia de ferramentas padrão GNU C/C++. cadeia deve ser uma lista de entradas (tuplas de rótulo/pacote) que fornecem funcionalidade equivalente, como o pacote gcc-toolchain.

O exemplo abaixo retorna uma variante do pacote hello criado com GCC 10.x e o restante da cadeia de ferramentas GNU (Binutils e a Biblioteca C GNU) em vez da cadeia de ferramentas padrão:

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

A cadeia de ferramentas de construção é parte das entradas implícitas dos pacotes—geralmente não é listada como parte dos vários campos “entradas” e, em vez disso, é puxada pelo sistema de construção. Consequentemente, esse procedimento funciona alterando o sistema de construção de pacote para que ele puxe cadeia de ferramentas em vez dos padrões. Veja Sistemas de compilação, para mais informações sobre sistemas de construção.


8.2.2 Referência do origin

Esta seção documenta origens. Uma declaração origin especifica dados que devem ser “produzidos”—baixados, normalmente—e cujo hash de conteúdo é conhecido com antecedência. Origens são usados principalmente para representar o código-fonte de pacotes (veja Definindo pacotes). Por esse motivo, o formulário origin permite que você declare remendos para aplicar ao código-fonte original, bem como trechos de código para modificá-lo.

Tipo de dados: origin

Este é o tipo de dado que representa a origem do código-fonte.

uri

Um objeto contendo o URI da fonte. O tipo de objeto depende do method (veja abaixo). Por exemplo, ao usar o método url-fetch de (guix download), os valores válidos de uri são: uma URL representada como uma string, ou uma lista delas.

method

Um procedimento monádico que manipula o URI fornecido. O procedimento deve aceitar pelo menos três argumentos: o valor do campo uri e o algoritmo de hash e o valor de hash especificados pelo campo hash. Ele deve retornar um item do armazém ou uma derivação na mônada do armazém (veja A mônada do armazém); a maioria dos métodos retorna uma derivação de saída fixa (veja Derivações).

Os métodos comumente usados incluem url-fetch, que busca dados de uma URL, e git-fetch, que busca dados de um repositório Git (veja abaixo).

sha256

Um bytevector contendo o hash SHA-256 da fonte. Isso é equivalente a fornecer um objeto SHA256 content-hash no campo hash descrito abaixo.

hash

O objeto content-hash da fonte — veja abaixo como usar content-hash.

You can obtain this information using guix download (veja Invocando guix download) or guix hash (veja Invocando guix hash).

file-name (padrão: #f)

O nome do arquivo sob o qual o código-fonte deve ser salvo. Quando for #f, um valor padrão sensato será usado na maioria dos casos. Caso a fonte seja obtida de uma URL, o nome do arquivo da URL será usado. Para checkouts de controle de versão, é recomendado fornecer o nome do arquivo explicitamente porque o padrão não é muito descritivo.

patches (padrão: '())

Uma lista de nomes de arquivos, origens ou objetos tipo arquivo (veja objetos tipo arquivo) apontando para remendos a serem aplicados à origem.

Esta lista de remendos deve ser incondicional. Em particular, não pode depender do valor de %current-system ou %current-target-system.

snippet (padrão: #f)

Uma expressão G (veja Expressões-G) ou expressão S que será executada no diretório de origem. Esta é uma maneira conveniente de modificar a origem, às vezes mais conveniente do que um patch.

patch-flags (padrão: '("-p1"))

Uma lista de sinalizadores de linha de comando que devem ser passados para o comando patch.

patch-inputs (padrão: #f)

Pacotes de entrada ou derivações para o processo de patching. Quando este é #f, o conjunto usual de entradas necessárias para patching é fornecido, como GNU Patch.

modules (padrão: '())

Uma lista de módulos Guile que devem ser carregados durante o processo de aplicação de remendos e durante a execução do código no campo snippet.

patch-guile (padrão: #f)

O pacote Guile que deve ser usado no processo de patching. Quando este é #f, um padrão sensato é usado.

Tipo de dados: content-hash valor [algoritmo]

Construa um objeto hash de conteúdo para o algoritmo fornecido, e com valor como seu valor hash. Quando algoritmo é omitido, presuma que é sha256.

valor pode ser uma string literal, nesse caso ela é decodificada em base32, ou pode ser um bytevector.

Os seguintes formulários são todos equivalentes:

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

Tecnicamente, content-hash é atualmente implementado como uma macro. Ele realiza verificações de sanidade no momento da expansão da macro, quando possível, como garantir que valor tenha o tamanho certo para algoritmo.

Como vimos acima, como exatamente os dados aos quais uma origem se refere são recuperados é determinado pelo seu campo method. O módulo (guix download) fornece o método mais comum, url-fetch, descrito abaixo.

Procedimento: url-fetch url hash-algo hash [nome] [#:executable?? #f]

Retorna uma derivação de saída fixa que busca dados de url (uma string, ou uma lista de strings denotando URLs alternativas), que deve ter hash hash do tipo hash-algo (um símbolo). Por padrão, o nome do arquivo é o nome base de URL; opcionalmente, nome pode especificar um nome de arquivo diferente. Quando executable? é verdadeiro, torna o arquivo baixado executável.

Quando uma das URLs começa com mirror://, sua parte host é interpretada como o nome de um esquema de espelho, obtido de %mirror-file.

Como alternativa, quando a URL começa com file://, retorne o nome do arquivo correspondente no armazém.

Da mesma forma, o módulo (guix git-download) define o método de origem git-fetch, que busca dados de um repositório de controle de versão Git, e o tipo de dados git-reference para descrever o repositório e a revisão a serem buscados.

Procedimento: git-fetch ref hash-algo hash [nome]

Retorna uma derivação de saída fixa que busca ref, um objeto <git-reference>. Espera-se que a saída tenha hash recursivo hash do tipo hash-algo (um símbolo). Use nome como o nome do arquivo, ou um nome genérico se #f.

Procedimento: git-fetch/lfs ref hash-algo hash [nome]

Esta é uma variante do procedimento git-fetch que suporta a extensão Git LFS (Large File Storage). Isso pode ser útil para extrair alguns dados de teste binários para executar o conjunto de testes de um pacote, por exemplo.

Tipo de dados: git-reference

Este tipo de dado representa uma referência Git para git-fetch a recuperar.

url

A URL do repositório Git a ser clonado.

commit

Esta string denota o commit a ser buscado (uma string hexadecimal) ou a tag a ser buscada. Você também pode usar um ID de commit “curto” ou um identificador de estilo git describe como v1.0.1-10-g58d7909c97.

recursive? (padrão: #f)

Este booleano indica se os submódulos do Git devem ser buscados recursivamente.

O exemplo abaixo denota a tag v2.10 do repositório GNU Hello:

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

Isso é equivalente à referência abaixo, que nomeia explicitamente o commit:

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

Para repositórios Mercurial, o módulo (guix hg-download) define o método de origem hg-fetch e o tipo de dados hg-reference para suporte ao sistema de controle de versão Mercurial.

Procedimento: hg-fetch ref hash-algo hash [nome]

Retorna uma derivação de saída fixa que busca ref, um objeto <hg-reference>. Espera-se que a saída tenha hash recursivo hash do tipo hash-algo (um símbolo). Use nome como o nome do arquivo, ou um nome genérico se #f.

Tipo de dados: hg-reference

Este tipo de dado representa uma referência Mercurial para hg-fetch a recuperar.

url

A URL do repositório Mercurial a ser clonado.

changeset

Esta sequência de caracteres indica a revisão a ser buscado.

Para repositórios Subversion, o módulo (guix svn-download) define o método de origem svn-fetch e o tipo de dados svn-reference para suporte ao sistema de controle de versão Subversion.

Procedimento: svn-fetch ref hash-algo hash [nome]

Retorna uma derivação de saída fixa que busca ref, um objeto <svn-reference>. Espera-se que a saída tenha hash recursivo hash do tipo hash-algo (um símbolo). Use nome como o nome do arquivo, ou um nome genérico se #f.

Tipo de dados: svn-reference

Este tipo de dado representa uma referência Subversion para svn-fetch a recuperar.

url

A URL do repositório Subversion a ser clonado.

revision

Esta sequência de caracteres denota a revisão a ser buscada especificada como um número.

recursive? (padrão: #f)

Este booleano indica se deve-se buscar recursivamente “externals” do Subversion.

user-name (padrão: #f)

O nome de uma conta que tem acesso de leitura ao repositório, se o repositório não for público.

password (padrão: #f)

Senha para acessar o repositório Subversion, se necessário.

Para repositórios Bazaar, o módulo (guix bzr-download) define o método de origem bzr-fetch e o tipo de dados bzr-reference para suporte ao sistema de controle de versão Bazaar.

Procedimento: bzr-fetch ref hash-algo hash [nome]

Retorna uma derivação de saída fixa que busca ref, um objeto <bzr-reference>. Espera-se que a saída tenha hash recursivo hash do tipo hash-algo (um símbolo). Use nome como o nome do arquivo, ou um nome genérico se #f.

Tipo de dados: bzr-reference

Este tipo de dado representa uma referência Bazaar para bzr-fetch a recuperar.

url

A URL do repositório Bazaar a ser clonado.

revision

Esta sequência de caracteres denota a revisão a ser buscada especificada como um número.

Para repositórios CVS, o módulo (guix cvs-download) define o método de origem cvs-fetch e o tipo de dados cvs-reference para suporte ao Concurrent Versions System (CVS).

Procedimento: cvs-fetch ref hash-algo hash [nome]

Retorna uma derivação de saída fixa que busca ref, um objeto <cvs-reference>. Espera-se que a saída tenha hash recursivo hash do tipo hash-algo (um símbolo). Use nome como o nome do arquivo, ou um nome genérico se #f.

Tipo de dados: cvs-reference

Este tipo de dado representa uma referência CVS para cvs-fetch a recuperar.

root-directory

O diretório raiz do CVS.

module

Módulo a ser buscado.

revision

Revisão para buscar.

O exemplo abaixo denota uma versão do gnu-standards para buscar:

(cvs-reference
  (root-directory ":pserver:anonymous@cvs.savannah.gnu.org:/sources/gnustandards")
  (module "gnustandards")
  (revision "2020-11-25"))

8.3 Definindo variantes de pacote

Uma das coisas boas com o Guix é que, dada uma definição de pacote, você pode facilmente derivar variantes desse pacote—para uma versão upstream diferente, com dependências diferentes, opções de compilação diferentes e assim por diante. Alguns desses pacotes personalizados podem ser definidos diretamente da linha de comando (veja Opções de transformação de pacote). Esta seção descreve como definir variantes de pacotes no código. Isso pode ser útil em “manifestos” (veja Escrevendo manifestos) e em sua própria coleção de pacotes (veja Criando um canal), entre outros!

Conforme discutido anteriormente, os pacotes são objetos de primeira classe na linguagem Scheme. O módulo (guix packages) fornece a construção package para definir novos objetos de pacote (veja Referência do package). A maneira mais fácil de definir uma variante de pacote é usando a palavra-chave inherit junto com package. Isso permite que você herde de uma definição de pacote enquanto substitui os campos que deseja.

Por exemplo, dada a variável hello, que contém uma definição para a versão atual do GNU Hello, veja como você definiria uma variante para a versão 2.2 (lançada em 2006, é vintage!):

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

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

O exemplo acima corresponde ao que as opções de transformação de pacote --with-version ou --with-source fazem. Essencialmente, hello-2.2 preserva todos os campos de hello, exceto version e source, que ele substitui. Observe que a variável hello original ainda está lá, no módulo (gnu packages base), inalterada. Quando você define um pacote personalizado como este, você está realmente adicionando uma nova definição de pacote; a original permanece disponível.

Você pode também definir variantes com um conjunto diferente de dependências do que o pacote original. Por exemplo, o pacote padrão gdb depende de guile, mas como essa é uma dependência opcional, você pode definir uma variante que remova essa dependência assim:

(use-modules (gnu packages gdb))   ;para 'gdb'

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

O formulário modify-inputs acima remove o pacote "guile" do campo inputs de gdb. A macro modify-inputs é um auxiliar que pode ser útil sempre que você quiser remover, adicionar ou substituir entradas de pacote.

Macro: modify-inputs entradas cláusulas

Modifique as entradas do pacote fornecido, conforme retornado por package-inputs & co., de acordo com as cláusulas fornecidas. Cada cláusula deve ter uma das seguintes formas:

(delete nome…)

Exclua dos pacotes de entrada os nomes (strings) fornecidos.

(prepend pacote…)

Adicione pacotes à frente da lista de entrada.

(append pacote…)

Adicione pacotes ao final da lista de entrada.

(replace nome substituição)

Substitua o pacote chamado nome por substituição.

O exemplo abaixo remove as entradas GMP e ACL do Coreutils e adiciona libcap à frente da lista de entradas:

(modify-inputs (package-inputs coreutils)
  (delete "gmp" "acl")
  (prepend libcap))

O exemplo abaixo substitui o pacote guile das entradas de guile-redis por guile-2.2:

(modify-inputs (package-inputs guile-redis)
  (replace "guile" guile-2.2))

The last type of clause is append, to add inputs at the back of the list.

Em alguns casos, você pode achar útil escrever funções (“procedimentos”, no jargão do Scheme) que retornam um pacote com base em alguns parâmetros. Por exemplo, considere a biblioteca luasocket para a linguagem de programação Lua. Queremos criar pacotes luasocket para as principais versões do Lua. Uma maneira de fazer isso é definir um procedimento que pega um pacote Lua e retorna um pacote luasocket que depende dele:

(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))

Aqui definimos os pacotes lua5.1-socket e lua5.2-socket chamando make-lua-socket com argumentos diferentes. Veja Procedures em GNU Guile Reference Manual, para mais informações sobre procedimentos. Ter definições públicas de nível superior para esses dois pacotes significa que eles podem ser referenciados a partir da linha de comando (veja Módulos de pacote).

Essas são variantes de pacote bem simples. Como uma conveniência, o módulo (guix transformations) fornece uma interface de alto nível que mapeia diretamente para as opções de transformação de pacote mais sofisticadas (veja Opções de transformação de pacote):

Procedimento: options->transformation opções

Retorna um procedimento que, quando passado um objeto para construção (pacote, derivação, etc.), aplica as transformações especificadas por opções e retorna os objetos resultantes. opções deve ser uma lista de pares símbolo/string como:

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

Cada símbolo nomeia uma transformação e a string correspondente é um argumento para essa transformação.

Por exemplo, um manifesto equivalente a este comando:

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

... ficaria assim:

(use-modules (guix transformations))

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

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

O procedimento options->transformation é conveniente, mas talvez também não seja tão flexível quanto você gostaria. Como ele é implementado? O leitor astuto provavelmente notou que a maioria das opções de transformação de pacotes vai além das mudanças superficiais mostradas nos primeiros exemplos desta seção: elas envolvem reescrita de entrada, por meio da qual o grafo de dependência de um pacote é reescrito pela substituição de entradas específicas por outras.

A reescrita do grafo de dependência, para fins de troca de pacotes no grafo, é o que o procedimento package-input-rewriting em (guix packages) implementa.

Procedimento: package-input-rewriting substituições [nome-da-reescrita] [#:deep? #t] [#:recursive? #f]

Retorna um procedimento que, quando recebe um pacote, substitui suas dependências diretas e indiretas, incluindo entradas implícitas quando deep? é verdadeiro, de acordo com substituições. substituições é uma lista de pares de pacotes; o primeiro elemento de cada par é o pacote a ser substituído, e o segundo é a substituição.

When recursive? is true, apply replacements to the right-hand sides of replacements as well, recursively.

Opcionalmente, nome-da-reescrita é um procedimento de um argumento que recebe o nome de um pacote e retorna seu novo nome após a reescrita.

Considere este exemplo:

(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))

Aqui, primeiro definimos um procedimento de reescrita que substitui openssl por libressl. Então, o usamos para definir uma variante do pacote git que usa libressl em vez de openssl. É exatamente isso que a opção de linha de comando --with-input faz (veja --with-input).

A seguinte variante de package-input-rewriting pode corresponder a pacotes a serem substituídos por nome em vez de identidade.

Procedimento: package-input-rewriting/spec substituições [#:deep? #t] [#:replace-hidden? #t]

Retorna um procedimento que, dado um pacote, aplica as substituições fornecidas a todo o grafo do pacote, incluindo entradas implícitas, a menos que deep? seja falso.

replacements is a list of spec/procedures pair; each spec is a package specification such as "gcc" or "guile@2", and each procedure takes a matching package and returns a replacement for that package. Matching packages that have the hidden? property set are not replaced unless replace-hidden? is set to true.

O exemplo acima poderia ser reescrito desta forma:

(define libressl-instead-of-openssl
  ;; Substitua todos os pacotes chamados "openssl" por LibreSSL.
  (package-input-rewriting/spec `(("openssl" . ,(const libressl)))))

A principal diferença aqui é que, dessa vez, os pacotes são correspondidos por spec e não por identidade. Em outras palavras, qualquer pacote no grafo que seja chamado openssl será substituído.

Um procedimento mais genérico para reescrever um grafo de dependência de pacote é package-mapping: ele suporta alterações arbitrárias em nós no grafo.

Procedimento: package-mapping proc [cortar?] [#:deep? #f]

Retorna um procedimento que, dado um pacote, aplica proc a todos os pacotes dependentes e retorna o pacote resultante. O procedimento para a recursão quando cortar? retorna true para um determinado pacote. Quando deep? é true, proc é aplicado a entradas implícitas também.

Dicas: Entender como uma variante realmente se parece pode ser difícil quando se começa a combinar as ferramentas mostradas acima. Há várias maneiras de inspecionar um pacote antes de tentar construí-lo que podem ser úteis:

  • Você pode inspecionar o pacote interativamente no REPL, por exemplo, para visualizar suas entradas, o código de suas fases de construção ou seus sinalizadores de configuração (veja Usando Guix interativamente).
  • Ao reescrever dependências, guix graph geralmente pode ajudar a visualizar as alterações feitas (veja Invocando guix graph).

8.4 Escrevendo manifestos

Os comandos guix permitem que você especifique listas de pacotes na linha de comando. Isso é conveniente, mas conforme a linha de comando se torna mais longa e menos trivial, rapidamente se torna mais conveniente ter essa lista de pacotes no que chamamos de manifesto. Um manifesto é algum tipo de “lista de materiais” que define um conjunto de pacotes. Você normalmente criaria um trecho de código que constrói o manifesto, o armazenaria em um arquivo, digamos manifest.scm, e então passaria esse arquivo para a opção -m (ou --manifest) que muitos comandos guix suportam. Por exemplo, aqui está como um manifesto para um conjunto de pacotes simples pode se parecer:

;; Manifesto para três pacotes.
(specifications->manifest '("gcc-toolchain" "make" "git"))

Depois de ter esse manifesto, você pode passá-lo, por exemplo, para guix package para instalar apenas esses três pacotes no seu perfil (veja -m opção de guix package):

guix package -m manifest.scm

... ou você pode passá-lo para guix shell (veja -m opção de guix shell) para gerar um ambiente efêmero:

guix shell -m manifest.scm

... ou você pode passá-lo para guix pack praticamente da mesma forma (veja -m opção de guix pack). Você pode armazenar o manifesto sob controle de versão, compartilhá-lo com outros para que eles possam facilmente configurar, etc.

Mas como você escreve seu primeiro manifesto? Para começar, talvez você queira escrever um manifesto que espelhe o que você já tem em um perfil. Em vez de começar do zero, guix package pode gerar um manifesto para você (veja guix package --export-manifest):

# Escreva em 'manifest.scm' um manifesto correspondente ao
# perfil padrão, ~/.guix-profile.
guix package --export-manifest > manifest.scm

Ou talvez você queira “traduzir” argumentos de linha de comando em um manifesto. Nesse caso, guix shell pode ajudar (veja 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

Em ambos os casos, a opção --export-manifest tenta arduamente gerar um manifesto fiel; em particular, ela leva em consideração as opções de transformação de pacotes (veja Opções de transformação de pacote).

Nota: Manifestos são simbólicos: eles se referem a pacotes dos canais atualmente em uso (veja Canais). No exemplo acima, gcc-toolchain pode se referir à versão 14 hoje, mas pode se referir à versão 16 daqui a dois anos.

Se você quiser “fixar” seu ambiente de software em versões e variantes de pacotes específicos, precisará de uma informação adicional: a lista de revisões de canal em uso, conforme retornado por guix describe. Veja Replicando Guix, para mais informações.

Depois de obter seu primeiro manifesto, talvez você queira personalizá-lo. Como seu manifesto é código, agora você tem acesso a todas as interfaces de programação Guix!

Vamos supor que você queira um manifesto para implantar uma variante personalizada do GDB, o GNU Debugger, que não depende do Guile, junto com outro pacote. Com base no exemplo visto na seção anterior (veja Definindo variantes de pacote), você pode escrever um manifesto seguindo estas linhas:

(use-modules (guix packages)
             (gnu packages gdb)               ;para 'gdb'
             (gnu packages version-control))  ;para '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))

Observe que neste exemplo, o manifesto se refere diretamente às variáveis gdb e git, que são vinculadas a um objeto package (veja Referência do package), em vez de chamar specifications->manifest para procurar pacotes por nome, como fizemos antes. O formulário use-modules no topo nos permite acessar a interface do pacote principal (veja Definindo pacotes) e os módulos que definem gdb e git (veja Módulos de pacote). Sem problemas, estamos entrelaçando tudo isso — as possibilidades são infinitas, libere sua criatividade!

O tipo de dados para manifestos, bem como procedimentos de suporte, são definidos no módulo (guix profiles), que está automaticamente disponível para o código passado para -m. A referência segue.

Tipo de dados: manifest

Data type representing a manifest.

Atualmente possui um campo:

entries

Esta deve ser uma lista de registros manifest-entry — veja abaixo.

Tipo de dados: manifest-entry

Tipo de dado que representa uma entrada de manifesto. Uma entrada de manifesto contém metadados essenciais: uma string de nome e versão, o objeto (geralmente um pacote) para essa entrada, a saída desejada (veja Pacotes com múltiplas saídas) e uma série de informações opcionais detalhadas abaixo.

Na maioria das vezes, você não construirá uma entrada de manifesto diretamente; em vez disso, você passará um pacote para package->manifest-entry, descrito abaixo. Em alguns casos incomuns, no entanto, você pode querer criar entradas de manifesto para coisas que são não pacotes, como neste exemplo:

;; 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
version

Nome e sequência de versão para esta entrada.

item

Um pacote ou outro objeto tipo arquivo (veja objetos tipo arquivo).

output (padrão: "out")

Saída de item a ser usada, caso item tenha múltiplas saídas (veja Pacotes com múltiplas saídas).

dependencies (padrão: '())

Lista de entradas de manifesto das quais esta entrada depende. Ao construir um perfil, dependências são adicionadas ao perfil.

Normalmente, as entradas propagadas de um pacote (veja propagated-inputs) acabam tendo uma entrada de manifesto correspondente entre as dependências da própria entrada de manifesto do pacote.

search-paths (padrão: '())

A lista de especificações de caminhos de pesquisa respeitadas por esta entrada (veja Caminhos de pesquisa).

properties (padrão: '())

Lista de pares de símbolo/valor. Ao construir um perfil, essas propriedades são serializadas.

Isso pode ser usado para adicionar metadados adicionais, por exemplo, as transformações aplicadas a um pacote (veja Opções de transformação de pacote).

parent (padrão: (delay #f))

Uma promessa apontando para a entrada do manifesto “pai”.

This is used as a hint to provide context when reporting an error related to a manifest entry coming from a dependencies field.

Procedure: concatenate-manifests lst

Concatenate the manifests listed in lst and return the resulting manifest.

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 (veja 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")))
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")))
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 (veja 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.

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 (veja Invocando 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.


8.5 Sistemas de compilação

Each package definition specifies a build system and arguments for that build system (veja Definindo pacotes). This build-system field represents the build procedure of the package, as well as implicit dependencies of that build procedure.

Build systems are <build-system> objects. The interface to create and manipulate them is provided by the (guix build-system) module, and actual build systems are exported by specific modules.

Under the hood, build systems first compile package objects to bags. A bag is like a package, but with less ornamentation—in other words, a bag is a lower-level representation of a package, which includes all the inputs of that package, including some that were implicitly added by the build system. This intermediate representation is then compiled to a derivation (veja Derivações). The package-with-c-toolchain is an example of a way to change the implicit inputs that a package’s build system pulls in (veja package-with-c-toolchain).

Build systems accept an optional list of arguments. In package definitions, these are passed via the arguments field (veja Definindo pacotes). They are typically keyword arguments (veja keyword arguments in Guile em GNU Guile Reference Manual). The value of these arguments is usually evaluated in the build stratum—i.e., by a Guile process launched by the daemon (veja Derivações).

O principal sistema de compilação é o gnu-build-system, que implementa o processo padrão de compilação para o GNU e muitos outros pacotes. É providenciado pelo módulo (guix build-system gnu).

Variável: gnu-build-system

gnu-build-system represents the GNU Build System, and variants thereof (veja configuration and makefile conventions em GNU Coding Standards).

In a nutshell, packages using it are configured, built, and installed with the usual ./configure && make && make check && make install command sequence. In practice, a few additional steps are often needed. All these steps are split up in separate phases. Veja Fases de construção, for more info on build phases and ways to customize them.

In addition, this build system ensures that the “standard” environment for GNU packages is available. This includes tools such as GCC, libc, Coreutils, Bash, Make, Diffutils, grep, and sed (see the (guix build-system gnu) module for a complete list). We call these the implicit inputs of a package, because package definitions do not have to mention them.

Esta sistema de compilação suporta um número de palavras-chave como argumentos, os quais podems er passados via o campo arguments de um pacote. Veja alguns dos principais parâmetros:

#:phases

This argument specifies build-side code that evaluates to an alist of build phases. Veja Fases de construção, for more information.

#:configure-flags

This is a list of flags (strings) passed to the configure script. Veja Definindo pacotes, for an example.

#:make-flags

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

#:out-of-source?

This Boolean, #f by default, indicates whether to run builds in a build directory separate from the source tree.

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

#:tests?

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

#:test-target

This string, "check" by default, gives the name of the makefile target used by the check phase.

#:parallel-build?
#:parallel-tests?

These Boolean values specify whether to build, respectively run the test suite, in parallel, with the -j flag of make. When they are true, make is passed -jn, where n is the number specified as the --cores option of guix-daemon or that of the guix client command (veja --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. Veja the validate-runpath phase, for details.

#:substituível?

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 (veja Substitutos).

#:allowed-references
#:disallowed-references

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

This is useful to ensure that a package does not erroneously keep a reference to some of it build-time inputs, in cases where doing so would, for example, unnecessarily increase its size (veja Invocando guix size).

Vários outros sistemas de compilação suportam tais argumentos em palavras-chave.

Other <build-system> objects are defined to support other conventions and tools used by free software packages. They inherit most of gnu-build-system, and differ mainly in the set of inputs implicitly added to the build process, and in the list of phases executed. Some of these build systems are listed below.

Variável: agda-build-system

This variable is exported by (guix build-system agda). It implements a build procedure for Agda libraries.

It adds agda to the set of inputs. A different Agda can be specified with the #:agda key.

The #:plan key is a list of cons cells (regexp . parameters), where regexp is a regexp that should match the .agda files to build, and parameters is an optional list of parameters that will be passed to agda when type-checking it.

When the library uses Haskell to generate a file containing all imports, the convenience #:gnu-and-haskell? can be set to #t to add ghc and the standard inputs of gnu-build-system to the input list. You will still need to manually add a phase or tweak the 'build phase, as in the definition of agda-stdlib.

Variável: ant-build-system

This variable is exported by (guix build-system ant). It implements the build procedure for Java packages that can be built with Ant build tool.

It adds both ant and the Java Development Kit (JDK) as provided by the icedtea package to the set of inputs. Different packages can be specified with the #:ant and #:jdk parameters, respectively.

When the original package does not provide a suitable Ant build file, the parameter #:jar-name can be used to generate a minimal Ant build file build.xml with tasks to build the specified jar archive. In this case the parameter #:source-dir can be used to specify the source sub-directory, defaulting to “src”.

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

The parameter #:build-target can be used to specify the Ant task that should be run during the build phase. By default the “jar” task will be run.

Variável: android-ndk-build-system

This variable is exported by (guix build-system android-ndk). It implements a build procedure for Android NDK (native development kit) packages using a Guix-specific build process.

O sistema de compilação presume que os pacotes instalam seu prório arquivo (header) de interface pública no subdiretório include da saída out bem como suas próprias bibliotecas no subdirectório lib da saída out.

Também é presumido que a união de todas as dependências de um pacote não possuem arquivos conflitantes.

For the time being, cross-compilation is not supported - so right now the libraries and header files are assumed to be host tools.

Variável: asdf-build-system/source
Variável: asdf-build-system/sbcl
Variável: asdf-build-system/ecl

These variables, exported by (guix build-system asdf), implement build procedures for Common Lisp packages using “ASDF”. ASDF is a system definition facility for Common Lisp programs and libraries.

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

The build system uses naming conventions. For binary packages, the package name should be prefixed with the lisp implementation, such as sbcl- for asdf-build-system/sbcl.

Additionally, the corresponding source package should be labeled using the same convention as Python packages (veja Módulos Python), using the cl- prefix.

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

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

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

Variável: cargo-build-system

This variable is exported by (guix build-system cargo). It supports builds of packages using Cargo, the build tool of the Rust programming language.

It adds rustc and cargo to the set of inputs. A different Rust package can be specified with the #:rust parameter.

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

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

Variável: chicken-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.

This build system adds chicken to the package inputs, as well as the packages of gnu-build-system.

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

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

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

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

Variável: copy-build-system

This variable is exported by (guix build-system copy). It supports builds of simple packages that don’t require much compiling, mostly just moving files around.

It adds much of the gnu-build-system packages to the set of inputs. Because of this, the copy-build-system does not require all the boilerplate code often needed for the trivial-build-system.

To further simplify the file installation process, an #:install-plan argument is exposed to let the packager specify which files go where. The install plan is a list of (source target [filters]). filters are optional.

  • When source matches a file or directory without trailing slash, install it to target.
    • If target has a trailing slash, install source basename beneath target.
    • Otherwise install source as target.
  • When source is a directory with a trailing slash, or when filters are used, the trailing slash of target is implied with the same meaning as above.
    • Without filters, install the full source content to target.
    • With filters among #:include, #:include-regexp, #:exclude, #:exclude-regexp, only select files are installed depending on the filters. Each filters is specified by a list of strings.
      • With #:include, install all the files which the path suffix matches at least one of the elements in the given list.
      • With #:include-regexp, install all the files which the subpaths match at least one of the regular expressions in the given list.
      • The #:exclude and #:exclude-regexp filters are the complement of their inclusion counterpart. Without #:include flags, install all files but those matching the exclusion filters. If both inclusions and exclusions are specified, the exclusions are done on top of the inclusions.
    • When a package has multiple outputs, the #:output argument can be used to specify which output label the files should be installed to.

    In all cases, the paths relative to source are preserved within target.

Exemplos:

  • ("foo/bar" "share/my-app/"): Install bar to share/my-app/bar.
  • ("foo/bar" "share/my-app/baz"): Install bar to share/my-app/baz.
  • ("foo/" "share/my-app"): Install the content of foo inside share/my-app, e.g., install foo/sub/file to share/my-app/sub/file.
  • ("foo/" "share/my-app" #:include ("sub/file")): Install only foo/sub/file to share/my-app/sub/file.
  • ("foo/sub" "share/my-app" #:include ("file")): Install foo/sub/file to share/my-app/file.
  • ("foo/doc" "share/my-app/doc" #:output "doc"): Install "foo/doc" to "share/my-app/doc" within the "doc" output.
Variável: vim-build-system

This variable is exported by (guix build-system vim). It is an extension of the copy-build-system, installing Vim and Neovim plugins into locations where these two text editors know to find their plugins, using their packpaths.

Packages which are prefixed with vim- will be installed in Vim’s packpath, while those prefixed with neovim- will be installed in Neovim’s packpath. If there is a doc directory with the plugin then helptags will be generated automatically.

There are a couple of keywords added with the vim-build-system:

  • With plugin-name it is possible to set the name of the plugin. While by default this is set to the name and version of the package, it is often more helpful to set this to name which the upstream author calls their plugin. This is the name used for :packadd from inside Vim.
  • With install-plan it is possible to augment the built-in install-plan of the vim-build-system. This is particularly helpful if you have files which should be installed in other locations. For more information about using the install-plan, see the copy-build-system (veja copy-build-system).
  • With #:vim it is possible to add this package to Vim’s packpath, in addition to if it is added automatically because of the vim- prefix in the package’s name.
  • With #:neovim it is possible to add this package to Neovim’s packpath, in addition to if it is added automatically because of the neovim- prefix in the package’s name.
  • With #:mode it is possible to adjust the path which the plugin is installed into. By default the plugin is installed into start and other options are available, including opt. Adding a plugin into opt will mean you will need to run, for example, :packadd foo to load the foo plugin from inside of Vim.
Variável: clojure-build-system

This variable is exported by (guix build-system clojure). It implements a simple build procedure for Clojure packages using plain old compile in Clojure. Cross-compilation is not supported yet.

It adds clojure, icedtea and zip to the set of inputs. Different packages can be specified with the #:clojure, #:jdk and #:zip parameters, respectively.

A list of source directories, test directories and jar names can be specified with the #:source-dirs, #:test-dirs and #:jar-names parameters, respectively. Compile directory and main class can be specified with the #:compile-dir and #:main-class parameters, respectively. Other parameters are documented below.

This build system is an extension of ant-build-system, but with the following phases changed:

build

This phase calls compile in Clojure to compile source files and runs jar to create jars from both source files and compiled files according to the include list and exclude list specified in #:aot-include and #:aot-exclude, respectively. The exclude list has priority over the include list. These lists consist of symbols representing Clojure libraries or the special keyword #:all representing all Clojure libraries found under the source directories. The parameter #:omit-source? decides if source should be included into the jars.

marcar

This phase runs tests according to the include list and exclude list specified in #:test-include and #:test-exclude, respectively. Their meanings are analogous to that of #:aot-include and #:aot-exclude, except that the special keyword #:all now stands for all Clojure libraries found under the test directories. The parameter #:tests? decides if tests should be run.

install

This phase installs all jars built previously.

Apart from the above, this build system also contains an additional phase:

install-doc

This phase installs all top-level files with base name matching %doc-regex. A different regex can be specified with the #:doc-regex parameter. All files (recursively) inside the documentation directories specified in #:doc-dirs are installed as well.

Variável: cmake-build-system

This variable is exported by (guix build-system cmake). It implements the build procedure for packages using the CMake build tool.

It automatically adds the cmake package to the set of inputs. Which package is used can be specified with the #:cmake parameter.

The #:configure-flags parameter is taken as a list of flags passed to the cmake command. The #:build-type parameter specifies in abstract terms the flags passed to the compiler; it defaults to "RelWithDebInfo" (short for “release mode with debugging information”), which roughly means that code is compiled with -O2 -g, as is the case for Autoconf-based packages by default.

Variável: composer-build-system

This variable is exported by (guix build-system composer). It implements the build procedure for packages using Composer, the PHP package manager.

It automatically adds the php package to the set of inputs. Which package is used can be specified with the #:php parameter.

The #:test-target parameter is used to control which script is run for the tests. By default, the test script is run if it exists. If the script does not exist, the build system will run phpunit from the source directory, assuming there is a phpunit.xml file.

Variável: dune-build-system

This variable is exported by (guix build-system dune). It supports builds of packages using Dune, a build tool for the OCaml programming language. It is implemented as an extension of the ocaml-build-system which is described below. As such, the #:ocaml and #:findlib parameters can be passed to this build system.

It automatically adds the dune package to the set of inputs. Which package is used can be specified with the #:dune parameter.

There is no configure phase because dune packages typically don’t need to be configured. The #:build-flags parameter is taken as a list of flags passed to the dune command during the build.

The #:jbuild? parameter can be passed to use the jbuild command instead of the more recent dune command while building a package. Its default value is #f.

The #:package parameter can be passed to specify a package name, which is useful when a package contains multiple packages and you want to build only one of them. This is equivalent to passing the -p argument to dune.

Variável: 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: veja Pacotes Elm for more details, including utilities provided by (guix build-system elm).

There are currently a few noteworthy limitations to elm-build-system:

  • The build system is focused on packages in the Elm sense of the word: Elm projects which declare { "type": "package" } in their elm.json files. Using elm-build-system to build Elm applications (which declare { "type": "application" }) is possible, but requires ad-hoc modifications to the build phases. For examples, see the definitions of the elm-todomvc example application and the elm package itself (because the front-end for the ‘elm reactor’ command is an Elm application).
  • Elm supports multiple versions of a package coexisting simultaneously under ELM_HOME, but this does not yet work well with elm-build-system. This limitation primarily affects Elm applications, because they specify exact versions for their dependencies, whereas Elm packages specify supported version ranges. As a workaround, the example applications mentioned above use the patch-application-dependencies procedure provided by (guix build elm-build-system) to rewrite their elm.json files to refer to the package versions actually present in the build environment. Alternatively, Guix package transformations (veja Definindo variantes de pacote) could be used to rewrite an application’s entire dependency graph.
  • We are not yet able to run tests for Elm projects because neither elm-test-rs nor the Node.js-based elm-test runner has been packaged for Guix yet.
Variável: go-build-system

This variable is exported by (guix build-system go). It implements a build procedure for Go packages using the standard Go build mechanisms.

The user is expected to provide a value for the key #:import-path and, in some cases, #:unpack-path. The import path corresponds to the file system path expected by the package’s build scripts and any referring packages, and provides a unique way to refer to a Go package. It is typically based on a combination of the package source code’s remote URI and file system hierarchy structure. In some cases, you will need to unpack the package’s source code to a different directory structure than the one indicated by the import path, and #:unpack-path should be used in such cases.

Packages that provide Go libraries should install their source code into the built output. The key #:install-source?, which defaults to #t, controls whether or not the source code is installed. It can be set to #f for packages that only provide executable files.

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.

The key #:go can be used to specify the Go compiler package with which to build the package.

The phase check provides a wrapper for go test which builds a test binary (or multiple binaries), vets the code and then runs the test binary. Build, test and test binary flags can be provided as #:test-flags parameter, default is '(). See go help test and go help testflag for more details.

The key #:embed-files, default is '(), provides a list of future embedded files or regexps matching files. They will be copied to build directory after unpack phase. See https://pkg.go.dev/embed for more details.

Variável: glib-or-gtk-build-system

This variable is exported by (guix build-system glib-or-gtk). It is intended for use with packages making use of GLib or GTK+.

This build system adds the following two phases to the ones defined by gnu-build-system:

glib-or-gtk-wrap

The phase glib-or-gtk-wrap ensures that programs in bin/ are able to find GLib “schemas” and GTK+ modules. This is achieved by wrapping the programs in launch scripts that appropriately set the XDG_DATA_DIRS and GTK_PATH environment variables.

It is possible to exclude specific package outputs from that wrapping process by listing their names in the #:glib-or-gtk-wrap-excluded-outputs parameter. This is useful when an output is known not to contain any GLib or GTK+ binaries, and where wrapping would gratuitously add a dependency of that output on GLib and GTK+.

glib-or-gtk-compile-schemas

The phase glib-or-gtk-compile-schemas makes sure that all GSettings schemas of GLib are compiled. Compilation is performed by the glib-compile-schemas program. It is provided by the package glib:bin which is automatically imported by the build system. The glib package providing glib-compile-schemas can be specified with the #:glib parameter.

Both phases are executed after the install phase.

Variável: guile-build-system

This build system is for Guile packages that consist exclusively of Scheme code and that are so lean that they don’t even have a makefile, let alone a configure script. It compiles Scheme code using guild compile (veja Compilation em GNU Guile Reference Manual) and installs the .scm and .go files in the right place. It also installs documentation.

This build system supports cross-compilation by using the --target option of ‘guild compile’.

Packages built with guile-build-system must provide a Guile package in their native-inputs field.

Variável: julia-build-system

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

The Julia package name 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 (veja Fases de construção) 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") "\")\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.

Variável: maven-build-system

This variable is exported by (guix build-system maven). It implements a build procedure for Maven packages. Maven is a dependency and lifecycle management tool for Java. A user of Maven specifies dependencies and plugins in a pom.xml file that Maven reads. When Maven does not have one of the dependencies or plugins in its repository, it will download them and use them to build the package.

The maven build system ensures that maven will not try to download any dependency by running in offline mode. Maven will fail if a dependency is missing. Before running Maven, the pom.xml (and subprojects) are modified to specify the version of dependencies and plugins that match the versions available in the guix build environment. Dependencies and plugins must be installed in the fake maven repository at lib/m2, and are symlinked into a proper repository before maven is run. Maven is instructed to use that repository for the build and installs built artifacts there. Changed files are copied to the lib/m2 directory of the package output.

You can specify a pom.xml file with the #:pom-file argument, or let the build system use the default pom.xml file in the sources.

In case you need to specify a dependency’s version manually, you can use the #:local-packages argument. It takes an association list where the key is the groupId of the package and its value is an association list where the key is the artifactId of the package and its value is the version you want to override in the pom.xml.

Some packages use dependencies or plugins that are not useful at runtime nor at build time in Guix. You can alter the pom.xml file to remove them using the #:exclude argument. Its value is an association list where the key is the groupId of the plugin or dependency you want to remove, and the value is a list of artifactId you want to remove.

You can override the default jdk and maven packages with the corresponding argument, #:jdk and #:maven.

The #:maven-plugins argument is a list of maven plugins used during the build, with the same format as the inputs fields of the package declaration. Its default value is (default-maven-plugins) which is also exported.

Variável: 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.

Variável: minify-build-system

This variable is exported by (guix build-system minify). It implements a minification procedure for simple JavaScript packages.

It adds uglify-js to the set of inputs and uses it to compress all JavaScript files in the src directory. A different minifier package can be specified with the #:uglify-js parameter, but it is expected that the package writes the minified code to the standard output.

When the input JavaScript files are not all located in the src directory, the parameter #:javascript-files can be used to specify a list of file names to feed to the minifier.

Variável: mozilla-build-system

This variable is exported by (guix build-system mozilla). It sets the --target and --host configuration flags to what software developed by Mozilla expects – due to historical reasons, Mozilla software expects --host to be the system that is cross-compiled from and --target to be the system that is cross-compiled to, contrary to the standard Autotools conventions.

Variável: ocaml-build-system

This variable is exported by (guix build-system ocaml). It implements a build procedure for OCaml packages, which consists of choosing the correct set of commands to run for each package. OCaml packages can expect many different commands to be run. This build system will try some of them.

When the package has a setup.ml file present at the top-level, it will run ocaml setup.ml -configure, ocaml setup.ml -build and ocaml setup.ml -install. The build system will assume that this file was generated by OASIS and will take care of setting the prefix and enabling tests if they are not disabled. You can pass configure and build flags with the #:configure-flags and #:build-flags. The #:test-flags key can be passed to change the set of flags used to enable tests. The #:use-make? key can be used to bypass this system in the build and install phases.

When the package has a configure file, it is assumed that it is a hand-made configure script that requires a different argument format than in the gnu-build-system. You can add more flags with the #:configure-flags key.

When the package has a Makefile file (or #:use-make? is #t), it will be used and more flags can be passed to the build and install phases with the #:make-flags key.

Finally, some packages do not have these files and use a somewhat standard location for its build system. In that case, the build system will run ocaml pkg/pkg.ml or ocaml pkg/build.ml and take care of providing the path to the required findlib module. Additional flags can be passed via the #:build-flags key. Install is taken care of by opam-installer. In this case, the opam package must be added to the native-inputs field of the package definition.

Note that most OCaml packages assume they will be installed in the same directory as OCaml, which is not what we want in guix. In particular, they will install .so files in their module’s directory, which is usually fine because it is in the OCaml compiler directory. In guix though, these libraries cannot be found and we use CAML_LD_LIBRARY_PATH. This variable points to lib/ocaml/site-lib/stubslibs and this is where .so libraries should be installed.

Variável: python-build-system

This variable is exported by (guix build-system python). It implements the more or less standard build procedure used by Python packages, which consists in running python setup.py build and then 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.

Which Python package is used to perform the build can be specified with the #:python parameter. This is a useful way to force a package to be built for a specific version of the Python interpreter, which might be necessary if the package is only compatible with a single interpreter version.

By default guix calls setup.py under control of setuptools, much like pip does. Some packages are not compatible with setuptools (and pip), thus you can disable this by setting the #:use-setuptools? parameter to #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.

Variável: pyproject-build-system

This is a variable exported by guix build-system pyproject. It is based on python-build-system, and adds support for pyproject.toml and PEP 517. It also supports a variety of build backends and test frameworks.

The API is slightly different from python-build-system:

  • #:use-setuptools? and #:test-target is removed.
  • #:configure-flags is changed. Instead of a list this option must be a JSON object, whose interpretation depends on the build backend. For instance the example from PEP 517 should be written as '(@ ("CC" "gcc") ("--global-option" ("--some-global-option")) ("--build-option" ("--build-option1" "--build-option2")))
  • #:backend-path is added. It defaults to #false, but when set to a list it will be appended to Python’s search path and overrides the definition in pyproject.toml.
  • #:build-backend is added. It defaults to #false and will try to guess the appropriate backend based on pyproject.toml.
  • #:test-backend is added. It defaults to #false and will guess an appropriate test backend based on what is available in package inputs.
  • #:test-flags is added. The default is '(). These flags are passed as arguments to the test command. Note that flags for verbose output is always enabled on supported backends.

It is considered “experimental” in that the implementation details are not set in stone yet, however users are encouraged to try it for new Python projects (even those using setup.py). The API is subject to change, but any breaking changes in the Guix channel will be dealt with.

Eventually this build system will be deprecated and merged back into python-build-system, probably some time in 2024.

Variável: perl-build-system

This variable is exported by (guix build-system perl). It implements the standard build procedure for Perl packages, which either consists in running perl Build.PL --prefix=/gnu/store/…, followed by Build and Build install; or in running perl Makefile.PL PREFIX=/gnu/store/…, followed by make and make install, depending on which of Build.PL or Makefile.PL is present in the package distribution. Preference is given to the former if both Build.PL and Makefile.PL exist in the package distribution. This preference can be reversed by specifying #t for the #:make-maker? parameter.

The initial perl Makefile.PL or perl Build.PL invocation passes flags specified by the #:make-maker-flags or #:module-build-flags parameter, respectively.

Which Perl package is used can be specified with #:perl.

Variável: renpy-build-system

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

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

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

Variável: qt-build-system

This variable is exported by (guix build-system qt). It is intended for use with applications using Qt or KDE.

This build system adds the following two phases to the ones defined by cmake-build-system:

check-setup

The phase check-setup prepares the environment for running the checks as commonly used by Qt test programs. For now this only sets some environment variables: QT_QPA_PLATFORM=offscreen, DBUS_FATAL_WARNINGS=0 and CTEST_OUTPUT_ON_FAILURE=1.

This phase is added before the check phase. It’s a separate phase to ease adjusting if necessary.

qt-wrap

The phase qt-wrap searches for Qt5 plugin paths, QML paths and some XDG in the inputs and output. In case some path is found, all programs in the output’s bin/, sbin/, libexec/ and lib/libexec/ directories are wrapped in scripts defining the necessary environment variables.

It is possible to exclude specific package outputs from that wrapping process by listing their names in the #:qt-wrap-excluded-outputs parameter. This is useful when an output is known not to contain any Qt binaries, and where wrapping would gratuitously add a dependency of that output on Qt, KDE, or such.

This phase is added after the install phase.

Variável: r-build-system

This variable is exported by (guix build-system r). It implements the build procedure used by R packages, which essentially is little more than running ‘R CMD INSTALL --library=/gnu/store/…’ in an environment where R_LIBS_SITE contains the paths to all R package inputs. Tests are run after installation using the R function tools::testInstalledPackage.

Variável: rakudo-build-system

This variable is exported by (guix build-system rakudo). It implements the build procedure used by Rakudo for Perl6 packages. It installs the package to /gnu/store/…/NAME-VERSION/share/perl6 and installs the binaries, library files and the resources, as well as wrap the files under the bin/ directory. Tests can be skipped by passing #f to the tests? parameter.

Which rakudo package is used can be specified with rakudo. Which perl6-tap-harness package used for the tests can be specified with #:prove6 or removed by passing #f to the with-prove6? parameter. Which perl6-zef package used for tests and installing can be specified with #:zef or removed by passing #f to the with-zef? parameter.

Variável: 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.

marcar

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,

install

This installs the files created in the default profile, or some other profile specified with #:install-profile.

Variável: texlive-build-system

Esta variável é exportada pelo (guix build-system texlive). É usado para compilar os pacotes TeX no modo de lote com um moter especificado. O sistema de compilação configura a variável TEXINPUTS para encontrar todos os arquivos de fonte TeX na entrada.

By default it tries to run luatex on all .ins files, and if it fails to find any, on all .dtx files. A different engine and format can be specified with, respectively, the #:tex-engine and #:tex-format arguments. Different build targets can be specified with the #:build-targets argument, which expects a list of file names.

It also generates font metrics (i.e., .tfm files) out of Metafont files whenever possible. Likewise, it can also create TeX formats (i.e., .fmt files) listed in the #:create-formats argument, and generate a symbolic link from bin/ directory to any script located in texmf-dist/scripts/, provided its file name is listed in #:link-scripts argument.

The build system adds texlive-bin from (gnu packages tex) to the native inputs. It can be overridden with the #:texlive-bin argument.

The package texlive-latex-bin, from the same module, contains most of the tools for building TeX Live packages; for convenience, it is also added by default to the native inputs. However, this can be troublesome when building a dependency of texlive-latex-bin itself. In this particular situation, the #:texlive-latex-bin? argument should be set to #f.

Variável: ruby-build-system

This variable is exported by (guix build-system ruby). It implements the RubyGems build procedure used by Ruby packages, which involves running gem build followed by gem install.

The source field of a package that uses this build system typically references a gem archive, since this is the format that Ruby developers use when releasing their software. The build system unpacks the gem archive, potentially patches the source, runs the test suite, repackages the gem, and installs it. Additionally, directories and tarballs may be referenced to allow building unreleased gems from Git or a traditional source release tarball.

Which Ruby package is used can be specified with the #:ruby parameter. A list of additional flags to be passed to the gem command can be specified with the #:gem-flags parameter.

Variável: waf-build-system

This variable is exported by (guix build-system waf). It implements a build procedure around the waf script. The common phases—configure, build, and install—are implemented by passing their names as arguments to the waf script.

The waf script is executed by the Python interpreter. Which Python package is used to run the script can be specified with the #:python parameter.

Variável: zig-build-system

This variable is exported by (guix build-system zig). It implements the build procedures for the Zig build system (zig build command).

Selecting this build system adds zig to the package inputs, in addition to the packages of gnu-build-system.

This build system by default installs package source to output. This behavior can be disabled by setting #:install-source? parameter to #f.

For packages that don’t install anything and don’t come with a test suite (likely library packages to be used by other Zig packages), you can set #:skip-build? parameter to #t, which skips build and check phases.

The configure phase sets up environment for zig build. You need to add custom phases after it if you want to invoke zig.

The #:zig-build-flags parameter is a list of flags that are passed to zig build in build phase. The #:zig-test-flags parameter is a list of flags that are passed to zig build test in check phase. The default compiler package can be overridden with the #:zig parameter.

The optional #:zig-release-type parameter declares the type of release. Possible values are: "safe", "fast", or "small". The default value is #f, which causes the release flag to be omitted from the zig command and results in a "debug" build.

Variável: scons-build-system

This variable is exported by (guix build-system scons). It implements the build procedure used by the SCons software construction tool. This build system runs scons to build the package, scons test to run tests, and then scons install to install the package.

Additional flags to be passed to scons can be specified with the #:scons-flags parameter. The default build and install targets can be overridden with #:build-targets and #:install-targets respectively. The version of Python used to run SCons can be specified by selecting the appropriate SCons package with the #:scons parameter.

Variável: haskell-build-system

This variable is exported by (guix build-system haskell). It implements the Cabal build procedure used by Haskell packages, which involves running runhaskell Setup.hs configure --prefix=/gnu/store/… and runhaskell Setup.hs build. Instead of installing the package by running runhaskell Setup.hs install, to avoid trying to register libraries in the read-only compiler store directory, the build system uses runhaskell Setup.hs copy, followed by runhaskell Setup.hs register. In addition, the build system generates the package documentation by running runhaskell Setup.hs haddock, unless #:haddock? #f is passed. Optional Haddock parameters can be passed with the help of the #:haddock-flags parameter. If the file Setup.hs is not found, the build system looks for Setup.lhs instead.

Which Haskell compiler is used can be specified with the #:haskell parameter which defaults to ghc.

Variável: dub-build-system

This variable is exported by (guix build-system dub). It implements the Dub build procedure used by D packages, which involves running dub build and dub run. Installation is done by copying the files manually.

Which D compiler is used can be specified with the #:ldc parameter which defaults to ldc.

Variável: emacs-build-system

This variable is exported by (guix build-system emacs). It implements an installation procedure similar to the packaging system of Emacs itself (veja Packages em The GNU Emacs Manual).

It first creates the package-autoloads.el file, then it byte compiles all Emacs Lisp files. Differently from the Emacs packaging system, the Info documentation files are moved to the standard documentation directory and the dir file is deleted. The Elisp package files are installed directly under share/emacs/site-lisp.

Variável: font-build-system

This variable is exported by (guix build-system font). It implements an installation procedure for font packages where upstream provides pre-compiled TrueType, OpenType, etc. font files that merely need to be copied into place. It copies font files to standard locations in the output directory.

Variável: meson-build-system

This variable is exported by (guix build-system meson). It implements the build procedure for packages that use Meson as their build system.

It adds both Meson and Ninja to the set of inputs, and they can be changed with the parameters #:meson and #:ninja if needed.

This build system is an extension of gnu-build-system, but with the following phases changed to some specific for Meson:

configure

The phase runs meson with the flags specified in #:configure-flags. The flag --buildtype is always set to debugoptimized unless something else is specified in #:build-type.

build

The phase runs ninja to build the package in parallel by default, but this can be changed with #:parallel-build?.

marcar

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.

install

The phase runs ninja install and can not be changed.

Apart from that, the build system also adds the following phases:

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

This phase is the phase provided by glib-or-gtk-build-system, and it is not enabled by default. It can be enabled with #:glib-or-gtk?.

glib-or-gtk-compile-schemas

This phase is the phase provided by glib-or-gtk-build-system, and it is not enabled by default. It can be enabled with #:glib-or-gtk?.

Variável: linux-module-build-system

linux-module-build-system allows building Linux kernel modules.

This build system is an extension of gnu-build-system, but with the following phases changed:

configure

This phase configures the environment so that the Linux kernel’s Makefile can be used to build the external kernel module.

build

This phase uses the Linux kernel’s Makefile in order to build the external kernel module.

install

This phase uses the Linux kernel’s Makefile in order to install the external kernel module.

It is possible and useful to specify the Linux kernel to use for building the module (in the arguments form of a package using the linux-module-build-system, use the key #:linux to specify it).

Variável: node-build-system

This variable is exported by (guix build-system node). It implements the build procedure used by Node.js, which implements an approximation of the npm install command, followed by an npm test command.

Which Node.js package is used to interpret the npm commands can be specified with the #:node parameter which defaults to node.

Variável: tree-sitter-build-system

This variable is exported by (guix build-system tree-sitter). It implements procedures to compile grammars for the Tree-sitter parsing library. It essentially runs tree-sitter generate to translate grammar.js grammars to JSON and then to C. Which it then compiles to native code.

Tree-sitter packages may support multiple grammars, so this build system supports a #:grammar-directories keyword to specify a list of locations where a grammar.js file may be found.

Grammars sometimes depend on each other, such as C++ depending on C and TypeScript depending on JavaScript. You may use inputs to declare such dependencies.

Lastly, for packages that do not need anything as sophisticated, a “trivial” build system is provided. It is trivial in the sense that it provides basically no support: it does not pull any implicit inputs, and does not have a notion of build phases.

Variável: trivial-build-system

This variable is exported by (guix build-system trivial).

This build system requires a #:builder argument. This argument must be a Scheme expression that builds the package output(s)—as with build-expression->derivation (veja build-expression->derivation).

Variável: 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 (veja Canais); 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).

Optionally, a #:channels argument specifying additional channels can be provided.

The resulting package is a Guix instance of the given channel(s), similar to how guix time-machine would build it.


8.6 Fases de construção

Almost all package build systems implement a notion build phases: a sequence of actions that the build system executes, when you build the package, leading to the installed byproducts in the store. A notable exception is the “bare-bones” trivial-build-system (veja Sistemas de compilação).

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 (veja Caminhos de pesquisa).

unpack

Unpack the source tarball, and change the current directory to the extracted source tree. If the source is actually a directory, copy it to the build tree, and enter that directory.

patch-source-shebangs

Patch shebangs encountered in source files so they refer to the right store file names. For instance, this changes #!/bin/sh to #!/gnu/store/…-bash-4.3/bin/sh.

configure

Run the configure script with a number of default options, such as --prefix=/gnu/store/…, as well as the options specified by the #:configure-flags argument.

build

Run make with the list of flags specified with #:make-flags. If the #:parallel-build? argument is true (the default), build with make -j.

marcar

Run make check, or some other target specified with #:test-target, unless #:tests? #f is passed. If the #:parallel-tests? argument is true (the default), run make check -j.

install

Run make install with the flags listed in #:make-flags.

patch-shebangs

Patch shebangs on the installed executable files.

strip

Strip debugging symbols from ELF files (unless #:strip-binaries? is false), copying them to the debug output when available (veja Instalando arquivos de depuração).

validate-runpath

Validate the RUNPATH of ELF binaries, unless #:validate-runpath? is false (veja Sistemas de compilação).

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. Veja -rpath em The GNU Linker, for more information on RUNPATH.

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

Build phases are represented as association lists or “alists” (veja Association Lists em GNU Guile Reference Manual) where each key is a symbol for the name of the phase and the associated value is a procedure that accepts an arbitrary number of arguments. By convention, those procedures receive information about the build in the form of keyword parameters, which they can use or ignore.

For example, here is how (guix build gnu-build-system) defines %standard-phases, the variable holding its alist of build phases21:

;; 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)))

This shows how %standard-phases is defined as a list of symbol/procedure pairs (veja Pairs em GNU Guile Reference Manual). The first pair associates the unpack procedure with the unpack symbol—a name; the second pair defines the configure phase similarly, and so on. When building a package that uses gnu-build-system with its default list of phases, those phases are executed sequentially. You can see the name of each phase started and completed in the build log of packages that you build.

Let’s now look at the procedures themselves. Each one is defined with define*: #:key lists keyword parameters the procedure accepts, possibly with a default value, and #:allow-other-keys specifies that other keyword parameters are ignored (veja Optional Arguments em GNU Guile Reference Manual).

The unpack procedure honors the source parameter, which the build system uses to pass the file name of the source tarball (or version control checkout), and it ignores other parameters. The configure phase only cares about the outputs parameter, an alist mapping package output names to their store file name (veja Pacotes com múltiplas saídas). It extracts the file name of for out, the default output, and passes it to ./configure as the installation prefix, meaning that make install will eventually copy all the files in that directory (veja configuration and makefile conventions em GNU Coding Standards). build and install ignore all their arguments. check honors the test-target argument, which specifies the name of the Makefile target to run tests; it prints a message and skips tests when tests? is false.

The list of phases used for a particular package can be changed with the #:phases parameter of the build system. Changing the set of build phases boils down to building a new alist of phases based on the %standard-phases alist described above. This can be done with standard alist procedures such as alist-delete (veja SRFI-1 Association Lists em GNU Guile Reference Manual); however, it is more convenient to do so with modify-phases (veja modify-phases).

Here is an example of a package definition that removes the configure phase of %standard-phases and inserts a new phase before the build phase, called set-prefix-in-makefile:

(define-public example
  (package
    (name "example")
    ;; other fields omitted
    (build-system gnu-build-system)
    (arguments
     (list
      #:phases
      #~(modify-phases %standard-phases
          (delete 'configure)
          (add-before 'build 'set-prefix-in-makefile
            (lambda* (#:key inputs #:allow-other-keys)
              ;; Modify the makefile so that its
              ;; 'PREFIX' variable points to #$output and
              ;; 'XMLLINT' points to the correct path.
              (substitute* "Makefile"
                (("PREFIX =.*")
                 (string-append "PREFIX = " #$output "\n"))
                (("XMLLINT =.*")
                 (string-append "XMLLINT = "
                                (search-input-file inputs "/bin/xmllint")
                                "\n"))))))))))

The new phase that is inserted is written as an anonymous procedure, introduced with lambda*; it looks for the xmllint executable under a /bin directory among the package’s inputs (veja Referência do package). It also honors the outputs parameter we have seen before. Veja Construir utilitários, for more about the helpers used by this phase, and for more examples of modify-phases.

Tip: You can inspect the code associated with a package’s #:phases argument interactively, at the REPL (veja Usando Guix interativamente).

Keep in mind that build phases are code evaluated at the time the package is actually built. This explains why the whole modify-phases expression above is quoted (it comes after the #~ or hash-tilde): it is staged for later execution. Veja Expressões-G, for an explanation of code staging and the code strata involved.


8.7 Construir utilitários

As soon as you start writing non-trivial package definitions (veja Definindo pacotes) or other build actions (veja Expressões-G), you will likely start looking for helpers for “shell-like” actions—creating directories, copying and deleting files recursively, manipulating build phases, and so on. The (guix build utils) module provides such utility procedures.

Most build systems load (guix build utils) (veja Sistemas de compilação). Thus, when writing custom build phases for your package definitions, you can usually assume those procedures are in scope.

When writing G-expressions, you can import (guix build utils) on the “build side” using with-imported-modules and then put it in scope with the use-modules form (veja Using Guile Modules em 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")))))

The remainder of this section is the reference for most of the utility procedures provided by (guix build utils).

8.7.1 Dealing with Store File Names

This section documents procedures that deal with store file names.

Procedure: %store-directory

Return the directory name of the store.

Procedure: store-file-name? file

Return true if file is in the store.

Procedure: strip-store-file-name file

Strip the /gnu/store and hash from file, a store file name. The result is typically a "package-version" string.

Procedure: package-name->name+version name

Given name, a package name like "foo-0.9.1b", return two values: "foo" and "0.9.1b". When the version part is unavailable, name and #f are returned. The first hyphen followed by a digit is considered to introduce the version part.

8.7.2 File Types

The procedures below deal with files and file types.

Procedure: directory-exists? dir

Return #t if dir exists and is a directory.

Procedure: executable-file? file

Return #t if file exists and is executable.

Return #t if file is a symbolic link (aka. a “symlink”).

Procedure: elf-file? file
Procedure: ar-file? file
Procedure: gzip-file? file

Return #t if file is, respectively, an ELF file, an ar archive (such as a .a static library), or a gzip file.

Procedure: reset-gzip-timestamp file [#:keep-mtime? #t]

If file is a gzip file, reset its embedded timestamp (as with gzip --no-name) and return true. Otherwise return #f. When keep-mtime? is true, preserve file’s modification time.

8.7.3 File Manipulation

The following procedures and macros help create, modify, and delete files. They provide functionality comparable to common shell utilities such as mkdir -p, cp -r, rm -r, and sed. They complement Guile’s extensive, but low-level, file system interface (veja POSIX em GNU Guile Reference Manual).

Macro: with-directory-excursion directory body …

Run body with directory as the process’s current directory.

Essentially, this macro changes the current directory to directory before evaluating body, using chdir (veja Processes em GNU Guile Reference Manual). It changes back to the initial directory when the dynamic extent of body is left, be it via normal procedure return or via a non-local exit such as an exception.

Procedure: mkdir-p dir

Create directory dir and all its ancestors.

Procedure: install-file file directory

Create directory if it does not exist and copy file in there under the same name.

Procedure: make-file-writable file

Make file writable for its owner.

Procedure: copy-recursively source destination [#:log (current-output-port)] [#:follow-symlinks? #f]  [#:copy-file

copy-file] [#:keep-mtime? #f] [#:keep-permissions? #t]  [#:select? (const #t)] Copy source directory to destination. Follow symlinks if follow-symlinks? is true; otherwise, just preserve them. Call copy-file to copy regular files. Call select?, taking two arguments, file and stat, for each entry in source, where file is the entry’s absolute file name and stat is the result of lstat (or stat if follow-symlinks? is true); exclude entries for which select? does not return true. 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.

Procedure: delete-file-recursively dir [#:follow-mounts? #f]

Delete dir recursively, like rm -rf, without following symlinks. Don’t follow mount points either, unless follow-mounts? is true. Report but ignore errors.

Macro: substitute* file ((regexp match-var…) body…) … Substitute regexp in

file by the string returned by body. body is evaluated with each match-var bound to the corresponding positional regexp sub-expression. For example:

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

Here, anytime a line of file contains hello, it is replaced by good morning. Anytime a line of file matches the second regexp, all is bound to the complete match, letters is bound to the first sub-expression, and end is bound to the last one.

When one of the match-var is _, no variable is bound to the corresponding match substring.

Alternatively, file may be a list of file names, in which case they are all subject to the substitutions.

Be careful about using $ to match the end of a line; by itself it won’t match the terminating newline of a line. For example, to match a whole line ending with a backslash, one needs a regex like "(.*)\\\\\n$".

8.7.5 Program Invocation

You’ll find handy procedures to spawn processes in this module, essentially convenient wrappers around Guile’s system* (veja system* em GNU Guile Reference Manual).

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.

Procedure: invoke-error? c

Return true if c is an &invoke-error condition.

Procedure: invoke-error-program c
Procedure: invoke-error-arguments c
Procedure: invoke-error-exit-status c
Procedure: invoke-error-term-signal c
Procedure: invoke-error-stop-signal c

Access specific fields of c, an &invoke-error condition.

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

8.7.6 Fases de construção

The (guix build utils) also contains tools to manipulate build phases as used by build systems (veja Sistemas de compilação). Build phases are represented as association lists or “alists” (veja Association Lists em GNU Guile Reference Manual) where each key is a symbol naming the phase and the associated value is a procedure (veja Fases de construção).

Guile core and the (srfi srfi-1) module both provide tools to manipulate alists. The (guix build utils) module complements those with tools written with build phases in mind.

Macro: modify-phases phases clause…

Modify phases sequentially as per each clause, which may have one of the following forms:

(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)

Where every phase-name above is an expression evaluating to a symbol, and new-phase an expression evaluating to a procedure.

The example below is taken from the definition of the grep package. It adds a phase to run after the install phase, called fix-egrep-and-fgrep. That phase is a procedure (lambda* is for anonymous procedures) that takes a #:outputs keyword argument and ignores extra keyword arguments (veja Optional Arguments em GNU Guile Reference Manual, for more on lambda* and optional and keyword arguments.) The phase uses substitute* to modify the installed egrep and fgrep scripts so that they refer to grep by its absolute file name:

(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")))))))

In the example below, phases are modified in two ways: the standard configure phase is deleted, presumably because the package does not have a configure script or anything similar, and the default install phase is replaced by one that manually copies the executable files to be installed:

(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)))))

8.7.7 Wrappers

It is not unusual for a command to require certain environment variables to be set for proper functioning, typically search paths (veja Caminhos de pesquisa). 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:

  • a shell script that assumes all the commands it uses are in PATH;
  • a Guile program that assumes all its modules are in GUILE_LOAD_PATH and GUILE_LOAD_COMPILED_PATH;
  • a Qt application that expects to find certain plugins in QT_PLUGIN_PATH.

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.

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.

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.


8.8 Caminhos de pesquisa

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 (veja Environment Variables em 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 (veja Invocando 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; veja 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 (:).

Nota: 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:

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

Tipo de dados: 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 (veja stat em GNU Guile Reference Manual).

In the XML_CATALOG_FILES 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 XML_CATALOG_FILES 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).

Variável: $SGML_CATALOG_FILES
Variável: $XML_CATALOG_FILES

These two search paths indicate where the TR9401 catalog22 or XML catalog files can be found.

Variável: $SSL_CERT_DIR
Variável: $SSL_CERT_FILE

These two search paths indicate where X.509 certificates can be found (veja Certificados 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.

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.


8.9 O armazém

Conceptually, the store is the place where derivations that have been built successfully are stored—by default, /gnu/store. Sub-directories in the store are referred to as store items or sometimes store paths. The store has an associated database that contains information such as the store paths referred to by each store path, and the list of valid store items—results of successful builds. This database resides in localstatedir/guix/db, where localstatedir is the state directory specified via --localstatedir at configure time, usually /var.

The store is always accessed by the daemon on behalf of its clients (veja Invocando guix-daemon). To manipulate the store, clients connect to the daemon over a Unix-domain socket, send requests to it, and read the result—these are remote procedure calls, or RPCs.

Nota: Users must never modify files under /gnu/store directly. This would lead to inconsistencies and break the immutability assumptions of Guix’s functional model (veja Introdução).

Veja guix gc --verify, for information on how to check the integrity of the store and attempt recovery from accidental modifications.

The (guix store) module provides procedures to connect to the daemon, and to perform RPCs. These are described below. By default, open-connection, and thus all the guix commands, connect to the local daemon or to the URI specified by the GUIX_DAEMON_SOCKET environment variable.

Environment Variable: GUIX_DAEMON_SOCKET

When set, the value of this variable should be a file name or a URI designating the daemon endpoint. When it is a file name, it denotes a Unix-domain socket to connect to. In addition to file names, the supported URI schemes are:

file
unix

These are for Unix-domain sockets. file:///var/guix/daemon-socket/socket is equivalent to /var/guix/daemon-socket/socket.

guix

These URIs denote connections over TCP/IP, without encryption nor authentication of the remote host. The URI must specify the host name and optionally a port number (by default port 44146 is used):

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

This setup is suitable on local networks, such as clusters, where only trusted nodes may connect to the build daemon at master.guix.example.org.

The --listen option of guix-daemon can be used to instruct it to listen for TCP connections (veja --listen).

ssh

These URIs allow you to connect to a remote daemon over SSH. This feature requires Guile-SSH (veja Requisitos) and a working guile binary in PATH on the destination machine. It supports public key and GSSAPI authentication. A typical URL might look like this:

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

As for guix copy, the usual OpenSSH client configuration files are honored (veja Invocando guix copy).

Additional URI schemes may be supported in the future.

Nota: The ability to connect to remote build daemons is considered experimental as of 4b5f040. Please get in touch with us to share any problems or suggestions you may have (veja Contribuindo).

Procedure: open-connection [uri] [#:reserve-space? #t]

Connect to the daemon over the Unix-domain socket at uri (a string). When reserve-space? is true, instruct it to reserve a little bit of extra space on the file system so that the garbage collector can still operate should the disk become full. Return a server object.

file defaults to %default-socket-path, which is the normal location given the options that were passed to configure.

Procedure: close-connection server

Close the connection to server.

Variável: current-build-output-port

This variable is bound to a SRFI-39 parameter, which refers to the port where build and error logs sent by the daemon should be written.

Procedures that make RPCs all take a server object as their first argument.

Procedure: valid-path? server path

Return #t when path designates a valid store item and #f otherwise (an invalid item may exist on disk but still be invalid, for instance because it is the result of an aborted or failed build).

A &store-protocol-error condition is raised if path is not prefixed by the store directory (/gnu/store).

Procedure: add-text-to-store server name text [references]

Add text under file name in the store, and return its store path. references is the list of store paths referred to by the resulting store path.

Procedure: build-derivations store derivations [mode]

Build derivations, a list of <derivation> objects, .drv file names, or derivation/output pairs, using the specified mode(build-mode normal) by default.

Note that the (guix monads) module provides a monad as well as monadic versions of the above procedures, with the goal of making it more convenient to work with code that accesses the store (veja A mônada do armazém).

This section is currently incomplete.


8.10 Derivações

Low-level build actions and the environment in which they are performed are represented by derivations. A derivation contains the following pieces of information:

  • The outputs of the derivation—derivations produce at least one file or directory in the store, but may produce more.
  • The inputs of the derivation—i.e., its build-time dependencies—which may be other derivations or plain files in the store (patches, build scripts, etc.).
  • The system type targeted by the derivation—e.g., x86_64-linux.
  • The file name of a build script in the store, along with the arguments to be passed.
  • A list of environment variables to be defined.

Derivations allow clients of the daemon to communicate build actions to the store. They exist in two forms: as an in-memory representation, both on the client- and daemon-side, and as files in the store whose name end in .drv—these files are referred to as derivation paths. Derivations paths can be passed to the build-derivations procedure to perform the build actions they prescribe (veja O armazém).

Operations such as file downloads and version-control checkouts for which the expected content hash is known in advance are modeled as fixed-output derivations. Unlike regular derivations, the outputs of a fixed-output derivation are independent of its inputs—e.g., a source code download produces the same result regardless of the download method and tools being used.

The outputs of derivations—i.e., the build results—have a set of references, as reported by the references RPC or the guix gc --references command (veja Invocando guix gc). References are the set of run-time dependencies of the build results. References are a subset of the inputs of the derivation; this subset is automatically computed by the build daemon by scanning all the files in the outputs.

The (guix derivations) module provides a representation of derivations as Scheme objects, along with procedures to create and otherwise manipulate derivations. The lowest-level primitive to create a derivation is the derivation procedure:

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 ’()] Build a derivation with the given arguments, and return the resulting <derivation> object.

When hash and hash-algo are given, a fixed-output derivation is created—i.e., one whose result is known in advance, such as a file download. If, in addition, recursive? is true, then that fixed output may be an executable file or a directory and hash must be the hash of an archive containing this output.

When references-graphs is true, it must be a list of file name/store path pairs. In that case, the reference graph of each store path is exported in the build environment in the corresponding file, in a simple text format.

When allowed-references is true, it must be a list of store items or outputs that the derivation’s output may refer to. Likewise, disallowed-references, if true, must be a list of things the outputs may not refer to.

When leaked-env-vars is true, it must be a list of strings denoting environment variables that are allowed to “leak” from the daemon’s environment to the build environment. This is only applicable to fixed-output derivations—i.e., when hash is true. The main use is to allow variables such as http_proxy to be passed to derivations that download files.

When local-build? is true, declare that the derivation is not a good candidate for offloading and should rather be built locally (veja Usando o recurso de descarregamento). This is the case for small derivations where the costs of data transfers would outweigh the benefits.

When substitutable? is false, declare that substitutes of the derivation’s output should not be used (veja Substitutos). This is useful, for instance, when building packages that capture details of the host CPU instruction set.

properties must be an association list describing “properties” of the derivation. It is kept as-is, uninterpreted, in the derivation.

Here’s an example with a shell script as its builder, assuming store is an open connection to the daemon, and bash points to a Bash executable in the 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>

As can be guessed, this primitive is cumbersome to use directly. A better approach is to write build scripts in Scheme, of course! The best course of action for that is to write the build code as a “G-expression”, and to pass it to gexp->derivation. For more information, veja Expressões-G.

Once upon a time, gexp->derivation did not exist and constructing derivations with build code written in Scheme was achieved with build-expression->derivation, documented below. This procedure is now deprecated in favor of the much nicer gexp->derivation.

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] Return a derivation that executes Scheme expression exp as a builder for derivation name. inputs must be a list of (name drv-path sub-drv) tuples; when sub-drv is omitted, "out" is assumed. modules is a list of names of Guile modules from the current search path to be copied in the store, compiled, and made available in the load path during the execution of exp—e.g., ((guix build utils) (guix build gnu-build-system)).

exp is evaluated in an environment where %outputs is bound to a list of output/path pairs, and where %build-inputs is bound to a list of string/output-path pairs made from inputs. Optionally, env-vars is a list of string pairs specifying the name and value of environment variables visible to the builder. The builder terminates by passing the result of exp to exit; thus, when exp returns #f, the build is considered to have failed.

exp is built using guile-for-build (a derivation). When guile-for-build is omitted or is #f, the value of the %guile-for-build fluid is used instead.

See the derivation procedure for the meaning of references-graphs, allowed-references, disallowed-references, local-build?, and substitutable?.

Here’s an example of a single-output derivation that creates a directory containing one file:

(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 => …>

8.11 A mônada do armazém

The procedures that operate on the store described in the previous sections all take an open connection to the build daemon as their first argument. Although the underlying model is functional, they either have side effects or depend on the current state of the store.

The former is inconvenient: the connection to the build daemon has to be carried around in all those functions, making it impossible to compose functions that do not take that parameter with functions that do. The latter can be problematic: since store operations have side effects and/or depend on external state, they have to be properly sequenced.

This is where the (guix monads) module comes in. This module provides a framework for working with monads, and a particularly useful monad for our uses, the store monad. Monads are a construct that allows two things: associating “context” with values (in our case, the context is the store), and building sequences of computations (here computations include accesses to the store). Values in a monad—values that carry this additional context—are called monadic values; procedures that return such values are called monadic procedures.

Consider this “normal” procedure:

(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))))

Using (guix monads) and (guix gexp), it may be rewritten as a monadic function:

(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))))

There are several things to note in the second version: the store parameter is now implicit and is “threaded” in the calls to the package->derivation and gexp->derivation monadic procedures, and the monadic value returned by package->derivation is bound using mlet instead of plain let.

As it turns out, the call to package->derivation can even be omitted since it will take place implicitly, as we will see later (veja Expressões-G):

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

Calling the monadic sh-symlink has no effect. As someone once said, “you exit a monad like you exit a building on fire: by running”. So, to exit the monad and get the desired effect, one must use 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 (veja Usando Guix interativamente). 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 => …>

The latter enters a recursive REPL, where all the return values are automatically run through the store:

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)>

Note that non-monadic values cannot be returned in the store-monad REPL.

Other meta-commands are available at the REPL, such as ,build to build a file-like object (veja Usando Guix interativamente).

The main syntactic forms to deal with monads in general are provided by the (guix monads) module and are described below.

Macro: with-monad monad body …

Evaluate any >>= or return forms in body as being in monad.

Macro: return val

Return a monadic value that encapsulates val.

Macro: >>= mval mproc …

Bind monadic value mval, passing its “contents” to monadic procedures mproc23. 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
Macro: mlet monad ((var mval) …) body …
Macro: 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 (veja Local Bindings em GNU Guile Reference Manual).

Macro: 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.

Macro: 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.

Macro: 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.

Variável: %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

Return the current state as a monadic value.

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.

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.

Variável: %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).

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 (veja Definindo pacotes).


8.12 Expressões-G

So we have “derivations”, which represent a sequence of build actions to be performed to produce an item in the store (veja Derivações). These build actions are performed when asking the daemon to actually build the derivations; they are run by the daemon in a container (veja Invocando 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 code24: 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 (veja Fases de construção).

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 (veja quasiquote em GNU Guile Reference Manual). However, there are major differences:

  • Gexps are meant to be written to a file and run or manipulated by other processes.
  • When a high-level object such as a package or derivation is unquoted inside a gexp, the result is as if its output file name had been introduced.
  • Gexps carry information about the packages or derivations they refer to, and these dependencies are automatically added as inputs to the build processes that use them.

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

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

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

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

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

As one would expect, the "/gnu/store/…-coreutils-8.22" string is substituted to the reference to the coreutils package in the actual build code, and coreutils is automatically made an input to the derivation. Likewise, #$output (equivalent to (ungexp output)) is replaced by a string containing the directory name of the output of the derivation.

In a cross-compilation context, it is useful to distinguish between references to the native build of a package—that can run on the host—versus references to cross builds of a package. To that end, the #+ plays the same role as #$, but is a reference to a native package build:

(gexp->derivation "vi"
   #~(begin
       (mkdir #$output)
       (mkdir (string-append #$output "/bin"))
       (system* (string-append #+coreutils "/bin/ln")
                "-s"
                (string-append #$emacs "/bin/emacs")
                (string-append #$output "/bin/vi")))
   #:target "aarch64-linux-gnu")

In the example above, the native build of coreutils is used, so that ln can actually run on the host; but then the cross-compiled build of emacs is referenced.

Another gexp feature is imported modules: sometimes you want to be able to use certain Guile modules from the “host environment” in the gexp, so those modules should be imported in the “build environment”. The with-imported-modules form allows you to express that:

(let ((build (with-imported-modules '((guix build utils))
               #~(begin
                   (use-modules (guix build utils))
                   (mkdir-p (string-append #$output "/bin"))))))
  (gexp->derivation "empty-dir"
                    #~(begin
                        #$build
                        (display "success!\n")
                        #t)))

In this example, the (guix build utils) module is automatically pulled into the isolated build environment of our gexp, such that (use-modules (guix build utils)) works as expected.

Usually you want the closure of the module to be imported—i.e., the module itself and all the modules it depends on—rather than just the module; failing to do that, attempts to use the module will fail because of missing dependent modules. The source-module-closure procedure computes the closure of a module by looking at its source file headers, which comes in handy in this case:

(use-modules (guix modules))   ;for 'source-module-closure'

(with-imported-modules (source-module-closure
                         '((guix build utils)
                           (gnu build 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.

Macro: #~exp
Macro: (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:saída
(ungexp obj saída)

This is like the form above, but referring explicitly to the output of obj—this is useful when obj produces multiple outputs (veja Pacotes com múltiplas saídas).

Sometimes a gexp unconditionally refers to the "out" output, but the user of that gexp would still like to insert a reference to another output. The gexp-input procedure aims to address that. Veja gexp-input.

#+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[:saída]
(ungexp output [saída])

Insert a reference to derivation output output, or to the main output when output is omitted.

This only makes sense for gexps passed to gexp->derivation.

#$@lst
(ungexp-splicing lst)

Like the above, but splices the contents of lst inside the containing list.

#+@lst
(ungexp-native-splicing lst)

Like the above, but refers to native builds of the objects listed in lst.

G-expressions created by gexp or #~ are run-time objects of the gexp? type (see below).

Macro: with-imported-modules modules body…

Mark the gexps defined in body… as requiring modules in their execution environment.

Each item in modules can be the name of a module, such as (guix build utils), or it can be a module name, followed by an arrow, followed by a file-like object:

`((guix build utils)
  (guix gcrypt)
  ((guix config) => ,(scheme-file "config.scm"
                                  #~(define-module ))))

In the example above, the first two modules are taken from the search path, and the last one is created from the given file-like object.

This form has lexical scope: it has an effect on the gexps directly defined in body…, but not on those defined, say, in procedures called from body….

Macro: with-extensions extensions body…

Mark the gexps defined in body… as requiring extensions in their build and execution environment. extensions is typically a list of package objects such as those defined in the (gnu packages guile) module.

Concretely, the packages listed in extensions are added to the load path while compiling imported modules in body…; they are also added to the load path of the gexp returned by body….

Procedure: gexp? obj

Return #t if obj is a G-expression.

G-expressions are meant to be written to disk, either as code building some derivation, or as plain files in the store. The monadic procedures below allow you to do that (veja A mônada do armazém, for more information about monads).

Monadic Procedure: gexp->derivation name exp [#:system (%current-system)] [#:target #f] [#:graft? #t]  [#:hash #f]

[#:hash-algo #f]  [#:recursive? #f] [#:env-vars ’()] [#:modules ’()]  [#:module-path %load-path]  [#:effective-version "2.2"]  [#:references-graphs #f] [#:allowed-references #f]  [#:disallowed-references #f]  [#:leaked-env-vars #f]  [#:script-name (string-append name "-builder")]  [#:deprecation-warnings #f]  [#:local-build? #f] [#:substitutable? #t]  [#:properties ’()] [#:guile-for-build #f] Return a derivation name that runs exp (a gexp) with guile-for-build (a derivation) on system; exp is stored in a file called script-name. When target is true, it is used as the cross-compilation target triplet for packages referred to by exp.

modules is deprecated in favor of with-imported-modules. Its meaning is to make modules available in the evaluation context of exp; modules is a list of names of Guile modules searched in module-path to be copied in the store, compiled, and made available in the load path during the execution of exp—e.g., ((guix build utils) (guix build gnu-build-system)).

effective-version determines the string to use when adding extensions of exp (see with-extensions) to the search path—e.g., "2.2".

graft? determines whether packages referred to by exp should be grafted when applicable.

When references-graphs is true, it must be a list of tuples of one of the following forms:

(file-name obj)
(file-name obj output)
(file-name gexp-input)
(file-name store-item)

The right-hand-side of each element of references-graphs is automatically made an input of the build process of exp. In the build environment, each file-name contains the reference graph of the corresponding item, in a simple text format.

allowed-references must be either #f or a list of output names and packages. In the latter case, the list denotes store items that the result is allowed to refer to. Any reference to another store item will lead to a build error. Similarly for disallowed-references, which can list items that must not be referenced by the outputs.

deprecation-warnings determines whether to show deprecation warnings while compiling modules. It can be #f, #t, or 'detailed.

The other arguments are as for derivation (veja Derivações).

The local-file, plain-file, computed-file, program-file, and scheme-file procedures below return file-like objects. That is, when unquoted in a G-expression, these objects lead to a file in the store. Consider this G-expression:

#~(system* #$(file-append glibc "/sbin/nscd") "-f"
           #$(local-file "/tmp/my-nscd.conf"))

The effect here is to “intern” /tmp/my-nscd.conf by copying it to the store. Once expanded, for instance via gexp->derivation, the G-expression refers to that copy under /gnu/store; thus, modifying or removing the file in /tmp does not have any effect on what the G-expression does. plain-file can be used similarly; it differs in that the file content is directly passed as a string.

Procedure: local-file file [name] [#:recursive? #f] [#:select? (const #t)]

Return an object representing local file file to add to the store; this object can be used in a gexp. If file is a literal string denoting a relative file name, it is looked up relative to the source file where it appears; if file is not a literal string, it is looked up relative to the current working directory at run time. file will be added to the store under name–by default the base name of file.

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

When recursive? is true, call (select? file stat) for each directory entry, where file is the entry’s absolute file name and stat is the result of lstat; exclude entries for which select? does not return true.

file can be wrapped in the assume-valid-file-name syntactic keyword. When this is done, there will not be a warning when local-file is used with a non-literal path. The path is still looked up relative to the current working directory at run time. Wrapping is done like this:

(define alice-key-file-path "alice.pub")
;; ...
(local-file (assume-valid-file-name alice-key-file-path))

file can be wrapped in the assume-source-relative-file-name syntactic keyword. When this is done, the file name will be looked up relative to the source file where it appears even when it is not a string literal.

This is the declarative counterpart of the interned-file monadic procedure (veja interned-file).

Procedure: plain-file name content

Return an object representing a text file called name with the given content (a string or a bytevector) to be added to the store.

This is the declarative counterpart of text-file.

Procedure: computed-file name gexp [#:local-build? #t] [#:options '()]

Return an object representing the store item name, a file or directory computed by gexp. When local-build? is true (the default), the derivation is built locally. options is a list of additional arguments to pass to gexp->derivation.

This is the declarative counterpart of gexp->derivation.

Monadic Procedure: gexp->script name exp [#:guile (default-guile)] [#:module-path %load-path]  [#:system

(%current-system)] [#:target #f] Return an executable script name that runs exp using guile, with exp’s imported modules in its search path. Look up exp’s modules in module-path.

The example below builds a script that simply invokes the ls command:

(use-modules (guix gexp) (gnu packages base))

(gexp->script "list-files"
              #~(execl #$(file-append coreutils "/bin/ls")
                       "ls"))

When “running” it through the store (veja run-with-store), we obtain a derivation that produces an executable file /gnu/store/…-list-files along these lines:

#!/gnu/store/…-guile-2.0.11/bin/guile -ds
!#
(execl "/gnu/store/…-coreutils-8.22"/bin/ls" "ls")
Procedure: program-file name exp [#:guile #f] [#:module-path %load-path]

Return an object representing the executable store item name that runs gexp. guile is the Guile package used to execute that script. Imported modules of gexp are looked up in module-path.

This is the declarative counterpart of gexp->script.

Monadic Procedure: gexp->file name exp [#:set-load-path? #t] [#:module-path %load-path]  [#:splice? #f]  [#:guile

(default-guile)] Return a derivation that builds a file name containing exp. When splice? is true, exp is considered to be a list of expressions that will be spliced in the resulting file.

When set-load-path? is true, emit code in the resulting file to set %load-path and %load-compiled-path to honor exp’s imported modules. Look up exp’s modules in module-path.

The resulting file holds references to all the dependencies of exp or a subset thereof.

Procedure: scheme-file name exp [#:splice? #f] [#:guile #f] [#:set-load-path? #t] Return an object representing the Scheme

file name that contains exp. guile is the Guile package used to produce that file.

This is the declarative counterpart of gexp->file.

Monadic Procedure: text-file* name text

Return as a monadic value a derivation that builds a text file containing all of text. text may list, in addition to strings, objects of any type that can be used in a gexp: packages, derivations, local file objects, etc. The resulting store file holds references to all these.

This variant should be preferred over text-file anytime the file to create will reference items from the store. This is typically the case when building a configuration file that embeds store file names, like this:

(define (profile.sh)
  ;; Return the name of a shell script in the store that
  ;; initializes the 'PATH' environment variable.
  (text-file* "profile.sh"
              "export PATH=" coreutils "/bin:"
              grep "/bin:" sed "/bin\n"))

In this example, the resulting /gnu/store/…-profile.sh file will reference coreutils, grep, and sed, thereby preventing them from being garbage-collected during its lifetime.

Procedure: mixed-text-file name text …

Return an object representing store file name containing text. text is a sequence of strings and file-like objects, as in:

(mixed-text-file "profile"
                 "export PATH=" coreutils "/bin:" grep "/bin")

This is the declarative counterpart of text-file*.

Procedure: file-union name files

Return a <computed-file> that builds a directory containing all of files. Each item in files must be a two-element list where the first element is the file name to use in the new directory, and the second element is a gexp denoting the target file. Here’s an example:

(file-union "etc"
            `(("hosts" ,(plain-file "hosts"
                                    "127.0.0.1 localhost"))
              ("bashrc" ,(plain-file "bashrc"
                                     "alias ls='ls --color=auto'"))))

This yields an etc directory containing these two files.

Procedure: directory-union name things

Return a directory that is the union of things, where things is a list of file-like objects denoting directories. For example:

(directory-union "guile+emacs" (list guile emacs))

yields a directory that is the union of the guile and emacs packages.

Procedure: file-append obj suffix …

Return a file-like object that expands to the concatenation of obj and suffix, where obj is a lowerable object and each suffix is a string.

As an example, consider this gexp:

(gexp->script "run-uname"
              #~(system* #$(file-append coreutils
                                        "/bin/uname")))

The same effect could be achieved with:

(gexp->script "run-uname"
              #~(system* (string-append #$coreutils
                                        "/bin/uname")))

There is one difference though: in the file-append case, the resulting script contains the absolute file name as a string, whereas in the second case, the resulting script contains a (string-append …) expression to construct the file name at run time.

Macro: let-system system body…
Macro: let-system (system target) body…

Bind system to the currently targeted system—e.g., "x86_64-linux"—within body.

In the second case, additionally bind target to the current cross-compilation target—a GNU triplet such as "arm-linux-gnueabihf"—or #f if we are not cross-compiling.

let-system is useful in the occasional case where the object spliced into the gexp depends on the target system, as in this example:

#~(system*
   #+(let-system system
       (cond ((string-prefix? "armhf-" system)
              (file-append qemu "/bin/qemu-system-arm"))
             ((string-prefix? "x86_64-" system)
              (file-append qemu "/bin/qemu-system-x86_64"))
             (else
              (error "dunno!"))))
   "-net" "user" #$image)
Macro: with-parameters ((parameter value) …) exp

This macro is similar to the parameterize form for dynamically-bound parameters (veja Parameters em GNU Guile Reference Manual). The key difference is that it takes effect when the file-like object returned by exp is lowered to a derivation or store item.

A typical use of with-parameters is to force the system in effect for a given object:

(with-parameters ((%current-system "i686-linux"))
  coreutils)

The example above returns an object that corresponds to the i686 build of Coreutils, regardless of the current value of %current-system.

Procedure: gexp-input obj [output] [#:native? #f]

Return a gexp input record for the given output of file-like object obj, with #:native? determining whether this is a native reference (as with ungexp-native) or not.

This procedure is helpful when you want to pass a reference to a specific output of an object to some procedure that may not know about that output. For example, assume you have this procedure, which takes one file-like object:

(define (make-symlink target)
  (computed-file "the-symlink"
                 #~(symlink #$target #$output)))

Here make-symlink can only ever refer to the default output of target—the "out" output (veja Pacotes com múltiplas saídas). To have it refer to, say, the "lib" output of the hwloc package, you can call it like so:

(make-symlink (gexp-input hwloc "lib"))

You can also compose it like any other file-like object:

(make-symlink
  (file-append (gexp-input hwloc "lib") "/lib/libhwloc.so"))

Of course, in addition to gexps embedded in “host” code, there are also modules containing build tools. To make it clear that they are meant to be used in the build stratum, these modules are kept in the (guix build …) name space.

Internally, high-level objects are lowered, using their compiler, to either derivations or store items. For instance, lowering a package yields a derivation, and lowering a plain-file yields a store item. This is achieved using the lower-object monadic procedure.

Monadic Procedure: lower-object obj [system] [#:target #f] Return as a value in %store-monad the derivation or

store item corresponding to obj for system, cross-compiling for target if target is true. obj must be an object that has an associated gexp compiler, such as a <package>.

Procedure: gexp->approximate-sexp gexp

Sometimes, it may be useful to convert a G-exp into a S-exp. For example, some linters (veja Invocando guix lint) peek into the build phases of a package to detect potential problems. This conversion can be achieved with this procedure. However, some information can be lost in the process. More specifically, lowerable objects will be silently replaced with some arbitrary object – currently the list (*approximate*), but this may change.


8.13 Invocando guix repl

The guix repl command makes it easier to program Guix in Guile by launching a Guile read-eval-print loop (REPL) for interactive programming (veja Using Guile Interactively em GNU Guile Reference Manual), or by running Guile scripts (veja Running Guile Scripts em GNU Guile Reference Manual). Compared to just launching the guile command, guix repl guarantees that all the Guix modules and all its dependencies are available in the search path.

A sintaxe geral é:

guix repl options [file args]

When a file argument is provided, file is executed as a Guile scripts:

guix repl my-script.scm

To pass arguments to the script, use -- to prevent them from being interpreted as arguments to guix repl itself:

guix repl -- my-script.scm --input=foo.txt

To make a script executable directly from the shell, using the guix executable that is on the user’s search path, add the following two lines at the top of the script:

#!/usr/bin/env -S guix repl --
!#

To make a script that launches an interactive REPL directly from the shell, use the --interactive flag:

#!/usr/bin/env -S guix repl --interactive
!#

Without a file name argument, a Guile REPL is started, allowing for interactive use (veja Usando Guix interativamente):

$ guix repl
scheme@(guile-user)> ,use (gnu packages base)
scheme@(guile-user)> coreutils
$1 = #<package coreutils@8.29 gnu/packages/base.scm:327 3e28300>

In addition, guix repl implements a simple machine-readable REPL protocol for use by (guix inferior), a facility to interact with inferiors, separate processes running a potentially different revision of Guix.

As opções disponíveis são as seguintes:

--list-types

Display the TYPE options for guix repl --type=TYPE and exit.

--type=type
-t tipo

Start a REPL of the given TYPE, which can be one of the following:

guile

This is default, and it spawns a standard full-featured Guile REPL.

machine

Spawn a REPL that uses the machine-readable protocol. This is the protocol that the (guix inferior) module speaks.

--listen=endpoint

By default, guix repl reads from standard input and writes to standard output. When this option is passed, it will instead listen for connections on endpoint. Here are examples of valid options:

--listen=tcp:37146

Accept connections on localhost on port 37146.

--listen=unix:/tmp/socket

Accept connections on the Unix-domain socket /tmp/socket.

--interactive
-i

Launch the interactive REPL after file is executed.

--load-path=directory
-L diretório

Add directory to the front of the package module search path (veja Módulos de pacote).

This allows users to define their own packages and make them visible to the script or REPL.

-q

Inhibit loading of the ~/.guile file. By default, that configuration file is loaded when spawning a guile REPL.


8.14 Usando Guix interativamente

The guix repl command gives you access to a warm and friendly read-eval-print loop (REPL) (veja Invocando guix repl). If you’re getting into Guix programming—defining your own packages, writing manifests, defining services for Guix System or Guix Home, etc.—you will surely find it convenient to toy with ideas at the REPL.

If you use Emacs, the most convenient way to do that is with Geiser (veja A configuração perfeita), but you do not have to use Emacs to enjoy the REPL. When using guix repl or guile in the terminal, we recommend using Readline for completion and Colorized to get colorful output. To do that, you can run:

guix install guile guile-readline guile-colorized

... and then create a .guile file in your home directory containing this:

(use-modules (ice-9 readline) (ice-9 colorized))

(activate-readline)
(activate-colorized)

The REPL lets you evaluate Scheme code; you type a Scheme expression at the prompt, and the REPL prints what it evaluates to:

$ guix repl
scheme@(guix-user)> (+ 2 3)
$1 = 5
scheme@(guix-user)> (string-append "a" "b")
$2 = "ab"

It becomes interesting when you start fiddling with Guix at the REPL. The first thing you’ll want to do is to “import” the (guix) module, which gives access to the main part of the programming interface, and perhaps a bunch of useful Guix modules. You could type (use-modules (guix)), which is valid Scheme code to import a module (veja Using Guile Modules em GNU Guile Reference Manual), but the REPL provides the use command as a shorthand notation (veja REPL Commands em GNU Guile Reference Manual):

scheme@(guix-user)> ,use (guix)
scheme@(guix-user)> ,use (gnu packages base)

Notice that REPL commands are introduced by a leading comma. A REPL command like use is not valid Scheme code; it’s interpreted specially by the REPL.

Guix extends the Guile REPL with additional commands for convenience. Among those, the build command comes in handy: it ensures that the given file-like object is built, building it if needed, and returns its output file name(s). In the example below, we build the coreutils and grep packages, as well as a “computed file” (veja computed-file), and we use the scandir procedure to list the files in Grep’s /bin directory:

scheme@(guix-user)> ,build coreutils
$1 = "/gnu/store/…-coreutils-8.32-debug"
$2 = "/gnu/store/…-coreutils-8.32"
scheme@(guix-user)> ,build grep
$3 = "/gnu/store/…-grep-3.6"
scheme@(guix-user)> ,build (computed-file "x" #~(mkdir #$output))
building /gnu/store/…-x.drv...
$4 = "/gnu/store/…-x"
scheme@(guix-user)> ,use(ice-9 ftw)
scheme@(guix-user)> (scandir (string-append $3 "/bin"))
$5 = ("." ".." "egrep" "fgrep" "grep")

As a packager, you may be willing to inspect the build phases or flags of a given package; this is particularly useful when relying a lot on inheritance to define package variants (veja Definindo variantes de pacote) or when package arguments are a result of some computation, both of which can make it harder to foresee what ends up in the package arguments. Additional commands let you inspect those package arguments:

scheme@(guix-user)> ,phases grep
$1 = (modify-phases %standard-phases
       (add-after 'install 'fix-egrep-and-fgrep
         (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")))))))
scheme@(guix-user)> ,configure-flags findutils
$2 = (list "--localstatedir=/var")
scheme@(guix-user)> ,make-flags binutils
$3 = '("MAKEINFO=true")

At a lower-level, a useful command is lower: it takes a file-like object and “lowers” it into a derivation (veja Derivações) or a store file:

scheme@(guix-user)> ,lower grep
$6 = #<derivation /gnu/store/…-grep-3.6.drv => /gnu/store/…-grep-3.6 7f0e639115f0>
scheme@(guix-user)> ,lower (plain-file "x" "Hello!")
$7 = "/gnu/store/…-x"

The full list of REPL commands can be seen by typing ,help guix and is given below for reference.

REPL command: build object

Lower object and build it if it’s not already built, returning its output file name(s).

REPL command: lower object

Lower object into a derivation or store file name and return it.

REPL command: verbosity level

Change build verbosity to level.

This is similar to the --verbosity command-line option (veja Opções de compilação comuns): level 0 means total silence, level 1 shows build events only, and higher levels print build logs.

REPL command: phases package
REPL command: configure-flags package
REPL command: make-flags package

These REPL commands return the value of one element of the arguments field of package (veja Referência do package): the first one show the staged code associated with #:phases (veja Fases de construção), the second shows the code for #:configure-flags, and ,make-flags returns the code for #:make-flags.

REPL command: run-in-store exp

Run exp, a monadic expression, through the store monad. Veja A mônada do armazém, for more information.

REPL command: enter-store-monad

Enter a new REPL to evaluate monadic expressions (veja A mônada do armazém). You can quit this “inner” REPL by typing ,q.


9 Utilitários

This section describes Guix command-line utilities. Some of them are primarily targeted at developers and users who write new package definitions, while others are more generally useful. They complement the Scheme programming interface of Guix in a convenient way.


9.1 Invocando guix build

The guix build command builds packages or derivations and their dependencies, and prints the resulting store paths. Note that it does not modify the user’s profile—this is the job of the guix package command (veja Invocando guix package). Thus, it is mainly useful for distribution developers.

A sintaxe geral é:

guix build options package-or-derivation

As an example, the following command builds the latest versions of Emacs and of Guile, displays their build logs, and finally displays the resulting directories:

guix build emacs guile

Similarly, the following command builds all the available packages:

guix build --quiet --keep-going \
  $(guix package -A | awk '{ print $1 "@" $2 }')

package-or-derivation may be either the name of a package found in the software distribution such as coreutils or coreutils@8.20, or a derivation such as /gnu/store/…-coreutils-8.19.drv. In the former case, a package with the corresponding name (and optionally version) is searched for among the GNU distribution modules (veja Módulos de pacote).

Alternatively, the --expression option may be used to specify a Scheme expression that evaluates to a package; this is useful when disambiguating among several same-named packages or package variants is needed.

There may be zero or more options. The available options are described in the subsections below.


9.1.1 Opções de compilação comuns

A number of options that control the build process are common to guix build and other commands that can spawn builds, such as guix package or guix archive. These are the following:

--load-path=directory
-L diretório

Add directory to the front of the package module search path (veja Módulos de pacote).

This allows users to define their own packages and make them visible to the command-line tools.

--keep-failed
-K

Keep the build tree of failed builds. Thus, if a build fails, its build tree is kept under /tmp, in a directory whose name is shown at the end of the build log. This is useful when debugging build issues. Veja Depurando falhas de compilação, for tips and tricks on how to debug build issues.

This option implies --no-offload, and it has no effect when connecting to a remote daemon with a guix:// URI (veja the GUIX_DAEMON_SOCKET variable).

--keep-going
-k

Keep going when some of the derivations fail to build; return only once all the builds have either completed or failed.

The default behavior is to stop as soon as one of the specified derivations has failed.

--dry-run
-n

Do not build the derivations.

--fallback

When substituting a pre-built binary fails, fall back to building packages locally (veja Falha na substituição).

--substitute-urls=urls

Consider urls the whitespace-separated list of substitute source URLs, overriding the default list of URLs of guix-daemon (veja guix-daemon URLs).

This means that substitutes may be downloaded from urls, provided they are signed by a key authorized by the system administrator (veja Substitutos).

When urls is the empty string, substitutes are effectively disabled.

--no-substitutes

Não use substitutos para compilar produtos. Ou seja, sempre crie coisas localmente, em vez de permitir downloads de binários pré-compilados (veja Substitutos).

--no-grafts

Do not “graft” packages. In practice, this means that package updates available as grafts are not applied. Veja Atualizações de segurança, for more information on grafts.

--rounds=n

Build each derivation n times in a row, and raise an error if consecutive build results are not bit-for-bit identical.

This is a useful way to detect non-deterministic builds processes. Non-deterministic build processes are a problem because they make it practically impossible for users to verify whether third-party binaries are genuine. Veja Invocando guix challenge, for more.

Quando usado em conjunto com --keep-failed, uma saída de comparação é mantida no armazém, sob /gnu/store/…-check. Isso facilita procurar por diferenças entre os dois resultados.

--no-offload

Não use compilações de offload para outras máquinas (veja Usando o recurso de descarregamento). Ou seja, sempre compile as coisas localmente em vez de descarregar compilações para máquinas remotas.

--max-silent-time=segundos

Quando o processo de compilação ou substituição permanecer em silêncio por mais de segundos, encerra-o e relata uma falha de compilação.

By default, the daemon’s setting is honored (veja --max-silent-time).

--timeout=segundos

Da mesma forma, quando o processo de compilação ou substituição durar mais que segundos, encerra-o e relata uma falha de compilação.

By default, the daemon’s setting is honored (veja --timeout).

-v level
--verbosity=level

Use the given verbosity level, an integer. Choosing 0 means that no output is produced, 1 is for quiet output; 2 is similar to 1 but it additionally displays download URLs; 3 shows all the build log output on standard error.

--cores=n
-c n

Allow the use of up to n CPU cores for the build. The special value 0 means to use as many CPU cores as available.

--max-jobs=n
-M n

Allow at most n build jobs in parallel. Veja --max-jobs, for details about this option and the equivalent guix-daemon option.

--debug=level

Produce debugging output coming from the build daemon. level must be an integer between 0 and 5; higher means more verbose output. Setting a level of 4 or more may be helpful when debugging setup issues with the build daemon.

Behind the scenes, guix build is essentially an interface to the package-derivation procedure of the (guix packages) module, and to the build-derivations procedure of the (guix derivations) module.

In addition to options explicitly passed on the command line, guix build and other guix commands that support building honor the GUIX_BUILD_OPTIONS environment variable.

Environment Variable: GUIX_BUILD_OPTIONS

Users can define this variable to a list of command line options that will automatically be used by guix build and other guix commands that can perform builds, as in the example below:

$ export GUIX_BUILD_OPTIONS="--no-substitutes -c 2 -L /foo/bar"

These options are parsed independently, and the result is appended to the parsed command-line options.


9.1.2 Opções de transformação de pacote

Another set of command-line options supported by guix build and also guix package are package transformation options. These are options that make it possible to define package variants—for instance, packages built from different source code. This is a convenient way to create customized packages on the fly without having to type in the definitions of package variants (veja Definindo pacotes).

Package transformation options are preserved across upgrades: guix upgrade attempts to apply transformation options initially used when creating the profile to the upgraded packages.

The available options are listed below. Most commands support them and also support a --help-transform option that lists all the available options and a synopsis (these options are not shown in the --help output for brevity).

--tune[=cpu]

Use versions of the packages marked as “tunable” optimized for cpu. When cpu is native, or when it is omitted, tune for the CPU on which the guix command is running.

Valid cpu names are those recognized by the underlying compiler, by default the GNU Compiler Collection. On x86_64 processors, this includes CPU names such as nehalem, haswell, and skylake (veja -march em Using the GNU Compiler Collection (GCC)).

As new generations of CPUs come out, they augment the standard instruction set architecture (ISA) with additional instructions, in particular instructions for single-instruction/multiple-data (SIMD) parallel processing. For example, while Core2 and Skylake CPUs both implement the x86_64 ISA, only the latter supports AVX2 SIMD instructions.

The primary gain one can expect from --tune is for programs that can make use of those SIMD capabilities and that do not already have a mechanism to select the right optimized code at run time. Packages that have the tunable? property set are considered tunable packages by the --tune option; a package definition with the property set looks like this:

(package
  (name "hello-simd")
  ;; ...

  ;; This package may benefit from SIMD extensions so
  ;; mark it as "tunable".
  (properties '((tunable? . #t))))

Other packages are not considered tunable. This allows Guix to use generic binaries in the cases where tuning for a specific CPU is unlikely to provide any gain.

Tuned packages are built with -march=CPU; under the hood, the -march option is passed to the actual wrapper by a compiler wrapper. Since the build machine may not be able to run code for the target CPU micro-architecture, the test suite is not run when building a tuned package.

To reduce rebuilds to the minimum, tuned packages are grafted onto packages that depend on them (veja grafts). Thus, using --no-grafts cancels the effect of --tune.

We call this technique package multi-versioning: several variants of tunable packages may be built, one for each CPU variant. It is the coarse-grain counterpart of function multi-versioning as implemented by the GNU tool chain (veja Function Multiversioning em Using the GNU Compiler Collection (GCC)).

--with-source=fonte
--with-source=pacote=fonte
--with-source=package@version=source

Use source as the source of package, and version as its version number. source must be a file name or a URL, as for guix download (veja Invocando guix download).

When package is omitted, it is taken to be the package name specified on the command line that matches the base of source—e.g., if source is /src/guile-2.0.10.tar.gz, the corresponding package is guile.

Likewise, when version is omitted, the version string is inferred from source; in the previous example, it is 2.0.10.

This option allows users to try out versions of packages other than the one provided by the distribution. The example below downloads ed-1.7.tar.gz from a GNU mirror and uses that as the source for the ed package:

guix build ed --with-source=mirror://gnu/ed/ed-1.4.tar.gz

As a developer, --with-source makes it easy to test release candidates, and even to test their impact on packages that depend on them:

guix build elogind --with-source=…/shepherd-0.9.0rc1.tar.gz

… or to build from a checkout in a pristine environment:

$ git clone git://git.sv.gnu.org/guix.git
$ guix build guix --with-source=guix@1.0=./guix
--with-input=pacote=substituto

Replace dependency on package by a dependency on replacement. package must be a package name, and replacement must be a package specification such as guile or guile@1.8.

For instance, the following command builds Guix, but replaces its dependency on the current stable version of Guile with a dependency on the legacy version of Guile, guile@2.2:

guix build --with-input=guile=guile@2.2 guix

This is a recursive, deep replacement. So in this example, both guix and its dependency guile-json (which also depends on guile) get rebuilt against guile@2.2.

This is implemented using the package-input-rewriting/spec Scheme procedure (veja package-input-rewriting/spec).

--with-graft=package=replacement

This is similar to --with-input but with an important difference: instead of rebuilding the whole dependency chain, replacement is built and then grafted onto the binaries that were initially referring to package. Veja Atualizações de segurança, for more information on grafts.

For example, the command below grafts version 3.5.4 of GnuTLS onto Wget and all its dependencies, replacing references to the version of GnuTLS they currently refer to:

guix build --with-graft=gnutls=gnutls@3.5.4 wget

This has the advantage of being much faster than rebuilding everything. But there is a caveat: it works if and only if package and replacement are strictly compatible—for example, if they provide a library, the application binary interface (ABI) of those libraries must be compatible. If replacement is somehow incompatible with package, then the resulting package may be unusable. Use with care!

--with-debug-info=package

Build package in a way that preserves its debugging info and graft it onto packages that depend on it. This is useful if package does not already provide debugging info as a debug output (veja Instalando arquivos de depuração).

For example, suppose you’re experiencing a crash in Inkscape and would like to see what’s up in GLib, a library deep down in Inkscape’s dependency graph. GLib lacks a debug output, so debugging is tough. Fortunately, you rebuild GLib with debugging info and tack it on Inkscape:

guix install inkscape --with-debug-info=glib

Only GLib needs to be recompiled so this takes a reasonable amount of time. Veja Instalando arquivos de depuração, for more info.

Nota: Under the hood, this option works by passing the ‘#:strip-binaries? #f’ to the build system of the package of interest (veja Sistemas de compilação). Most build systems support that option but some do not. In that case, an error is raised.

Likewise, if a C/C++ package is built without -g (which is rarely the case), debugging info will remain unavailable even when #:strip-binaries? is false.

--with-c-toolchain=package=toolchain

This option changes the compilation of package and everything that depends on it so that they get built with toolchain instead of the default GNU tool chain for C/C++.

Considere este exemplo:

guix build octave-cli \
  --with-c-toolchain=fftw=gcc-toolchain@10 \
  --with-c-toolchain=fftwf=gcc-toolchain@10

The command above builds a variant of the fftw and fftwf packages using version 10 of gcc-toolchain instead of the default tool chain, and then builds a variant of the GNU Octave command-line interface using them. GNU Octave itself is also built with gcc-toolchain@10.

This other example builds the Hardware Locality (hwloc) library and its dependents up to intel-mpi-benchmarks with the Clang C compiler:

guix build --with-c-toolchain=hwloc=clang-toolchain \
           intel-mpi-benchmarks

Nota: There can be application binary interface (ABI) incompatibilities among tool chains. This is particularly true of the C++ standard library and run-time support libraries such as that of OpenMP. By rebuilding all dependents with the same tool chain, --with-c-toolchain minimizes the risks of incompatibility but cannot entirely eliminate them. Choose package wisely.

--with-git-url=pacote=url

Build package from the latest commit of the master branch of the Git repository at url. Git sub-modules of the repository are fetched, recursively.

For example, the following command builds the NumPy Python library against the latest commit of the master branch of Python itself:

guix build python-numpy \
  --with-git-url=python=https://github.com/python/cpython

This option can also be combined with --with-branch or --with-commit (see below).

Obviously, since it uses the latest commit of the given branch, the result of such a command varies over time. Nevertheless it is a convenient way to rebuild entire software stacks against the latest commit of one or more packages. This is particularly useful in the context of continuous integration (CI).

Checkouts are kept in a cache under ~/.cache/guix/checkouts to speed up consecutive accesses to the same repository. You may want to clean it up once in a while to save disk space.

--with-branch=pacote=ramo

Build package from the latest commit of branch. If the source field of package is an origin with the git-fetch method (veja Referência do origin) or a git-checkout object, the repository URL is taken from that source. Otherwise you have to use --with-git-url to specify the URL of the Git repository.

For instance, the following command builds guile-sqlite3 from the latest commit of its master branch, and then builds guix (which depends on it) and cuirass (which depends on guix) against this specific guile-sqlite3 build:

guix build --with-branch=guile-sqlite3=master cuirass
--with-commit=pacote=commit

This is similar to --with-branch, except that it builds from commit rather than the tip of a branch. commit must be a valid Git commit SHA1 identifier, a tag, or a git describe style identifier such as 1.0-3-gabc123.

--with-patch=package=file

Add file to the list of patches applied to package, where package is a spec such as python@3.8 or glibc. file must contain a patch; it is applied with the flags specified in the origin of package (veja Referência do origin), which by default includes -p1 (veja patch Directories em Comparing and Merging Files).

As an example, the command below rebuilds Coreutils with the GNU C Library (glibc) patched with the given patch:

guix build coreutils --with-patch=glibc=./glibc-frob.patch

In this example, glibc itself as well as everything that leads to Coreutils in the dependency graph is rebuilt.

--with-configure-flag=package=flag

Append flag to the configure flags of package, where package is a spec such as guile@3.0 or glibc. The build system of package must support the #:configure-flags argument.

For example, the command below builds GNU Hello with the configure flag --disable-nls:

guix build hello --with-configure-flag=hello=--disable-nls

The following command passes an extra flag to cmake as it builds lapack:

guix build lapack \
  --with-configure-flag=lapack=-DBUILD_SHARED_LIBS=OFF

Nota: Under the hood, this option works by passing the ‘#:configure-flags’ argument to the build system of the package of interest (veja Sistemas de compilação). Most build systems support that option but some do not. In that case, an error is raised.

--with-latest=package
--with-version=package=version

So you like living on the bleeding edge? The --with-latest option is for you! It replaces occurrences of package in the dependency graph with its latest upstream version, as reported by guix refresh (veja Invocando guix refresh).

It does so by determining the latest upstream release of package (if possible), downloading it, and authenticating it if it comes with an OpenPGP signature.

As an example, the command below builds Guix against the latest version of Guile-JSON:

guix build guix --with-latest=guile-json

The --with-version works similarly except that it lets you specify that you want precisely version, assuming that version exists upstream. For example, to spawn a development environment with SciPy built against version 1.22.4 of NumPy (skipping its test suite because hey, we’re not gonna wait this long), you would run:

guix shell python python-scipy --with-version=python-numpy=1.22.4

Aviso: Because they depend on source code published at a given point in time on upstream servers, deployments made with --with-latest and --with-version may be non-reproducible: source might disappear or be modified in place on the servers.

To deploy old software versions without compromising on reproducibility, veja guix time-machine.

There are limitations. First, in cases where the tool cannot or does not know how to authenticate source code, you are at risk of running malicious code; a warning is emitted in this case. Second, this option simply changes the source used in the existing package definitions, which is not always sufficient: there might be additional dependencies that need to be added, patches to apply, and more generally the quality assurance work that Guix developers normally do will be missing.

You’ve been warned! When those limitations are acceptable, it’s a snappy way to stay on top. We encourage you to submit patches updating the actual package definitions once you have successfully tested an upgrade with --with-latest (veja Contribuindo).

--without-tests=package

Build package without running its tests. This can be useful in situations where you want to skip the lengthy test suite of a intermediate package, or if a package’s test suite fails in a non-deterministic fashion. It should be used with care because running the test suite is a good way to ensure a package is working as intended.

Turning off tests leads to a different store item. Consequently, when using this option, anything that depends on package must be rebuilt, as in this example:

guix install --without-tests=python python-notebook

The command above installs python-notebook on top of python built without running its test suite. To do so, it also rebuilds everything that depends on python, including python-notebook itself.

Internally, --without-tests relies on changing the #:tests? option of a package’s check phase (veja Sistemas de compilação). Note that some packages use a customized check phase that does not respect a #:tests? #f setting. Therefore, --without-tests has no effect on these packages.

Wondering how to achieve the same effect using Scheme code, for example in your manifest, or how to write your own package transformation? Veja Definindo variantes de pacote, for an overview of the programming interfaces available.


9.1.3 Opções de compilação adicional

The command-line options presented below are specific to guix build.

--quiet
-q

Build quietly, without displaying the build log; this is equivalent to --verbosity=0. Upon completion, the build log is kept in /var (or similar) and can always be retrieved using the --log-file option.

--file=arquivo
-f arquivo

Build the package, derivation, or other file-like object that the code within file evaluates to (veja file-like objects).

As an example, file might contain a package definition like this (veja Definindo pacotes):

(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+))

The file may also contain a JSON representation of one or more package definitions. Running guix build -f on hello.json with the following contents would result in building the packages myhello and greeter:

[
  {
    "name": "myhello",
    "version": "2.10",
    "source": "mirror://gnu/hello/hello-2.10.tar.gz",
    "build-system": "gnu",
    "arguments": {
      "tests?": false
    },
    "home-page": "https://www.gnu.org/software/hello/",
    "synopsis": "Hello, GNU world: An example GNU package",
    "description": "GNU Hello prints a greeting.",
    "license": "GPL-3.0+",
    "native-inputs": ["gettext"]
  },
  {
    "name": "greeter",
    "version": "1.0",
    "source": "mirror://gnu/hello/hello-2.10.tar.gz",
    "build-system": "gnu",
    "arguments": {
      "test-target": "foo",
      "parallel-build?": false
    },
    "home-page": "https://example.com/",
    "synopsis": "Greeter using GNU Hello",
    "description": "This is a wrapper around GNU Hello.",
    "license": "GPL-3.0+",
    "inputs": ["myhello", "hello"]
  }
]
--manifest=manifest
-m manifest

Build all packages listed in the given manifest (veja --manifest).

--expression=expr
-e expr

Build the package or derivation expr evaluates to.

For example, expr may be (@ (gnu packages guile) guile-1.8), which unambiguously designates this specific variant of version 1.8 of Guile.

Alternatively, expr may be a G-expression, in which case it is used as a build program passed to gexp->derivation (veja Expressões-G).

Lastly, expr may refer to a zero-argument monadic procedure (veja A mônada do armazém). The procedure must return a derivation as a monadic value, which is then passed through run-with-store.

--development
-D

Build the “development environment” (build dependencies) of the following package.

For example, the following command builds the inputs of hello, but not hello itself, and also builds guile:

guix build -D hello guile

Notice that -D (or --development) only applies to the immediately following package on the command line. Under the hood, it uses package->development-manifest (veja package->development-manifest).

Nota: The effect of combining --development with --target (for cross-compilation) may not be what you expect: it will cross-compile all the dependencies of the given package when it is built natively.

--dependents[=depth]
-P [depth]

Build the dependents of the following package. By default, build all the direct and indirect dependents; when depth is provided, limit to dependents at that distance: 1 for direct dependents, 2 for dependents of dependents, and so on.

For example, the command below builds all the dependents of libgit2:

guix build --dependents libgit2

To build all the packages that directly depend on NumPy, run:

guix build -P1 python-numpy

The list of dependents is computed in the same way as with guix refresh --list-dependent (veja Invocando guix refresh).

--source
-S

Build the source derivations of the packages, rather than the packages themselves.

For instance, guix build -S gcc returns something like /gnu/store/…-gcc-4.7.2.tar.bz2, which is the GCC source tarball.

The returned source tarball is the result of applying any patches and code snippets specified in the package origin (veja Definindo pacotes).

As with other derivations, the result of building a source derivation can be verified using the --check option (veja build-check). This is useful to validate that a (potentially already built or substituted, thus cached) package source matches against its declared hash.

Note that guix build -S compiles the sources only of the specified packages. They do not include the sources of statically linked dependencies and by themselves are insufficient for reproducing the packages.

--sources

Fetch and return the source of package-or-derivation and all their dependencies, recursively. This is a handy way to obtain a local copy of all the source code needed to build packages, allowing you to eventually build them even without network access. It is an extension of the --source option and can accept one of the following optional argument values:

package

This value causes the --sources option to behave in the same way as the --source option.

all

Build the source derivations of all packages, including any source that might be listed as inputs. This is the default value.

$ guix build --sources tzdata
The following derivations will be built:
   /gnu/store/…-tzdata2015b.tar.gz.drv
   /gnu/store/…-tzcode2015b.tar.gz.drv
transitive

Build the source derivations of all packages, as well of all transitive inputs to the packages. This can be used e.g. to prefetch package source for later offline building.

$ guix build --sources=transitive tzdata
The following derivations will be built:
   /gnu/store/…-tzcode2015b.tar.gz.drv
   /gnu/store/…-findutils-4.4.2.tar.xz.drv
   /gnu/store/…-grep-2.21.tar.xz.drv
   /gnu/store/…-coreutils-8.23.tar.xz.drv
   /gnu/store/…-make-4.1.tar.xz.drv
   /gnu/store/…-bash-4.3.tar.xz.drv
…
--system=sistema
-s sistema

Attempt to build for system—e.g., i686-linux—instead of the system type of the build host. The guix build command allows you to repeat this option several times, in which case it builds for all the specified systems; other commands ignore extraneous -s options.

Nota: The --system flag is for native compilation and must not be confused with cross-compilation. See --target below for information on cross-compilation.

An example use of this is on Linux-based systems, which can emulate different personalities. For instance, passing --system=i686-linux on an x86_64-linux system or --system=armhf-linux on an aarch64-linux system allows you to build packages in a complete 32-bit environment.

Nota: Building for an armhf-linux system is unconditionally enabled on aarch64-linux machines, although certain aarch64 chipsets do not allow for this functionality, notably the ThunderX.

Similarly, when transparent emulation with QEMU and binfmt_misc is enabled (veja qemu-binfmt-service-type), you can build for any system for which a QEMU binfmt_misc handler is installed.

Builds for a system other than that of the machine you are using can also be offloaded to a remote machine of the right architecture. Veja Usando o recurso de descarregamento, for more information on offloading.

--target=tripleto

Cross-build for triplet, which must be a valid GNU triplet, such as "aarch64-linux-gnu" (veja GNU configuration triplets em Autoconf).

--list-systems

List all the supported systems, that can be passed as an argument to --system.

--list-targets

List all the supported targets, that can be passed as an argument to --target.

--check

Rebuild package-or-derivation, which are already available in the store, and raise an error if the build results are not bit-for-bit identical.

This mechanism allows you to check whether previously installed substitutes are genuine (veja Substitutos), or whether the build result of a package is deterministic. Veja Invocando guix challenge, for more background information and tools.

Quando usado em conjunto com --keep-failed, uma saída de comparação é mantida no armazém, sob /gnu/store/…-check. Isso facilita procurar por diferenças entre os dois resultados.

--repair

Attempt to repair the specified store items, if they are corrupt, by re-downloading or rebuilding them.

This operation is not atomic and thus restricted to root.

--derivations
-d

Return the derivation paths, not the output paths, of the given packages.

--root=arquivo
-r arquivo

Make file a symlink to the result, and register it as a garbage collector root.

Consequently, the results of this guix build invocation are protected from garbage collection until file is removed. When that option is omitted, build results are eligible for garbage collection as soon as the build completes. Veja Invocando guix gc, for more on GC roots.

--log-file

Return the build log file names or URLs for the given package-or-derivation, or raise an error if build logs are missing.

This works regardless of how packages or derivations are specified. For instance, the following invocations are equivalent:

guix build --log-file $(guix build -d guile)
guix build --log-file $(guix build guile)
guix build --log-file guile
guix build --log-file -e '(@ (gnu packages guile) guile-2.0)'

If a log is unavailable locally, and unless --no-substitutes is passed, the command looks for a corresponding log on one of the substitute servers.

So for instance, imagine you want to see the build log of GDB on aarch64, but you are actually on an x86_64 machine:

$ guix build --log-file gdb -s aarch64-linux
https://bordeaux.guix.gnu.org/log/…-gdb-7.10

You can freely access a huge library of build logs!


9.1.4 Depurando falhas de compilação

When defining a new package (veja Definindo pacotes), you will probably find yourself spending some time debugging and tweaking the build until it succeeds. To do that, you need to operate the build commands yourself in an environment as close as possible to the one the build daemon uses.

To that end, the first thing to do is to use the --keep-failed or -K option of guix build, which will keep the failed build tree in /tmp or whatever directory you specified as TMPDIR (veja --keep-failed).

From there on, you can cd to the failed build tree and source the environment-variables file, which contains all the environment variable definitions that were in place when the build failed. So let’s say you’re debugging a build failure in package foo; a typical session would look like this:

$ guix build foo -K
… build fails
$ cd /tmp/guix-build-foo.drv-0
$ source ./environment-variables
$ cd foo-1.2

Now, you can invoke commands as if you were the daemon (almost) and troubleshoot your build process.

Sometimes it happens that, for example, a package’s tests pass when you run them manually but they fail when the daemon runs them. This can happen because the daemon runs builds in containers where, unlike in our environment above, network access is missing, /bin/sh does not exist, etc. (veja Configuração do ambiente de compilação).

In such cases, you may need to inspect the build process from within a container similar to the one the build daemon creates:

$ guix build -K foo
…
$ cd /tmp/guix-build-foo.drv-0
$ guix shell --no-grafts -C -D foo strace gdb
[env]# source ./environment-variables
[env]# cd foo-1.2

Here, guix shell -C creates a container and spawns a new shell in it (veja Invocando guix shell). The strace gdb part adds the strace and gdb commands to the container, which you may find handy while debugging. The --no-grafts option makes sure we get the exact same environment, with ungrafted packages (veja Atualizações de segurança, for more info on grafts).

To get closer to a container like that used by the build daemon, we can remove /bin/sh:

[env]# rm /bin/sh

(Don’t worry, this is harmless: this is all happening in the throw-away container created by guix shell.)

The strace command is probably not in the search path, but we can run:

[env]# $GUIX_ENVIRONMENT/bin/strace -f -o log make check

In this way, not only you will have reproduced the environment variables the daemon uses, you will also be running the build process in a container similar to the one the daemon uses.


9.2 Invocando guix edit

So many packages, so many source files! The guix edit command facilitates the life of users and packagers by pointing their editor at the source file containing the definition of the specified packages. For instance:

guix edit gcc@4.9 vim

launches the program specified in the VISUAL or in the EDITOR environment variable to view the recipe of GCC 4.9.3 and that of Vim.

If you are using a Guix Git checkout (veja Compilando do git), or have created your own packages on GUIX_PACKAGE_PATH (veja Módulos de pacote), you will be able to edit the package recipes. In other cases, you will be able to examine the read-only recipes for packages currently in the store.

Instead of GUIX_PACKAGE_PATH, the command-line option --load-path=directory (or in short -L directory) allows you to add directory to the front of the package module search path and so make your own packages visible.


9.3 Invocando guix download

When writing a package definition, developers typically need to download a source tarball, compute its SHA256 hash, and write that hash in the package definition (veja Definindo pacotes). The guix download tool helps with this task: it downloads a file from the given URI, adds it to the store, and prints both its file name in the store and its SHA256 hash.

The fact that the downloaded file is added to the store saves bandwidth: when the developer eventually tries to build the newly defined package with guix build, the source tarball will not have to be downloaded again because it is already in the store. It is also a convenient way to temporarily stash files, which may be deleted eventually (veja Invocando guix gc).

The guix download command supports the same URIs as used in package definitions. In particular, it supports mirror:// URIs. https URIs (HTTP over TLS) are supported provided the Guile bindings for GnuTLS are available in the user’s environment; when they are not available, an error is raised. Veja how to install the GnuTLS bindings for Guile em GnuTLS-Guile, for more information.

guix download verifies HTTPS server certificates by loading the certificates of X.509 authorities from the directory pointed to by the SSL_CERT_DIR environment variable (veja Certificados X.509), unless --no-check-certificate is used.

Alternatively, guix download can also retrieve a Git repository, possibly a specific commit, tag, or branch.

The following options are available:

--hash=algorithm
-H algorithm

Compute a hash using the specified algorithm. Veja Invocando guix hash, for more information.

--format=fmt
-f fmt

Write the hash in the format specified by fmt. For more information on the valid values for fmt, veja Invocando guix hash.

--no-check-certificate

Do not validate the X.509 certificates of HTTPS servers.

When using this option, you have absolutely no guarantee that you are communicating with the authentic server responsible for the given URL, which makes you vulnerable to “man-in-the-middle” attacks.

--output=arquivo
-o arquivo

Save the downloaded file to file instead of adding it to the store.

--git
-g

Checkout the Git repository at the latest commit on the default branch.

--commit=commit-or-tag

Checkout the Git repository at commit-or-tag.

commit-or-tag can be either a tag or a commit defined in the Git repository.

--branch=ramo

Checkout the Git repository at branch.

The repository will be checked out at the latest commit of branch, which must be a valid branch of the Git repository.

--recursive
-r

Recursively clone the Git repository.


9.4 Invocando guix hash

The guix hash command computes the hash of a file. It is primarily a convenience tool for anyone contributing to the distribution: it computes the cryptographic hash of one or more files, which can be used in the definition of a package (veja Definindo pacotes).

A sintaxe geral é:

guix hash option file ...

When file is - (a hyphen), guix hash computes the hash of data read from standard input. guix hash has the following options:

--hash=algorithm
-H algorithm

Compute a hash using the specified algorithm, sha256 by default.

algorithm must be the name of a cryptographic hash algorithm supported by Libgcrypt via Guile-Gcrypt—e.g., sha512 or sha3-256 (veja Hash Functions em Guile-Gcrypt Reference Manual).

--format=fmt
-f fmt

Write the hash in the format specified by fmt.

Supported formats: base64, nix-base32, base32, base16 (hex and hexadecimal can be used as well).

If the --format option is not specified, guix hash will output the hash in nix-base32. This representation is used in the definitions of packages.

--recursive
-r

The --recursive option is deprecated in favor of --serializer=nar (see below); -r remains accepted as a convenient shorthand.

--serializer=type
-S type

Compute the hash on file using type serialization.

type may be one of the following:

none

This is the default: it computes the hash of a file’s contents.

nar

Compute the hash of a “normalized archive” (or “nar”) containing file, including its children if it is a directory. Some of the metadata of file is part of the archive; for instance, when file is a regular file, the hash is different depending on whether file is executable or not. Metadata such as time stamps have no impact on the hash (veja Invocando guix archive, for more info on the nar format).

git

Compute the hash of the file or directory as a Git “tree”, following the same method as the Git version control system.

--exclude-vcs
-x

When combined with --recursive, exclude version control system directories (.bzr, .git, .hg, etc.).

As an example, here is how you would compute the hash of a Git checkout, which is useful when using the git-fetch method (veja Referência do origin):

$ git clone http://example.org/foo.git
$ cd foo
$ guix hash -x --serializer=nar .

9.5 Invoking guix import

The guix import command is useful for people who would like to add a package to the distribution with as little work as possible—a legitimate demand. The command knows of a few repositories from which it can “import” package metadata. The result is a package definition, or a template thereof, in the format we know (veja Definindo pacotes).

A sintaxe geral é:

guix import [global-options…] importer package [options…]

importer specifies the source from which to import package metadata, and options specifies a package identifier and other options specific to importer. guix import itself has the following global-options:

--insert=file
-i file

Insert the package definition(s) that the importer generated into the specified file, either in alphabetical order among existing package definitions, or at the end of the file otherwise.

Some of the importers rely on the ability to run the gpgv command. For these, GnuPG must be installed and in $PATH; run guix install gnupg if needed.

Currently, the available “importers” are:

gnu

Import metadata for the given GNU package. This provides a template for the latest version of that GNU package, including the hash of its source tarball, and its canonical synopsis and description.

Additional information such as the package dependencies and its license needs to be figured out manually.

For example, the following command returns a package definition for GNU Hello:

guix import gnu hello

Specific command-line options are:

--key-download=policy

As for guix refresh, specify the policy to handle missing OpenPGP keys when verifying the package signature. Veja --key-download.

pypi

Import metadata from the Python Package Index. Information is taken from the JSON-formatted description available at pypi.python.org and usually includes all the relevant information, including package dependencies. For maximum efficiency, it is recommended to install the unzip utility, so that the importer can unzip Python wheels and gather data from them.

The command below imports metadata for the latest version of the itsdangerous Python package:

guix import pypi itsdangerous

You can also ask for a specific version:

guix import pypi itsdangerous@1.1.0
--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

gem

Import metadata from RubyGems. Information is taken from the JSON-formatted description available at rubygems.org and includes most relevant information, including runtime dependencies. There are some caveats, however. The metadata doesn’t distinguish between synopses and descriptions, so the same string is used for both fields. Additionally, the details of non-Ruby dependencies required to build native extensions is unavailable and left as an exercise to the packager.

The command below imports metadata for the rails Ruby package:

guix import gem rails

You can also ask for a specific version:

guix import gem rails@7.0.4
--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

minetest

Import metadata from ContentDB. Information is taken from the JSON-formatted metadata provided through ContentDB’s API and includes most relevant information, including dependencies. There are some caveats, however. The license information is often incomplete. The commit hash is sometimes missing. The descriptions are in the Markdown format, but Guix uses Texinfo instead. Texture packs and subgames are unsupported.

The command below imports metadata for the Mesecons mod by Jeija:

guix import minetest Jeija/mesecons

The author name can also be left out:

guix import minetest mesecons
--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

cpan

Import metadata from MetaCPAN. Information is taken from the JSON-formatted metadata provided through MetaCPAN’s API and includes most relevant information, such as module dependencies. License information should be checked closely. If Perl is available in the store, then the corelist utility will be used to filter core modules out of the list of dependencies.

The command below imports metadata for the Acme::Boolean Perl module:

guix import cpan Acme::Boolean

Like many other importers, the cpan importer supports recursive imports:

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

cran

Import metadata from CRAN, the central repository for the GNU R statistical and graphical environment.

Information is extracted from the DESCRIPTION file of the package.

The command below imports metadata for the Cairo R package:

guix import cran Cairo

You can also ask for a specific version:

guix import cran rasterVis@0.50.3

When --recursive is added, the importer will traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

When --style=specification is added, the importer will generate package definitions whose inputs are package specifications instead of references to package variables. This is useful when generated package definitions are to be appended to existing user modules, as the list of used package modules need not be changed. The default is --style=variable.

When --prefix=license: is added, the importer will prefix license atoms with license:, allowing a prefixed import of (guix licenses).

When --archive=bioconductor is added, metadata is imported from Bioconductor, a repository of R packages for the analysis and comprehension of high-throughput genomic data in bioinformatics.

Information is extracted from the DESCRIPTION file contained in the package archive.

The command below imports metadata for the GenomicRanges R package:

guix import cran --archive=bioconductor GenomicRanges

Finally, you can also import R packages that have not yet been published on CRAN or Bioconductor as long as they are in a git repository. Use --archive=git followed by the URL of the git repository:

guix import cran --archive=git https://github.com/immunogenomics/harmony
texlive

Import TeX package information from the TeX Live package database for TeX packages that are part of the TeX Live distribution.

Information about the package is obtained from the TeX Live package database, a plain text file that is included in the texlive-scripts package. The source code is downloaded from possibly multiple locations in the SVN repository of the Tex Live project. Note that therefore SVN must be installed and in $PATH; run guix install subversion if needed.

The command below imports metadata for the fontspec TeX package:

guix import texlive fontspec

Additional options include:

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

json

Import package metadata from a local JSON file. Consider the following example package definition in JSON format:

{
  "name": "hello",
  "version": "2.10",
  "source": "mirror://gnu/hello/hello-2.10.tar.gz",
  "build-system": "gnu",
  "home-page": "https://www.gnu.org/software/hello/",
  "synopsis": "Hello, GNU world: An example GNU package",
  "description": "GNU Hello prints a greeting.",
  "license": "GPL-3.0+",
  "native-inputs": ["gettext"]
}

The field names are the same as for the <package> record (Veja Definindo pacotes). References to other packages are provided as JSON lists of quoted package specification strings such as guile or guile@2.0.

The importer also supports a more explicit source definition using the common fields for <origin> records:

{
  …
  "source": {
    "method": "url-fetch",
    "uri": "mirror://gnu/hello/hello-2.10.tar.gz",
    "sha256": {
      "base32": "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"
    }
  }
  …
}

The command below reads metadata from the JSON file hello.json and outputs a package expression:

guix import json hello.json
hackage

Import metadata from the Haskell community’s central package archive Hackage. Information is taken from Cabal files and includes all the relevant information, including package dependencies.

Specific command-line options are:

--stdin
-s

Read a Cabal file from standard input.

--no-test-dependencies
-t

Do not include dependencies required only by the test suites.

--cabal-environment=alist
-e alist

alist is a Scheme alist defining the environment in which the Cabal conditionals are evaluated. The accepted keys are: os, arch, impl and a string representing the name of a flag. The value associated with a flag has to be either the symbol true or false. The value associated with other keys has to conform to the Cabal file format definition. The default value associated with the keys os, arch and impl is ‘linux’, ‘x86_64’ and ‘ghc’, respectively.

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

The command below imports metadata for the latest version of the HTTP Haskell package without including test dependencies and specifying the value of the flag ‘network-uri’ as false:

guix import hackage -t -e "'((\"network-uri\" . false))" HTTP

A specific package version may optionally be specified by following the package name by an at-sign and a version number as in the following example:

guix import hackage mtl@2.1.3.1
stackage

The stackage importer is a wrapper around the hackage one. It takes a package name, looks up the package version included in a long-term support (LTS) Stackage release and uses the hackage importer to retrieve its metadata. Note that it is up to you to select an LTS release compatible with the GHC compiler used by Guix.

Specific command-line options are:

--no-test-dependencies
-t

Do not include dependencies required only by the test suites.

--lts-version=versão
-l versão

version is the desired LTS release version. If omitted the latest release is used.

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

The command below imports metadata for the HTTP Haskell package included in the LTS Stackage release version 7.18:

guix import stackage --lts-version=7.18 HTTP
elpa

Import metadata from an Emacs Lisp Package Archive (ELPA) package repository (veja Packages em The GNU Emacs Manual).

Specific command-line options are:

--archive=repo
-a repo

repo identifies the archive repository from which to retrieve the information. Currently the supported repositories and their identifiers are:

  • - GNU, selected by the gnu identifier. This is the default.

    Packages from elpa.gnu.org are signed with one of the keys contained in the GnuPG keyring at share/emacs/25.1/etc/package-keyring.gpg (or similar) in the emacs package (veja ELPA package signatures em The GNU Emacs Manual).

  • - NonGNU, selected by the nongnu identifier.
  • - MELPA-Stable, selected by the melpa-stable identifier.
  • - MELPA, selected by the melpa identifier.
--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

crate

Import metadata from the crates.io Rust package repository crates.io, as in this example:

guix import crate blake2-rfc

The crate importer also allows you to specify a version string:

guix import crate constant-time-eq@0.1.0

Additional options include:

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

--recursive-dev-dependencies

If --recursive-dev-dependencies is specified, also the recursively imported packages contain their development dependencies, which are recursively imported as well.

--allow-yanked

If no non-yanked version of a crate is available, use the latest yanked version instead instead of aborting.

--mark-missing

If a crate dependency is not (yet) packaged, make the corresponding input in #:cargo-inputs or #:cargo-development-inputs into a comment.

elm

Import metadata from the Elm package repository package.elm-lang.org, as in this example:

guix import elm elm-explorations/webgl

The Elm importer also allows you to specify a version string:

guix import elm elm-explorations/webgl@1.1.3

Additional options include:

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

npm-binary

Import metadata from the npm Registry, as in this example:

guix import npm-binary buffer-crc32

The npm-binary importer also allows you to specify a version string:

guix import npm-binary buffer-crc32@1.0.0

Nota: Generated package expressions skip the build step of the node-build-system. As such, generated package expressions often refer to transpiled or generated files, instead of being built from source.

Additional options include:

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

opam

Import metadata from the OPAM package repository used by the OCaml community.

Additional options include:

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

composer

Import metadata from the Composer package archive used by the PHP community, as in this example:

guix import composer phpunit/phpunit

Additional options include:

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

--repo

By default, packages are searched in the official OPAM repository. This option, which can be used more than once, lets you add other repositories which will be searched for packages. It accepts as valid arguments:

  • the name of a known repository - can be one of opam, coq (equivalent to coq-released), coq-core-dev, coq-extra-dev or grew.
  • the URL of a repository as expected by the opam repository add command (for instance, the URL equivalent of the above opam name would be https://opam.ocaml.org).
  • the path to a local copy of a repository (a directory containing a packages/ sub-directory).

Repositories are assumed to be passed to this option by order of preference. The additional repositories will not replace the default opam repository, which is always kept as a fallback.

Also, please note that versions are not compared across repositories. The first repository (from left to right) that has at least one version of a given package will prevail over any others, and the version imported will be the latest one found in this repository only.

go

Import metadata for a Go module using proxy.golang.org.

guix import go gopkg.in/yaml.v2

It is possible to use a package specification with a @VERSION suffix to import a specific version.

Additional options include:

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

--pin-versions

When using this option, the importer preserves the exact versions of the Go modules dependencies instead of using their latest available versions. This can be useful when attempting to import packages that recursively depend on former versions of themselves to build. When using this mode, the symbol of the package is made by appending the version to its name, so that multiple versions of the same package can coexist.

egg

Import metadata for CHICKEN eggs. The information is taken from PACKAGE.egg files found in the eggs-5-all Git repository. However, it does not provide all the information that we need, there is no “description” field, and the licenses used are not always precise (BSD is often used instead of BSD-N).

guix import egg sourcehut

You can also ask for a specific version:

guix import egg arrays@1.0

Additional options include:

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

hexpm

Import metadata from the hex.pm Erlang and Elixir package repository hex.pm, as in this example:

guix import hexpm stun

The importer tries to determine the build system used by the package.

The hexpm importer also allows you to specify a version string:

guix import hexpm cf@0.3.0

Additional options include:

--recursive
-r

Traverse the dependency graph of the given upstream package recursively and generate package expressions for all those packages that are not yet in Guix.

The structure of the guix import code is modular. It would be useful to have more importers for other package formats, and your help is welcome here (veja Contribuindo).


9.6 Invocando guix refresh

The primary audience of the guix refresh command is packagers. As a user, you may be interested in the --with-latest option, which can bring you package update superpowers built upon guix refresh (veja --with-latest). By default, guix refresh reports any packages provided by the distribution that are outdated compared to the latest upstream version, like this:

$ guix refresh
gnu/packages/gettext.scm:29:13: gettext would be upgraded from 0.18.1.1 to 0.18.2.1
gnu/packages/glib.scm:77:12: glib would be upgraded from 2.34.3 to 2.37.0

Alternatively, one can specify packages to consider, in which case a warning is emitted for packages that lack an updater:

$ guix refresh coreutils guile guile-ssh
gnu/packages/ssh.scm:205:2: warning: no updater for guile-ssh
gnu/packages/guile.scm:136:12: guile would be upgraded from 2.0.12 to 2.0.13

guix refresh browses the upstream repository of each package and determines the highest version number of the releases therein. The command knows how to update specific types of packages: GNU packages, ELPA packages, etc.—see the documentation for --type below. There are many packages, though, for which it lacks a method to determine whether a new upstream release is available. However, the mechanism is extensible, so feel free to get in touch with us to add a new method!

--recursive

Consider the packages specified, and all the packages upon which they depend.

$ guix refresh --recursive coreutils
gnu/packages/acl.scm:40:13: acl would be upgraded from 2.2.53 to 2.3.1
gnu/packages/m4.scm:30:12: 1.4.18 is already the latest version of m4
gnu/packages/xml.scm:68:2: warning: no updater for expat
gnu/packages/multiprecision.scm:40:12: 6.1.2 is already the latest version of gmp
…

If for some reason you don’t want to update to the latest version, you can update to a specific version by appending an equal sign and the desired version number to the package specification. Note that not all updaters support this; an error is reported when an updater cannot refresh to the specified version.

$ guix refresh trytond-party
gnu/packages/guile.scm:392:2: guile would be upgraded from 3.0.3 to 3.0.5
$ guix refresh -u guile=3.0.4
…
gnu/packages/guile.scm:392:2: guile: updating from version 3.0.3 to version 3.0.4...
…
$ guix refresh -u guile@2.0=2.0.12
…
gnu/packages/guile.scm:147:2: guile: updating from version 2.0.10 to version 2.0.12...
…

In some specific cases, you may have many packages specified via a manifest or a module selection which should all be updated together; for these cases, the --target-version option can be provided to have them all refreshed to the same version, as shown in the examples below:

$ guix refresh qtbase qtdeclarative --target-version=6.5.2
gnu/packages/qt.scm:1248:13: qtdeclarative would be upgraded from 6.3.2 to 6.5.2
gnu/packages/qt.scm:584:2: qtbase would be upgraded from 6.3.2 to 6.5.2
$ guix refresh --manifest=qt5-manifest.scm --target-version=5.15.10
gnu/packages/qt.scm:1173:13: qtxmlpatterns would be upgraded from 5.15.8 to 5.15.10
gnu/packages/qt.scm:1202:13: qtdeclarative would be upgraded from 5.15.8 to 5.15.10
gnu/packages/qt.scm:1762:13: qtserialbus would be upgraded from 5.15.8 to 5.15.10
gnu/packages/qt.scm:2070:13: qtquickcontrols2 would be upgraded from 5.15.8 to 5.15.10
…

Sometimes the upstream name differs from the package name used in Guix, and guix refresh needs a little help. Most updaters honor the upstream-name property in package definitions, which can be used to that effect:

(define-public network-manager
  (package
    (name "network-manager")
    ;; …
    (properties '((upstream-name . "NetworkManager")))))

When passed --update, it modifies distribution source files to update the version numbers and source code hashes of those package definitions, as well as possibly their inputs (veja Definindo pacotes). This is achieved by downloading each package’s latest source tarball and its associated OpenPGP signature, authenticating the downloaded tarball against its signature using gpgv, and finally computing its hash—note that GnuPG must be installed and in $PATH; run guix install gnupg if needed.

When the public key used to sign the tarball is missing from the user’s keyring, an attempt is made to automatically retrieve it from a public key server; when this is successful, the key is added to the user’s keyring; otherwise, guix refresh reports an error.

The following options are supported:

--expression=expr
-e expr

Considere o pacote que expr avalia.

This is useful to precisely refer to a package, as in this example:

guix refresh -l -e '(@@ (gnu packages commencement) glibc-final)'

This command lists the dependents of the “final” libc (essentially all the packages).

--update
-u

Update distribution source files (package definitions) in place. This is usually run from a checkout of the Guix source tree (veja Executando guix antes dele ser instalado):

./pre-inst-env guix refresh -s non-core -u

Veja Definindo pacotes, for more information on package definitions. You can also run it on packages from a third-party channel:

guix refresh -L /path/to/channel -u package

Veja Criando um canal, on how to create a channel.

This command updates the version and source code hash of the package. Depending on the updater being used, it can also update the various ‘inputs’ fields of the package. In some cases, the updater might get inputs wrong—it might not know about an extra input that’s necessary, or it might add an input that should be avoided.

To address that, packagers can add properties stating inputs that should be added to those found by the updater or inputs that should be ignored: the updater-extra-inputs and updater-ignored-inputs properties pertain to “regular” inputs, and there are equivalent properties for ‘native’ and ‘propagated’ inputs. In the example below, we tell the updater that we need ‘openmpi’ as an additional input:

(define-public python-mpi4py
  (package
    (name "python-mpi4py")
    ;; …
    (inputs (list openmpi))
    (properties
     '((updater-extra-inputs . ("openmpi"))))))

That way, guix refresh -u python-mpi4py will leave the ‘openmpi’ input, even if it is not among the inputs it would normally add.

--select=[subset]
-s subset

Select all the packages in subset, one of core, non-core or module:name.

The core subset refers to all the packages at the core of the distribution—i.e., packages that are used to build “everything else”. This includes GCC, libc, Binutils, Bash, etc. Usually, changing one of these packages in the distribution entails a rebuild of all the others. Thus, such updates are an inconvenience to users in terms of build time or bandwidth used to achieve the upgrade.

The non-core subset refers to the remaining packages. It is typically useful in cases where an update of the core packages would be inconvenient.

The module:name subset refers to all the packages in a specified guile module. The module can be specified as module:guile or module:(gnu packages guile), the former is a shorthand for the later.

--manifest=arquivo
-m arquivo

Select all the packages from the manifest in file. This is useful to check if any packages of the user manifest can be updated.

--type=updater
-t updater

Select only packages handled by updater (may be a comma-separated list of updaters). Currently, updater may be one of:

gnu

the updater for GNU packages;

savannah

the updater for packages hosted at Savannah;

sourceforge

the updater for packages hosted at SourceForge;

gnome

the updater for GNOME packages;

kde

the updater for KDE packages;

xorg

the updater for X.org packages;

kernel.org

the updater for packages hosted on kernel.org;

egg

the updater for Egg packages;

elpa

the updater for ELPA packages;

cran

the updater for CRAN packages;

bioconductor

the updater for Bioconductor R packages;

cpan

the updater for CPAN packages;

pypi

the updater for PyPI packages.

gem

the updater for RubyGems packages.

github

the updater for GitHub packages.

hackage

the updater for Hackage packages.

stackage

the updater for Stackage packages.

crate

the updater for Crates packages.

launchpad

the updater for Launchpad packages.

generic-html

a generic updater that crawls the HTML page where the source tarball of the package is hosted, when applicable, or the HTML page specified by the release-monitoring-url property of the package.

generic-git

a generic updater for packages hosted on Git repositories. It tries to be smart about parsing Git tag names, but if it is not able to parse the tag name and compare tags correctly, users can define the following properties for a package.

  • release-tag-prefix: a regular expression for matching a prefix of the tag name.
  • release-tag-suffix: a regular expression for matching a suffix of the tag name.
  • release-tag-version-delimiter: a string used as the delimiter in the tag name for separating the numbers of the version.
  • accept-pre-releases: by default, the updater will ignore pre-releases; to make it also look for pre-releases, set the this property to #t.
(package
  (name "foo")
  ;; ...
  (properties
    '((release-tag-prefix . "^release0-")
      (release-tag-suffix . "[a-z]?$")
      (release-tag-version-delimiter . ":"))))

For instance, the following command only checks for updates of Emacs packages hosted at elpa.gnu.org and for updates of CRAN packages:

$ guix refresh --type=elpa,cran
gnu/packages/statistics.scm:819:13: r-testthat would be upgraded from 0.10.0 to 0.11.0
gnu/packages/emacs.scm:856:13: emacs-auctex would be upgraded from 11.88.6 to 11.88.9
--list-updaters

List available updaters and exit (see --type above).

For each updater, display the fraction of packages it covers; at the end, display the fraction of packages covered by all these updaters.

In addition, guix refresh can be passed one or more package names, as in this example:

$ ./pre-inst-env guix refresh -u emacs idutils gcc@4.8

The command above specifically updates the emacs and idutils packages. The --select option would have no effect in this case. You might also want to update definitions that correspond to the packages installed in your profile:

$ ./pre-inst-env guix refresh -u \
       $(guix package --list-installed | cut -f1)

When considering whether to upgrade a package, it is sometimes convenient to know which packages would be affected by the upgrade and should be checked for compatibility. For this the following option may be used when passing guix refresh one or more package names:

--list-dependent
-l

List top-level dependent packages that would need to be rebuilt as a result of upgrading one or more packages.

Veja the reverse-package type of guix graph, for information on how to visualize the list of dependents of a package.

Veja guix build --dependents, for a convenient way to build all the dependents of a package.

Be aware that the --list-dependent option only approximates the rebuilds that would be required as a result of an upgrade. More rebuilds might be required under some circumstances.

$ guix refresh --list-dependent flex
Building the following 120 packages would ensure 213 dependent packages are rebuilt:
hop@2.4.0 emacs-geiser@0.13 notmuch@0.18 mu@0.9.9.5 cflow@1.4 idutils@4.6 …

The command above lists a set of packages that could be built to check for compatibility with an upgraded flex package.

--list-transitive
-T

List all the packages which one or more packages depend upon.

$ guix refresh --list-transitive flex
flex@2.6.4 depends on the following 25 packages: perl@5.28.0 help2man@1.47.6
bison@3.0.5 indent@2.2.10 tar@1.30 gzip@1.9 bzip2@1.0.6 xz@5.2.4 file@5.33 …

The command above lists a set of packages which, when changed, would cause flex to be rebuilt.

The following options can be used to customize GnuPG operation:

--gpg=command

Use command as the GnuPG 2.x command. command is searched for in $PATH.

--keyring=file

Use file as the keyring for upstream keys. file must be in the keybox format. Keybox files usually have a name ending in .kbx and the GNU Privacy Guard (GPG) can manipulate these files (veja kbxutil em Using the GNU Privacy Guard, for information on a tool to manipulate keybox files).

When this option is omitted, guix refresh uses ~/.config/guix/upstream/trustedkeys.kbx as the keyring for upstream signing keys. OpenPGP signatures are checked against keys from this keyring; missing keys are downloaded to this keyring as well (see --key-download below).

You can export keys from your default GPG keyring into a keybox file using commands like this one:

gpg --export rms@gnu.org | kbxutil --import-openpgp >> mykeyring.kbx

Likewise, you can fetch keys to a specific keybox file like this:

gpg --no-default-keyring --keyring mykeyring.kbx \
  --recv-keys 3CE464558A84FDC69DB40CFB090B11993D9AEBB5

Veja --keyring em Using the GNU Privacy Guard, for more information on GPG’s --keyring option.

--key-download=policy

Handle missing OpenPGP keys according to policy, which may be one of:

always

Always download missing OpenPGP keys from the key server, and add them to the user’s GnuPG keyring.

never

Never try to download missing OpenPGP keys. Instead just bail out.

interactive

When a package signed with an unknown OpenPGP key is encountered, ask the user whether to download it or not. This is the default behavior.

--key-server=host

Use host as the OpenPGP key server when importing a public key.

--load-path=directory
-L diretório

Add directory to the front of the package module search path (veja Módulos de pacote).

This allows users to define their own packages and make them visible to the command-line tools.

The github updater uses the GitHub API to query for new releases. When used repeatedly e.g. when refreshing all packages, GitHub will eventually refuse to answer any further API requests. By default 60 API requests per hour are allowed, and a full refresh on all GitHub packages in Guix requires more than this. Authentication with GitHub through the use of an API token alleviates these limits. To use an API token, set the environment variable GUIX_GITHUB_TOKEN to a token procured from https://github.com/settings/tokens or otherwise.


9.7 Invoking guix style

The guix style command helps users and packagers alike style their package definitions and configuration files according to the latest fashionable trends. It can either reformat whole files, with the --whole-file option, or apply specific styling rules to individual package definitions. The command currently provides the following styling rules:

  • formatting package definitions according to the project’s conventions (veja Formatação de código);
  • rewriting package inputs to the “new style”, as explained below.

The way package inputs are written is going through a transition (veja Referência do package, for more on package inputs). Until version 1.3.0, package inputs were written using the “old style”, where each input was given an explicit label, most of the time the package name:

(package
  ;; …
  ;; The "old style" (deprecated).
  (inputs `(("libunistring" ,libunistring)
            ("libffi" ,libffi))))

Today, the old style is deprecated and the preferred style looks like this:

(package
  ;; …
  ;; The "new style".
  (inputs (list libunistring libffi)))

Likewise, uses of alist-delete and friends to manipulate inputs is now deprecated in favor of modify-inputs (veja Definindo variantes de pacote, for more info on modify-inputs).

In the vast majority of cases, this is a purely mechanical change on the surface syntax that does not even incur a package rebuild. Running guix style -S inputs can do that for you, whether you’re working on packages in Guix proper or in an external channel.

A sintaxe geral é:

guix style [options] package

This causes guix style to analyze and rewrite the definition of package… or, when package is omitted, of all the packages. The --styling or -S option allows you to select the style rule, the default rule being format—see below.

To reformat entire source files, the syntax is:

guix style --whole-file file

The available options are listed below.

--dry-run
-n

Show source file locations that would be edited but do not modify them.

--whole-file
-f

Reformat the given files in their entirety. In that case, subsequent arguments are interpreted as file names (rather than package names), and the --styling option has no effect.

As an example, here is how you might reformat your operating system configuration (you need write permissions for the file):

guix style -f /etc/config.scm
--alphabetical-sort
-A

Place the top-level package definitions in the given files in alphabetical order. Package definitions with matching names are placed with versions in descending order. This option only has an effect in combination with --whole-file.

--styling=rule
-S rule

Apply rule, one of the following styling rules:

format

Format the given package definition(s)—this is the default styling rule. For example, a packager running Guix on a checkout (veja Executando guix antes dele ser instalado) might want to reformat the definition of the Coreutils package like so:

./pre-inst-env guix style coreutils
inputs

Rewrite package inputs to the “new style”, as described above. This is how you would rewrite inputs of package whatnot in your own channel:

guix style -L ~/my/channel -S inputs whatnot

Rewriting is done in a conservative way: preserving comments and bailing out if it cannot make sense of the code that appears in an inputs field. The --input-simplification option described below provides fine-grain control over when inputs should be simplified.

arguments

Rewrite package arguments to use G-expressions (veja Expressões-G). For example, consider this package definition:

(define-public my-package
  (package
    ;; …
    (arguments      ;old-style quoted arguments
     '(#:make-flags '("V=1")
       #:phases (modify-phases %standard-phases
                  (delete 'build))))))

Running guix style -S arguments on this package would rewrite its arguments field like to:

(define-public my-package
  (package
    ;; …
    (arguments
      (list #:make-flags #~'("V=1")
            #:phases #~(modify-phases %standard-phases
                         (delete 'build))))))

Note that changes made by the arguments rule do not entail a rebuild of the affected packages. Furthermore, if a package definition happens to be using G-expressions already, guix style leaves it unchanged.

--list-stylings
-l

List and describe the available styling rules and exit.

--load-path=directory
-L diretório

Add directory to the front of the package module search path (veja Módulos de pacote).

--expression=expr
-e expr

Style the package expr evaluates to.

Por exemplo, executando:

guix style -e '(@ (gnu packages gcc) gcc-5)'

styles the gcc-5 package definition.

--input-simplification=policy

When using the inputs styling rule, with ‘-S inputs’, this option specifies the package input simplification policy for cases where an input label does not match the corresponding package name. policy may be one of the following:

silent

Simplify inputs only when the change is “silent”, meaning that the package does not need to be rebuilt (its derivation is unchanged).

safe

Simplify inputs only when that is “safe” to do: the package might need to be rebuilt, but the change is known to have no observable effect.

always

Simplify inputs even when input labels do not match package names, and even if that might have an observable effect.

The default is silent, meaning that input simplifications do not trigger any package rebuild.


9.8 Invocando guix lint

The guix lint command is meant to help package developers avoid common errors and use a consistent style. It runs a number of checks on a given set of packages in order to find common mistakes in their definitions. Available checkers include (see --list-checkers for a complete list):

synopsis
description

Validate certain typographical and stylistic rules about package descriptions and synopses.

inputs-should-be-native

Identify inputs that should most likely be native inputs.

source
home-page
mirror-url
github-url
source-file-name

Probe home-page and source URLs and report those that are invalid. Suggest a mirror:// URL when applicable. If the source URL redirects to a GitHub URL, recommend usage of the GitHub URL. Check that the source file name is meaningful, e.g. is not just a version number or “git-checkout”, without a declared file-name (veja Referência do origin).

source-unstable-tarball

Parse the source URL to determine if a tarball from GitHub is autogenerated or if it is a release tarball. Unfortunately GitHub’s autogenerated tarballs are sometimes regenerated.

derivation

Check that the derivation of the given packages can be successfully computed for all the supported systems (veja Derivações).

profile-collisions

Check whether installing the given packages in a profile would lead to collisions. Collisions occur when several packages with the same name but a different version or a different store file name are propagated. Veja propagated-inputs, for more information on propagated inputs.

archival

Checks whether the package’s source code is archived at Software Heritage.

When the source code that is not archived comes from a version-control system (VCS)—e.g., it’s obtained with git-fetch, send Software Heritage a “save” request so that it eventually archives it. This ensures that the source will remain available in the long term, and that Guix can fall back to Software Heritage should the source code disappear from its original host. The status of recent “save” requests can be viewed on-line.

When source code is a tarball obtained with url-fetch, simply print a message when it is not archived. As of this writing, Software Heritage does not allow requests to save arbitrary tarballs; we are working on ways to ensure that non-VCS source code is also archived.

Software Heritage limits the request rate per IP address. When the limit is reached, guix lint prints a message and the archival checker stops doing anything until that limit has been reset.

cve

Report known vulnerabilities found in the Common Vulnerabilities and Exposures (CVE) databases of the current and past year published by the US NIST.

To view information about a particular vulnerability, visit pages such as:

  • https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-YYYY-ABCD
  • https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-YYYY-ABCD

where CVE-YYYY-ABCD is the CVE identifier—e.g., CVE-2015-7554.

Package developers can specify in package recipes the Common Platform Enumeration (CPE) name and version of the package when they differ from the name or version that Guix uses, as in this example:

(package
  (name "grub")
  ;; …
  ;; CPE calls this package "grub2".
  (properties '((cpe-name . "grub2")
                (cpe-version . "2.3"))))

Some entries in the CVE database do not specify which version of a package they apply to, and would thus “stick around” forever. Package developers who found CVE alerts and verified they can be ignored can declare them as in this example:

(package
  (name "t1lib")
  ;; …
  ;; These CVEs no longer apply and can be safely ignored.
  (properties `((lint-hidden-cve . ("CVE-2011-0433"
                                    "CVE-2011-1553"
                                    "CVE-2011-1554"
                                    "CVE-2011-5244")))))
formatting

Warn about obvious source code formatting issues: trailing white space, use of tabulations, etc.

input-labels

Report old-style input labels that do not match the name of the corresponding package. This aims to help migrate from the “old input style”. Veja Referência do package, for more information on package inputs and input styles. Veja Invoking guix style, on how to migrate to the new style.

A sintaxe geral é:

guix lint opções pacote

If no package is given on the command line, then all packages are checked. The options may be zero or more of the following:

--list-checkers
-l

List and describe all the available checkers that will be run on packages and exit.

--checkers
-c

Only enable the checkers specified in a comma-separated list using the names returned by --list-checkers.

--exclude
-x

Only disable the checkers specified in a comma-separated list using the names returned by --list-checkers.

--expression=expr
-e expr

Considere o pacote que expr avalia.

This is useful to unambiguously designate packages, as in this example:

guix lint -c archival -e '(@ (gnu packages guile) guile-3.0)'
--no-network
-n

Only enable the checkers that do not depend on Internet access.

--load-path=directory
-L diretório

Add directory to the front of the package module search path (veja Módulos de pacote).

This allows users to define their own packages and make them visible to the command-line tools.


9.9 Invocando guix size

The guix size command helps package developers profile the disk usage of packages. It is easy to overlook the impact of an additional dependency added to a package, or the impact of using a single output for a package that could easily be split (veja Pacotes com múltiplas saídas). Such are the typical issues that guix size can highlight.

The command can be passed one or more package specifications such as gcc@4.8 or guile:debug, or a file name in the store. Consider this example:

$ guix size coreutils
store item                               total    self
/gnu/store/…-gcc-5.5.0-lib           60.4    30.1  38.1%
/gnu/store/…-glibc-2.27              30.3    28.8  36.6%
/gnu/store/…-coreutils-8.28          78.9    15.0  19.0%
/gnu/store/…-gmp-6.1.2               63.1     2.7   3.4%
/gnu/store/…-bash-static-4.4.12       1.5     1.5   1.9%
/gnu/store/…-acl-2.2.52              61.1     0.4   0.5%
/gnu/store/…-attr-2.4.47             60.6     0.2   0.3%
/gnu/store/…-libcap-2.25             60.5     0.2   0.2%
total: 78.9 MiB

The store items listed here constitute the transitive closure of Coreutils—i.e., Coreutils and all its dependencies, recursively—as would be returned by:

$ guix gc -R /gnu/store/…-coreutils-8.23

Here the output shows three columns next to store items. The first column, labeled “total”, shows the size in mebibytes (MiB) of the closure of the store item—that is, its own size plus the size of all its dependencies. The next column, labeled “self”, shows the size of the item itself. The last column shows the ratio of the size of the item itself to the space occupied by all the items listed here.

In this example, we see that the closure of Coreutils weighs in at 79 MiB, most of which is taken by libc and GCC’s run-time support libraries. (That libc and GCC’s libraries represent a large fraction of the closure is not a problem per se because they are always available on the system anyway.)

Since the command also accepts store file names, assessing the size of a build result is straightforward:

guix size $(guix system build config.scm)

When the package(s) passed to guix size are available in the store25, guix size queries the daemon to determine its dependencies, and measures its size in the store, similar to du -ms --apparent-size (veja du invocation em GNU Coreutils).

When the given packages are not in the store, guix size reports information based on the available substitutes (veja Substitutos). This makes it possible to profile the disk usage of store items that are not even on disk, only available remotely.

You can also specify several package names:

$ guix size coreutils grep sed bash
store item                               total    self
/gnu/store/…-coreutils-8.24          77.8    13.8  13.4%
/gnu/store/…-grep-2.22               73.1     0.8   0.8%
/gnu/store/…-bash-4.3.42             72.3     4.7   4.6%
/gnu/store/…-readline-6.3            67.6     1.2   1.2%
…
total: 102.3 MiB

In this example we see that the combination of the four packages takes 102.3 MiB in total, which is much less than the sum of each closure since they have a lot of dependencies in common.

When looking at the profile returned by guix size, you may find yourself wondering why a given package shows up in the profile at all. To understand it, you can use guix graph --path -t references to display the shortest path between the two packages (veja Invocando guix graph).

The available options are:

--substitute-urls=urls

Use substitute information from urls. Veja the same option for guix build.

--sort=key

Sort lines according to key, one of the following options:

próprio

the size of each item (the default);

fechamento

the total size of the item’s closure.

--map-file=arquivo

Write a graphical map of disk usage in PNG format to file.

For the example above, the map looks like this:

map of Coreutils disk usage produced
by guix size

This option requires that Guile-Charting be installed and visible in Guile’s module search path. When that is not the case, guix size fails as it tries to load it.

--system=sistema
-s sistema

Consider packages for system—e.g., x86_64-linux.

--load-path=directory
-L diretório

Add directory to the front of the package module search path (veja Módulos de pacote).

This allows users to define their own packages and make them visible to the command-line tools.


9.10 Invocando guix graph

Packages and their dependencies form a graph, specifically a directed acyclic graph (DAG). It can quickly become difficult to have a mental model of the package DAG, so the guix graph command provides a visual representation of the DAG. By default, guix graph emits a DAG representation in the input format of Graphviz, so its output can be passed directly to the dot command of Graphviz. It can also emit an HTML page with embedded JavaScript code to display a “chord diagram” in a Web browser, using the d3.js library, or emit Cypher queries to construct a graph in a graph database supporting the openCypher query language. With --path, it simply displays the shortest path between two packages. The general syntax is:

guix graph opções pacote

For example, the following command generates a PDF file representing the package DAG for the GNU Core Utilities, showing its build-time dependencies:

guix graph coreutils | dot -Tpdf > dag.pdf

The output looks like this:

Dependency graph of the GNU Coreutils

Nice little graph, no?

You may find it more pleasant to navigate the graph interactively with xdot (from the xdot package):

guix graph coreutils | xdot -

But there is more than one graph! The one above is concise: it is the graph of package objects, omitting implicit inputs such as GCC, libc, grep, etc. It is often useful to have such a concise graph, but sometimes one may want to see more details. guix graph supports several types of graphs, allowing you to choose the level of detail:

package

This is the default type used in the example above. It shows the DAG of package objects, excluding implicit dependencies. It is concise, but filters out many details.

reverse-package

This shows the reverse DAG of packages. For example:

guix graph --type=reverse-package ocaml

... yields the graph of packages that explicitly depend on OCaml (if you are also interested in cases where OCaml is an implicit dependency, see reverse-bag below).

Note that for core packages this can yield huge graphs. If all you want is to know the number of packages that depend on a given package, use guix refresh --list-dependent (veja --list-dependent).

bag-emerged

This is the package DAG, including implicit inputs.

For instance, the following command:

guix graph --type=bag-emerged coreutils

... yields this bigger graph:

Detailed dependency graph of the GNU
Coreutils

At the bottom of the graph, we see all the implicit inputs of gnu-build-system (veja gnu-build-system).

Now, note that the dependencies of these implicit inputs—that is, the bootstrap dependencies (veja Inicializando)—are not shown here, for conciseness.

bag

Similar to bag-emerged, but this time including all the bootstrap dependencies.

bag-with-origins

Similar to bag, but also showing origins and their dependencies.

reverse-bag

This shows the reverse DAG of packages. Unlike reverse-package, it also takes implicit dependencies into account. For example:

guix graph -t reverse-bag dune

... yields the graph of all packages that depend on Dune, directly or indirectly. Since Dune is an implicit dependency of many packages via dune-build-system, this shows a large number of packages, whereas reverse-package would show very few if any.

derivation

This is the most detailed representation: It shows the DAG of derivations (veja Derivações) and plain store items. Compared to the above representation, many additional nodes are visible, including build scripts, patches, Guile modules, etc.

For this type of graph, it is also possible to pass a .drv file name instead of a package name, as in:

guix graph -t derivation $(guix system build -d my-config.scm)
module

This is the graph of package modules (veja Módulos de pacote). For example, the following command shows the graph for the package module that defines the guile package:

guix graph -t module guile | xdot -

All the types above correspond to build-time dependencies. The following graph type represents the run-time dependencies:

references

This is the graph of references of a package output, as returned by guix gc --references (veja Invocando guix gc).

If the given package output is not available in the store, guix graph attempts to obtain dependency information from substitutes.

Here you can also pass a store file name instead of a package name. For example, the command below produces the reference graph of your profile (which can be big!):

guix graph -t references $(readlink -f ~/.guix-profile)
referrers

This is the graph of the referrers of a store item, as returned by guix gc --referrers (veja Invocando guix gc).

This relies exclusively on local information from your store. For instance, let us suppose that the current Inkscape is available in 10 profiles on your machine; guix graph -t referrers inkscape will show a graph rooted at Inkscape and with those 10 profiles linked to it.

It can help determine what is preventing a store item from being garbage collected.

Often, the graph of the package you are interested in does not fit on your screen, and anyway all you want to know is why that package actually depends on some seemingly unrelated package. The --path option instructs guix graph to display the shortest path between two packages (or derivations, or store items, etc.):

$ guix graph --path emacs libunistring
emacs@26.3
mailutils@3.9
libunistring@0.9.10
$ guix graph --path -t derivation emacs libunistring
/gnu/store/…-emacs-26.3.drv
/gnu/store/…-mailutils-3.9.drv
/gnu/store/…-libunistring-0.9.10.drv
$ guix graph --path -t references emacs libunistring
/gnu/store/…-emacs-26.3
/gnu/store/…-libidn2-2.2.0
/gnu/store/…-libunistring-0.9.10

Sometimes you still want to visualize the graph but would like to trim it so it can actually be displayed. One way to do it is via the --max-depth (or -M) option, which lets you specify the maximum depth of the graph. In the example below, we visualize only libreoffice and the nodes whose distance to libreoffice is at most 2:

guix graph -M 2 libreoffice | xdot -f fdp -

Mind you, that’s still a big ball of spaghetti, but at least dot can render it quickly and it can be browsed somewhat.

The available options are the following:

--type=type
-t tipo

Produce a graph output of type, where type must be one of the values listed above.

--list-types

Lista os tipos de grafos disponíveis.

--backend=backend
-b backend

Produce a graph using the selected backend.

--list-backends

Lista os backends de grafos disponíveis.

Currently, the available backends are Graphviz and d3.js.

--path

Display the shortest path between two nodes of the type specified by --type. The example below shows the shortest path between libreoffice and llvm according to the references of libreoffice:

$ guix graph --path -t references libreoffice llvm
/gnu/store/…-libreoffice-6.4.2.2
/gnu/store/…-libepoxy-1.5.4
/gnu/store/…-mesa-19.3.4
/gnu/store/…-llvm-9.0.1
--expression=expr
-e expr

Considere o pacote que expr avalia.

This is useful to precisely refer to a package, as in this example:

guix graph -e '(@@ (gnu packages commencement) gnu-make-final)'
--system=sistema
-s sistema

Display the graph for system—e.g., i686-linux.

The package dependency graph is largely architecture-independent, but there are some architecture-dependent bits that this option allows you to visualize.

--load-path=directory
-L diretório

Add directory to the front of the package module search path (veja Módulos de pacote).

This allows users to define their own packages and make them visible to the command-line tools.

On top of that, guix graph supports all the usual package transformation options (veja Opções de transformação de pacote). This makes it easy to view the effect of a graph-rewriting transformation such as --with-input. For example, the command below outputs the graph of git once openssl has been replaced by libressl everywhere in the graph:

guix graph git --with-input=openssl=libressl

So many possibilities, so much fun!


9.11 Invocando guix publish

The purpose of guix publish is to enable users to easily share their store with others, who can then use it as a substitute server (veja Substitutos).

When guix publish runs, it spawns an HTTP server which allows anyone with network access to obtain substitutes from it. This means that any machine running Guix can also act as if it were a build farm, since the HTTP interface is compatible with Cuirass, the software behind the bordeaux.guix.gnu.org build farm.

For security, each substitute is signed, allowing recipients to check their authenticity and integrity (veja Substitutos). Because guix publish uses the signing key of the system, which is only readable by the system administrator, it must be started as root; the --user option makes it drop root privileges early on.

The signing key pair must be generated before guix publish is launched, using guix archive --generate-key (veja Invocando guix archive).

When the --advertise option is passed, the server advertises its availability on the local network using multicast DNS (mDNS) and DNS service discovery (DNS-SD), currently via Guile-Avahi (veja Using Avahi in Guile Scheme Programs).

A sintaxe geral é:

guix publish options

Running guix publish without any additional arguments will spawn an HTTP server on port 8080:

guix publish

guix publish can also be started following the systemd “socket activation” protocol (veja make-systemd-constructor em The GNU Shepherd Manual).

Once a publishing server has been authorized, the daemon may download substitutes from it. Veja Obtendo substitutos de outros servidores.

By default, guix publish compresses archives on the fly as it serves them. This “on-the-fly” mode is convenient in that it requires no setup and is immediately available. However, when serving lots of clients, we recommend using the --cache option, which enables caching of the archives before they are sent to clients—see below for details. The guix weather command provides a handy way to check what a server provides (veja Invocando guix weather).

As a bonus, guix publish also serves as a content-addressed mirror for source files referenced in origin records (veja Referência do origin). For instance, assuming guix publish is running on example.org, the following URL returns the raw hello-2.10.tar.gz file with the given SHA256 hash (represented in nix-base32 format, veja Invocando guix hash):

http://example.org/file/hello-2.10.tar.gz/sha256/0ssi1…ndq1i

Obviously, these URLs only work for files that are in the store; in other cases, they return 404 (“Not Found”).

Build logs are available from /log URLs like:

http://example.org/log/gwspk…-guile-2.2.3

When guix-daemon is configured to save compressed build logs, as is the case by default (veja Invocando guix-daemon), /log URLs return the compressed log as-is, with an appropriate Content-Type and/or Content-Encoding header. We recommend running guix-daemon with --log-compression=gzip since Web browsers can automatically decompress it, which is not the case with Bzip2 compression.

The following options are available:

--port=porta
-p porta

Ouve requisições HTTP na porta.

--listen=host

Listen on the network interface for host. The default is to accept connections from any interface.

--user=usuário
-u usuário

Change privileges to user as soon as possible—i.e., once the server socket is open and the signing key has been read.

--compression[=method[:level]]
-C [method[:level]]

Compress data using the given method and level. method is one of lzip, zstd, and gzip; when method is omitted, gzip is used.

When level is zero, disable compression. The range 1 to 9 corresponds to different compression levels: 1 is the fastest, and 9 is the best (CPU-intensive). The default is 3.

Usually, lzip compresses noticeably better than gzip for a small increase in CPU usage; see benchmarks on the lzip Web page. However, lzip achieves low decompression throughput (on the order of 50 MiB/s on modern hardware), which can be a bottleneck for someone who downloads over a fast network connection.

The compression ratio of zstd is between that of lzip and that of gzip; its main advantage is a high decompression speed.

Unless --cache is used, compression occurs on the fly and the compressed streams are not cached. Thus, to reduce load on the machine that runs guix publish, it may be a good idea to choose a low compression level, to run guix publish behind a caching proxy, or to use --cache. Using --cache has the advantage that it allows guix publish to add Content-Length HTTP header to its responses.

This option can be repeated, in which case every substitute gets compressed using all the selected methods, and all of them are advertised. This is useful when users may not support all the compression methods: they can select the one they support.

--cache=directory
-c directory

Cache archives and meta-data (.narinfo URLs) to directory and only serve archives that are in cache.

When this option is omitted, archives and meta-data are created on-the-fly. This can reduce the available bandwidth, especially when compression is enabled, since this may become CPU-bound. Another drawback of the default mode is that the length of archives is not known in advance, so guix publish does not add a Content-Length HTTP header to its responses, which in turn prevents clients from knowing the amount of data being downloaded.

Conversely, when --cache is used, the first request for a store item (via a .narinfo URL) triggers a background process to bake the archive—computing its .narinfo and compressing the archive, if needed. Once the archive is cached in directory, subsequent requests succeed and are served directly from the cache, which guarantees that clients get the best possible bandwidth.

That first .narinfo request nonetheless returns 200, provided the requested store item is “small enough”, below the cache bypass threshold—see --cache-bypass-threshold below. That way, clients do not have to wait until the archive is baked. For larger store items, the first .narinfo request returns 404, meaning that clients have to wait until the archive is baked.

The “baking” process is performed by worker threads. By default, one thread per CPU core is created, but this can be customized. See --workers below.

When --ttl is used, cached entries are automatically deleted when they have expired.

--workers=N

When --cache is used, request the allocation of N worker threads to “bake” archives.

--ttl=ttl

Produce Cache-Control HTTP headers that advertise a time-to-live (TTL) of ttl. ttl must denote a duration: 5d means 5 days, 1m means 1 month, and so on.

This allows the user’s Guix to keep substitute information in cache for ttl. However, note that guix publish does not itself guarantee that the store items it provides will indeed remain available for as long as ttl.

Additionally, when --cache is used, cached entries that have not been accessed for ttl and that no longer have a corresponding item in the store, may be deleted.

--negative-ttl=ttl

Similarly produce Cache-Control HTTP headers to advertise the time-to-live (TTL) of negative lookups—missing store items, for which the HTTP 404 code is returned. By default, no negative TTL is advertised.

This parameter can help adjust server load and substitute latency by instructing cooperating clients to be more or less patient when a store item is missing.

--cache-bypass-threshold=size

When used in conjunction with --cache, store items smaller than size are immediately available, even when they are not yet in cache. size is a size in bytes, or it can be suffixed by M for megabytes and so on. The default is 10M.

“Cache bypass” allows you to reduce the publication delay for clients at the expense of possibly additional I/O and CPU use on the server side: depending on the client access patterns, those store items can end up being baked several times until a copy is available in cache.

Increasing the threshold may be useful for sites that have few users, or to guarantee that users get substitutes even for store items that are not popular.

--nar-path=path

Use path as the prefix for the URLs of “nar” files (veja normalized archives).

By default, nars are served at a URL such as /nar/gzip/…-coreutils-8.25. This option allows you to change the /nar part to path.

--public-key=file
--private-key=file

Use the specific files as the public/private key pair used to sign the store items being published.

The files must correspond to the same key pair (the private key is used for signing and the public key is merely advertised in the signature metadata). They must contain keys in the canonical s-expression format as produced by guix archive --generate-key (veja Invocando guix archive). By default, /etc/guix/signing-key.pub and /etc/guix/signing-key.sec are used.

--repl[=port]
-r [porta]

Spawn a Guile REPL server (veja REPL Servers em GNU Guile Reference Manual) on port (37146 by default). This is used primarily for debugging a running guix publish server.

Enabling guix publish on Guix System is a one-liner: just instantiate a guix-publish-service-type service in the services field of the operating-system declaration (veja guix-publish-service-type).

If you are instead running Guix on a “foreign distro”, follow these instructions:

  • If your host distro uses the systemd init system:
    # ln -s ~root/.guix-profile/lib/systemd/system/guix-publish.service \
            /etc/systemd/system/
    # systemctl start guix-publish && systemctl enable guix-publish
    
  • Se sua distro hospedeira usa o sistema init Upstart:
    # ln -s ~root/.guix-profile/lib/upstart/system/guix-publish.conf /etc/init/
    # start guix-publish
    
  • Otherwise, proceed similarly with your distro’s init system.

9.12 Invocando guix challenge

Do the binaries provided by this server really correspond to the source code it claims to build? Is a package build process deterministic? These are the questions the guix challenge command attempts to answer.

The former is obviously an important question: Before using a substitute server (veja Substitutos), one had better verify that it provides the right binaries, and thus challenge it. The latter is what enables the former: If package builds are deterministic, then independent builds of the package should yield the exact same result, bit for bit; if a server provides a binary different from the one obtained locally, it may be either corrupt or malicious.

We know that the hash that shows up in /gnu/store file names is the hash of all the inputs of the process that built the file or directory—compilers, libraries, build scripts, etc. (veja Introdução). Assuming deterministic build processes, one store file name should map to exactly one build output. guix challenge checks whether there is, indeed, a single mapping by comparing the build outputs of several independent builds of any given store item.

The command output looks like this:

$ guix challenge \
  --substitute-urls="https://bordeaux.guix.gnu.org https://guix.example.org" \
  openssl git pius coreutils grep
updating substitutes from 'https://bordeaux.guix.gnu.org'... 100.0%
updating substitutes from 'https://guix.example.org'... 100.0%
/gnu/store/…-openssl-1.0.2d contents differ:
  local hash: 0725l22r5jnzazaacncwsvp9kgf42266ayyp814v7djxs7nk963q
  https://bordeaux.guix.gnu.org/nar/…-openssl-1.0.2d: 0725l22r5jnzazaacncwsvp9kgf42266ayyp814v7djxs7nk963q
  https://guix.example.org/nar/…-openssl-1.0.2d: 1zy4fmaaqcnjrzzajkdn3f5gmjk754b43qkq47llbyak9z0qjyim
  differing files:
    /lib/libcrypto.so.1.1
    /lib/libssl.so.1.1

/gnu/store/…-git-2.5.0 contents differ:
  local hash: 00p3bmryhjxrhpn2gxs2fy0a15lnip05l97205pgbk5ra395hyha
  https://bordeaux.guix.gnu.org/nar/…-git-2.5.0: 069nb85bv4d4a6slrwjdy8v1cn4cwspm3kdbmyb81d6zckj3nq9f
  https://guix.example.org/nar/…-git-2.5.0: 0mdqa9w1p6cmli6976v4wi0sw9r4p5prkj7lzfd1877wk11c9c73
  differing file:
    /libexec/git-core/git-fsck

/gnu/store/…-pius-2.1.1 contents differ:
  local hash: 0k4v3m9z1zp8xzzizb7d8kjj72f9172xv078sq4wl73vnq9ig3ax
  https://bordeaux.guix.gnu.org/nar/…-pius-2.1.1: 0k4v3m9z1zp8xzzizb7d8kjj72f9172xv078sq4wl73vnq9ig3ax
  https://guix.example.org/nar/…-pius-2.1.1: 1cy25x1a4fzq5rk0pmvc8xhwyffnqz95h2bpvqsz2mpvlbccy0gs
  differing file:
    /share/man/man1/pius.1.gz

…

5 store items were analyzed:
  - 2 (40.0%) were identical
  - 3 (60.0%) differed
  - 0 (0.0%) were inconclusive

In this example, guix challenge queries all the substitute servers for each of the fives packages specified on the command line. It then reports those store items for which the servers obtained a result different from the local build (if it exists) and/or different from one another; here, the ‘local hash’ lines indicate that a local build result was available for each of these packages and shows its hash.

As an example, guix.example.org always gets a different answer. Conversely, bordeaux.guix.gnu.org agrees with local builds, except in the case of Git. This might indicate that the build process of Git is non-deterministic, meaning that its output varies as a function of various things that Guix does not fully control, in spite of building packages in isolated environments (veja Recursos). Most common sources of non-determinism include the addition of timestamps in build results, the inclusion of random numbers, and directory listings sorted by inode number. See https://reproducible-builds.org/docs/, for more information.

To find out what is wrong with this Git binary, the easiest approach is to run:

guix challenge git \
  --diff=diffoscope \
  --substitute-urls="https://bordeaux.guix.gnu.org https://guix.example.org"

This automatically invokes diffoscope, which displays detailed information about files that differ.

Alternatively, we can do something along these lines (veja Invocando guix archive):

$ wget -q -O - https://bordeaux.guix.gnu.org/nar/lzip/…-git-2.5.0 \
   | lzip -d | guix archive -x /tmp/git
$ diff -ur --no-dereference /gnu/store/…-git.2.5.0 /tmp/git

This command shows the difference between the files resulting from the local build, and the files resulting from the build on bordeaux.guix.gnu.org (veja Comparing and Merging Files em Comparing and Merging Files). The diff command works great for text files. When binary files differ, a better option is Diffoscope, a tool that helps visualize differences for all kinds of files.

Once you have done that work, you can tell whether the differences are due to a non-deterministic build process or to a malicious server. We try hard to remove sources of non-determinism in packages to make it easier to verify substitutes, but of course, this is a process that involves not just Guix, but a large part of the free software community. In the meantime, guix challenge is one tool to help address the problem.

If you are writing packages for Guix, you are encouraged to check whether bordeaux.guix.gnu.org and other substitute servers obtain the same build result as you did with:

guix challenge package