Varsayılan gcc ve g ++ sürümü nasıl seçilir?


206

Bu yüzden gcc-4.4 ve gcc-4.3'ü yükledim (g ++ ile aynı). Şimdi hatırladığım kadarıyla, sadece hangi sürümü istediğinizi söylerseniz Ubuntu'da sizin için sembolik bağlantıları ayarlayan bir araç var. Ancak hayal kırıklığı yaratan en yeni sürümde işe yaramadı.

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

Herhangi bir fikir?


1
@Oli'nin açıkladığı gibi, bu kötü bir fikir. Debian-devel mail listesi: "Versiyonlama için alternatiflerin kullanılması gerektiğini düşünmüyorum. Örneğin, gcc için alternatifleri Python için kullanmıyoruz." lists.debian.org/debian-devel/2014/06/msg00381.html
hmijail

1
Tamam, ne yapmak sen sürüm için kullanmak?
WillC

Yanıtlar:


271

İlk önce gcc ve g ++ için geçerli güncelleme alternatifleri kurulumunu sildim:

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

Paketleri Kur

Hem gcc-4.3 hem de gcc-4.4 kurulum temelli yüklendikten sonra görünüyor. Ancak, aşağıdaki paketleri açıkça yükleyebiliriz:

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

Alternatifleri Yükle

Sembolik bağlantılar cc ve c ++ varsayılan olarak yüklenir. Gcc ve g ++ için sembol linkleri kuracağız, daha sonra sırasıyla cc ve c ++ linklerini gcc ve g ++ linklerine yükleyeceğiz. (Not 10, 20ve 30seçenekler her alternatif için önceliklerdir.)

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

Alternatifleri Yapılandır

Son adım, gcc, g ++ için varsayılan komutları yapılandırmaktır. 4.3 ve 4.4 arasında etkileşimli olarak geçiş yapmak kolaydır:

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

Veya komut dosyasını kullanarak geçiş yapın:

#!/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"

4
Teşekkürler, bu yüzden güncelleme alternatiflerine manuel olarak eklemelisiniz .. IIRC önceki Ubuntu sürümleri bunu otomatik olarak yaptı.
Nils,

1
Bu özellikle farklı çekirdekler için nvidia modüllerini derlerken benim için faydalıdır. Güncelleme alternatiflerini açıkladığınız için çok teşekkür ederim
earthmeLon

1
Teşekkür ederim! Diğer cevabınızı 4.6 ila 4.7 arasında güncellemek için kullandım. Bu cevabı kullanmak istedim, ancak bazı komutlardan sonra neden 10 20 30 gibi rakamlar girdiğinizden emin değildim. Lütfen açıklar mısın?
Martin Drozdik

7
Manpage'e göre rakamlar ortaya çıktığı gibi öncelikler. Sürümün birinin kaldırılması durumunda, hangisinin yeni varsayılan olacağını belirlemek için bu öncelikleri kullanacağını hayal ediyorum.
Ibrahim

1
@ İbrahim: Hayır, otomatik mod seçtiğinizde neyin seçileceğini belirlerler
Cookie

41

terminalde yürütmek:

gcc -v
g++ -v

Tamam, bu kısım oldukça basit. İşin en zor yanı, GCC komutunu verdiğinizde gerçekte kullandığınız GCC sürümünü içeren bir sybolic link olmasıdır. Bunun anlamı, GCC'den istediğimiz GCC sürümüne kadar sembolik bir bağlantı oluşturabiliriz.

  • Sembolik bağlantıyı görebilirsiniz:
ls -la /usr/bin | grep gcc-4.4
ls -la /usr/bin | grep g++-4.4
  • Öyleyse yapmamız gereken, GCC sembolik linkini ve G ++ sembolik linkini kaldırmak ve sonra bunları GCC 4.3 ve G ++ 4.3 ile bağlantılı olarak yeniden yaratmak:
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++
  • Şimdi sembolik bağları tekrar kontrol edersek, GCC ve G ++ 'nın GCC 4.3 ve G ++ 4.3 ile bağlantılı olduğunu göreceğiz:
ls -la /usr/bin/ | grep gcc
ls -la /usr/bin/ | grep g++
  • Sonunda GCC -v'yi tekrar kontrol edebilir ve doğru sürümü kullandığımızdan emin olabiliriz:
gcc -v
g++ -v

1
Tam olarak aradığım şey! Yüklemiş olduğum sürüme "gcc" ile bağlantı kurma özelliğini unuttum. Teşekkürler!
CalebHC

