Vraag Hoe de standaard gcc- en g ++ -versie te kiezen?


Dus ik heb gcc-4.4 en gcc-4.3 geïnstalleerd (zelfde voor g ++). Voor zover ik me herinner is er een tool in Ubuntu die de symbolische koppelingen voor je instelt als je het gewoon vertelt welke versie je wilt. Het lijkt echter niet te werken in de nieuwste versie, wat ik teleurstellend vind.

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

Om het even welke ideeën?


171
2018-02-15 15:52


oorsprong


Zoals @ Oli uitlegde, is dit een slecht idee. Debian-devel mail lijst: "Ik denk niet dat alternatieven moeten worden gebruikt voor versiebeheer, we gebruiken bijvoorbeeld geen alternatieven voor gcc, ook niet voor Python." lists.debian.org/debian-devel/2014/06/msg00381.html - hmijail


antwoorden:


Eerst de huidige update-alternatieven setup voor gcc en g ++ gewist:

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

Pakketten installeren

Het lijkt erop dat zowel gcc-4.3 als gcc-4.4 zijn geïnstalleerd na installatie essentieel. We kunnen echter expliciet de volgende pakketten installeren:

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

Installeer alternatieven

Symbolische links cc en c ++ worden standaard geïnstalleerd. We zullen symboolkoppelingen voor gcc en g ++ installeren en vervolgens cc en c ++ aan respectievelijk gcc en g ++ koppelen.

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

Alternatieven configureren

De laatste stap is het configureren van de standaardopdrachten voor gcc, g ++. Het is eenvoudig om interactief tussen 4.3 en 4.4 te schakelen:

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

Of schakel om met 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, dus je moet ze handmatig toevoegen aan update-alternatieven. IIRC eerdere Ubuntu-versies deden dat automatisch. - Nils
Dit is vooral handig voor mij bij het compileren van nvidia-modules voor verschillende kernels. Heel erg bedankt voor het uitleggen van update-alternatieven - earthmeLon
Dank je! Ik heb je andere antwoord gebruikt om te updaten van 4.6 naar 4.7. Ik wilde dit antwoord gebruiken, maar ik wist niet zeker waarom je nummers als 10 20 30 na sommige van je commando's zet. Zou je het kunnen uitleggen? - Martin Drozdik
De cijfers zijn prioriteiten zoals blijkt, volgens de manpage. Ik veronderstel dat in het geval dat een van de versies wordt verwijderd, deze de prioriteiten zal gebruiken om te bepalen welke de nieuwe standaard moet worden. - Ibrahim
@Ibrahim: Nee, ze bepalen wat er wordt gekozen wanneer je de automatische modus selecteert - Cookie


uitvoeren in terminal:

gcc -v
g++ -v

Oké, dus dat deel is vrij eenvoudig. Het lastige is dat wanneer je de opdracht GCC geeft, het in feite een sybolische koppeling is naar welke versie van GCC je ook gebruikt. Wat dit betekent is dat we een symbolische link van GCC naar elke versie van GCC die we willen kunnen maken.

  • Je kunt de symbolische link zien:
ls -la /usr/bin | grep gcc-4.4
ls -la /usr/bin | grep g++-4.4
  • Dus wat we moeten doen is de GCC-symlink en de G ++ -symlink verwijderen en deze vervolgens opnieuw koppelen aan GCC 4.3 en 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++
  • Als we nu de symbolische koppelingen opnieuw controleren, zien we dat GCC en G ++ nu zijn gekoppeld aan GCC 4.3 en G ++ 4.3:
ls -la /usr/bin/ | grep gcc
ls -la /usr/bin/ | grep g++
  • Eindelijk kunnen we onze GCC -v opnieuw bekijken en controleren of we de juiste versie gebruiken:
gcc -v
g++ -v

30
2018-02-15 16:49





Is dit echt wenselijk? Er zijn ABI-veranderingen tussen gcc versies. Iets compileren met één versie (bijvoorbeeld het volledige besturingssysteem) en vervolgens iets anders samenstellen met een andere versie, kan conflicten veroorzaken.

