8.29.1. Instalação do GCC
        
        
          Se construir em x86_64, [então] mude o nome padrão de diretório
          para bibliotecas de 64 bits para “lib”:
        
        case $(uname -m) in
  x86_64)
    sed -e '/m64=/s/lib64/lib/' \
        -i.orig gcc/config/i386/t-linux64
  ;;
esac
        
          A documentação do GCC recomenda construir o GCC em um diretório de
          construção dedicado:
        
        mkdir -v build
cd      build
        
          Prepare o GCC para compilação:
        
        ../configure --prefix=/usr            \
             LD=ld                    \
             --enable-languages=c,c++ \
             --enable-default-pie     \
             --enable-default-ssp     \
             --enable-host-pie        \
             --disable-multilib       \
             --disable-bootstrap      \
             --disable-fixincludes    \
             --with-system-zlib
        
          O GCC suporta sete linguagens computacionais, porém os
          pré-requisitos para a maior parte delas ainda não foram instalados.
          Veja-se a 
          página do GCC do Livro BLFS para instruções a respeito do como
          construir todas as linguagens suportadas do GCC.
        
        
          
            O significado dos novos parâmetros de
            configuração:
          
          
            - 
              
LD=ld
             
            - 
              
                Esse parâmetro induz o script configure a usar o aplicativo
                ld instalado pelo pacote Binutils, construído anteriormente
                neste capítulo, em vez da versão construída cruzadamente, a
                qual de outra maneira seria usada.
              
             
            - 
              
--disable-fixincludes
             
            - 
              
                Por padrão, durante a instalação do GCC alguns cabeçalhos de
                sistema seriam “corrigidos” para serem usados com o
                GCC. Isso não é necessário para um sistema moderno Linux e
                potencialmente danoso se um pacote for reinstalado depois de
                instalar o GCC. Essa chave evita que o GCC “corrija” os
                cabeçalhos.
              
             
            - 
              
--with-system-zlib
             
            - 
              
                Essa chave diz ao GCC para vincular à cópia instalada do
                sistema da biblioteca Zlib, em vez da própria cópia interna
                dele.
              
             
          
         
        
          
          
            Nota
          
          
            PIE (position-independent executables) são aplicativos binários
            que conseguem ser carregados em qualquer lugar em memória. Sem
            PIE, o recurso de segurança chamado de ASLR (Address Space Layout
            Randomization) consegue ser aplicado para as bibliotecas
            compartilhadas, porém não para os próprios executáveis. Habilitar
            PIE permite ASLR para os executáveis em adição às bibliotecas
            compartilhadas e mitiga alguns ataques baseados em endereços
            fixos de código ou dados sensível(is) nos executáveis.
          
          
            SSP (Stack Smashing Protection) é uma técnica para garantir que a
            pilha de parâmetros não está corrompida. A corrupção da pilha
            consegue, por exemplo, alterar o endereço de retorno de uma
            sub-rotina, dessa forma transferindo controle para algum código
            perigoso (existente no aplicativo ou nas bibliotecas
            compartilhadas; ou injetado pelo(a) atacante de alguma maneira).
          
         
        
          Compile o pacote:
        
        make
        
          
          
            Importante
          
          
            Nesta seção, a suíte de teste para o GCC é considerada
            importante, porém ela toma um tempo longo. Construtoras(es) de
            primeira vez são encorajadas(os) a executar a suíte de teste. O
            tempo para executar os testes pode ser reduzido significantemente
            adicionando-se -jx ao comando make
            -k check abaixo, onde x é o número de núcleos da
            CPU em seu sistema.
          
         
        
          O GCC pode precisar de mais espaço de pilha para compilar alguns
          padrões de código extremamente complexos. Como precaução para as
          distribuições anfitriãs com um limite de pilha apertado, configure
          explicitamente o limite rígido do tamanho da pilha como infinito.
          Na maioria das distribuições anfitriãs (e no sistema LFS final), o
          limite rígido é infinito por padrão, mas não há mal algum em
          configurá-lo explicitamente. Não é necessário mudar o limite
          flexível do tamanho da pilha porque o GCC o configurará
          automaticamente para um valor apropriado, desde que o valor não
          exceda o limite rígido:
        
        ulimit -s -H unlimited
        
          Agora remova várias falhas conhecidas de teste:
        
        sed -e '/cpython/d' -i ../gcc/testsuite/gcc.dg/plugin/plugin.exp
        
          Teste os resultados como um(a) usuário(a) não privilegiado(a),
          porém não pare em erros:
        
        chown -R tester .
