Solarian Programmer

My programming ramblings

Building GCC on Ubuntu Linux

Posted on October 7, 2016 by Sol

11 May 2017 - Article updated for GCC 7.1

This is a short article about compiling GCC 7.1 from sources on Ubuntu 16.04 64 bits. The default version of GCC on Ubuntu 16.04 is 5.4 which is not bad, however version 7 is has complete C++11, C++14 support and experimental C++17 support. GCC 7 has C11 and C++14 support enabled by default, no need to add -std=c11 or -std=c++14, versus version 5 where you needed to add the standard version explicitly.

First, let’s make sure that we have an up to date system:

1 sudo apt update
2 sudo apt upgrade

Now, install the default GCC toolchain with:

1 sudo apt install build-essential

Next, we’ll download the GCC 7 source and prerequisites from

1 cd ~
2 wget
3 tar xf gcc-7.1.0.tar.bz2
4 cd gcc-7.1.0
5 contrib/download_prerequisites

At this point, we can configure the build. In order to keep the system clean, we will use /usr/local/gcc-7.1 for the installation folder and append the suffix -7.1 to the GCC compilers. You typically don’t want to mess the system’s default GCC because other packages may depend on the default version.

1 cd ~
2 mkdir build && cd build
3 ../gcc-7.1.0/configure -v --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --prefix=/usr/local/gcc-7.1 --enable-checking=release --enable-languages=c,c++,fortran --disable-multilib --program-suffix=-7.1

Now, we are ready to build GCC, you typically want to pass twice the number of your computer cores to the make command in order to speed up the build. I have a quad-core system, so I will use 8 parallel jobs to build GCC:

1 make -j 8

Depending on the speed of your computer the build phase could take from about 30 minutes to a few hours.

Once the above phase is finished, you can install the built GCC with:

1 sudo make install

If you want to permanently add the compilers to your system’s path, add the next two lines at the end of your .bashrc file:

1 export export PATH=/usr/local/gcc-7.1/bin:$PATH
2 export LD_LIBRARY_PATH=/usr/local/gcc-7.1/lib64:$LD_LIBRARY_PATH

Don’t know how to open .bashrc ? No problem, you can find it from your Terminal:

1 cd ~
2 gedit .bashrc

Paste at the end .bashrc the above export lines, save the file and close gedit. Now, you just need to instruct Bash to reload .bashrc (this is automatically done when you restart your machine):

1 . .bashrc

Time to test our shiny new compilers. Open your favorite text editor and copy the next piece of code (I assume you’ll save the file as test_lambda.cpp):

1 // C++14 generalized lambda (could use "auto" for the type of a parameter)
2 #include <iostream>
4 int main() {
5     std::cout << [](auto a, auto b) { return a + b; } (5, 6) << std::endl;
6     std::cout << [](auto a, auto b) { return a + b; } (5.23, 6.45) << std::endl;
7     return 0;
8 }

The code uses a generalized lambda (we could use auto for the type of the parameters), this was introduced in the C++14 standard. We can compile and test the above program with:

1 g++-7.1 -Wall -pedantic test_lambda.cpp -o test_lambda
2 ./test_lambda
3 11
4 11.68

As mentioned at the beginning of this article, GCC 7 has experimental support for C++17. Let’s test an example of using C++17 modification to static_assert:

 1 #include <type_traits>
 2 #include <iostream>
 4 struct A {
 5 	int foo;
 6 };
 8 struct B {
 9 	int foo = 0;
10 };
12 template <typename T>
13 void print(const T& a){
14 	static_assert(std::is_pod<T>::value);
15 	std::cout << << '\n';
16 }
18 int main() {
19 	A x{1};
20 	B y{2};
21 	B z;
23 	print<A>(x);
24 	print<B>(y);
25 	print<B>(z);
27 	return 0;
28 }

You can compile the above code if you pass std=c++1z to the compiler and you should get a compiler error triggered by lines 14 and 20 from the above code

1 g++-7.1 -std=c++1z -Wall -pedantic test_assert.cpp -o test_assert
2 test_assert.cpp: In instantiation of ‘void print(const T&) [with T = B]’:
3 test_assert.cpp:24:15:   required from here
4 test_assert.cpp:14:5: error: static assertion failed
5     static_assert(std::is_pod<T>::value);
6     ^~~~~~~~~~~~~

If you are a Fortran programmer, you can use some of the Fortran 2008 features like do concurrent with gfortran-7.1:

 1 integer,parameter::mm=100000
 2 real::a(mm), b(mm)
 3 real::fact=0.5
 5 ! initialize the arrays
 6 ! ...
 8 do concurrent (i = 1 : mm)
 9     a(i) = a(i) + b(i)
10 enddo
12 end

The above code can be compiled with (supposing you’ve named it test_concurrent_do.f90s):

1 gfortran-7.1 test_concurrent_do.f90 -o test_concurrent_do
2 ./test_concurrent_do

If you are interested to learn more about the new C++11 syntax I would recommend reading The C++ Programming Language by Bjarne Stroustrup.

or, Professional C++ by M. Gregoire, N. A. Solter, S. J. Kleper 2nd edition:

If you need to brush your Fortran knowledge a good book is Modern Fortran Explained by M. Metcalf, J. Reid and M. Cohen:

comments powered by Disqus