Questão Como escolher a versão padrão gcc e g ++?


Então eu instalei o gcc-4.4 e o gcc-4.3 (o mesmo para g ++). Agora, tanto quanto eu me lembro, há uma ferramenta no Ubuntu que define os links simbólicos para você, se você acabou de dizer qual versão você quer. No entanto, não parece funcionar na versão mais recente, o que acho decepcionante.

root@nexus:~# update-alternatives --config gcc
update-alternatives: error: no alternatives for gcc.
root@nexus:~# update-alternatives --config cc
There is only one alternative in link group cc: /usr/bin/gcc
Nothing to configure.


root@nexus:~# dpkg -l | grep gcc | awk '{print $2}'
gcc
gcc-4.3
gcc-4.3-base
gcc-4.3-multilib
gcc-4.4
gcc-4.4-base
gcc-4.4-multilib
gcc-4.5-base
gcc-multilib
lib32gcc1
libgcc1

Alguma ideia?


171
2018-02-15 15:52


origem


Como @Oli explicou, esta é uma má ideia. Lista de discussão do Debian-devel: "Eu não acho que as alternativas devam ser usadas para versionamento. Por exemplo, nós não usamos alternativas para o gcc, nem para o Python." lists.debian.org/debian-devel/2014/06/msg00381.html - hmijail


Respostas:


Primeiro, apagou a configuração atual de update-alternatives para gcc e g ++:

sudo update-alternatives --remove-all gcc 
sudo update-alternatives --remove-all g++

Instalar pacotes

Parece que tanto o gcc-4.3 quanto o gcc-4.4 são instalados após a instalação. No entanto, podemos instalar explicitamente os seguintes pacotes:

sudo apt-get install gcc-4.3 gcc-4.4 g++-4.3 g++-4.4

Instalar alternativas

Links simbólicos cc e c ++ são instalados por padrão. Vamos instalar os links simbólicos para gcc e g ++, e então vincular cc e c ++ para gcc e g ++ respectivamente.

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.3 10
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4 20

sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.3 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.4 20

sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30
sudo update-alternatives --set cc /usr/bin/gcc

sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30
sudo update-alternatives --set c++ /usr/bin/g++

Configurar alternativas

O último passo é configurar os comandos padrão para gcc, g ++. É fácil alternar entre 4.3 e 4.4 interativamente:

sudo update-alternatives --config gcc
sudo update-alternatives --config g++

Ou alterne usando script:

#!/bin/sh

if [ -z "$1" ]; then
    echo "usage: $0 version" 1>&2
    exit 1
fi

if [ ! -f "/usr/bin/gcc-$1" ] || [ ! -f "/usr/bin/g++-$1" ]; then
    echo "no such version gcc/g++ installed" 1>&2
    exit 1
fi

update-alternatives --set gcc "/usr/bin/gcc-$1"
update-alternatives --set g++ "/usr/bin/g++-$1"

229
2018-02-15 19:05



Thx, então você tem que adicioná-los manualmente para atualizar-alternativas .. IIRC versões anteriores do Ubuntu fizeram isso automaticamente. - Nils
Isso é especialmente útil para compilar módulos nvidia para diferentes kernels. Muito obrigado por explicar as alternativas de atualização - earthmeLon
Obrigado! Eu usei sua outra resposta para atualizar de 4.6 para 4.7. Eu queria usar essa resposta, mas não tinha certeza por que você coloca números como 10 20 30 depois de alguns de seus comandos. Você poderia por favor explicar? - Martin Drozdik
Os números são prioridades, de acordo com a manpage. Eu imagino que no caso em que uma das versões seja desinstalada, ela usará essas prioridades para determinar qual delas deve se tornar o novo padrão. - Ibrahim
@Ibrahim: Não, eles determinam o que é escolhido quando você seleciona o modo automático - Cookie


executar no terminal:

gcc -v
g++ -v

Ok, então essa parte é bem simples. A parte complicada é que quando você emite o comando GCC, ele é na verdade um link simbólico para a versão do GCC que você está usando. O que isso significa é que podemos criar um link simbólico do GCC para qualquer versão do GCC que desejarmos.

  • Você pode ver o link simbólico:
ls -la /usr/bin | grep gcc-4.4
ls -la /usr/bin | grep g++-4.4
  • Então, o que precisamos fazer é remover o link simbólico GCC e o link simbólico G ++ e, em seguida, recriá-los vinculados ao GCC 4.3 e ao G ++ 4.3:
rm /usr/bin/gcc
rm /usr/bin/g++

ln -s /usr/bin/gcc-4.3 /usr/bin/gcc
ln -s /usr/bin/g++-4.3 /usr/bin/g++
  • Agora, se verificarmos os links simbólicos novamente, veremos o GCC e o G ++ agora vinculados ao GCC 4.3 e ao G ++ 4.3:
ls -la /usr/bin/ | grep gcc
ls -la /usr/bin/ | grep g++
  • Finalmente, podemos verificar o nosso GCC -v novamente e verificar se estamos usando a versão correta:
gcc -v
g++ -v

30
2018-02-15 16:49





Isso é realmente desejável? Existem alterações na ABI entre gcc versões. Compilar algo com uma versão (por exemplo, o sistema operacional inteiro) e depois compilar outra coisa com outra versão, pode causar conflito.

