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


J'ai donc installé gcc-4.4 et gcc-4.3 (même chose pour g ++). Maintenant, autant que je me souvienne, il y a un outil dans Ubuntu qui définit les liens symboliques pour vous si vous lui dites simplement quelle version vous voulez. Cependant, il ne semble pas fonctionner dans la version la plus récente, ce que je trouve décevant.

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?


171
2018-02-15 15:52


origine


Comme l'explique @Oli, c'est une mauvaise idée. Liste de diffusion Debian-devel: "Je ne pense pas que des alternatives devraient être utilisées pour la gestion des versions. Par exemple, nous n'utilisons pas d'alternatives pour gcc, ni pour Python." lists.debian.org/debian-devel/2014/06/msg00381.html - hmijail


Réponses:


Tout d'abord effacé la configuration actuelle de update-alternatives pour gcc et g ++:

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

Installer des paquets

Il semble que gcc-4.3 et gcc-4.4 soient tous deux installés après le build-essential. Cependant, nous pouvons explicitement installer les paquets suivants:

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

Installer des alternatives

Les liens symboliques cc et c ++ sont installés par défaut. Nous allons installer les liens de symboles pour gcc et g ++, puis lier cc et c ++ à gcc et g ++ respectivement.

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 entre 4.3 et 4.4 de manière interactive:

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

Ou passer en utilisant un 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, vous devez donc les ajouter manuellement aux alternatives de mise à jour. - Nils
Cela m’est particulièrement utile lors de la compilation de modules nvidia pour différents noyaux. Merci beaucoup d'avoir expliqué update-alternatives - earthmeLon
Je vous remercie! J'ai utilisé votre autre réponse pour mettre à jour de 4,6 à 4,7. Je voulais utiliser cette réponse, mais je ne savais pas pourquoi vous mettiez des chiffres comme 10 20 30 après certaines de vos commandes. Pourriez-vous s'il vous plaît expliquer? - Martin Drozdik
Les chiffres sont des priorités au fur et à mesure, selon la page de manuel. J'imagine que si l'une des versions est désinstallée, elle utilisera ces priorités pour déterminer celle qui deviendra la nouvelle valeur par défaut. - Ibrahim
@ Ibrahim: Non, ils déterminent ce qui est choisi lorsque vous sélectionnez le mode automatique - Cookie


exécuter dans le terminal:

gcc -v
g++ -v

Ok, alors cette partie est assez simple. La partie la plus délicate est que lorsque vous lancez la commande GCC, il s’agit en fait d’un lien sybolique vers la version de GCC que vous utilisez. Cela signifie que nous pouvons créer un lien symbolique entre GCC et la version de GCC que nous souhaitons.

  • 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 en liaison avec 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 notre GCC -v à nouveau et nous assurer que nous utilisons la bonne version:
gcc -v
g++ -v

30
2018-02-15 16:49





Est-ce vraiment souhaitable? Il y a des changements ABI entre gcc versions. Compiler quelque chose avec une seule version (par exemple, le système d’exploitation entier) et ensuite compiler quelque chose avec une autre version peut provoquer des conflits.

Par exemple, les modules du noyau doivent toujours être compilés avec la même version de gcc utilisé pour compiler le noyau. Dans cette optique, 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 le mauvais gcc version.

Si vous voulez juste construire des choses avec une version différente de gcc, c'est assez facile, même avec des marques Par exemple, vous pouvez transmettre la version de gcc dans le CC variable d'environnement:

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

Vous n'en avez peut-être pas besoin sur la commande make (les scripts de configuration le font généralement), mais cela ne fait pas de mal.


20
2018-02-15 16:22



Merci pour votre commentaire. Je suis au courant de la variable CC, mais ce n'était pas vraiment la question. - Nils
C'est vrai, mais j'ai expliqué pourquoi gcc ne fait pas partie de la alternatives système et pourquoi ce n'est pas particulièrement souhaitable. Si aucun de ceux-là ne va changer d'avis, faites-le simplement manuellement. - Oli♦
C'était avant? Maintenant ils l'ont juste enlevé?! Compiler (espace utilisateur) des logiciels avec différentes versions de gcc devrait être parfaitement correct. - Nils
Pouvez-vous expliquer pourquoi les variables d'environnement par invocation sont préférables à un paramètre de configuration à l'échelle du système? $ sudo apt-get install gcc-6 gcc-7 $ CC="gcc-7" ./configure <much output> $ make # uses gcc-7 Tandis que sudo update-alternatives gcc gcc-7 aurait fait en sorte que vous ne changez pas accidentellement les ABI. - kfsone


Modifier:

Cela suppose que vous avez installé la version en premier, avec par exemple:

sudo apt install gcc-4.9 g++-4.9

Original:

Et voici une page pour ceux qui sont paresseux, changez simplement le numéro à la fin de la version que vous voulez. 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 des erreurs et que pas dans cet exemple, vous pouvez donc vérifier ce qui sera exécuté avant de l'exécuter. Ajoutez simplement échoavant sudo. Pour être complet, 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 doit ê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:

gcc --version

Explication semi-détaillée:

  • ls -la / usr / bin / liste tous les fichiers dans / usr / bin
  • | canaliser (envoyer) la sortie à la commande suivante
  • grep -oP correspond à l'expression rationnelle par ligne. o affiche uniquement le résultat et non la totalité de la ligne correspondante. P demande à grep d'utiliser perl-regex. Je ne vais pas entrer dans regex ici, lisez-le si vous voulez.
  • xargs tout simplement, il rassemble les résultats qui lui sont transmis et les envoie tous à la fin. c'est-à-dire à la commande suivant xargs
  • frapper Eh bien, c'est bash. le c flag lui indique d'utiliser la chaîne en tant que commande. Dans cet exemple, il passe en revue les arguments envoyés depuis xargs  en sautant le premier argument (0), dans ce cas la boucle saute 4.9. Le 0ème argument est utilisé dans la boucle pour modifier le lien.
  • ln -s -f le s le drapeau fait un lien symbolique, F les forces se dissocient en premier si nécessaire.

10
2017-10-15 20:52



Très vieille question, mais cette réponse semble être l'un des joyaux que nous devrions rechercher lorsque nous examinons les réponses à d'anciens messages ... - mook765
Brillant! Meilleure réponse haut la main! - Gabriel Staples


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 assez compatible. Vous auriez à peine besoin d'un ancien.


-1
2017-10-29 20:02