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

Поэтому я установил 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

Есть идеи?

10 ответов

Решение

Сначала стерли текущую установку альтернатив обновлений для 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 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"

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

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

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

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

Если вы просто хотите построить вещи с другой версией gccЭто достаточно просто, даже с make cripts. Например, вы можете перейти на версию gcc в CC переменная окружения:

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

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

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

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

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

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

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

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

В этом примере нет проверок на ошибки, а что нет, поэтому вы можете проверить, что будет запущено, прежде чем запускать его. Просто добавьте эхо перед sudo. Для полноты картины я также предоставлю строку проверки:

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-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.3

sudo 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 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.4 20

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

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

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

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

Рассмотрим один способ обновления:

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

В этом случае apt будет автоматически обрабатывать ссылки на персонал. Новая версия C/C++ довольно совместима. Тебе вряд ли когда-нибудь понадобится старый.

Вы можете использовать команду альтернатив, я надеюсь, что это поможет!

      sudo apt install build-essential

sudo apt install gcc-8 g++-8 gcc-9 g++-9 gcc-10 g++-10

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 --slave /usr/bin/gcov gcov /usr/bin/gcov-10

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 --slave /usr/bin/g++ g++ /usr/bin/g++-9 --slave /usr/bin/gcov gcov /usr/bin/gcov-9

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 80 --slave /usr/bin/g++ g++ /usr/bin/g++-8 --slave /usr/bin/gcov gcov /usr/bin/gcov-8

sudo update-alternatives --config gcc

https://snipboard.io/zE4B9D.jpg

Полный набор (надеюсь) команд для с подчиненными записями дляcpp, ,gcc-ar,gcc-nm,gcc-ranlib,gcov,gcov-dump,gcov-tool,lto-dumpи соответствующие ссылки! Реализовано / протестировано на книжном черве Debian (тестирование) Очевидно, дважды проверьте перед копированием/вставкой и нажатием ⮐Enter

ФОН

Я не программист, не кодер или что-то в этом роде, но я администрирую несколько серверов Linux (CentOS и Debian) и провожу тестирование Debian дома. Обычно я простоapt installчто-нибудь. Редко мне приходится./configure && make && make installтак что помимо этого у меня мало знаний. До этого я знал толькоgccиg++, но обнаружил по крайней мере 15 других ссылок, связанных с коллекцией компиляторов GNU в моей системе, каждая из которых указывает на соответствующий двоичный файл или другую ссылку.

Сегодня я установил GCC 12 и пытаюсь что-то собрать, но это какой-то старый код, поэтому GCC 12 слишком новый. Время действительно летит, я помню, когда GCC 4 был обычным явлением! Когда я проверил, моя система также имеет версии 8, 9, 10 и 11. Тем не менее, когда я обновил GCC, чтобы указать на двоичные файлы версии 11, это ничего не изменило. Я понял, что gcc-11 больше не был двоичным файлом. Теперь это тоже ссылка наx86_64-linux-gnu-gcc-11который является целевым двоичным файлом. Фактически, все двоичные файлы теперь начинаются с и заканчиваются на-versи иметь соответствующую общую ссылку, начинающуюся сx86_64-linux-gnu-.

Тогда я придумал эту команду, чтобы установить альтернативы, которые можно переключать с помощьюupdate-alternativesкоманда. Просто замените значениеversв начале, чтобы соответствовать установленной версии, приоритет будет зависеть от версии, поэтому версия 12 имеет приоритет 120, 11 — 110 и так далее. В итоге обновляется по 20 ссылок на каждую версию!

