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.
Enquanto você pode manter os arquivos do fonte em qualquer lugar que queira, nós assumimos que você desempacotou o pacote e mudou para o diretório criado pelo processo de desempacotamento (o diretório de 'construção'). Nós assumimos também que você descomprimiu quaisquer remendos exigidos e que eles estão no diretório imediatamente acima do diretório de 'construção'.
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 Makefile
s 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, você precisa estar apto(a) a
desempacotar remendos que geralmente não estão no formato
.tar
. A melhor maneira de fazer isso
é a de copiar o arquivo do remendo para o ancestral do diretório da
'construção' e, então, executar um dos seguintes comandos,
dependendo se o arquivo for um arquivo .gz
ou um .bz2
:
gunzip -v nome_remendo.gz bunzip2 -v nome_remendo.bz2
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.12 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.0 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 quantos processadores estão disponíveis. Por exemplo, um Core2Duo pode suportar dois processos simultâneos com:
export MAKEFLAGS='-j2'
ou apenas construir com:
make -j2
Se você tiver aplicado o sed opcional quando da construção do ninja no LFS, [então] você pode usar:
export NINJAJOBS=2
quando um pacote usar o ninja; ou apenas:
ninja -j2
porém, para o ninja, o número padrão de trabalhos é <N>+2, onde <N> é o número de processadores disponíveis, de forma que usar os comandos acima é preferencialmente para limitar o número de trabalhos (veja-se abaixo para o porque isso poderia ser necessário).
Geralmente o número de processos não deveria exceder o número de
núcleos suportados pela CPU. Para listar os processadores em seu
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, [então] 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
.
Quando se executar os testes de pacote ou a porção instalar do processo de construção do pacote, nós não recomendamos usar uma opção maior que '-j1', a menos que especificado de outra maneira. Os procedimentos ou verificações da instalação não foram validados usando-se procedimentos paralelos e possivelmente falhem com problemas que são difíceis de se depurar.
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.
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 Makefile
s; 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.
Construir o pacote CUPS é um bom exemplo de como redirecionar um arquivo como entrada gerada para solicitações pode te ajudar a automatizar a construção. Se você executar a suíte de teste, [então] você é solicitado(a) a responder a uma série de perguntas relacionadas ao tipo do teste a executar e se você tem quaisquer aplicativos auxiliares que o teste possa usar. Você pode criar um arquivo com as suas respostas, uma resposta por linha, e usar um comando similar ao mostrado abaixo para automatizar a execução da suíte de teste:
make check < ../cups-1.1.23-testsuite_parms
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 | more
Certamente, você será exigido(a) a visualizar a saída gerada uma
página por vez, pois o filtro more 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 | more > 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 script curto do Bash é exigido:
cat > blfs-yes-test2 << "EOF"
#!/bin/bash
ls -l /usr/bin | more
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 consegue ser corretamente construído sem a dependência tendo primeiro sido instalada.
Recomendada significa que o BLFS enfaticamente sugere que esse pacote seja instalado primeiro para uma construção limpa e livre de problemas; que não teria problemas seja durante o processo de construção, seja em tempo de execução. As instruções no livro assumem que esses pacotes estejam instalados. Algumas mudanças ou gambiarras possivelmente sejam exigidas se esses pacotes não estiverem instalados.
Opcional significa que esse pacote poderia estar instalado para funcionalidade adicionada. Frequentemente o BLFS descreverá a dependência para explicar a funcionalidade adicionada que resultará.
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, a remoção de símbolos de depuração e entradas desnecessárias na tabela de símbolos foi discutida algumas vezes. Ao construir pacotes BLFS, geralmente não existem instruções especiais que discutam a remoção novamente. A remoção pode ser feita durante a instalação de 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 "Meson" conseguem
aceitar -Dstrip=true
ao executar meson. Se esqueceu de
adicionar essa opção executando o meson, [então] 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 lugar, 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). O script 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 "Precisa ser root"
exit 1
fi
{ find /usr/lib -type f -name '*.so*' ! -name '*dbg'
find /usr/lib -type f -name '*.a'
find /usr/{bin,sbin,libexec} -type f
} | while read 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
cp --preserve $file ${file}.tmp
strip --strip-unneeded ${file}.tmp
mv ${file}.tmp $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(as) 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 e CXXFLAGS. 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), [entã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 forçar-se a compilação para uma microarquitetura específica (por exemplo, -march=amdfam10; -march=native) 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 desabilitados em lançamentos usando-se -DNDEBUG. Especificamente, se o Mesa-22.3.5 for construído com essas asserções habilitadas, [então] 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 tem um script de configuração que não é 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, [então] 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 largos 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 é configurado e nenhum sinalizador é gerado. Quaisquer CFLAGS ou CXXFLAGS no ambiente serão usados. Se o(a) programador(a) tiver codificado quaisquer asserções de depuração, [então] essas serão habilitadas, a menos que - DNDEBUG 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 -DNDEBUG
|
RelWithDebInfo |
-O2 -g -DNDEBUG
|
MinSizeRel |
-Os -DNDEBUG
|
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<alguma_opção>=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.
plano : 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 largos 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 -DNDEBUG' (porém, ocasionalmente, um pacote forçará -O2 aqui)
Apesar do tipo de construção 'lançamento' estar descrito como habilitante do -DNDEBUG e todas as construções CMake Release passarem isso, tem, até agora, somente sido observado (em construções verbosas) para o Mesa-22.3.5. Isso sugere que somente poderia ser usado quando existirem asserções de depuração presentes.
O sinalizador -DNDEBUG também pode ser fornecido passando-se -Db_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 transferirão conforme
necessário. Esses pacotes são construídos usando-se cargo --release. Na teoria, você
consegue manipular o RUSTFLAGS para mudar o nível de otimização
(padrão é 3, semelhante a -03; por exemplo, -Copt-level=3
) 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ê encontrar um aplicativo rustc interessante que seja
fornecido apenas como fonte desempacotado, [então] você deveria,
pelo menos, especificar RUSTFLAGS=-Copt-level=2
; do contrário, fará uma
compilação não otimizada, com informação de depuração e executará
muito mais lento.
Os(As) desenvolvedores(as) do rust parecem presumir que todos
compilarão em uma máquina dedicada a produzir construções, de forma
que, por padrão, todas as CPUs serão usadas. Isso, frequentemente,
pode ser contornado, seja exportando-se CARGO_BUILD_JOBS=<N>,
seja passando-se --jobs <N> para o cargo. Para compilar o
próprio rustc, especificar-se --jobs <N> em invocações de
x.py (junto com a variável de ambiente CARGO_BUILD_JOBS
, que se parece com uma abordagem
"cinto e suspensórios", porém parece ser necessária) na maioria das
vezes funciona. 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/Optimize-Options.html; e https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html; e info gcc.
Alguns pacotes padronizam para '-O2 -g'; outros para '-O3 -g'; e, se CFLAGS ou CXXFLAGS forem fornecidos, [então] eles poderiam ser adicionados aos padrões do pacote; substituir os padrões do pacote; ou até serem ignorados. Existem detalhes acerca de alguns pacotes de área de trabalho que eram na maioria das vezes atuais 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 particular a se lembrar é a de que, se você quiser tentar algum dos mais interessantes sinalizadores, [então] você possivelmente precise forçar construções verbosas para confirmar o que está sendo usado.
Claramente, se você estiver otimizando seu próprio aplicativo, [então] você pode gastar tempo para perfilá-lo e, talvez, re-codificar 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, [então] nem tudo executará em um SandyBridge.
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 do Perl ou do Python; ou pacotes do Qt que usam o qmake, [então], no geral, os CFLAGS e CXXFLAGS usados são aqueles que foram usados por aqueles pacotes 'ancestrais'.
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 reforçamento (com opções para
desativar parte dele por pacote). Os livros atuais LFS e BLFS estão
levando adiante uma parte do espírito dele, habilitando "PIE"
(-fPIE -pie
) e "SSP" (-fstack-protector-strong
) como padrões para o "GCC"
e o "clang". O que está sendo abordado aqui é diferente - primeiro,
você precisa ter certeza de que o pacote está realmente usando os
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
e (para "C++")
-D_GLIBCXX_ASSERTIONS
. Nas máquinas
modernas, isso deveria ter somente um pequeno impacto na rapidez
com que as coisas funcionam e, muitas vezes, não serão
perceptíveis.
As principais distribuições usam muito mais, como "RELRO"
("Relocation Read Only") e talvez -fstack-clash-protection
. Você também possivelmente
encontre a chamada “retpoline do espaço de usuário(a)”
(-mindirect-branch=thunk
etc.), que é o
equivalente às mitigações de espectro aplicadas ao núcleo Linux no
final de 2018. As mitigações do núcleo causaram muitas reclamações
acerca de perda de desempenho; se você tiver um servidor de
produção, você pode desejar considerar testá-las, juntamente com
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.