Як вибрати версію gcc та g ++ за замовчуванням?


206

Тому я встановив gcc-4.4 та gcc-4.3 (те саме для g ++). Наскільки я пам'ятаю, в Ubuntu є інструмент, який встановлює для вас символьні посилання, якщо ви просто скажете, яку версію ви хочете. Однак це, здається, не працює в новітній версії, що мені здається невтішним.

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

Будь-які ідеї?


1
Як пояснив @Oli, це погана ідея. Список розсилки Debian-devel: "Я не думаю, що альтернативи не слід використовувати для версії. Наприклад, ми не використовуємо альтернативи для gcc, ні для Python." lists.debian.org/debian-devel/2014/06/msg00381.html
hmijail

1
ОК, так що ж ви використовуєте для управління версіями?
WillC

Відповіді:


271

Вперше видалено поточну установку альтернатив оновлення для gcc та g ++:

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

Встановити пакети

Схоже, що і gcc-4.3, і gcc-4.4 встановлюються після встановлення. Однак ми можемо явно встановити такі пакети:

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

Встановіть альтернативи

Символічні посилання cc і c ++ встановлені за замовчуванням. Ми встановимо символьні посилання для gcc і g ++, потім зв’яжемо cc і c ++ до gcc і g ++ відповідно. (Зверніть увагу , що 10, 20і 30варіанти є пріоритетними для кожної альтернативи.)

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

Налаштування альтернатив

Останній крок - налаштування команд за замовчуванням для gcc, g ++. Легко перемикатися між 4.3 та 4.4 інтерактивно:

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

Або переключитися за допомогою сценарію:

#!/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
Thx, тому вам доведеться додавати їх вручну до оновлень-альтернатив. IIRC, більш ранні версії Ubuntu, зробили це автоматично.
Нілс

1
Це особливо корисно для мене при складанні модулів nvidia для різних ядер. Дякую вам за роз'яснення альтернатив оновленням
earthmeLon

1
Дякую! Я використовував вашу іншу відповідь, щоб оновити з 4,6 до 4,7. Я хотів використати цю відповідь, але я не був впевнений, чому ви ставите числа, як 10 20 30, після деяких з вас команд. Не могли б ви пояснити?
Мартін Дроздик

7
Номери є пріоритетними, як виявилося, згідно з даними сторінки. Я думаю, що в разі видалення однієї з версій вона використовуватиме ті пріоритети, щоб визначити, яка з них повинна стати новою за замовчуванням.
Ібрагім

1
@Ibrahim: Ні, вони визначають, що обирається, коли ви вибираєте автоматичний режим
Cookie

41

виконати в терміналі:

gcc -v
g++ -v

Гаразд, так що ця частина досить проста. Складна частина полягає в тому, що при видачі команди GCC це фактично сиболічне посилання на будь-яку версію GCC, яку ви використовуєте. Що це означає, що ми можемо створити символічний зв’язок від GCC до тієї версії GCC, яку ми хочемо.

  • Ви можете побачити символічне посилання:
ls -la /usr/bin | grep gcc-4.4
ls -la /usr/bin | grep g++-4.4
  • Тож, що нам потрібно зробити, - це видалити симпосилання GCC та симпосилання G ++, а потім відтворити їх, пов'язані з GCC 4.3 та 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++
  • Тепер якщо ми ще раз перевіримо символічні посилання, ми побачимо, що GCC & G ++ тепер пов'язані з GCC 4.3 та G ++ 4.3:
ls -la /usr/bin/ | grep gcc
ls -la /usr/bin/ | grep g++
  • Нарешті ми можемо перевірити наш GCC -v ще раз і переконатися, що ми використовуємо правильну версію:
gcc -v
g++ -v

1
Саме те, що я шукав! Забув про здатність символізувати "gcc" до будь-якої інстальованої вами версії. Дякую!
CalebHC

