Aquelas pessoas que tenham construído um sistema LFS possivelmente estejam cientes dos princípios gerais da transferência e do desempacotamento de software. Alguma daquela informação está repetida aqui para aquelas novatas em construir o próprio software delas.
Cada conjunto de instruções de instalação contém um URL a partir do qual você pode transferir o pacote. Os remendos, no entanto, estão armazenados nos servidores do LFS e estão disponíveis via HTTP. Esses estão referenciados conforme necessários nas instruções de instalação.
Embora possa manter os arquivos do fonte onde quiser, presumimos que você desempacotou o pacote e mudou para o diretório criado pelo processo de desempacotamento (o diretório do fonte). Também presumimos que você descomprimiu quaisquer remendos exigidos e que eles estão no diretório imediatamente acima do diretório do fonte.
        Nós não podemos enfatizar fortemente o suficiente que você deveria
        iniciar a partir de uma árvore limpa do
        fonte a cada vez. Isso significa que, se você tiver tido
        um erro durante a configuração ou a compilação, [então] geralmente é
        melhor deletar a árvore do fonte e desempacotá-la outra vez
        antes de tentar novamente.
        Isso, obviamente, não se aplica se você for um(a) usuário(a)
        avançado(a) habituado(a) a hackear Makefiles e código C; porém, se em dúvida, [então]
        inicie a partir de uma árvore limpa.
      
          A regra de ouro da Administração do Sistema Unix é a de usar os
          seus super poderes somente quando necessário. Assim, o BLFS
          recomenda que você construa software como um(a) usuário(a) não
          privilegiado(a) e somente se torne o(a) usuário(a) root quando instalar o software. Essa filosofia
          é seguida em todos os pacotes neste livro. A menos que especificado
          de outra maneira, todas as instruções deveriam ser executadas como
          um(a) usuário(a) não privilegiado(a). O livro alertará você acerca
          de instruções que precisarem de privilégios do(a) root.
        
          Se um arquivo estiver no formato .tar
          e comprimido, [então] ele é desempacotado executando-se um dos
          seguintes comandos:
        
tar -xvf nome_arquivo.tar.gz tar -xvf nome_arquivo.tgz tar -xvf nome_arquivo.tar.Z tar -xvf nome_arquivo.tar.bz2
          
            Você possivelmente omita o uso do parâmetro v nos comandos mostrados acima e abaixo se você
            desejar suprimir a listagem verbosa de todos os arquivos no
            arquivamento conforme eles forem extraídos. Isso pode ajudar a
            acelerar a extração, bem como torna quaisquer erros produzidos
            durante a extração mais óbvios para você.
          
Você também pode usar um método ligeiramente diferente:
bzcat nome_arquivo.tar.bz2 | tar -xv
          Finalmente, ocasionalmente, temos um arquivo de remendo comprimido
          no formato .patch.gz ou .patch.bz2. A melhor maneira de aplicar o remendo
          é a de canalizar a saída gerada do descompressor para o utilitário
          patch. Por exemplo:
        
gzip -cd ../patchname.patch.gz | patch -p1
Ou para um remendo comprimido com bzip2:
bzcat ../nome_remendo.patch.bz2 | patch -p1
          Geralmente, para se averiguar se o arquivo transferido está
          completo, muitos(as) mantenedores(as) de pacote também distribuem
          somas de verificação md5 dos arquivos. Para averiguar a soma de
          verificação md5 dos arquivos transferidos, transfira ambos, o
          arquivo e o arquivo correspondente de soma de verificação md5, para
          o mesmo diretório (preferencialmente a partir de locais diferentes
          online) e (assumindo que arquivo.md5sum seja o arquivo de soma de
          verificação md5 transferido) execute o seguinte comando:
        
md5sum -c arquivo.md5sum
          Se existirem quaisquer erros, [então] eles serão informados.
          Observe que o livro BLFS inclui somas de verificação md5 para todos
          os arquivos de fonte também. Para usar as somas de verificação md5
          fornecidas pelo BLFS, você pode criar um arquivo.md5sum (coloque os dados da soma de
          verificação md5 e o nome exato do arquivo transferido na mesma
          linha de um arquivo, separados por espaço em branco) e executar o
          comando mostrado acima. Alternativamente, simplesmente execute o
          comando mostrado abaixo e compare a saída gerada para os dados da
          soma de verificação md5 mostrada no livro BLFS.
        
md5sum <nome_do_arquivo_transferido>
        MD5 não é seguro criptograficamente, de forma que as somas de verificação md5 são fornecidas somente para se detectar mudanças não maliciosas para o conteúdo do arquivo. Por exemplo, um erro ou truncamento introduzido durante a transferência de rede de comunicação; ou uma atualização “furtiva” para o pacote oriunda do(a) desenvolvedor(a) (atualizando o conteúdo de um tarball liberado em vez de fazer um lançamento novo adequadamente).
Não existe maneira “100%” segura de garantir a genuinidade dos arquivos do fonte. Assumindo que o(a) desenvolvedor(a) esteja gerenciando corretamente o sítio da web dele(a) (a chave privada não vazou e o domínio não esteja sequestrado); e que as âncoras de confiança tenham sido configuradas corretamente usando make-ca-1.16.1 no sistema BLFS; nós podemos razoavelmente confiar nos URLs de transferência para o sítio oficial da web do(a) desenvolvedor(a) com protocolo https. Observe que o próprio livro BLFS está publicado em um sítio da web com https, de forma que você já deveria ter alguma confiança no protocolo https ou você não confiaria no conteúdo do livro.
Se o pacote for transferido a partir de um local não oficial (por exemplo, um espelho local), [então] as somas de verificação geradas por algoritmos de resumo criptograficamente seguros (por exemplo, SHA256) podem ser usadas para averiguar a genuinidade do pacote. Transfira o arquivo da soma de verificação a partir do sítio da web oficial do(a) desenvolvedor(a) (ou algum lugar que você possa confiar) e compare a soma de verificação do pacote oriunda do local não oficial com ele. Por exemplo, a soma de verificação SHA256 pode ser verificada com o comando:
          Se a soma de verificação e o pacote forem transferidos a partir do mesmo local não confiável, [então] você não ganharia melhoramento de segurança averiguando o pacote com a soma de verificação. O(A) atacante pode falsear a soma de verificação assim como comprometer o próprio pacote.
sha256sum -c arquivo.sha256sum
        Se o GnuPG-2.4.8 estiver instalado, [então] você também pode averiguar a genuinidade do pacote com uma assinatura GPG. Importe a chave pública GPG do(a) desenvolvedor(a) com:
