Как выбрать версию gcc и g++ по умолчанию?

Итак, я установил gcc-4.4 и gcc-4.3 (то же самое для g++). Теперь, насколько я помню, в Ubuntu есть инструмент, который устанавливает символические ссылки для вас, если вы просто укажете ему, какую версию вы хотите. Однако, похоже, это не работает в новейшей версии, что я нахожу разочаровывающим.

root@nexus:~# update-alternatives --config gccupdate-alternatives: error: no alternatives for gcc.root@nexus:~# update-alternatives --config ccThere is only one alternative in link group cc: /usr/bin/gccNothing to configure.root@nexus:~# dpkg -l | grep gcc | awk '{print $2}'gccgcc-4.3gcc-4.3-basegcc-4.3-multilibgcc-4.4gcc-4.4-basegcc-4.4-multilibgcc-4.5-basegcc-multiliblib32gcc1libgcc1

Есть какие-нибудь идеи?

Сначала сотрите текущий update-alternatives установка для gcc и g++:

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

Установка Пакетов

Похоже, что оба gcc-4.3 и gcc-4.4 устанавливаются после установки build-essential. Однако мы можем явно установить следующие пакеты:

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 10sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4 20sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.3 10sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.4 20sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30sudo update-alternatives --set cc /usr/bin/gccsudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30sudo update-alternatives --set c++ /usr/bin/g++

Настройка альтернатив

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

sudo update-alternatives --config gccsudo update-alternatives --config g++

Или переключитесь с помощью скрипта:

#!/bin/shif [ -z "$1" ]; then    echo "usage: $0 version" 1>&2    exit 1fiif [ ! -f "/usr/bin/gcc-$1" ] || [ ! -f "/usr/bin/g++-$1" ]; then    echo "no such version gcc/g++ installed" 1>&2    exit 1fiupdate-alternatives --set gcc "/usr/bin/gcc-$1"update-alternatives --set g++ "/usr/bin/g++-$1"

выполнить в терминале :

gcc -vg++ -v

Ладно, эта часть довольно проста. Сложность заключается в том, что когда вы выполняете команду GCC, на самом деле это символьная ссылка на ту версию GCC, которую вы используете. Это означает, что мы можем создать символическую ссылку из GCC на любую версию GCC, которую мы захотим.

  • Вы можете увидеть символическую ссылку :
ls -la /usr/bin | grep gcc-4.4ls -la /usr/bin | grep g++-4.4
  • Итак, что нам нужно сделать, это удалить символическую ссылку GCC и символическую ссылку G++, а затем воссоздать их, связанные с GCC 4.3 и G++ 4.3:
rm /usr/bin/gccrm /usr/bin/g++ln -s /usr/bin/gcc-4.3 /usr/bin/gccln -s /usr/bin/g++-4.3 /usr/bin/g++
  • Теперь, если мы снова проверим символические ссылки, мы увидим, что GCC и G++ теперь связаны с GCC 4.3 и G++ 4.3:
ls -la /usr/bin/ | grep gccls -la /usr/bin/ | grep g++
  • Наконец, мы можем снова проверить наш GCC -v и убедиться, что мы используем правильную версию:
gcc -vg++ -v

Действительно ли это желательно? Существуют изменения ABI между gcc версии. Компиляция чего-либо с одной версией (например, всей операционной системы), а затем компиляция чего-либо другого с другой версией может привести к конфликту.

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

Если вы просто хотите создавать что-то с другой версией gcc, это достаточно просто, даже с помощью makescripts. Например, вы можете передать версию gcc в CC переменная среды:

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

Возможно, вам это не понадобится в команде make (сценарии настройки обычно подключают ее), но это не повредит.

Редактировать:

Это предполагает, что вы сначала установили версию, например, с:

sudo apt install gcc-4.9 g++-4.9

Оригинал:

А вот однострочник для тех, кому лень, просто измените номер в конце на нужную вам версию. Это внесет изменения в ссагпз и/или 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/gccsudo ln -s -f /usr/bin/gcc-ar-4.9 /usr/bin/gcc-arsudo ln -s -f /usr/bin/gcc-nm-4.9 /usr/bin/gcc-nmsudo ln -s -f /usr/bin/gcc-ranlib-4.9 /usr/bin/gcc-ranlibsudo 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-gccsudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-ar-4.9 /usr/bin/x86_64-linux-gnu-gcc-arsudo ln -s -f /usr/bin/x86_64-linux-gnu-gcc-nm-4.9 /usr/bin/x86_64-linux-gnu-gcc-nmsudo 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 /usr/bin
  • | передайте (отправьте) выходные данные следующей команде
  • grep -oP соответствует регулярному выражению поиска для каждой строки. o показывает только результат, а не всю совпадающую строку. P сообщает grep использовать perl-regex. Я не буду здесь вдаваться в регулярные выражения, почитайте об этом, если хотите.
  • xargs проще говоря, он собирает результаты, которые передаются ему по конвейеру, и отправляет их все в конец. т.е. в команду, следующую за xargs
  • удар что ж, это баш. То c флаг указывает ему использовать строку в качестве команды. В этом примере он перебирает аргументы, отправленные из xargs пропуская первый (0-й) аргумент, в этом случае цикл пропускается 4.9. 0-й аргумент используется в цикле для изменения ссылки.
  • ln -s -f То s флаг создает символическую ссылку, f при необходимости сначала отключите соединение.

Я обычно настраиваю также связанные инструменты gcc (gcc-ar, ...) в качестве подчиненных устройств, так что вы можете переключать их все сразу:

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.3 10 \    --slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-4.3 \    --slave /usr/bin/gcc-nm gcc-nm /usr/bin/gcc-nm-4.3 \    --slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-4.3sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4 20 \    --slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-4.4 \    --slave /usr/bin/gcc-nm gcc-nm /usr/bin/gcc-nm-4.4 \    --slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-4.4
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.3 10sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.4 20

Затем, чтобы выбрать значение по умолчанию:

sudo update-alternatives --config gccsudo update-alternatives --config g++

Я хотел переключиться с gcc / g++ 9.x (был установлен) на 10.x:

  1. Установлена новая желаемая версия:
sudo apt install gcc-10sudo apt install g++-10
  1. Перейти на новую версию:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10
  1. Тест с:
gcc --versiong++ --version

Старая версия все еще установлена, на случай, если вам нужно переключиться обратно, просто используйте форму команд 2. с вашей старой версией!

Как насчет символической ссылки во временном каталоге:

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

Хорошо, так что же вы используете для управления версиями?

Как объяснил @Oli, это плохая идея. Список рассылки Debian-devel: “Я не думаю, что для управления версиями следует использовать альтернативные варианты. Например, мы не используем альтернативы ни для gcc, ни для Python.” Re: llvm-defaults vs update alternatives