Kernelmodules moeten bijvoorbeeld altijd worden gecompileerd met dezelfde versie van gcc gebruikt om de kernel te compileren. Met dat in gedachten, als je de symlink handmatig hebt gewijzigd /usr/bin/gcc en de versie die wordt gebruikt in uw versie van Ubuntu, toekomstige DKMS-gebouwde modules kunnen de verkeerde gebruiken gcc versie.

Als je gewoon dingen wilt bouwen met een andere versie van gcc, dat is gemakkelijk genoeg, zelfs met make-scripten. U kunt bijvoorbeeld de versie van doorgeven gcc in de CC omgevingsvariabele:

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

Je hebt het misschien niet nodig op de make-opdracht (configureer scripts meestal wel), maar het doet geen pijn.


20
2018-02-15 16:22



Thx voor je reactie. Ik ben me bewust van de CC-variabele, maar dit was niet echt de vraag. - Nils
Dat is waar genoeg, maar ik heb uitgelegd waarom gcc maakt geen deel uit van de alternatives systeem en waarom dit niet bijzonder wenselijk is. Als geen van beide van gedachten verandert, doe het dan gewoon handmatig. - Oli♦
Het was daarvoor? Nu hebben ze het gewoon verwijderd ?! Het compileren van (gebruikersruimte) software met verschillende gcc-versies zou perfect moeten zijn .. deze discussie wordt sill .. - Nils
Kun je uitleggen waarom variabelen per aanroepomgeving de voorkeur hebben boven een systeembrede configuratie-instelling? $ sudo apt-get install gcc-6 gcc-7 $ CC="gcc-7" ./configure <much output> $ make # uses gcc-7 Terwijl sudo update-alternatives gcc gcc-7 zou ervoor hebben gezorgd dat u niet per abuis van ABI wisselt. - kfsone


Bewerk:

Hierbij wordt ervan uitgegaan dat u de versie eerst hebt geïnstalleerd, met bijvoorbeeld:

sudo apt install gcc-4.9 g++-4.9

origineel:

En hier is een one-liner voor degenen die lui zijn, verander gewoon van het aantal aan het einde naar de gewenste versie. Het zal de verandering maken voor gcc en / of 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

In dit voorbeeld stapte ik over naar 4.9

Er zijn geen foutcontroles en wat niet in dit voorbeeld, dus u wilt misschien controleren wat er wordt uitgevoerd voordat u het uitvoert. Voeg gewoon toe echovoor sudo. Voor de volledigheid bied ik ook een controlelijn aan:

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

De uitvoer van de cheque moet ongeveer zo zijn:

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

U kunt de versie hierna controleren met:

gcc --version

Semi-gedetailleerde uitleg:

  • ls -la / usr / bin / geeft een lijst van alle bestanden in / Usr / bin
  • | pijp (verzend) de uitvoer naar de volgende opdracht
  • grep -oP komt overeen met de zoekregex per regel. O toont alleen het resultaat, niet de volledige overeenkomende regel. P vertelt grep om perl-regex te gebruiken. Ik ga hier niet in op regex, lees het verder als je dat wilt.
  • xargs eenvoudig gezegd, verzamelt het de resultaten die eraan worden doorgegeven en stuurt ze allemaal naar het einde. d.w.z. naar het commando na xargs
  • bash Nou, het is bash. De c flag vertelt het om de string als een commando te gebruiken. In dit voorbeeld worden de argumenten doorgestuurd die worden verzonden xargs  door het eerste (0e) argument over te slaan, in dit geval slaat de lus over 4.9. Het 0de argument wordt in de lus gebruikt om de koppeling te wijzigen.
  • ln -s-f De s vlag maakt een symbolische link, f krachten eerst ontkoppelen indien nodig.

10
2017-10-15 20:52



Zeer oude vraag, maar dit antwoord lijkt een van de pareltjes te zijn waarnaar we moeten zoeken bij het bekijken van antwoorden op oude berichten ... - mook765
Briljant! Beste antwoord zonder twijfel! - Gabriel Staples


Overweeg een upgrade voor een manier:

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

apt zal in dit geval automatisch het personeel van koppelingen afhandelen. Nieuwe C / C ++ -versie is redelijk compatibel. Je hebt de oude bijna nooit nodig.


-1
2017-10-29 20:02