su tester -c "PATH=$PATH make -k check"
        
          Para extrair um sumário dos resultados da suíte de teste, execute:
        
        ../contrib/test_summary
        
          Para filtrar somente os sumários, entube a saída gerada por
          grep -A7 Summ.
        
        
          Os resultados podem ser comparados com aqueles localizados em
          https://www.linuxfromscratch.org/lfs/build-logs/12.4/
          e https://gcc.gnu.org/ml/gcc-testresults/.
        
        
          Os testes relacionados a pr90579.c
          são conhecidos por falharem.
        
        
          Umas poucas falhas inesperadas não podem ser evitadas sempre. A
          menos que os resultados do teste sejam amplamente diferentes
          daqueles na URL acima, é seguro continuar.
        
        
          Instale o pacote:
        
        make install
        
          O diretório de construção do GCC é de propriedade de tester agora e a propriedade do diretório do
          cabeçalho instalado (e o conteúdo dele) está incorreto. Mude a
          propriedade para o(a) usuário(a) e grupo root:
        
        chown -v -R root:root \
    /usr/lib/gcc/$(gcc -dumpmachine)/15.2.0/include{,-fixed}
        
          Crie um link simbólico exigido pelo FHS
          por razões "históricas".
        
        ln -svr /usr/bin/cpp /usr/lib
        
          Muitos pacotes usam o nome cc para chamar o compilador C. Já
          criamos cc como um
          link simbólico em gcc-passagem2; crie a página de
          manual dele como um link simbólico também:
        
        ln -sv gcc.1 /usr/share/man/man1/cc.1
        
          Adicione um link simbólico de compatibilidade para habilitar a
          construção de aplicativos com Link Time Optimization (LTO):
        
        ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/15.2.0/liblto_plugin.so \
        /usr/lib/bfd-plugins/
        
          Agora que nosso conjunto de ferramentas final está no lugar, é
          importante certificar-se novamente de que compilação e vinculação
          funcionarão como esperado. Nós fazemos isso realizando algumas
          verificações de sanidade:
        
        echo 'int main(){}' | cc -x c - -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'
        
          Não deveriam existir erros, e a saída gerada do último comando será
          (levando em consideração diferenças específicas da plataforma no
          nome do vinculador dinâmico):
        
        [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
        
          Agora certifique-se de que nós estamos configurados para usar os
          arquivos corretos de iniciação:
        
        grep -E -o '/usr/lib.*/S?crt[1in].*succeeded' dummy.log
        
          A saída gerada do último comando deveria ser:
        
        /usr/lib/gcc/x86_64-pc-linux-gnu/15.2.0/../../../../lib/Scrt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/15.2.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/15.2.0/../../../../lib/crtn.o succeeded
        
          Dependendo da arquitetura da sua máquina, o acima possivelmente
          difira ligeiramente. A diferença será o nome do diretório depois de
          /usr/lib/gcc. A coisa importante a se
          olhar aqui é que o gcc tenha encontrado todos os
          três arquivos crt*.o sob o diretório
          /usr/lib.
        
        
          Verifique se o compilador está procurando os arquivos corretos de
          cabeçalho:
        
        grep -B4 '^ /usr/include' dummy.log
        
          Esse comando deveria retornar a seguinte saída gerada:
        
        #include <...> search starts here:
 /usr/lib/gcc/x86_64-pc-linux-gnu/15.2.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/15.2.0/include-fixed
 /usr/include
        
          Novamente, o diretório nomeado depois do teu tripleto alvo
          possivelmente seja diferente do acima, dependendo da arquitetura do
          teu sistema.
        
        
          Agora, verifique se o novo vinculador está sendo usado com os
          caminhos corretos de procura:
        
        grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
        
          Referências para caminhos que tenham componentes com '-linux-gnu'
          deveriam ser ignoradas, porém, do contrário, a saída gerada do
          último comando deveria ser:
        
        SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
        
          Um sistema de 32 bits possivelmente use uns poucos outros
          diretórios. Por exemplo, aqui está a saída gerada originária de uma
          máquina i686:
        
        SEARCH_DIR("/usr/i686-pc-linux-gnu/lib32")
SEARCH_DIR("/usr/local/lib32")
SEARCH_DIR("/lib32")
SEARCH_DIR("/usr/lib32")
SEARCH_DIR("/usr/i686-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
        
          Em seguida, tenha certeza de que nós estamos usando a libc correta:
        
        grep "/lib.*/libc.so.6 " dummy.log
        
          A saída gerada do último comando deveria ser:
        
        attempt to open /usr/lib/libc.so.6 succeeded
        
          Tenha certeza de que GCC está usando o vinculador dinâmico correto:
        
        grep found dummy.log
        
          A saída gerada do último comando deveria ser (levando em
          consideração diferenças específicas da plataforma no nome do
          vinculador dinâmico):
        
        found ld-linux-x86-64.so.2 at /usr/lib/ld-linux-x86-64.so.2
        
          Se a saída gerada não aparecer conforme mostrado acima ou não for
          recebida, então alguma coisa está seriamente errada. Investigue e
          refaça as etapas para descobrir onde está o problema e corrija-o.
          Quaisquer problemas deveriam ser resolvidos antes de se continuar
          com o processo.
        
        
          Uma vez que tudo esteja funcionando corretamente, remova os
          arquivos de teste:
        
        rm -v a.out dummy.log
        
          Finalmente, mova um arquivo mal colocado:
        
        mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib