GCC 16.2 can be installed directly from the Ubuntu 26.10 repositories. On Ubuntu 24.04, the exact release can instead be built from source alongside the existing GCC 13 installation. This guide puts the package-based installation first, followed by the source build, then shows how to switch GCC and G++ together with update-alternatives for existing CMake projects.
Choose the installation section for your Ubuntu release. Ubuntu 26.04 LTS and Ubuntu 26.10 have different GCC packages: the catalog checked for 26.04 lists a development snapshot, while 26.10 provides GCC 16.2. These are installation instructions; the source-build starting machine has Ubuntu 24.04 on x86-64 and GCC 13.3.0.
Ubuntu 26.10: install GCC 16.2 from the repository
The standard universe repository provides gcc-16 and g++-16 from the GCC 16.2 release series. No PPA or compiler source build is needed. Enable Universe if necessary, refresh the package index and inspect the candidate versions before installing:
sudo add-apt-repository universe
sudo apt update
apt-cache policy gcc-16 g++-16
sudo apt install gcc-16 g++-16
gcc-16 -dumpfullversion
g++-16 -dumpfullversion
For the release discussed here, the version checks should print 16.2.0. Later repository updates may provide a newer patch release; apt-cache policy shows the actual candidate. The versioned compiler paths are /usr/bin/gcc-16 and /usr/bin/g++-16. Installing those packages does not by itself select them as the generic gcc and g++ commands.
To keep the GCC 13 series available on Ubuntu 26.10 too, install its versioned packages if they are not already present:
sudo apt install gcc-13 g++-13
The repository supplies its supported GCC 13 patch version, which need not be the 13.3.0 installed on the original Ubuntu 24.04 machine. Continue with the alternatives section after installation; skip the source-build section below.
What about Ubuntu 26.04 LTS?
Do not assume every Ubuntu 26 release provides the same compiler. The Ubuntu package catalog checked for resolute (26.04 LTS) lists 16-20260322-1ubuntu1, a pre-release development snapshot, rather than GCC 16.2. Check apt-cache policy gcc-16 g++-16 on that system, since updates and enabled repositories can change availability. The simple GCC 16.2 package installation above specifically targets Ubuntu 26.10 (stonking).
Ubuntu 24.04: build the exact GCC 16.2.0 release
The enabled Ubuntu repositories on this machine do not provide GCC 16. The Ubuntu Toolchain test PPA index checked for Noble contains a development snapshot named 16-20260315-1ubuntu1~24~ppa1, so simply installing a package called gcc-16 from that index would not install the 16.2 release. To select the exact release, use the official GCC 16.2.0 source archive. Package availability can change; check the candidate version before choosing a package-based installation.
Run the following in Bash. Use new source and build directories for this version. The build runs as an ordinary user; only package installation and the final installation into /opt need sudo.
sudo apt update
sudo apt install build-essential flex bison texinfo curl wget xz-utils
mkdir -p "$HOME/dev/tools/src" "$HOME/dev/build/gcc-16.2.0"
cd "$HOME/dev/tools/src"
curl -fLO https://gcc.gnu.org/pub/gcc/releases/gcc-16.2.0/gcc-16.2.0.tar.xz
curl -fLO https://gcc.gnu.org/pub/gcc/releases/gcc-16.2.0/sha512.sum
sha512sum --check --ignore-missing sha512.sum
tar -xf gcc-16.2.0.tar.xz
cd gcc-16.2.0
./contrib/download_prerequisites
cd "$HOME/dev/build/gcc-16.2.0"
CC=/usr/bin/gcc-13 CXX=/usr/bin/g++-13 \
"$HOME/dev/tools/src/gcc-16.2.0/configure" \
--prefix=/opt/gcc-16.2.0 \
--enable-languages=c,c++ \
--disable-multilib
make -j6
sudo make install
/opt/gcc-16.2.0/bin/gcc -dumpfullversion
/opt/gcc-16.2.0/bin/g++ -dumpfullversion
Run the download, checksum, extraction, configuration, build and installation steps in order, and continue only when the preceding step succeeds. sha512sum should report that the downloaded archive is OK. The final version checks should print 16.2.0. Building GCC uses substantial disk space and can take a long time; adjust -j6 to the memory and CPU capacity available.
The download_prerequisites script fetches the support-library sources required by GCC. The compiler is built outside its source directory, as recommended by the GCC configuration guide. --enable-languages=c,c++ selects the C and C++ front ends; --disable-multilib avoids building 32-bit multilib support on this x86-64 machine.
The CC=/usr/bin/gcc-13 and CXX=/usr/bin/g++-13 assignments select the existing compilers used to bootstrap GCC itself. They do not select the version being installed: that comes from the GCC 16.2.0 sources. A normal native bootstrap builds the initial compiler with GCC 13, then uses the new compiler for the later stages.
Register both versions with update-alternatives
First inspect the current setup:
update-alternatives --query gcc
update-alternatives --query g++
update-alternatives --query cc
update-alternatives --query c++
ls -l /usr/bin/gcc /usr/bin/g++ /usr/bin/cc /usr/bin/c++
On the original Ubuntu 24.04 machine, gcc and g++ are ordinary symlinks with no alternatives groups of their own, while cc and c++ already have separate groups. The following setup uses gcc as the master and g++, gcc-ar, gcc-nm and gcc-ranlib as its slaves. If another machine already has independent groups for these commands, inspect and reconcile that configuration before applying this setup.
Register the installed GCC 13 drivers:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 130 \
--slave /usr/bin/g++ g++ /usr/bin/g++-13 \
--slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-13 \
--slave /usr/bin/gcc-nm gcc-nm /usr/bin/gcc-nm-13 \
--slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-13
For the Ubuntu 26.10 package installation, register GCC 16 using the versioned paths under /usr/bin:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-16 160 \
--slave /usr/bin/g++ g++ /usr/bin/g++-16 \
--slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-16 \
--slave /usr/bin/gcc-nm gcc-nm /usr/bin/gcc-nm-16 \
--slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-16
For the Ubuntu 24.04 source installation, use this command instead of the preceding GCC 16 registration command:
sudo update-alternatives --install /usr/bin/gcc gcc /opt/gcc-16.2.0/bin/gcc 160 \
--slave /usr/bin/g++ g++ /opt/gcc-16.2.0/bin/g++ \
--slave /usr/bin/gcc-ar gcc-ar /opt/gcc-16.2.0/bin/gcc-ar \
--slave /usr/bin/gcc-nm gcc-nm /opt/gcc-16.2.0/bin/gcc-nm \
--slave /usr/bin/gcc-ranlib gcc-ranlib /opt/gcc-16.2.0/bin/gcc-ranlib
Keep the separate cc and c++ groups pointing at the generic GCC drivers. On the standard Ubuntu layout, these alternatives are already registered:
sudo update-alternatives --set cc /usr/bin/gcc
sudo update-alternatives --set c++ /usr/bin/g++
The priorities, 130 and 160, determine the preferred choice in automatic mode. The explicit --set commands below select manual mode. Installing the second alternative can already select it if the group is still in automatic mode.
Switch to GCC 16.2
For the package installation on Ubuntu 26.10:
sudo update-alternatives --set gcc /usr/bin/gcc-16
For the source installation on Ubuntu 24.04:
sudo update-alternatives --set gcc /opt/gcc-16.2.0/bin/gcc
After the appropriate selection, clear Bash’s command cache and check all four commands:
hash -r
gcc --version
g++ --version
cc --version
c++ --version
All four version checks should identify GCC 16.2.0. The C++ compiler and GCC binutils wrappers switch with the master, so there is only one alternatives selection to make. For an interactive menu, run:
sudo update-alternatives --config gcc
Switch back to GCC 13
sudo update-alternatives --set gcc /usr/bin/gcc-13
hash -r
gcc --version
g++ --version
cc --version
c++ --version
This restores the installed version-13 drivers without uninstalling GCC 16.2. The exact GCC 13 patch version depends on the Ubuntu release and its package updates. Do not switch alternatives while a compilation is already running.
What CMake will use
For a new build directory, an explicit CMAKE_C_COMPILER or CMAKE_CXX_COMPILER setting takes precedence. Otherwise, CC and CXX can choose the compilers; when no explicit choice is supplied, CMake searches the available compiler commands through PATH. Alternatives affect the generic commands that resolve to these links. See the CMake documentation for CC, CXX and CMAKE_<LANG>_COMPILER.
Check that a shell setting, toolchain file, preset or IDE configuration does not pin a versioned compiler. A quick shell check is:
command -v gcc g++ cc c++
printenv CC CXX
readlink -f /usr/bin/cc
readlink -f /usr/bin/c++
printenv prints nothing for an unset variable. CMake caches the compiler and the results of its compiler checks. If it cached /usr/bin/g++-13, alternatives do not redirect that path. If it cached /usr/bin/c++, switching alternatives can change the executable behind the same path, but does not automatically make the cached compiler information and old object files consistent with the new compiler.
For the project moving to GCC 16, use a fresh build directory after selecting GCC 16. Keep the other project’s existing GCC 13 build directory and select GCC 13 before building that project. This preserves its normal CMake commands and source configuration. A generic first configuration for the GCC 16 project is:
cmake -S . -B build-gcc16 -G Ninja
cmake --build build-gcc16 --parallel 6
Keep the project’s usual dependency and configuration arguments when adapting these commands. The Ninja generator assumes Ninja is installed. When checking an existing build directory, inspect the saved compiler paths with:
grep -E '^CMAKE_(C|CXX)_COMPILER(:|_)' build-gcc16/CMakeCache.txt
The C++ runtime is a separate choice
Alternatives choose compiler executables; they do not change the dynamic loader’s library search path. A program built with GCC 16 may require newer libstdc++ symbols than the system runtime provides. Switching back to GCC 13 does not remove the GCC 16 runtime.
The Ubuntu 26.10 packages install their runtime dependencies through APT. The following extra library-path example applies to the source installation under /opt/gcc-16.2.0. For an individual program that needs that runtime, launch it with:
LD_LIBRARY_PATH="/opt/gcc-16.2.0/lib64:/opt/gcc-16.2.0/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" ./your-program
This sets the library path for that process and its children. Adapt the library directories if the GCC installation uses a different layout. For a distributed application, configure an appropriate RUNPATH/RPATH or provide the required runtime as part of its deployment.
References
Downloading GCC and its prerequisites; configuring GCC; final installation; update-alternatives manual.
A GCC 13 coroutine bug that motivated the upgrade
While building the trading client with GCC 13.3, I encountered internal compiler error: in build_special_member_call when a braced initializer created a temporary container inside a co_await expression. The following small fragment illustrates the pattern; acquire takes ownership of its vector by value:
struct Charge
{
std::string budget;
int weight;
int limit;
};
boost::asio::awaitable<void> acquire(std::vector<Charge> charges);
boost::asio::awaitable<void> example()
{
co_await acquire({{"ip", 1, 3}, {"uid", 1, 3}});
}
A workaround for GCC 13 is to create the vector in a separate statement and then pass it to the coroutine:
boost::asio::awaitable<void> example()
{
std::vector<Charge> charges{{"ip", 1, 3}, {"uid", 1, 3}};
co_await acquire(std::move(charges));
}
The original form is valid C++: the by-value vector parameter belongs to the coroutine frame and owns its elements across suspension. The separate variable is a compiler workaround, not a lifetime requirement. Related GCC reports include PR c++/103580 and PR c++/109227. An equivalent minimal reproduction tested on Compiler Explorer crashed GCC 13.3 with the same diagnostic and compiled successfully with GCC 16.2 using -std=c++23 -O2. That check covers this pattern; it does not establish that the entire application builds with GCC 16.2.

