Update alternatives error no alternatives for gcc

So I have installed gcc-4.4 and gcc-4.3 (same for g++). Now as far as I remember there is a tool in Ubuntu which sets the symlinks for you if you just tell it which version you want. However it doe...

Complete set (I hope) of update-alternatives commands for gcc with slave entries for cpp, g++, gcc-ar, gcc-nm, gcc-ranlib, gcov, gcov-dump, gcov-tool, lto-dump & matching x86_64-linux-gnu- links!
Implemented / tested on Debian bookworm (testing)
Obviously, double-check before copy/pasting and hitting ⮐Enter

BACKGROUND

I’m not a programmer or coder or anything, but I do admin a number of Linux servers (CentOS and Debian) and run Debian testing at home.  Usually I just apt install something.  Rarely do I have to ./configure && make && make install so beyond that I don’t have much knowledge.  Before this, I only knew of gcc and g++, but have discovered at least 15 other links associated with the GNU Compiler Collection on my system, each pointing to a corresponding binary or other link.

Today, I have GCC 12 installed and trying to build something, but it’s some older code so GCC 12 is too new.  Time sure does fly, I remember when GCC 4 was common!  When I checked, my system has versions 8, 9, 10, and 11 also.  Yet when I updated GCC to point to the version 11 binaries, it didn’t change anything.  I realized gcc-11 wasn’t even a binary anymore.  It’s a link now too, to x86_64-linux-gnu-gcc-11 which is the target binary.  In fact, all of the binaries now start with a x86_64-linux-gnu- and end with a -vers and have a corresponding generic link starting with x86_64-linux-gnu-.

I came up with this command then, to install the alternatives that can be switched with update-alternatives command.  Just replace the value of the vers variable in the beginning to correspond to the version you have installed, the priority will be based on the version, so version 12 has 120 priority, 11 has 110, and so on.  In the end, 20 links are updated for each version!

Multi-line:

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}"

Single line:
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}"

I am running ubuntu 18.04 and I currently have:

(tensorflow_p36) ubuntu@user:~$ gcc --version
gcc (GCC) 4.8.5

(tensorflow_p36) ubuntu@user:~$ gcc-8 --version
gcc-8 (Ubuntu 8.3.0-6ubuntu1~18.04.1) 8.3.0

(tensorflow_p36) ubuntu@user:~$ which gcc
/home/ubuntu/anaconda3/envs/tensorflow_p36/bin/gcc

I am trying to use the latest gcc-8 as show here. However when I run

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

I get the following error:

update-alternatives: error: alternative g++ can’t be slave of gcc: it
is a master alternative

When I try:

(tensorflow_p36) ubuntu@user:~$ sudo update-alternatives --config gcc

I get another error:

update-alternatives: error: no alternatives for gcc

How is it that I do not have alternative for gcc? Any suggestions on how I can resolve this error and configure gcc-8 to be the default gcc installation would be appreciated.


Running which gcc from outside the conda environment does not return anything:

ubuntu@user:~$ which gcc
ubuntu@user:~$

but

ubuntu@user:~$ gcc-8 --version
gcc-8 (Ubuntu 8.3.0-6ubuntu1~18.04.1) 8.3.0

Update. I’m trying the following as per the helpful suggestion below, but still to no avail.

(tensorflow_p36) ubuntu@user:~$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 40
(tensorflow_p36) ubuntu@user:~$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 60
(tensorflow_p36) ubuntu@user:~$ sudo update-alternatives --config g++
There are 3 choices for the alternative g++ (providing /usr/bin/g++).

  Selection    Path                             Priority   Status
------------------------------------------------------------
* 0            /usr/bin/x86_64-linux-gnu-g++-7   100       auto mode
  1            /usr/bin/g++-4.8                  60        manual mode
  2            /usr/bin/g++-8                    40        manual mode
  3            /usr/bin/x86_64-linux-gnu-g++-7   100       manual mode

Press <enter> to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/bin/g++-8 to provide /usr/bin/g++ (g++) in manual mode

So far so good, but when I test the g++ version, it’s still the same!

~$ g++ --version
g++ (GCC) 4.8.5

It is often useful to have installed never versions of the compiler in our systems as they often provide better performance and extended features, such as support for newer language features and better debugging information. In the case of ubuntu the new GCC stable packages can be obtained from the Ubuntu Toolchain PPA.

To install them add the ppa repository and update the APT database:

$ sudo add-apt-repository ppa:ubuntu-toolchain-r/test
$ sudo apt-get update

Then install the desired GCC and G++ versions. At the moment of writing this page the latest available version is 7.2.0 (that correspond to the packages gcc-7 g++-7). Check if newer versions are available.

$ sudo apt-get install gcc g++ gcc-5 g++-5 gcc-6 g++-6 gcc-7 g++-7

Now the different compiler versions are available in the system by using different command names (that is, gcc-5, gcc-6, etc.), but the default version, the one that is executed with the command gcc, will still be the previous one. To change the default version executed with the gcc command we have to configure the alternatives in the system. First lets remove any previous configuration with:

$ sudo update-alternatives --remove-all gcc

Which can show the error update-alternatives: error: no alternatives for gcc if no previous alternatives were configured. The configure the alternatives modifying it accordingly to the versions available on your system. Each alternative has a priority associated with it. When a link group is in automatic mode, the alternatives pointed to by members of the group will be those which have the highest priority.

$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 90 --slave /usr/bin/g++ g++ /usr/bin/g++-5
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 80 --slave /usr/bin/g++ g++ /usr/bin/g++-6
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70 --slave /usr/bin/g++ g++ /usr/bin/g++-7

Once the different alternatives for the gcc package have been created then it can be configured with:

$ sudo update-alternatives --config gcc

And a menu similar to this will appear. Select, for example, the option 3 to set as default gcc-7 instead of gcc-5:

There are 3 choices for the alternative gcc (providing /usr/bin/gcc).

  Selection    Path            Priority   Status
------------------------------------------------------------
* 0            /usr/bin/gcc-5   90        auto mode
  1            /usr/bin/gcc-5   90        manual mode
  2            /usr/bin/gcc-6   80        manual mode
  3            /usr/bin/gcc-7   70        manual mode

Press <enter> to keep the current choice[*], or type selection number: 3
update-alternatives: using /usr/bin/gcc-7 to provide /usr/bin/gcc (gcc) in manual mode

Then test the version executed with the gcc command:

$ g++ -v
....
gcc version 7.2.0 (Ubuntu 7.2.0-1ubuntu1~16.04)


Introduction

The GNU Compiler Collection (https://gcc.gnu.org/) is the default compiler on GNU/Linux operating systems like Ubuntu and Raspbian. It evolved from the GNU C Compiler project and kept its acronym while adding support for programming languages like C++, Objective-C, and Go.

Switching between GCC versions in Ubuntu

The versions of GCC in the Ubuntu main repositories are

  • Ubuntu 16.04: GCC 5.5
  • Ubuntu 18.04: GCC 7.3

Sometimes, however, you need to use a different version of GCC, and you want to easily switch between versions. For example, between GCC 6 and GCC 7 in Ubuntu 18.04. To do so, you can use the update-alternatives tool. Here is how to configure update-alternatives for GCC.

First, make sure that no alternatives group for GCC exists by typing

sudo update-alternatives --remove-all gcc

which should result in the error message

update-alternatives: error: no alternatives for gcc

Now enter

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 10
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-6 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 20

where the last number in each line is the priority of the corresponding alternative.
You can check that the alternatives groups are configured by entering

update-alternatives --list gcc
update-alternatives --list g++

You can now select the desired GCC version via the interactive chooser

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

or directly via

sudo update-alternatives --set gcc [/usr/bin/gcc-6 | /usr/bin/gcc-7]
sudo update-alternatives --set g++ [/usr/bin/g++-6 | /usr/bin/g++-7]

where only one of the options inside the square brackets must be entered.

Usage

Some Useful Command-Line Options

-g generate debug output
-c compile only (do not link)
-O2 optimize for size and speed
-std=c++14 enable C++14 features
-x process for the given programming language
-c -x c++-header -o m.gch m.h turn m.h into a precompiled header (m.gch)
-Wl,-rpath,<path> -L<path> -lmylib make the linker embed the given relative path to the given library

The full list of command-line options can be viewed here.

Gotchas

Here are some of the fine points of using GCC:

Linker flags come last

When compiling source files into object files or linking object files into an executable or library file, the placement of the linker flags relative to the input file within the GCC command matters! External libraries that are being linked to need to be specified AFTER THE OBJECT FILE that refers to the symbols in the library. The linker does not know it needs to link to the external library before it sees the references in the object file. You will see error messages that complain about «undefined reference to» some external symbol if the library is not specified, or specified too early.

From the GNU documentation: «It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.»

By the way, you can use the ldd command line tool to check if all the linked libraries can be located by the dynamic loader.

C++ ABI change in GCC 5.1

The ABI for C++11 changed in GCC 5.1. This requires that libraries that were built with an older version of GCC need to be linked against after compiling with the environment variable set to «0». That is,

g++ -D_GLIBCXX_USE_CXX11_ABI=0 my_code.cpp -o my_code.o
Hiding internal implementation details

When creating a library you may want to remove internal implementation details to reduce the size of the library or to protect your intellectual property. Use the compiler flag -fvisibility=hidden in order to mark generated symbols as local (= not to be exported) by default. In your code mark selected functions, methods, or variables as global (= to be exported) by placing the GCC visibility attribute

__attribute__ (( visibility("default") ))

in front of the declaration. See this GCC Wiki entry for more information on the visibility attribute.

We’re not done yet. The library created by the linker still contains all the symbols that were marked as local. You can check whether symbols inside the binary are local or global (exported) by inspecting the library with the command-line tool nm:

nm --demangle my_library.so

where the option —demangle is for displaying C++ symbols with the familiar double-semicolon scope separators instead of cryptic alphanumeric sequences. Symbols are listed with a letter next to it, like ‘A’, ‘C’ or ‘R’. The letter indicates the type of the symbol. If the letter is in upper case, the symbol is global, otherwise it is usually local. Refer to the nm manual for details. In order to purge our local symbols from the library file, we use the command line tool «strip»:

strip -x my_library.so

where the option -x specifies that all non-global symbols should be removed.

Specifying the path to your library

If you don’t want to place your shared libraries into one of the default folders where the library loader of the operating system can find them (on Linux systems these folders are specified in /etc/ld.so.conf and in additional .conf files lying in /etc/ld.so.conf.d/) then you need to specify the paths to your libraries either by setting the LD_LIBRARY_PATH environment variable before launching the executable that links to the library, or by baking the (relative) path to the library into the executable itself.

Use the rpath option in the linking step of your executable to specify the relative path from your executable to the library. For example,

g++ class1.o class2.o -Wl,-rpath,../../my_libs -L../../my_libs -lMyLib -o my_app

creates the executable my_app that links to the dynamic library libMyLib.so located in the folder ../../my_libs, relative to the executable. If you are not familiar with -Wl; it denotes the beginning of a comma-separated sequence of options to be passed to the GCC linker (as a whitespace-separated sequence).

On Linux, you can use the readelf command-line tool to verify that the correct library search paths are baked into the generated ELF binary:

readelf -d <path to library or executable>

On macOS, look for the keyword LC_RPATH in the output of

otool -l <path to library or executable>

Sanitizers

On Ubuntu 18.04, you can install Address Sanitizer and Undefined Behavior Sanitizer for GCC 7.x via

sudo apt install libubsan0 libasan4

Address Sanitizer

This sanitizer catches certain problems related to memory management. It is instrumented into the executable with the following GCC flag

-fsanitize=address

which needs to be specified separately for the compiler and the linker.

A number of options can be passed to the address sanitizer either via the ASAN_OPTIONS environment variable or by embedding the following function:

extern "C" {
const char* __asan_default_options() {
  return "verbosity=1:help=1"; // add options here
}
}

Undefined Behavior Sanitizer

This sanitizer is for catching undefined behavior in C/C++ code. It is instrumented into the executable by passing

-fsanitize=undefined

to both the compiler and the linker.

For more information see the GCC documentation page on instrumentation options.


This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters

Show hidden characters

These commands are based on a askubuntu answer http://askubuntu.com/a/581497
To install gcc-6 (gcc-6.1.1), I had to do more stuff as shown below.
USE THOSE COMMANDS AT YOUR OWN RISK. I SHALL NOT BE RESPONSIBLE FOR ANYTHING.
ABSOLUTELY NO WARRANTY.
If you are still reading let’s carry on with the code.
sudo apt-get update &&
sudo apt-get install build-essential software-properties-common -y &&
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y &&
sudo apt-get update &&
sudo apt-get install gcc-snapshot -y &&
sudo apt-get update &&
sudo apt-get install gcc-6 g++-6 -y &&
sudo update-alternatives —install /usr/bin/gcc gcc /usr/bin/gcc-6 60 —slave /usr/bin/g++ g++ /usr/bin/g++-6 &&
sudo apt-get install gcc-4.8 g++-4.8 -y &&
sudo update-alternatives —install /usr/bin/gcc gcc /usr/bin/gcc-4.8 60 —slave /usr/bin/g++ g++ /usr/bin/g++-4.8;
When completed, you must change to the gcc you want to work with by default. Type in your terminal:
sudo update-alternatives —config gcc
To verify if it worked. Just type in your terminal
gcc -v
If everything went fine you should see gcc 6.1.1 by the time I am writing this gist
Happy coding!
See my blog post at https://www.application2000.com

I recently had the need to install a newer version of the g++ compiler on Ubuntu 12.04 LTS. I documented the approach here.

Ubuntu does not typically release new toolchains for their stable versions, instead newer toolchains are made available in a PPA (Personal Package Archive) “https://launchpad.net/~ubuntu-toolchain-r/+archive/test“ to use the repository we can use the add-apt-repository command:

sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-4.7 g++-4.7

Currently the PPA contains gcc/g++-4.7 and 4.8. After installing one or multiple of the newer versions we can use update-alternatives to switch between the different versions. The update-alternatives tool manages symlinks to the different installed versions and allow us to easily switch between them.

Before we add the new gcc/g++ lets check if we already have any alternatives setup by running:
$ update-alternatives --display gcc

If you don’t have any alternatives installed it will just print:
update-alternatives: error: no alternatives for gcc.

Lets see how to add an alternative:

$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.7
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.6

As a default when we install new alternatives they are added to a group (in this case gcc) in automatic mode. This means that the link with the highest priority will become the default. In the case above we gave gcc-4.7 a priority of 60 and gcc-4.6 a priority of 40, so the default with be gcc-4.7
The –slave options tells update-alternative that when we change gcc it should also update the g++ links.

To check that everything is ok or to switch between the compilers we can use

$ sudo update-alternatives --config gcc
There are 2 choices for the alternative gcc (providing /usr/bin/gcc).

Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/gcc-4.7 60 auto mode
1 /usr/bin/gcc-4.6 40 manual mode
2 /usr/bin/gcc-4.7 60 manual mode

Press enter to keep the current choice[*], or type selection number: 0

That is more or less it. Running gcc --version shows that we are now using the newer version:

gcc (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04) 4.7.3
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Понравилась статья? Поделить с друзьями:
  • Update alternatives error alternative path
  • Unrecoverable playback error unknown error code 0x88890008
  • Update after error teyes
  • Upc exe ошибка приложения
  • Upc exe ошибка uplay