Monday 23 March 2020

Upgrading GNU C/C++ compilers on Ubuntu

Here I want to share my experience with upgrading gcc and g++ compilers on Ubuntu. Probably it's better to say installing their newer version, as both old and new(er) versions can live happily side by side. Setting default version (picked up by CMake) is just a matter of re-routing two symlinks. Let me give the background problem which made me do this.





CMake was reporting that my C++ project is compiled by /usr/bin/c++.

build/CMakeCache.txt:

//CXX compiler
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++

When I tried to use C++17 header:

#include <filesystem>

...I'd get:

fatal error: filesystem: No such file or directory

...although I have in CMakeLists.txt:

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++17 -lstdc++fs")

GCC 8.0 support std::filesystem (#include ) now : cpp => I need GCC v8 in order to get <filesystem> and std::filesystem.

Let's just check my current GCC binary path by following symlinks:

$ ls -la /usr/bin/c++
lrwxrwxrwx 1 root root 21 Mar 28  2019 /usr/bin/c++ -> /etc/alternatives/c++

$ ls -la /etc/alternatives/c++
lrwxrwxrwx 1 root root 12 Mar 28  2019 /etc/alternatives/c++ -> /usr/bin/g++

$ ls -la /usr/bin/g++
lrwxrwxrwx 1 root root 5 May 20  2019 /usr/bin/g++ -> g++-7

$ which g++-7
/usr/bin/g++-7

$ ls -la /usr/bin/g++-7
lrwxrwxrwx 1 root root 22 Dec  4 14:25 /usr/bin/g++-7 -> x86_64-linux-gnu-g++-7

$ which x86_64-linux-gnu-g++-7
/usr/bin/x86_64-linux-gnu-g++-7

Checking the --version gives the same output for all aliases:

$ /usr/bin/x86_64-linux-gnu-g++-7 --version
x86_64-linux-gnu-g++-7 (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 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.

$ g++-7 --version
g++-7 (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 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.

$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 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.

Also, the following command would not return anything:

$ which gcc-8

I have GCC version 7.5.0 and want to upgrade it to 8.0.

$ sudo apt install gcc-8 g++-8

Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following package was automatically installed and is no longer required:
  libllvm8
Use 'sudo apt autoremove' to remove it.
The following additional packages will be installed:
  cpp-8 libasan5 libgcc-8-dev libstdc++-8-dev libubsan1
Suggested packages:
  gcc-8-locales g++-8-multilib gcc-8-doc libstdc++6-8-dbg gcc-8-multilib libgcc1-dbg libgomp1-dbg libitm1-dbg libatomic1-dbg libasan5-dbg liblsan0-dbg
  libtsan0-dbg libubsan1-dbg libmpx2-dbg libquadmath0-dbg libstdc++-8-doc
The following NEW packages will be installed
  cpp-8 g++-8 gcc-8 libasan5 libgcc-8-dev libstdc++-8-dev libubsan1
0 to upgrade, 7 to newly install, 0 to remove and 31 not to upgrade.
Need to get 27.7 MB of archives.
After this operation, 113 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://gb.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 cpp-8 amd64 8.3.0-26ubuntu1~18.04 [7,224 kB]
Get:2 http://gb.archive.ubuntu.com/ubuntu bionic-updates/main amd64 libasan5 amd64 8.3.0-26ubuntu1~18.04 [366 kB]
Get:3 http://gb.archive.ubuntu.com/ubuntu bionic-updates/main amd64 libubsan1 amd64 8.3.0-26ubuntu1~18.04 [122 kB]
Get:4 http://gb.archive.ubuntu.com/ubuntu bionic-updates/main amd64 libgcc-8-dev amd64 8.3.0-26ubuntu1~18.04 [2,306 kB]
Get:5 http://gb.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 gcc-8 amd64 8.3.0-26ubuntu1~18.04 [8,038 kB]                                          
Get:6 http://gb.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 libstdc++-8-dev amd64 8.3.0-26ubuntu1~18.04 [1,533 kB]                                
Get:7 http://gb.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 g++-8 amd64 8.3.0-26ubuntu1~18.04 [8,122 kB]                                          
Fetched 27.7 MB in 31s (887 kB/s)                                                                                                                             
Selecting previously unselected package cpp-8.
(Reading database ... 253903 files and directories currently installed.)
Preparing to unpack .../0-cpp-8_8.3.0-26ubuntu1~18.04_amd64.deb ...
Unpacking cpp-8 (8.3.0-26ubuntu1~18.04) ...
Selecting previously unselected package libasan5:amd64.
Preparing to unpack .../1-libasan5_8.3.0-26ubuntu1~18.04_amd64.deb ...
Unpacking libasan5:amd64 (8.3.0-26ubuntu1~18.04) ...
Selecting previously unselected package libubsan1:amd64.
Preparing to unpack .../2-libubsan1_8.3.0-26ubuntu1~18.04_amd64.deb ...
Unpacking libubsan1:amd64 (8.3.0-26ubuntu1~18.04) ...
Selecting previously unselected package libgcc-8-dev:amd64.
Preparing to unpack .../3-libgcc-8-dev_8.3.0-26ubuntu1~18.04_amd64.deb ...
Unpacking libgcc-8-dev:amd64 (8.3.0-26ubuntu1~18.04) ...
Selecting previously unselected package gcc-8.
Preparing to unpack .../4-gcc-8_8.3.0-26ubuntu1~18.04_amd64.deb ...
Unpacking gcc-8 (8.3.0-26ubuntu1~18.04) ...
Selecting previously unselected package libstdc++-8-dev:amd64.
Preparing to unpack .../5-libstdc++-8-dev_8.3.0-26ubuntu1~18.04_amd64.deb ...
Unpacking libstdc++-8-dev:amd64 (8.3.0-26ubuntu1~18.04) ...
Selecting previously unselected package g++-8.
Preparing to unpack .../6-g++-8_8.3.0-26ubuntu1~18.04_amd64.deb ...
Unpacking g++-8 (8.3.0-26ubuntu1~18.04) ...
Setting up cpp-8 (8.3.0-26ubuntu1~18.04) ...
Setting up libasan5:amd64 (8.3.0-26ubuntu1~18.04) ...
Setting up libubsan1:amd64 (8.3.0-26ubuntu1~18.04) ...
Setting up libgcc-8-dev:amd64 (8.3.0-26ubuntu1~18.04) ...
Setting up libstdc++-8-dev:amd64 (8.3.0-26ubuntu1~18.04) ...
Setting up gcc-8 (8.3.0-26ubuntu1~18.04) ...
Setting up g++-8 (8.3.0-26ubuntu1~18.04) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...

To verify installation we can use:

$ which gcc-8
/usr/bin/gcc-8

$ which g++-8
/usr/bin/g++-8

gcc and g++ symlinks are not updated automatically, they are still pointing to GCC v7:

$ ls -la /usr/bin/gcc
lrwxrwxrwx 1 root root 5 May 20  2019 /usr/bin/gcc -> gcc-7

$ ls -la /usr/bin/g++
lrwxrwxrwx 1 root root 5 May 20  2019 /usr/bin/g++ -> g++-7

$ which gcc-7
/usr/bin/gcc-7

$ which g++-7
/usr/bin/g++-7

We can update them manually to point to GCC v8.

Let's do it for gcc first:

$ sudo rm /usr/bin/gcc
$ sudo ln -s /usr/bin/gcc-8 /usr/bin/gcc

Let's verify the symlink:

$ ls -la /usr/bin/gcc
lrwxrwxrwx 1 root root 14 Mar 23 18:26 /usr/bin/gcc -> /usr/bin/gcc-8

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8.3.0-26ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 8.3.0 (Ubuntu 8.3.0-26ubuntu1~18.04)

Let's do it for g++ now:

$ sudo rm /usr/bin/g++
$ sudo ln -s /usr/bin/g++-8 /usr/bin/g++

Let's verify it:

$ ls -l /usr/bin/g++
lrwxrwxrwx 1 root root 14 Mar 23 18:30 /usr/bin/g++ -> /usr/bin/g++-8

$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8.3.0-26ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 8.3.0 (Ubuntu 8.3.0-26ubuntu1~18.04) 


With CMakeLists.txt changes:

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++17")
target_link_libraries(${PROJECT_NAME} stdc++fs)

NOTE: target_link_libraries() must come after add_executable()

My project now builds with no issues and it uses GCC v8:

> Executing task: cmake make -DCMAKE_BUILD_TYPE=Debug .. && make -j 4 <

-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
...
[100%] Built target cpp-demo