gpg --recv-key ID_da_chave
        
          ID_da_chave deveria ser
          substituído pelo ID da chave oriundo de algum lugar que
          você possa confiar (por
          exemplo, copie-o a partir do sítio da web oficial do(a)
          desenvolvedor(a) usando https). Agora, você consegue averiguar a
          assinatura com:
        
gpg --recv-keyarquivo.sigarquivo
A vantagem da assinatura GnuPG é, tão logo você importou uma chave pública que possa ser confiada, você pode transferir ambos, o pacote e a assinatura dele, a partir do mesmo local não oficial e averiguá-los com a chave pública. Assim, você não precisaria conectar com o sítio da web oficial do(a) desenvolvedor(a) para ir buscar uma soma de verificação para cada lançamento novo. Você somente precisa atualizar a chave pública se ela estiver expirada ou revogada.
          Para pacotes mais largos, é conveniente se criar arquivos de
          registro em vez de olhar fixamente para a tela esperando pegar um
          erro ou aviso em particular. Os arquivos de registro também são
          úteis para depuração e para manter registros. O seguinte comando
          permite a você criar um registro da instalação. Substitua
          <comando> pelo
          comando que você pretende executar.
        
( <comando> 2>&1 | tee compile.log && exit $PIPESTATUS )
        
          2>&1 redireciona as mensagens de
          erro para o mesmo local que a saída gerada padrão. O comando
          tee permite
          visualizar a saída gerada enquanto se registra os resultados em um
          arquivo. Os parênteses em volta do comando executam o comando
          inteiro em um sub shell; e, finalmente, o comando exit $PIPESTATUS garante que o
          resultado do <comando> seja retornado como
          o resultado e não o resultado do comando tee.
        
Para muitos sistemas modernos com múltiplos processadores (ou núcleos) o tempo de compilação para um pacote pode ser reduzido realizando-se um "make paralelo", ou configurando-se uma variável de ambiente, ou dizendo-se ao aplicativo make para simultaneamente executar múltiplas tarefas.
Por exemplo, uma CPU Intel Core i9-13900K contém 8 núcleos de desempenho (P) e 16 núcleos de eficiência (E), e os núcleos P suportam SMT (Simultaneous MultiThreading, também conhecido como “Hyper-Threading”), portanto cada núcleo P pode executar duas camadas simultaneamente e o núcleo Linux tratará cada núcleo P como dois núcleos lógicos. Como resultado, existem 32 núcleos lógicos no total. Para utilizar todos esses núcleos lógicos executando make, nós podemos configurar uma variável de ambiente para dizer ao make para executar 32 tarefas simultaneamente:
export MAKEFLAGS='-j32'
ou apenas construir com:
make -j32
Se você tiver aplicado o sed opcional quando da construção do ninja no LFS, [então] você pode usar:
export NINJAJOBS=32
quando um pacote usar o ninja; ou apenas:
ninja -j32
Se você não tiver certeza acerca do número de núcleos lógicos, execute o comando nproc.
Para make, o número padrão de tarefas é 1. Mas para ninja, o número padrão de tarefas é N + 2, se o número de núcleos lógicos N for maior que 2; ou N + 1 se N for 1 ou 2. A razão para usar um número de tarefas ligeiramente maior que o número de núcleos lógicos é a de manter todos os processadores lógicos ocupados, mesmo se algumas tarefas estiverem realizando operações de E/S.
          Observe que as chaves -j somente
          limitam as tarefas paralelas iniciadas por make ou ninja, mas cada tarefa
          possivelmente ainda gere os próprios processos ou camadas dela. Por
          exemplo, alguns testes de pacotes podem gerar várias camadas para
          testar propriedades de segurança de camadas. Não existe uma maneira
          genérica de o sistema de construção saber o número de processos ou
          camadas gerados por uma tarefa. Portanto, geralmente nós não
          deveríamos considerar o valor passado com -j como um limite rígido do número de núcleos
          lógicos a serem usados. Leia-se “Use
          o Grupo de Controle do Linux para Limitar o Uso de Recursos” se
          você quiser configurar tal limite tão rígido.
        
          Geralmente o número de processos não deveria exceder muito o número
          de elementos de processamento suportados pela CPU. Para listar os
          processadores em teu sistema, emita: grep processor /proc/cpuinfo.
        
Em alguns casos, usar múltiplos processos possivelmente resulte em uma condição de 'corrida' onde o sucesso da construção depende da ordem dos comandos executados pelo aplicativo make. Por exemplo, se um executável precisar do Arquivo A e do Arquivo B, [então] tentar-se vincular o aplicativo antes que um dos componentes dependentes esteja disponível resultará em uma falha. Essa condição geralmente surge, pois o(a) desenvolvedor(a) do aplicativo não designou adequadamente todos os pré requisitos necessários para realizar uma etapa no Makefile.
          Se isso ocorrer, a melhor maneira de se proceder é a de se voltar
          para uma construção de processador único. Adicionar -j1 a um comando make substituirá a configuração
          semelhante na variável de ambiente MAKEFLAGS.
        
          Outro problema possivelmente ocorra com CPUs modernas, as quais tem um monte de núcleos. Cada trabalho iniciado consome memória e, se a soma da memória necessária para cada trabalho exceder da memória disponível, [então] você possivelmente encontre, ou uma interrupção de kernel Out of Memory (OOM), ou troca intensa, que retardará a construção além de limites razoáveis.
Algumas compilações com o g++ possivelmente consumam até 2,5 GB de memória, de forma que, para estar seguro(a), você deveria restringir o número de trabalhos a (Memória Total em GB)/2,5, ao menos para pacotes grandes, tais como o LLVM; o WebKitGtk; o QtWebEngine; ou o Libreoffice.
Às vezes queremos limitar o uso de recursos quando construímos um pacote. Por exemplo, quando temos 8 núcleos lógicos, podemos querer usar somente 6 núcleos para construir o pacote e reservar outros 2 núcleos para reproduzir um filme. O núcleo Linux fornece um recurso chamado grupos de controle (cgroup) para tal necessidade.
Habilite o grupo de controle na configuração do núcleo, em seguida reconstrua o núcleo e reinicialize se necessário:
General setup ---> [*] Control Group support ---> [CGROUPS] [*] Memory controller [MEMCG] [*] Cpuset controller [CPUSETS]
          Certifique-se de que Systemd-257.8 e Shadow-4.18.0
          tenham sido reconstruídos com suporte Linux-PAM-1.7.1 (se você estiver interagindo
          por meio de SSH ou sessão gráfica, certifique-se também de que o
          servidor OpenSSH-10.0p1 ou o gerenciador de área de
          trabalho tenha sido construído com Linux-PAM-1.7.1). Como o(a) usuário(a)
          root, crie um arquivo de
          configuração para permitir o controle de recursos sem o privilégio
          de root e instrua systemd a recarregar a
          configuração:
        