daha basit ve daha kolay ve daha güvenli bir yöntem!
sailfish009

21

Bu gerçekten arzu edilir mi? gccSürümler arasında ABI değişiklikleri var . Bir sürümle (örneğin tüm işletim sistemi) bir şeyler derlemek ve ardından başka bir sürümle başka bir şey derlemek çakışmaya neden olabilir.

Örneğin, çekirdek modülleri her zaman gccçekirdeği derlemek için kullanılanla aynı sürümle derlenmelidir. Bunu akılda tutarak, /usr/bin/gccUbuntu sürümünüzde kullanılan sürüm ile sembolik bağlantıyı elle değiştirdiyseniz , gelecekteki DKMS tabanlı modüller yanlış gccsürümü kullanabilir .

Eğer sadece farklı bir versiyonuyla bir şeyler yapmak istiyorsanız gcc, makecripts ile bile bu kadar kolay. Örneğin gcc, CCortam değişkenindeki sürümünü iletebilirsiniz :

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

Make komutunda buna ihtiyaç duymayabilirsiniz (komut dosyalarını yapılandırın, genellikle çeker) ancak zarar vermez.


1
Yorumunuz için teşekkürler. CC değişkeninin farkındayım ama bu gerçekten bir soru değildi.
Nils,

2
Yeterince doğru ama neden sistemin bir gccparçası olmadığını alternativesve bunun neden istenmeyeceğini açıkladım . Bunların hiçbiri fikrinizi değiştirmeyecekse, sadece manuel olarak yapın.
Oli

1
O önceydi? Şimdi yeni kaldırdılar mı? Farklı gcc sürümleriyle derleme (kullanıcı alanı) yazılımı mükemmel olmalı. Bu tartışma eşik hale geliyor ..
Nils

1
Sistem başına bir konfigürasyon ayarına neden her bir kullanım ortamı ortam değişkeninin tercih edildiğini açıklayabilir misiniz? $ sudo apt-get install gcc-6 gcc-7 $ CC="gcc-7" ./configure <much output> $ make # uses gcc-7 Oysa sudo update-alternatives gcc gcc-7ABI’leri yanlışlıkla değiştirmemeniz gerektiğinden emin olurdu.
kfsone

14

Düzenle:

Bu, örneğin ilk önce sürümü yüklediğinizi varsayar:

sudo apt install gcc-4.9 g++-4.9

Orijinal:

Ve burada tembel olanlar için tek bir gömlek var, sadece istediğiniz versiyondaki numarayı değiştirin. Gcc ve / veya g ++ için değişiklik yapacak

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

Bu örnekte 4.9'a geçtim.

Hata kontrolü yoktur ve bu örnekte olmayanlar vardır, bu yüzden çalıştırmadan önce neyin çalıştırılacağını kontrol etmek isteyebilirsiniz. Sadece eklemek yankı önce sudo . Bütünlüğü sağlamak için de kontrol satırı sağlarım:

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

Çekin çıktısı şöyle bir şey olmalı:

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

Sonrasında sürümü kontrol edebilirsiniz:

gcc --version

Yarı detaylı açıklama:

  • ls -la / usr / bin / / usr / bin içindeki tüm dosyaları listeler
  • | pipe (send) çıkışı bir sonraki komuta
  • grep -oP , satır başına arama düzeniyle eşleşir. o sadece eşleşen çizginin tamamını değil sonucu gösterir. P'ye perl-regex kullanmasını söyler. Burada regex'e girmeyeceğim, istersen oku.
  • xargs basitçe söylemek gerekirse, ona aktarılan sonuçları toplar ve hepsini sonuna kadar gönderir. yani xargs izleyen komuta
  • iyi bash , bu bash. C bayrağı bir komut olarak dizesi kullanmak söyler. Bu örnekte , ilk (0) argümanı atlayarak xargs'dan gönderilen argümanların üzerinden atlar, bu durumda döngü 4.9 atlar . 0 argümanı bağlantıyı değiştirmek için döngüde kullanılır.
  • ln -s -f s bayrağı sembolik bir bağlantı yapar f gerekirse ilk bağlantısını kaldırdıktan kuvvetler.

2
Çok eski bir soru, ancak bu cevap eski mesajların cevaplarını gözden geçirirken aramamız gereken cevherlerden biri gibi görünüyor ...
mook765

Parlak! En iyi cevap eller aşağı!
Gabriel Staples,

-1

Geçici bir dizinde sembolik bir bağlantıya ne dersiniz:

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


Kabul etmeliyim ki: bu mükemmel bir cevap.
user643722
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.