Domanda Come scegliere la versione predefinita di gcc e g ++?


Così ho installato gcc-4.4 e gcc-4.3 (lo stesso per g ++). Ora per quanto mi ricordo c'è uno strumento in Ubuntu che imposta i collegamenti simbolici per te se gli dici semplicemente quale versione vuoi. Tuttavia non sembra funzionare nella versione più recente, che trovo deludente.

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

Qualche idea?


171
2018-02-15 15:52


origine


Come ha spiegato @Oli, questa è una cattiva idea. Elenco di posta Debian-devel: "Non penso che debbano essere usate alternative per il controllo delle versioni. Ad esempio, non usiamo alternative per gcc, né per Python." lists.debian.org/debian-devel/2014/06/msg00381.html - hmijail


risposte:


Prima ho cancellato l'attuale aggiornamento-setup alternativo per gcc e g ++:

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

Installa pacchetti

Sembra che sia gcc-4.3 che gcc-4.4 siano installati dopo l'installazione build-essential. Tuttavia, possiamo installare esplicitamente i seguenti pacchetti:

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

Installa alternative

I collegamenti simbolici cc e c ++ sono installati per impostazione predefinita. Installeremo link simbolici per gcc e g ++, quindi colleghiamo cc e c ++ rispettivamente a gcc e g ++.

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

Configura le alternative

L'ultimo passo è la configurazione dei comandi predefiniti per gcc, g ++. È facile passare da 4.3 a 4.4 in modo interattivo:

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

Oppure cambia usando lo 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, quindi devi aggiungerli manualmente alle alternative di aggiornamento. IIRC prima versioni di Ubuntu lo facevano automaticamente. - Nils
Questo è particolarmente utile per me quando compilo i moduli nvidia per diversi kernel. Grazie mille per aver spiegato le alternative di aggiornamento - earthmeLon
Grazie! Ho usato l'altra risposta per aggiornare da 4.6 a 4.7. Volevo usare questa risposta, ma non ero sicuro del perché tu metti numeri come 10 20 30 dopo alcuni di voi comandi. Potresti spiegare per favore? - Martin Drozdik
I numeri sono priorità come risulta, secondo la manpage. Immagino che nel caso in cui una delle versioni venga disinstallata, utilizzerà quelle priorità per determinare quale dovrebbe diventare il nuovo valore predefinito. - Ibrahim
@Ibrahim: No, determinano cosa viene scelto quando si seleziona la modalità automatica - Cookie


eseguire nel terminale:

gcc -v
g++ -v

Ok, quindi quella parte è abbastanza semplice. La parte difficile è che quando si impartisce il comando GCC è in realtà un collegamento simbolico a cui si sta utilizzando la versione di GCC. Ciò significa che possiamo creare un collegamento simbolico da GCC a qualsiasi versione di GCC che vogliamo.

  • Puoi vedere il link simbolico:
ls -la /usr/bin | grep gcc-4.4
ls -la /usr/bin | grep g++-4.4
  • Quindi quello che dobbiamo fare è rimuovere il link simbolico GCC e il link simbolico G ++ e quindi ricrearli collegati a GCC 4.3 e 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++
  • Ora se controlliamo nuovamente i collegamenti simbolici vedremo GCC e G ++ ora collegati a GCC 4.3 e G ++ 4.3:
ls -la /usr/bin/ | grep gcc
ls -la /usr/bin/ | grep g++
  • Finalmente possiamo controllare nuovamente il nostro GCC -v e assicurarci di utilizzare la versione corretta:
gcc -v
g++ -v

30
2018-02-15 16:49





È davvero desiderabile? Ci sono cambiamenti ABI tra gcc versioni. Compilare qualcosa con una versione (ad es. L'intero sistema operativo) e poi compilare qualcos'altro con un'altra versione, può causare conflitti.

Ad esempio, i moduli del kernel dovrebbero sempre essere compilati con la stessa versione di gcc usato per compilare il kernel. Con questo in mente, se hai modificato manualmente il collegamento simbolico tra /usr/bin/gcc e la versione usata nella tua versione di Ubuntu, i futuri moduli creati da DKMS potrebbero usare il torto gcc versione.

Se vuoi solo costruire cose con una versione diversa di gcc, è abbastanza facile, anche con i makescripts. Ad esempio, puoi passare la versione di gcc nel CC variabile d'ambiente:

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

Potresti non averne bisogno con il comando make (solitamente gli script di configurazione lo inseriscono) ma non fa male.


20
2018-02-15 16:22



Grazie per il tuo commento. Sono a conoscenza della variabile CC, ma questa non era la vera domanda. - Nils
È vero, ma ho spiegato perché gcc non fa parte del alternatives sistema e perché questo non è particolarmente auspicabile. Se nessuno di questi cambierà idea, fallo semplicemente manualmente. - Oli♦
Era prima? Ora l'hanno appena rimosso ?! Il software di compilazione (userspace) con diverse versioni di gcc dovrebbe essere perfettamente ok .. questa discussione sta diventando sill .. - Nils
Puoi spiegare perché le variabili di ambiente per invocazione sono preferibili a un'impostazione di configurazione a livello di sistema? $ sudo apt-get install gcc-6 gcc-7 $ CC="gcc-7" ./configure <much output> $ make # uses gcc-7 Mentre sudo update-alternatives gcc gcc-7 si sarebbe assicurato di non commutare accidentalmente gli ABI. - kfsone


Modificare:

Ciò presuppone che tu abbia installato la versione per prima, con ad esempio:

sudo apt install gcc-4.9 g++-4.9

Originale:

Ed ecco un one-liner per coloro che sono pigri, basta cambiare il numero alla fine della versione desiderata. Farà il cambiamento per gcc e / o 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 questo esempio sono passato a 4.9

Non ci sono controlli di errore e cosa no in questo esempio, quindi potresti voler controllare ciò che verrà eseguito prima di eseguirlo. Basta aggiungere ecoprima sudo. Per completezza fornisco anche la linea di controllo:

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

L'output dal controllo dovrebbe essere qualcosa del tipo:

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

Puoi verificare la versione dopo con:

gcc --version

Spiegazione semi-dettagliata:

  • ls -la / usr / bin / elenca tutti i file in / Usr / bin
  • | pipe (send) l'output al comando successivo
  • grep -oP corrisponde alla regex di ricerca per riga. o mostra solo il risultato, non l'intera riga abbinata. P dice a grep di usare perl-regex. Non entrerò in regex qui, leggilo se vuoi.
  • xargs semplicemente, raccoglie i risultati che sono stati convogliati e li manda tutti alla fine. cioè al comando che segue xargs
  • bash bene, è un colpo. Il c flag dice di usare la stringa come comando. In questo esempio scorre sugli argomenti inviati da xargs  saltando il primo (0) argomento, in questo caso il ciclo salta 4.9. L'argomento 0 viene utilizzato nel ciclo per modificare il collegamento.
  • ln -s -f Il S la bandiera crea un collegamento simbolico, f obbliga a scollegare prima se necessario.

10
2017-10-15 20:52



Domanda molto vecchia, ma questa risposta sembra essere una delle gemme che dovremmo cercare quando esaminiamo le risposte ai vecchi post ... - mook765
Brillante! La migliore risposta per le mani! - Gabriel Staples


Considera l'upgrade in un modo:

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

apt gestirà il personale dei link automaticamente in questo caso. La nuova versione di C / C ++ è piuttosto compatibile. Non avresti quasi mai bisogno del vecchio.


-1
2017-10-29 20:02