mkdir -pv /etc/systemd/system/user@.service.d &&
cat > /etc/systemd/system/user@.service.d/delegate.conf << EOF &&
[Service]
Delegate=memory cpuset
EOF
systemctl daemon-reload
        Em seguida, deslogue-se e logue-se novamente. Agora, para executar make -j5 com os primeiros 4 núcleos lógicos e 8 GB de memória do sistema, emita:
systemctl   --user start dbus                &&
systemd-run --user --pty --pipe --wait -G -d \
            -p MemoryHigh=8G                 \
            -p AllowedCPUs=0-3               \
            make -j5
        
          Com MemoryHigh=8G, um limite
          flexível de uso de memória está configurado. Se os processos no
          cgroup (make e todos
          os descendentes dele) usarem mais que 8 GB de memória do sistema no
          total, o núcleo irá desacelerar os processos e tentará recuperar a
          memória do sistema proveniente deles. Mas eles ainda podem usar
          mais que 8 GB de memória do sistema. Se você quiser definir um
          limite rígido, substitua MemoryHigh por MemoryMax. Mas fazer isso
          causará a interrupção dos processos se 8 GB não forem suficientes
          para eles.
        
          AllowedCPUs=0-3 faz com que o
          núcleo execute somente os processos no cgroup nos núcleos lógicos
          com números 0, 1, 2 ou 3. Você possivelmente precise ajustar essa
          configuração baseada no mapeamento entre os núcleos lógicos e os
          núcleos físicos. Por exemplo, com uma CPU Intel Core i9-13900K, os
          núcleos lógicos 0, 2, 4, ..., 14 são mapeados para as primeiras
          camadas dos oito núcleos P físicos; os núcleos lógicos 1, 3, 5,
          ..., 15 são mapeados para as segundas camadas dos núcleos P
          físicos; e os núcleos lógicos 16, 17, ..., 31 são mapeados para os
          16 núcleos E físicos. Portanto, se quisermos usar quatro camadas de
          quatro núcleos P, precisamos especificar 0,2,4,6 em vez de 0-3. Observe que os outros modelos de CPU podem
          usar um esquema de mapeamento diferente. Se você não tiver certeza
          acerca do mapeamento entre os núcleos lógicos e os núcleos físicos,
          execute o comando lscpu
          --extended que gerará IDs de núcleo lógico na
          coluna CPU e IDs de núcleo
          físico na coluna CORE.
        
          Quando o comando nproc ou ninja executa em um cgroup, ele
          usará o número de núcleos lógicos atribuídos para o cgroup como a
          “contagem de núcleos
          lógicos do sistema”. Por exemplo, em um cgroup com
          núcleos lógicos 0-3 atribuídos, nproc imprimirá 4 e ninja executará 6 (4 + 2) tarefas
          simultaneamente se nenhuma configuração -j for fornecida explicitamente.
        
Leiam-se as páginas de manual systemd-run(1) e systemd.resource-control(5) para a explicação detalhada dos parâmetros no comando.
          Existem ocasiões onde automatizar a construção de um pacote pode
          vir a calhar. Todo mundo tem razões próprias para querer
          automatizar a construção e todo mundo faz isso de maneira própria.
          Criar Makefiles; scripts do
          Bash; scripts do Perl; ou, simplesmente, uma lista de comandos
          usados para recortar e colar, são apenas alguns dos métodos que
          você pode usar para automatizar a construção de pacotes do BLFS.
          Detalhar como e fornecer exemplos das muitas maneiras que você pode
          automatizar a construção de pacotes está além do escopo desta
          seção. Esta seção exporá você ao uso do redirecionamento de arquivo
          e do comando yes para
          ajudar a fornecer ideias acerca do como automatizar suas
          construções.
        
Você achará ocasiões ao longo da sua jornada BLFS quando você se deparará com um pacote que tenha um comando solicitando informação. Essa informação poderia ser detalhes de configuração; um caminho de diretório; ou uma resposta a um acordo de licença. Isso pode apresentar um desafio para automatizar a construção desse pacote. Ocasionalmente, você será consultado(a) para diferentes informações em uma série de perguntas. Um método para automatizar esse tipo de cenário exige colocar as respostas desejadas em um arquivo e usar redirecionamento, de forma que o aplicativo use os dados no arquivo como as respostas para as perguntas.
Isso, efetivamente, faz com que a suíte de teste use as respostas no arquivo como a entrada gerada para as perguntas. Ocasionalmente você possivelmente termine fazendo um bocado de tentativa e erro para determinar o formato exato do seu arquivo de entrada gerada para algumas coisas, porém, tão logo determinado e documentado, você consegue usar isso para automatizar a construção do pacote.
Ocasionalmente você somente precisará fornecer uma resposta ou fornecer a mesma resposta para muitas solicitações. Para tais instâncias, o comando yes funciona realmente bem. O comando yes pode ser usado para fornecer uma resposta (a mesma) para uma ou mais instâncias de perguntas. Ele pode ser usado para simular o pressionamento apenas da tecla Enter; informar a tecla Y; ou informar uma sequência de caracteres de texto. Talvez a maneira mais fácil de mostrar o uso dele é em um exemplo.
Primeiro, crie um script curto do Bash informando os seguintes comandos:
cat > blfs-yes-test1 << "EOF"
#!/bin/bash
echo -n -e "\n\nPor favor, digite algo (ou nada) e pressione Enter ---> "
read A_STRING
if test "$A_STRING" = ""; then A_STRING="Apenas a tecla Enter foi pressionada"
else A_STRING="Você informou '$A_STRING'"
fi
echo -e "\n\n$A_STRING\n\n"
EOF
chmod 755 blfs-yes-test1
        Agora execute o script emitindo ./blfs-yes-test1 a partir da linha de comando. Ele aguardará por uma resposta, que pode ser algo (ou nada) seguida pela tecla Enter. Depois de informar alguma coisa, o resultado será ecoado para a tela. Agora use o comando yes para automatizar a entrada de uma resposta:
yes | ./blfs-yes-test1
Perceba que canalizar o próprio yes para o script resulta em y sendo passada para o script. Agora tente com uma sequência de caracteres de texto:
yes 'Este é algum texto' | ./blfs-yes-test1
A sequência exata de caracteres foi usada como a resposta para o script. Finalmente, tente usando uma sequência de caracteres vazia (nula):
yes '' | ./blfs-yes-test1
Perceba que isso resulta na passagem apenas do pressionamento da tecla Enter para o script. Isso é útil para ocasiões quando a resposta padrão para a solicitação for suficiente. Essa sintaxe é usada nas instruções do Net-tools para aceitar todos os padrões para as muitas solicitações durante a etapa de configuração. Você possivelmente agora remova o script de teste, se desejado.
Para a finalidade de automatizar a construção de alguns pacotes, especialmente aqueles que exigem que você leia um acordo de licença em uma página por vez, exige-se usar um método que evite ter que pressionar uma tecla para exibir cada página. Redirecionar a saída gerada para um arquivo pode ser usado nessas instâncias para auxiliar com a automação. A seção anterior nesta página tocou na criação de arquivos de registro da saída gerada da construção. O método de redirecionamento mostrado lá usou o comando tee para redirecionar a saída gerada para um arquivo enquanto também exibia a saída gerada na tela. Aqui, a saída gerada somente será enviada para um arquivo.
Novamente, a maneira mais fácil para demonstrar a técnica é de mostrar um exemplo. Primeiro, emita o comando:
ls -l /usr/bin | less
          Certamente, você será exigido(a) a visualizar a saída gerada uma
          página por vez, pois o filtro less foi usado. Agora tente o
          mesmo comando, porém, dessa vez, redirecione a saída gerada para um
          arquivo. O arquivo especial /dev/null
          pode ser usado em vez do nome de arquivo mostrado, porém você não
          terá arquivo de registro para examinar:
        
ls -l /usr/bin | less > redirect_test.log 2>&1
Perceba que, dessa vez, o comando imediatamente retornou ao prompt do shell sem ter que paginar ao longo da saída gerada. Você agora possivelmente remova o arquivo de registro.
          O último exemplo usará o comando yes em combinação com o
          redirecionamento da saída gerada para desviar-se de ter que paginar
          ao longo da saída gerada e, então, fornecerá um y para uma solicitação. Essa
          técnica poderia ser usada em instâncias quando, de outra maneira,
          você teria que paginar ao longo da saída gerada de um arquivo (como
          um acordo de licença) e, então, responder à pergunta de
          você aceita o acima?. Para esse
          exemplo, outro conjunto curto de comandos sequenciais do
          Bash é exigido:
        
cat > blfs-yes-test2 << "EOF"
#!/bin/bash
ls -l /usr/bin | less
echo -n -e "\n\nVocê curtiu ler isso? (y,n) "
read A_STRING
if test "$A_STRING" = "y"; then A_STRING="Você informou a tecla 'y'"
else A_STRING="Você NÃO informou a tecla 'y'"
fi
echo -e "\n\n$A_STRING\n\n"
EOF
chmod 755 blfs-yes-test2
        Esse script pode ser usado para simular um aplicativo que exige que você leia um acordo de licença, então responda apropriadamente que aceita o acordo antes do aplicativo instalar qualquer coisa. Primeiro, execute o script sem quaisquer técnicas de automação emitindo ./blfs-yes-test2.
