web-dev-qa-db-fra.com

Comment choisir la version par défaut de gcc et g ++?

J'ai donc installé gcc-4.4 et gcc-4.3 (idem pour g ++). Pour autant que je m'en souvienne, il existe un outil dans Ubuntu qui définit les liens symboliques pour vous si vous lui indiquez simplement la version de votre choix. Cependant, cela ne semble pas fonctionner dans la nouvelle version, ce qui me déçoit.

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

Des idées?

196
Nils

D'abord effacé la configuration actuelle des alternatives de mise à jour pour gcc et g ++:

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

Installer les paquets

Il semble que gcc-4.3 et gcc-4.4 sont tous deux installés après l'installation de build-essential. Cependant, nous pouvons installer explicitement les packages suivants:

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

Installer les alternatives

Les liens symboliques cc et c ++ sont installés par défaut. Nous installerons les liens de symboles pour gcc et g ++, puis lierons cc et c ++ à gcc et g ++ respectivement. (Notez que les options 10, 20 et 30 sont les priorités pour chaque alternative.)

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

Configurer des alternatives

La dernière étape consiste à configurer les commandes par défaut pour gcc, g ++. Il est facile de basculer de manière interactive entre 4.3 et 4.4:

Sudo update-alternatives --config gcc
Sudo update-alternatives --config g++

Ou passez en utilisant le 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"
256
hhlp

exécuter dans le terminal:

gcc -v
g++ -v

Ok, donc cette partie est assez simple. La difficulté réside dans le fait que lorsque vous exécutez la commande GCC, il s’agit en réalité d’un lien sybolique vers la version de GCC que vous utilisez. Cela signifie que nous pouvons créer un lien symbolique de GCC vers la version de GCC de notre choix.

  • Vous pouvez voir le lien symbolique:
ls -la /usr/bin | grep gcc-4.4
ls -la /usr/bin | grep g++-4.4
  • Nous devons donc supprimer le lien symbolique GCC et le lien symbolique G ++, puis les recréer liés à GCC 4.3 et 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++
  • Maintenant, si nous vérifions à nouveau les liens symboliques, nous verrons que GCC et G ++ sont maintenant liés à GCC 4.3 et G ++ 4.3:
ls -la /usr/bin/ | grep gcc
ls -la /usr/bin/ | grep g++
  • Enfin, nous pouvons vérifier à nouveau notre GCC -v et nous assurer que nous utilisons la version correcte:
gcc -v
g++ -v
38
hhlp

Est-ce vraiment souhaitable? Il y a des modifications ABI entre les versions de gccname__. Compiler quelque chose avec une version (par exemple l’ensemble du système d’exploitation) puis compiler quelque chose d’autre avec une autre version peut être source de conflit.

Par exemple, les modules du noyau doivent toujours être compilés avec la même version de gccutilisée pour compiler le noyau. Dans cet esprit, si vous modifiez manuellement le lien symbolique entre /usr/bin/gcc et la version utilisée dans votre version d'Ubuntu, les futurs modules construits par DKMS pourraient utiliser la mauvaise version de gccname__.

Si vous voulez simplement construire des choses avec une version différente de gccname__, c'est assez simple, même avec les scripts. Par exemple, vous pouvez transmettre la version de gccdans la variable d’environnement CCname__:

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

Vous n’avez peut-être pas besoin de cela dans la commande make (les scripts de configuration le tirent habituellement) mais cela ne fait pas de mal.

21
Oli

Edit:

Cela suppose que vous ayez d'abord installé la version, avec par exemple:

Sudo apt install gcc-4.9 g++-4.9

Original:

Et voici un one-line pour ceux qui sont paresseux, il suffit de changer le numéro à la fin pour obtenir la version souhaitée. Il fera le changement pour gcc et/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

Dans cet exemple, je suis passé à 4.9

Il n'y a pas de vérification d'erreur et ce qui n'est pas dans cet exemple, vous voudrez peut-être vérifier ce qui sera exécuté avant de l'exécuter. Ajoutez simplement echo avant Sudo. Par souci d'exhaustivité, je fournis également une ligne de contrôle:

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

Le résultat de la vérification devrait être quelque chose comme:

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

Vous pouvez vérifier la version après avec avec:

gcc --version

Explication semi-détaillée:

  • ls -la/usr/bin / répertorie tous les fichiers de / usr/bin
  • diriger (envoyer) la sortie vers la commande suivante
  • grep -oP correspond au regex de recherche par ligne. o affiche uniquement le résultat, pas la totalité de la ligne correspondante. P indique à grep d'utiliser Perl-regex. Je ne vais pas entrer dans l'expression régulière ici, lisez-le si vous le souhaitez.
  • xargs tout simplement, il rassemble les résultats qui lui sont transmis et les envoie tous à la fin. c'est-à-dire à la commande qui suit xargs
  • bash bien, c'est bash. L’indicateur c lui dit d’utiliser la chaîne en tant que commande. Dans cet exemple, il boucle sur les arguments envoyés par xargs en ignorant le premier argument (0e), dans ce cas, la boucle saute 4.9. Le 0ème argument est utilisé dans la boucle pour changer le lien.
  • ln -s -f Le drapeau s crée un lien symbolique, f force le déblocage en premier si nécessaire.
14
Ale

Envisagez une mise à niveau à sens unique:

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

dans ce cas, apt gérera automatiquement le personnel des liens. La nouvelle version de C/C++ est très compatible. Vous aurez à peine besoin d'un vieux.

0
Sergei

Que diriez-vous d'un lien symbolique dans un répertoire temporaire:

mkdir x && PATH=$PWD/x:$PATH && ln -s /usr/bin/g++-7 $PWD/x/g++

0
user643722