більш простий і легший і безпечніший метод!
sailfish009

21

Це дійсно бажано? Є зміни ABI між gccверсіями. Якщо компілювати щось з однією версією (наприклад, всією операційною системою), а потім компілювати щось інше з іншою версією, це може спричинити конфлікт.

Наприклад, модулі ядра завжди повинні бути зібрані з тією ж версією, яка gccвикористовується для компіляції ядра. Зважаючи на це, якщо ви вручну змінили симпосилання між /usr/bin/gccверсією, яка використовується у вашій версії Ubuntu, майбутні вбудовані в DKMS модулі можуть використовувати неправильну gccверсію.

Якщо ви просто хочете створювати речі з іншою версією gcc, це досить просто, навіть із написами. Наприклад, ви можете передати в версії gccв CCзмінної оточення:

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

Можливо, він вам не знадобиться в команді make (сценарії налаштування зазвичай втягують його), але це не зашкодить.


1
Thx для вашого коментаря. Я знаю змінну CC, але це насправді не було питанням.
Нілс

2
Щоправда, але я пояснив, чому gccце не є частиною alternativesсистеми, і чому це не особливо бажано. Якщо жоден із них не передумає, просто зробіть це вручну.
Олі

1
Це було раніше? Тепер вони просто зняли його ?! Компіляція програмного забезпечення (користувацького простору) з різними версіями gcc має бути абсолютно нормальною .. ця дискусія стає підвіконням ..
Nils

1
Чи можете ви пояснити, чому змінні середовища для виклику переважніші для налаштувань конфігурації для всієї системи? $ sudo apt-get install gcc-6 gcc-7 $ CC="gcc-7" ./configure <much output> $ make # uses gcc-7 Тоді як sudo update-alternatives gcc gcc-7би переконався, що ви випадково не переключите ІБС.
kfsone

14

Редагувати:

Це передбачає, що ви встановили версію спочатку, наприклад:

sudo apt install gcc-4.9 g++-4.9

Оригінал:

А ось однолінійний для тих, хто лінивий, просто змініть, змінивши номер в кінці на потрібну версію. Він внесе зміни для gcc та / або 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

У цьому прикладі я перейшов на 4,9

У цьому прикладі немає перевірок помилок, а що ні, у цьому прикладі, тому ви, можливо, захочете перевірити, що буде запущено, перш ніж запустити його. Просто додайте ехо перед судо . Для повноти надаю і контрольну лінію:

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

Вихід з чека повинен бути приблизно таким:

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

Ви можете перевірити версію після:

gcc --version

Напівточне пояснення:

  • ls -la / usr / bin / перелічує всі файли в / usr / bin
  • | передати (відправити) вихід до наступної команди
  • grep -oP відповідає пошуковому знаку за рядком. o показує результат не лише у всіх збіганих рядках. P говорить grep використовувати perl-регулярний вираз. Я не буду тут вдаватися в регулярний вираз, читайте його, якщо хочете.
  • xargs, просто кажучи, він збирає результати, які передаються до нього, і надсилає їх усі до кінця. тобто до команди, що слідує за xargs
  • баш добре, це баш. З прапором каже його використовувати рядок в якості команди. У цьому прикладі він циркулює над аргументами, надісланими з xargs , пропускаючи перший (0-й) аргумент, в цьому випадку цикл пропускає 4.9 . 0-й аргумент використовується в циклі для зміни посилання.
  • пер -s -f s прапор має символічне посилання, ф сил видалити зв'язок першим , якщо це необхідно.

2
Дуже давнє запитання, але ця відповідь, здається, є однією з дорогоцінних каменів, на які слід шукати, переглядаючи відповіді на старі дописи ...
mook765

Блискуче! Найкраща відповідь руки вниз!
Габріель Степлес

-1

Як щодо символічного посилання у тимчасовому каталозі:

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


Мушу визнати: це відмінна відповідь.
користувач643722
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.