Многострочный:

      vers=<vers>; update-alternatives \
  --install /usr/bin/gcc gcc /usr/bin/gcc-"${vers}" "${vers}"0 \
  --slave /usr/bin/x86_64-linux-gnu-gcc x86_64-linux-gnu-gcc /usr/bin/x86_64-linux-gnu-gcc-"${vers}" \
  --slave /usr/bin/g++ g++ /usr/bin/g++-"${vers}" \
  --slave /usr/bin/x86_64-linux-gnu-g++ x86_64-linux-gnu-g++ /usr/bin/x86_64-linux-gnu-g++-"${vers}" \
  --slave /usr/bin/cpp cpp /usr/bin/cpp-"${vers}" \
  --slave /usr/bin/x86_64-linux-gnu-cpp x86_64-linux-gnu-cpp /usr/bin/x86_64-linux-gnu-cpp-"${vers}" \
  --slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-"${vers}" \
  --slave /usr/bin/x86_64-linux-gnu-gcc-ar x86_64-linux-gnu-gcc-ar /usr/bin/x86_64-linux-gnu-gcc-ar-"${vers}" \
  --slave /usr/bin/gcc-nm gcc-nm /usr/bin/gcc-nm-"${vers}" \
  --slave /usr/bin/x86_64-linux-gnu-gcc-nm x86_64-linux-gnu-gcc-nm /usr/bin/x86_64-linux-gnu-gcc-nm-"${vers}" \
  --slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-"${vers}" \
  --slave /usr/bin/x86_64-linux-gnu-gcc-ranlib x86_64-linux-gnu-gcc-ranlib /usr/bin/x86_64-linux-gnu-gcc-ranlib-"${vers}" \
  --slave /usr/bin/gcov gcov /usr/bin/gcov-"${vers}" \
  --slave /usr/bin/x86_64-linux-gnu-gcov x86_64-linux-gnu-gcov /usr/bin/x86_64-linux-gnu-gcov-"${vers}" \
  --slave /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-"${vers}" \
  --slave /usr/bin/x86_64-linux-gnu-gcov-dump x86_64-linux-gnu-gcov-dump /usr/bin/x86_64-linux-gnu-gcov-dump-"${vers}" \
  --slave /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-"${vers}" \
  --slave /usr/bin/x86_64-linux-gnu-gcov-tool x86_64-linux-gnu-gcov-tool /usr/bin/x86_64-linux-gnu-gcov-tool-"${vers}" \
  --slave /usr/bin/lto-dump lto-dump /usr/bin/lto-dump-"${vers}" \
  --slave /usr/bin/x86_64-linux-gnu-lto-dump x86_64-linux-gnu-lto-dump /usr/bin/x86_64-linux-gnu-lto-dump-"${vers}"

Одна линия:
vers=<vers>; update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-"${vers}" "${vers}"0 --slave /usr/bin/x86_64-linux-gnu-gcc x86_64-linux-gnu-gcc /usr/bin/x86_64-linux-gnu-gcc-"${vers}" --slave /usr/bin/g++ g++ /usr/bin/g++-"${vers}" --slave /usr/bin/x86_64-linux-gnu-g++ x86_64-linux-gnu-g++ /usr/bin/x86_64-linux-gnu-g++-"${vers}" --slave /usr/bin/cpp cpp /usr/bin/cpp-"${vers}" --slave /usr/bin/x86_64-linux-gnu-cpp x86_64-linux-gnu-cpp /usr/bin/x86_64-linux-gnu-cpp-"${vers}" --slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-"${vers}" --slave /usr/bin/x86_64-linux-gnu-gcc-ar x86_64-linux-gnu-gcc-ar /usr/bin/x86_64-linux-gnu-gcc-ar-"${vers}" --slave /usr/bin/gcc-nm gcc-nm /usr/bin/gcc-nm-"${vers}" --slave /usr/bin/x86_64-linux-gnu-gcc-nm x86_64-linux-gnu-gcc-nm /usr/bin/x86_64-linux-gnu-gcc-nm-"${vers}" --slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-"${vers}" --slave /usr/bin/x86_64-linux-gnu-gcc-ranlib x86_64-linux-gnu-gcc-ranlib /usr/bin/x86_64-linux-gnu-gcc-ranlib-"${vers}" --slave /usr/bin/gcov gcov /usr/bin/gcov-"${vers}" --slave /usr/bin/x86_64-linux-gnu-gcov x86_64-linux-gnu-gcov /usr/bin/x86_64-linux-gnu-gcov-"${vers}" --slave /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-"${vers}" --slave /usr/bin/x86_64-linux-gnu-gcov-dump x86_64-linux-gnu-gcov-dump /usr/bin/x86_64-linux-gnu-gcov-dump-"${vers}" --slave /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-"${vers}" --slave /usr/bin/x86_64-linux-gnu-gcov-tool x86_64-linux-gnu-gcov-tool /usr/bin/x86_64-linux-gnu-gcov-tool-"${vers}" --slave /usr/bin/lto-dump lto-dump /usr/bin/lto-dump-"${vers}" --slave /usr/bin/x86_64-linux-gnu-lto-dump x86_64-linux-gnu-lto-dump /usr/bin/x86_64-linux-gnu-lto-dump-"${vers}"

Другие вопросы по тегам