Por exemplo, os módulos do kernel devem sempre ser compilados com a mesma versão gcc usado para compilar o kernel. Com isso em mente, se você alterou manualmente o symlink entre /usr/bin/gcc e a versão usada em sua versão do Ubuntu, os futuros módulos criados pelo DKMS podem usar o gcc versão.

Se você quer apenas construir coisas com uma versão diferente de gcc, é fácil o suficiente, mesmo com os roteiros. Por exemplo, você pode passar a versão do gcc no CC variável de ambiente:

CC="gcc-4.5" ./configure
CC="gcc-4.5" make

Você pode não precisar dele no comando make (configure scripts geralmente o puxam), mas não faz mal.


20
2018-02-15 16:22



Thx pelo seu comentário. Estou ciente da variável CC, mas essa não era a questão. - Nils
É verdade, mas eu expliquei por que gcc não faz parte do alternatives sistema e por que isso não é particularmente desejável. Se nenhum desses for mudar de ideia, faça isso manualmente. - Oli♦
Foi antes? Agora eles apenas removeram ?! Compilando (userspace) software com diferentes versões do gcc deve ser perfeitamente ok .. esta discussão está ficando .. - Nils
Você pode explicar por que as variáveis ​​de ambiente por invocação são preferíveis a uma configuração de todo o sistema? $ sudo apt-get install gcc-6 gcc-7 $ CC="gcc-7" ./configure <much output> $ make # uses gcc-7 Enquanto que sudo update-alternatives gcc gcc-7 teria certeza de que você não acidentalmente trocaria a ABIs. - kfsone


Editar:

Isso pressupõe que você tenha instalado a versão primeiro, por exemplo:

sudo apt install gcc-4.9 g++-4.9

Original:

E aqui está um one-liner para quem é preguiçoso, basta trocar o número no final da versão que você quer. Ele fará a mudança para gcc e / ou g ++

ls -la /usr/bin/ | grep -oP "[\S]*(gcc|g\+\+)(-[a-z]+)*[\s]" | xargs bash -c 'for link in ${@:1}; do sudo ln -s -f "/usr/bin/${link}-${0}" "/usr/bin/${link}"; done' 4.9

Neste exemplo eu mudei para 4.9

Não há verificações de erro e o que não está neste exemplo, portanto, você pode querer verificar o que será executado antes de executá-lo. Basta adicionar ecoantes sudo. Para completar, eu também ofereço linha de seleção:

ls -la /usr/bin/ | grep -oP "[\S]*(gcc|g\+\+)(-[a-z]+)*[\s]" | xargs bash -c 'for link in ${@:1}; do echo sudo ln -s -f "/usr/bin/${link}-${0}" "/usr/bin/${link}"; done' 4.9

A saída do cheque deve ser algo como:

sudo ln -s -f /usr/bin/g++-4.9 /usr/bin/g++
sudo ln -s -f /usr/bin/gcc-4.9 /usr/bin/gcc
sudo ln -s -f /usr/bin/gcc-ar-4.9 /usr/bin/gcc-ar
sudo ln -s -f /usr/bin/gcc-nm-4.9 /usr/bin/gcc-nm
sudo ln -s -f /usr/bin/gcc-ranlib-4.9 /usr/bin/gcc-ranlib
sudo ln -s -f /usr/bin/x86_64-linux-gnu-g++-4.9 /usr/bin/x86_64-linux-gnu-g++
sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-4.9 /usr/bin/x86_64-linux-gnu-gcc
sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-ar-4.9 /usr/bin/x86_64-linux-gnu-gcc-ar
sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-nm-4.9 /usr/bin/x86_64-linux-gnu-gcc-nm
sudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-ranlib-4.9 /usr/bin/x86_64-linux-gnu-gcc-ranlib

Você pode verificar a versão depois com:

gcc --version

Explicação semi-detalhada:

  • ls -la / usr / bin / lista todos os arquivos / usr / bin
  • | pipe (send) a saída para o próximo comando
  • grep -oP corresponde à regex de pesquisa por linha. o mostra apenas o resultado e não toda a linha correspondente. P diz ao grep para usar o perl-regex. Eu não vou entrar no regex aqui, leia-o se você quiser.
  • xargs Em outras palavras, ele reúne os resultados que são canalizados para ele e envia todos eles para o final. isto é, para o comando seguinte xargs
  • festança bem, é bash. o c flag diz para usar a string como um comando. Neste exemplo, ele passa pelos argumentos enviados de xargs  ignorando o primeiro (0º) argumento, neste caso o loop ignora 4,9. O 0º argumento é usado no loop para alterar o link.
  • ln -s -f o s bandeira faz um link simbólico, f obriga a desvincular primeiro, se necessário.

10
2017-10-15 20:52



Pergunta muito antiga, mas essa resposta parece ser uma das gemas que devemos procurar ao analisar respostas para postagens antigas ... - mook765
Brilhante! Melhor resposta, mãos para baixo! - Gabriel Staples


Considere uma maneira de atualizar:

  • sudo apt install gcc-7
  • sudo apt remove gcc-5

O apt irá lidar com a equipe de links automaticamente nesse caso. A nova versão do C / C ++ é bastante compatível. Você dificilmente precisaria de um velho.


-1
2017-10-29 20:02