Agora emita o seguinte comando que usa duas técnicas de automação, tornando-o adequado para uso em um script automatizado de construção:
yes | ./blfs-yes-test2 > blfs-yes-test2.log 2>&1
Se desejado, emita tail blfs-yes-test2.log para ver o final da saída gerada paginada e a confirmação de que y foi passada ao longo para o script. Tão logo satisfeito que ele funciona como deveria, você possivelmente remova o script e o arquivo de registro.
Finalmente, tenha em mente que existem muitas maneiras de automatizar e (ou) roteirizar os comandos de construção. Não existe maneira única “correta” para fazê-lo. Sua imaginação é o único limite.
Para cada pacote descrito, o BLFS lista as dependências conhecidas. Essas são listadas sob vários títulos, cujo significado é como segue:
Exigida significa que o pacote alvo não pode ser construído corretamente sem que a dependência tenha sido instalada primeiro, exceto se a dependência for considerada de “tempo de execução”, o que significa que o pacote alvo pode ser construído, mas não pode funcionar sem ela.
Observe que um pacote alvo pode começar a “funcionar” de muitas maneiras sutis: um arquivo de configuração instalado pode fazer o sistema init, o processo de segundo plano cron ou o processo de segundo plano de barramento executar um aplicativo automaticamente; outro pacote usando o pacote alvo como dependência pode executar um aplicativo oriundo do pacote alvo no sistema de construção; e as seções de configuração no livro BLFS também podem executar um aplicativo a partir de um pacote recém-instalado. Portanto, se estiver instalando o pacote alvo sem uma dependência Exigida (tempo de execução) instalada, você deveria instalar a dependência o mais rápido possível depois da instalação do pacote alvo.
Recomendada significa que o BLFS sugere fortemente que esse pacote seja instalado primeiro (exceto se for dito ser “tempo de execução,” veja-se abaixo) para uma construção limpa e sem problemas, que não terá problemas nem durante o processo de construção nem em tempo de execução. As instruções no livro pressupõem que esses pacotes estejam instalados. Em muitos casos, se uma dependência recomendada (não apenas “tempo de execução”) não estiver instalada, o pacote construído pode carecer algumas funcionalidades importantes (por exemplo, um reprodutor de vídeo pode reproduzir somente áudio). Às vezes, é necessário modificar as instruções do livro para desabilitar essas funcionalidades importantes. Em outros casos, o sistema de construção do pacote pode construir uma cópia da dependência (frequentemente desatualizada e às vezes com vulnerabilidades conhecidas de segurança) enviada na árvore do fonte ou pode ser baixada da a partir da Internet durante o processo de construção. Isso aumenta o tempo de construção e o uso do disco. Isso poderia causar outros problemas. Se uma dependência recomendada for “tempo de execução,” isso significa que o BLFS sugere fortemente que essa dependência seja instalada antes de usar o pacote, para obter funcionalidade completa.
Opcional significa que esse pacote pode ser instalado para funcionalidade adicional. Frequentemente, o BLFS descreverá a dependência para explicar a funcionalidade adicional que resultará. Algumas dependências opcionais são automaticamente selecionadas pelo pacote alvo se a dependência estiver instalada, enquanto outras também precisam de opções de configuração adicionais para serem habilitadas quando o pacote alvo for construído. Essas opções adicionais frequentemente estão documentadas no livro BLFS. Se uma dependência opcional for dita como “tempo de execução”, significa que você pode instalar a dependência depois de instalar o pacote alvo para suportar alguns recursos opcionais do pacote alvo se precisar desses recursos.
Uma dependência opcional possivelmente esteja fora do BLFS. Se precisar de tal dependência opcional externa para alguns recursos que você queira, leia Indo Além do BLFS para as dicas gerais acerca de instalar um pacote fora do BLFS. Observe que os(as) editores(as) do BLFS geralmente não testam uma configuração com pacotes externos; portanto, não existe absolutamente nenhuma garantia de qualidade para as dependências externas listadas no livro. A lista de dependências externas possivelmente esteja incompleta ou contenha algum item redundante. No pior caso, a mera existência de uma dependência externa no sistema pode deflagrar um defeito no pacote, causando uma falha de construção ou de tempo de execução.
Ocasionalmente você possivelmente se encontre em uma situação no livro onde um pacote não construirá ou não funcionará adequadamente. Apesar dos(as) Editores(as) tentarem garantir que cada pacote no livro construa e funcione adequadamente, ocasionalmente um pacote tenha sido negligenciado ou não foi testado com esta versão particular do BLFS.
Se você descobrir que um pacote não construirá ou não funcionará adequadamente, [então] você deveria ver se existe uma versão mais recente do pacote. Tipicamente isso significa você ir ao sítio da web do(a) mantenedor(a) e transferir o tarball mais recente e tentar construir o pacote. Se você não conseguir determinar o sítio da web do(a) mantenedor(a) olhando para os URLs de transferência, [então] use o Google e consulte o nome do pacote. Por exemplo, na barra de pesquisa do Google, digite: 'nome_do_pacote download' (omita as aspas) ou algo semelhante. Ocasionalmente, digitar: 'nome_do_pacote home page' resultará em você encontrar o sítio da web do(a) mantenedor(a).
No LFS, despojamento de símbolos de depuração foi discutido algumas vezes. Ao construir pacotes do BLFS, geralmente não existem instruções especiais que discutam despojamento novamente. Despojamento pode ser feito enquanto se instala um pacote ou posteriormente.
Existem várias maneiras de se despojar executáveis instalados por um pacote. Elas dependem do sistema de construção usado (veja-se abaixo a seção acerca de sistemas de construção), de modo que somente algumas generalidades podem ser listadas aqui:
          Os métodos a seguir que usam o recurso de um sistema de construção ("autotools", "meson" ou "cmake") não despojarão bibliotecas estáticas, se alguma estiver instalada. Felizmente não existem muitas bibliotecas estáticas no BLFS, e uma biblioteca estática sempre pode ser despojada com segurança executando strip --strip-unneeded nela manualmente.
                Os pacotes que usam "Autotools" geralmente tem um alvo
                install-strip nos
                arquivos Makefile gerados
                deles. Portanto, instalar executáveis despojados é apenas uma
                questão de usar make
                install-strip em vez de make install.
              
                Os pacotes que usam o sistema de construção do meson
                conseguem aceitar -D
                strip=true ao executar meson. Se tiver esquecido
                de adicionar essa opção executando o meson, você também consegue
                executar meson install
                --strip em vez de ninja install.
              
                cmake gera
                alvos install/strip
                para ambos os geradores Unix
                Makefiles e Ninja (o padrão é Unix Makefiles no Linux).
                Portanto, basta executar make
                install/strip ou ninja install/strip em vez
                das contrapartes install.
              
                A remoção (ou não geração) de símbolos de depuração também
                consegue ser obtida removendo-se as opções -g<alguma_coisa> em
                chamadas "C/C++". Como fazer isso é muito específico para
                cada pacote. E não remove entradas desnecessárias da tabela
                de símbolos. Portanto, não será explicado em detalhes aqui.
                Veja-se também abaixo os parágrafos acerca de otimização.
              
          O utilitário strip
          muda arquivos no local, o que possivelmente quebre alguma coisa que
          os usem se estiverem carregados na memória. Observe que se um
          arquivo estiver em uso, mas recém removido do disco (ou seja, não
          sobrescrito nem modificado), isso não será um problema, pois o
          núcleo consegue usar arquivos “deletados”. Veja-se /proc/*/maps e é provável que você veja algumas
          entradas (deleted). O
          mv apenas remove o
          arquivo de destino a partir do diretório, mas não toca no conteúdo
          dele, de modo que satisfaça a condição para o núcleo usar o arquivo
          antigo (deletado). Porém, essa abordagem pode desanexar links
          rígidos em cópias duplicadas, causando um inchaço que, obviamente,
          é indesejado, pois estamos despojando para reduzir o tamanho do
          sistema. Se dois arquivos em um mesmo sistema de arquivos
          compartilharem o mesmo número de inode, eles serão links rígidos
          entre eles e deveríamos reconstruir o link. O conjunto de comandos
          sequenciais abaixo é apenas um exemplo. Ele deveria ser executado
          como o(a) usuário(a) root:
        
cat > /usr/sbin/strip-all.sh << "EOF"
#!/usr/bin/bash
if [ $EUID -ne 0 ]; then
  echo "Need to be root"
  exit 1
fi
last_fs_inode=
last_file=
{ find /usr/lib -type f -name '*.so*' ! -name '*dbg'
  find /usr/lib -type f -name '*.a'
  find /usr/{bin,sbin,libexec} -type f
} | xargs stat -c '%m %i %n' | sort | while read fs inode file; do
       if ! readelf -h $file >/dev/null 2>&1; then continue; fi
       if file $file | grep --quiet --invert-match 'not stripped'; then continue; fi
       if [ "$fs $inode" = "$last_fs_inode" ]; then
         ln -f $last_file $file;
         continue;
       fi
       cp --preserve $file ${file}.tmp
       strip --strip-debug ${file}.tmp
       mv ${file}.tmp $file
       last_fs_inode="$fs $inode"
       last_file=$file
done
EOF
chmod 744 /usr/sbin/strip-all.sh
        
          Se você instalar aplicativos em outros diretórios, como
          /opt ou /usr/local, você possivelmente queira despojar os
          arquivos lá também . Basta adicionar outros diretórios a escanear
          na lista composta de comandos find entre chaves.
        
Para mais informações acerca de despojamento, veja-se https://www.technovelty.org/linux/stripping-shared-libraries.html.
          Existem, agora, três sistemas de construção em uso comum para
          converter código fonte C ou C++ em aplicativos ou bibliotecas
          compilados e os detalhes deles (particularmente, descobrir acerca
          de opções disponíveis e os valores padrão delas) diferem.
          Possivelmente seja mais fácil entender os problemas causados por
          algumas escolhas (tipicamente, execução lenta; ou uso inesperado
          de, ou omissão de, otimizações) iniciando-se com as variáveis de
          ambiente CFLAGS, CXXFLAGS e LDFLAGS.
          Também existem alguns aplicativos que usam Rust.
        
          A maioria dos(as) construtores(as) do LFS e do BLFS provavelmente
          está ciente dos básicos de CFLAGS e
          CXXFLAGS para alterar como um aplicativo
          é compilado. Tipicamente, alguma forma de otimização é usada
          pelos(as) desenvolvedores(as) de aplicativos (-O2 ou -O3),
          ocasionalmente com a criação de símbolos de depuração (-g), como padrões.
        
          Se existirem sinalizadores contraditórios (por exemplo, múltiplos
          valores -O), o último valor será usado. Ocasionalmente,
          isso significa que os sinalizadores especificados em variáveis de
          ambiente serão escolhidos antes dos valores codificados rigidamente
          no Makefile, e, portanto, ignorados. Por exemplo, onde um(a)
          usuário(a) especificar -O2 e isso for
          seguido por -O3, a construção usará
          -O3.
        
          Existem várias outras coisas que podem ser passadas em CFLAGS ou em
          CXXFLAGS, tais como permitir-se usar as extensões de conjunto de
          instruções disponíveis com uma microarquitetura específica (por
          exemplo, -march=amdfam10 ou
          -march=native) ajustar o código gerado
          para uma microarquitetura específica (por exemplo, -mtune=tigerlake ou -mtune=native; se -mtune= não for usada, a microarquitetura oriunda
          da configuração -march= será usada) ou
          especificar-se um padrão específico para C ou C++ (-std=c++17, por exemplo). Porém, uma coisa que
          agora veio à tona é que os(as) programadores(as) poderiam incluir
          asserções de depuração no código deles(as), esperando que sejam
          desabilitadas em lançamentos usando-se -D
          NDEBUG. Especificamente, se o Mesa-25.1.8 for construído
          com essas asserções habilitadas, algumas atividades, tais como o
          carregamento de níveis dos jogos, podem tomar tempos extremamente
          longos, mesmo em placas de vídeo de alta qualidade.
        
Essa combinação frequentemente é descrita como “CMMI” (configure; make; make install) e é usada aqui também para cobrir os poucos pacotes que tenham um conjunto de comandos sequenciais de configuração que não seja gerado por autotools.
Ocasionalmente, executar-se ./configure --help produzirá opções úteis acerca de chaves que poderiam ser usadas. Em outras ocasiões, depois de olhar para a saída gerada a partir do configure, você possivelmente precise olhar para os detalhes do script para descobrir pelo que ele estava procurando atualmente.
Muitos scripts de configuração escolherão quaisquer CFLAGS ou CXXFLAGS a partir do ambiente, porém os pacotes CMMI variam acerca do como esses serão misturados com quaisquer sinalizadores que, de outra maneira, seriam usados (variadamente: ignorados; usados para substituir a sugestão do(a) programador(a); usados antes da sugestão do(a) programador(a); ou usados depois da sugestão do(a) programador(a)).
          Na maioria dos pacotes CMMI, executar-se make listará cada comando e o
          executará, intercalado com quaisquer avisos. Porém, alguns pacotes
          tentam ser “silenciosos” e mostram somente qual arquivo
          eles estão compilando ou vinculando em vez de mostrar a linha de
          comando. Se você precisar inspecionar o comando, seja por causa de
          um erro, seja apenas para ver quais opções e sinalizadores estão
          sendo usados, adicionar V=1 à invocação
          do make possivelmente ajude.
        
          O CMake funciona de uma maneira muito diferente e ele tem duas
          estruturas de retaguarda que conseguem ser usadas no BLFS:
          make e ninja. A estrutura de retaguarda
          padrão é o make, porém o ninja pode ser mais rápido sobre pacotes
          grandes com múltiplos processadores. Para usar o ninja, especifique
          -G Ninja no comando cmake. Entretanto,
          existem alguns pacotes que criam erros fatais nos arquivos ninja
          deles, porém constroem com sucesso usando o padrão dos Makefiles do
          Unix.
        
A parte mais difícil do usar-se o CMake é saber quais opções você poderia desejar especificar. A única maneira de se obter uma lista do que o pacote conhece é a de executar cmake -LAH e olhar para a saída gerada para esta configuração padrão.
          Talvez a coisa mais importante acerca do CMake é que ele tem uma
          variedade de valores CMAKE_BUILD_TYPE e esses afetam os
          sinalizadores. O padrão é o de que isso não seja configurado e
          nenhum sinalizador seja gerado. Quaisquer CFLAGS ou CXXFLAGS no
          ambiente serão usadas. Se o(a) programador(a) tiver codificado
          quaisquer asserções de depuração, essas estarão habilitadas, a
          menos que -D NDEBUG seja usado. Os seguintes valores
          CMAKE_BUILD_TYPE gerarão os sinalizadores mostrados e esses virão
          depois de quaisquer
          sinalizadores no ambiente e, portanto, terão precedência.
        
| Valor | Sinalizadores | 
|---|---|
| Debug | 
                  -g
                 | 
              
| Release | 
                  -O3 -D NDEBUG
                 | 
              
| RelWithDebInfo | 
                  -O2 -g -D NDEBUG
                 | 
              
| MinSizeRel | 
                  -Os -D NDEBUG
                 | 
              
O "CMake" tenta produzir construções silenciosas. Para ver os detalhes dos comandos que estão sendo executados, use make VERBOSE=1 ou ninja -v.
          Por padrão, o "CMake" trata a instalação de arquivos diferentemente
          dos outros sistemas de construção: se um arquivo já existir e não
          for mais recente que um arquivo que o sobrescreveria, então o
          arquivo não será instalado. Isso possivelmente seja um problema se
          um(a) usuário(a) quiser registrar qual arquivo pertence a um
          pacote, seja usando LD_PRELOAD, ou
          listando arquivos mais recentes que um carimbo de tempo. O padrão
          pode ser mudado definindo-se a variável CMAKE_INSTALL_ALWAYS como um ("1") no ambiente, por exemplo, via export.
        
          O Meson tem algumas semelhanças com o CMake, porém muitas
          diferenças. Para obter os detalhes das definições que você
          possivelmente queira mudar, você pode olhar para o meson_options.txt que normalmente está no
          diretório de nível de topo.
        
Se você já configurou o pacote executando o meson e, agora, deseja mudar uma ou mais configurações, [então] você ou pode remover o diretório de construção, recriá-lo e usar as opções alteradas; ou, dentro do diretório de construção, executar meson configure, por exemplo, para configurar uma opção:
meson configure -D <some_option>=true
          Se você fizer isso, [então] o arquivo meson-private/cmd_line.txt mostrará os
          últimos comandos que foram
          usados.
        
O Meson fornece os seguintes valores de tipo de construção e os sinalizadores que eles habilitam vem depois de quaisquer sinalizadores fornecidos no ambiente e, portanto, tem precedência.
                simples: nenhum sinalizador adicionado. Isso é para os(as)
                distribuidores(as) fornecerem os próprios CFLAGS, CXXFLAGS e
                LDFLAGS deles(as). Não existe
                razão óbvia para usar isso no BLFS.
              
                depuração: -g - isso é o padrão,
                se nada for especificado, seja no meson.build, seja na linha de comando.
                Entretanto, resulta em binários grandes e lentos, de forma
                que nós deveríamos substitui-lo no BLFS.
              
                depuração otimizada: -O2 -g :
                isso é o padrão, especificado no meson.build, de alguns pacotes.
              
                lançamento: -O3 (ocasionalmente
                um pacote forçará -O2 aqui) -
                esse é o tipo de construção que usamos para a maioria dos
                pacotes com sistema de construção Meson no BLFS.
              
          O sinalizador -D NDEBUG está implícito
          pelo tipo de construção de lançamento para alguns pacotes (por
          exemplo Mesa-25.1.8). Também pode ser fornecido
          explicitamente passando-se -D
          b_ndebug=true.
        
Para ver os detalhes dos comandos que estão sendo executados em um pacote usando o meson, use ninja -v.
          A maioria dos aplicativos rustc lançados é fornecida como engradado
          (tarballs de fonte), que consultarão um servidor para verificar as
          versões atuais de dependências e, então, as baixarão conforme
          necessário. Esses pacotes são construídos usando-se cargo --release. Na teoria, você
          consegue manipular a RUSTFLAGS para mudar o nível de otimização
          (padrão para --release é 3, isto é,
          -Copt-level=3, semelhante a
          -03) ou para forçá-lo a construir para
          a máquina na qual está sendo compilado, usando -Ctarget-cpu=native; porém, na prática, isso parece
          não fazer uma diferença significante.
        
          Se você estiver compilando um programa Rust independente (como um
          arquivo .rs desempacotado) executando
          rustc diretamente,
          você deveria especificar -O (a
          abreviatura de -Copt-level=2) ou
          -Copt-level=3, caso contrário ele fará
          uma compilação não otimizada e executará muito mais lento. Se estiver compilando
          o programa para depurá-lo, substitua as opções -O ou -Copt-level= por
          -g para produzir um programa não
          otimizado com informações de depuração.
        
          Semelhante ao ninja,
          por padrão cargo usa
          todos os núcleos lógicos. Isso frequentemente pode ser contornado,
          seja exportando-se CARGO_BUILD_JOBS= seja passando-se
          <N>--jobs  para cargo. Para compilar o próprio
          rustc, especificar-se <N>--jobs  para invocações do
          x.py (juntamente com
          a variável de ambiente <N>CARGO_BUILD_JOBS=, que se parece com uma abordagem
          “cinto e
          suspensórios”, porém parece ser necessária) funciona
          na maioria. A exceção é a de executar-se os testes quando
          construir-se o rustc; alguns deles, ainda assim, usarão todas as
          CPUs online, pelo menos desde o rustc-1.42.0.
        
          Muitas pessoas preferirão otimizar compilações como acharem melhor,
          fornecendo CFLAGS ou CXXFLAGS. Para uma introdução às opções disponíveis
          com o gcc e com o g++, veja-se 
          https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gcc/Optimize-Options.html.
          O mesmo conteúdo também pode ser encontrado em info gcc.
        
          Alguns pacotes são padronizados como -O2
          -g, outros como -O3 -g, e se
          CFLAGS ou CXXFLAGS forem fornecidas, elas podem ser
          adicionadas aos padrões do pacote, substituir os padrões do pacote
          ou até mesmo serem ignoradas. Existem detalhes acerca de alguns
          pacotes de área de trabalho que estavam mais atualizados em abril
          de 2019 em https://www.linuxfromscratch.org/~ken/tuning/
          - em particular, README.txt,
          tuning-1-packages-and-notes.txt e
          tuning-notes-2B.txt. A coisa
          específica a lembrar é que se quiser experimentar alguns dos
          sinalizadores mais interessantes, você possivelmente precise forçar
          construções detalhadas para confirmar o que está sendo usado.
        
          Claramente, se estiver otimizando teu próprio aplicativo, você pode
          gastar tempo para perfilá-lo e, talvez, recodificar algo dele, se
          ele estiver lento demais. Porém, para construir um sistema inteiro,
          essa abordagem é impraticável. No geral, -O3 geralmente produz aplicativos mais rápidos que
          -O2. Especificar-se -march=native também é benéfico, porém significa
          que você não pode mover os binários para uma máquina incompatível -
          isso também pode se aplicar a máquinas mais novas, não apenas às
          máquinas mais antigas. Por exemplo, os aplicativos compilados para
          amdfam10 executam em Phenoms antigos;
          Kaveris; e Ryzens; porém, os aplicativos compilados para um Kaveri
          não executarão em um Ryzen, pois certos códigos de operação não
          estão presentes. Similarmente, se você construir para um Haswell,
          nem tudo executará em um SandyBridge.
        
          
            Atente-se que o nome de uma configuração -march nem sempre corresponde à linha de base da
            microarquitetura com o mesmo nome. Por exemplo, os processadores
            Intel Celeron baseados em Skylake não suportam AVX, mas
            -march=skylake assume AVX e até mesmo
            AVX2.
          
          Quando uma biblioteca compartilhada é construída pelo GCC, um
          recurso chamado “interposição semântica” é habilitado por
          padrão. Quando a biblioteca compartilhada se refere a um nome de
          símbolo com ligação externa e visibilidade padrão, se o símbolo
          existir tanto na biblioteca compartilhada quanto no executável
          principal, a interposição semântica garante que o símbolo no
          executável principal sempre seja usado. Esse recurso foi inventado
          na tentativa de tornar o comportamento de vincular uma biblioteca
          compartilhada e vincular uma biblioteca estática o mais semelhante
          possível. Hoje, somente um pequeno número de pacotes ainda depende
          da interposição semântica, mas o recurso ainda está ativado por
          padrão do GCC, fazendo com que muitas otimizações sejam
          desabilitadas para bibliotecas compartilhadas porque entram em
          conflito com a interposição semântica. A opção -fno-semantic-interposition pode ser passada para
          gcc ou g++ para desabilitar a
          interposição semântica e habilitar mais otimizações para
          bibliotecas compartilhadas. Essa opção é usada como padrão de
          alguns pacotes (por exemplo Python-3.13.7)
          e também é o padrão do Clang.
        
Existem também várias outras opções que algumas pessoas alegam que são benéficas. Na pior das hipóteses, você consegue recompilar e testar e, então, descobrir que, em seu uso, as opções não fornecem um benefício.
          Se construir módulos Perl ou Python, em geral as CFLAGS e CXXFLAGS usadas
          são aquelas que foram usadas por esses pacotes “ancestrais”.
        
          Para LDFLAGS, três opções podem ser
          usadas para otimização. Elas são bastante seguras de usar e o
          sistema de construção de alguns pacotes usa algumas dessas opções
          como padrão.
        
          Com -Wl,-O1, o vinculador otimizará a
          tabela de resumo para acelerar a vinculação dinâmica. Observe que
          -Wl,-O1 não tem nenhuma relação com o
          sinalizador de otimização do compilador -O1.
        
          Com -Wl,--as-needed, o vinculador
          desconsiderará opções -l desnecessárias da linha
          de comando, ou seja, a biblioteca compartilhada foolib só será vinculada se um
          símbolo em foolib realmente estiver
          referenciado pelo executável ou biblioteca compartilhada sendo
          vinculado. Às vezes, isso pode atenuar os problemas de “dependências excessivas de bibliotecas
          compartilhadas” causados pela libtool.
        foo
          Com -Wl,-z,pack-relative-relocs, o
          vinculador gera uma forma mais compactada das entradas relativas de
          realocação para PIEs e bibliotecas compartilhadas. Ele reduz o
          tamanho do PIE vinculado ou da biblioteca compartilhada e acelera o
          carregamento do PIE ou da biblioteca compartilhada.
        
          O prefixo -Wl, é necessário porque,
          apesar da variável ser chamada LDFLAGS,
          o conteúdo dela é na verdade passado para o gcc (ou g++, clang, etc.) durante o estágio de
          ligação, não passado diretamente para o ld.
        
Mesmo em sistemas de área de trabalho, existe ainda um monte de vulnerabilidades exploráveis. Para muitas dessas, o ataque vem via javascript em um navegador. Frequentemente, uma série de vulnerabilidades é usada para ganhar acesso a dados (ou, às vezes, para pwn, isto é, dominar, a máquina e instalar rootkits). A maioria das distribuições comerciais aplicará várias medidas de fortalecimento.
          No passado, existia o LFS Reforçado, onde o gcc (uma versão muito
          mais antiga) era forçado a usar o reforçamento (com opções para
          desativar parte dele na base do por pacote). Os livros atuais do
          LFS e BLFS estão levando adiante uma parte do espírito dele ao
          habilitar PIE (-fPIE -pie) e SSP
          (-fstack-protector-strong) como padrões
          para GCC e clang. E o lincador (ld) também habilitou -Wl,-z,relro, o que torna uma parte da Global
          Offset Table (GOT) imutável, por padrão desde Binutils 2.27. O que
          está sendo coberto aqui é diferente - primeiro você tem que ter
          certeza de que o pacote está realmente usando teus sinalizadores
          adicionados e não os substituindo.
        
          Para opções de reforço que são razoavelmente baratas, existe alguma
          discussão no link "ajuste" acima (ocasionalmente, uma ou mais
          dessas opções podem ser inadequadas para um pacote). Essas opções
          são -D _FORTIFY_SOURCE=2 (ou
          -D _FORTIFY_SOURCE=3 que é mais seguro,
          mas com maior sobrecarga de desempenho) e (para C++) -D _GLIBCXX_ASSERTIONS. Nas máquinas modernas, isso
          deveria ter somente um pequeno impacto na rapidez com que as coisas
          executam e, muitas vezes, não serão perceptíveis.
        
As principais distribuições usam muito mais, como:
                -Wl,-z,now: desabilita vinculação
                preguiçosa para aprimorar -Wl,-z,relro, de forma que todo o GOT possa se tornar
                imutável.
              
                -fstack-clash-protection: impede
                o(a) atacante de usar um deslocamento grande o suficiente e
                não verificado adequadamente para pular a página de proteção
                de pilha colocada pelo núcleo e o canário de pilha colocado
                por -fstack-protector=strong, e
                modificar a pilha a partir de um endereço de pilha, ou
                vice-versa.
              
                -ftrivial-auto-var-init=zero:
                inicializa algumas variáveis preenchendo zero bytes se elas
                não forem inicializadas por outros meios.
              
                -fcf-protection=full: utiliza a
                tecnologia CET da Intel e da AMD para limitar os endereços
                alvo das instruções de transferência de fluxo de controle.
                Para torná-lo realmente eficaz para um pacote, todos os
                pacotes que fornecem uma biblioteca compartilhada para o
                pacote usar precisam ser construídos com essa opção, bem como
                o próprio pacote, a Glibc precisa ser configurada com a opção
                --enable-cet habilitada, e o
                sistema precisa executar no Intel Tiger Lake ou mais recente,
                ou no AMD Zen 3 ou mais recente. Se o critério não for
                atendido, o programa compilado com essa opção ainda
                executará, mas não realmente protegido pelo CET.
              
          No GCC 14, a opção -fhardened é uma
          abreviação para habilitar todas as opções de reforçamento
          mencionadas acima. Ela configura -D
          _FORTIFY_SOURCE=3 em vez de -D
          _FORTIFY_SOURCE=2.
        
          Você também pode encontrar o assim chamado “retpoline de espaço de
          usuário(a)” (-mindirect-branch=thunk etc.), que é o equivalente
          das mitigações de espectro aplicadas para o núcleo Linux no final
          de 2018. As mitigações do núcleo causaram muitas reclamações acerca
          da perda de desempenho. Se tiver um servidor de produção, você pode
          desejar considerar testar isso, junto com as outras opções
          disponíveis, para ver se o desempenho ainda é suficiente.
        
Embora o gcc tenha muitas opções de fortalecimento, os pontos fortes do clang/LLVM estão em outro lugar. Algumas opções que o gcc fornece são ditas serem menos efetivas no clang/LLVM.