Perception

Technology vs. Humanity

Installing a newer version of GCC on Ubuntu 64-bit operating systems

Ubuntu released a newer version — version 12.10 after the LTS version of 12.04, which contains the latest version of GNU Compiler Collection (GCC) binaries. Nevertheless, I believe that a majority of people using Ubuntu are with 12.04 or even earlier versions, becasue the compatability problem is a huge headache for the Ubuntu platform sometimes. The latest release of GCC supports the powerful brandnew C++ 11 standard, making curiosity burn I believe for lots of folks. In other linux releases, or even the virtual Cygwin environment, compiling and installing GCC from source is a piece of cake — just follow the instructions on the GCC official website and nothing can go wrong. But for the mysterious Ubuntu, which focuses on “completing against MS and Apple” and becoming “a strong alternative of commercial desktop operating systems”, which does not seem quite possible by the way, installing a newer version of GCC from source is never like the common “./configure && make && make install” thing we are used to… With lots of prerequisites missing and strange structure of library paths, Ubuntu needs us to fix these problems manually to get GCC updated. The method described in this article works well for Ubuntu 12.04 64-bit system. Generally it should work for all 64-bit releases of Ubuntu (it should…), and I strongly recommend 64-bit operating systems because it is much more robust in terms of handling memory issues.

Before everything, make sure you have at least GCC 2.4 running and a working Internet connection without which you cannot download any packages or see this page…

To build GCC from source we will need several utilities availble at the default apt-get repository.

$ sudo apt-get install g++
$ sudo apt-get install gawk
$ sudo apt-get install m4
$ sudo apt-get install gcc-multilib

Note that g++ is not by default installed in Ubuntu. Since newer version of GCC (from 4.7.2) will be implemented in C++, g++ is our friend for build GCC.

I know there is some kind of recursive humor in this context… Building a newer version of C compiler using an older version of C compiler… Unfortunately that’s how this works and astonishingly it worked and brings us the mordern compilers we have at our hands…

Okay more recursive humor to come. GCC requires three libraries in terms of high-precision floating-point manupilations. They are called GMP(The GNU Multiple Precision Arithmetic Library), MPFR(The GNU Library for Multiple-Precision Floating-point Computations with Correct Rounding), and MPC(The GNU Multiple-Precision Library for Complex Arithmetics), respectively. They are really long names so thanks to the abbreviations… All these libraries also can be retrived from apt-get, but if don’t want the new compiler to mess your old stuff up you’d better build them from source and install them manually in some safe location — they may serve as practises for your GCC building process as well.

Download the GMP, MPFR, and MPC library source from their official websites.

GMP: http://gmplib.org

MPFR: http://www.mpfr.org

MPC: http://www.multiprecision.org

Be sure to download the latest version. For example, when this article is posted, what I downloaded is gmp-5.0.5.tar.bz2, mpfr-3.1.1.tar.bz2, and mpc-1.0.1.tar.bz2.

Create a temporary directory to hold all source files. Say this directory to be /home/yourname/installgcc, now we copy all the files we just downloaded in to that folder and go into that folder via terminal. Extract all three archive files by doing

$ tar -xf gmp-5.0.5.tar.bz2
$ tar -xf mpfr-3.1.1.tar.bz2
$ tar -xf mpc-1.0.1.tar.bz2

These commands should create three directories with trivial names, and they contain all the source files you need to build these libraries. Choose and create a directory where you wanted to install the new GCC. To conform to the so-called CAEN environment, what I chose was /usr/um/gcc-4.7.0. Be sure to run the mkdir command with sudo because /usr is no longer within your home directory. Go back to your temporary directory containing the source files, and we are ready to build these three libraries.

Because of the underlying dependencies among these three libs, we must follow the exact order of building them as following: GMP->MPFR->MPC. Let do with the GMP first.

Go to the source directory of GMP:

$ cd gmp-5.0.5

Create an empty directory to hold temporary object files and the Makefiles, and go into it:

$ mkdir build && cd build

This step is recommended in case of a failed configuration of installation. You can just delete this directory and start everything over again without re-extracting the archive file.

Tell the make utility where to install the library and which platform you are using:

$ ../configure --prefix=/usr/um/gcc-4.7.0 --build=x86_64-linux-gnu

This will generate approperiate Makefiles for you within your working directory. Now the famous part comes:

$ make -j 4 && make check && make install

The -j 4 options allows four parallel threads to build the libaray concurrently, which should speed up the building process a lot. Of course you should limit the number after -j under the physical/logical number of CPUs you have or you will encounter a slow system response and a huge performance lag as well. The process should exit without any error messages. If errors do occur, double check for prerequisites.

Run the clean step to free some disk space after the installation.

$ make clean

The steps are almost exactly the same for the rest of the two, just be sure to follow the correct order and don’t forget to tell configure where the dependencies locates. I will just “mumble through” here for the build and installation of MPFR and MPC, with all the commands you will need to run.

In the MPFR folder:

$ mkdir build && cd build
$ ../configure --prefix=/usr/um/gcc-4.7.0 --build=x86_64-linux-gnu --with-gmp=/usr/um/gcc-4.7.0
$ make -j 4 && make check && make install
$ make clean
$ cd ../mpc-1.0.1

In the MPC folder:

$ mkdir build && cd build
$ ../configure --prefix=/usr/um/gcc-4.7.0 --build=x86_64-linux-gnu --with-gmp=/usr/um/gcc-4.7.0 --with-mpfr=/usr/um/gcc-4.7.0
$ make -j 4 && make check && make install
$ make clean

Now you have all the prerequisites installed to compile and install GCC, so be ready to welcome the largest part of recursive humor in this story: building the compiler by itself!

Fetch the GCC source from http://gcc.gnu.org/mirrors.html. For me, in the US, the fastest site turns out to be the St. Louis site — no wonder it’s called STL lol. Downloading the .tar.bz2 file will be fine, though the tar.gz file will be faster to extract but bigger in size. The latest available version is 4.7.2, but I will just build 4.7.0 to conform to the so-called C-something environment, so the 4.7.2 part will be your homework today.

Again, copy the archive file into your temporary directory and extract it, then go to the directory of the source files:

$ tar -xf gcc-4.7.0.tar.bz2

It is also necessary to create a build directory and work in it during the building process, but in GCC’s case we cannot create it with in the source directory. So make sure the build directory is in parallel with the source folder, which is /home/yourname/installgcc/gcc-4.7.0 in this example. Run the following command in your temporary folder holding all tar.bz2 files:

$ mkdir build && cd build

Before we start configuring, we need to set up some environment virables to tell GCC where we have just installed the above three bizarre libraries.

$ export LD_LIBRARY_PATH=/usr/um/gcc-4.7.0/lib:$LD_LIBRARY_PATH
$ export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/
$ export C_INCLUDE_PATH=/usr/include/x86_64-linux-gnu
$ export CPLUS_INCLUDE_PATH=/usr/include/x86_64-linux-gnu

Now we can start the configuration:

$ ../gcc-4.7.0/configure --prefix=/usr/um/gcc-4.7.0 --build=x86_64-linux-gnu --with-gmp=/usr/um/gcc-4.7.0 --with-mpfr=/usr/um/gcc-4.7.0 --with-mpc=/usr/um/gcc-4.7.0 --enable-checking=release --enable-languages=c,c++ --disable-multilib

Maybe a little explanation on what’s going on here. Apart from some basic parameters and telling GCC where we have installed the arithmetic libraries, we are enabling only C and C++ support of GCC. GCC is a huge collection of all kinds of programming languages, including fortran and java, so building GCC without specifying language explicitly will result in a building process for over 4 hours long. We are disabling multilibrary support to supress an error, and we only enable release check to speed up the verifying process after the build.

Now we can build GCC. Be prepared because it will be a truly long process, and it takes my Intel i3 machine about half an hour to compile the entire thing, even with the -j 4 option. Be sure to use -j 4 here, or it will possibly ruin your night.

$ make -j 4
# after a long long long time...
$ make check
$ make install
$ make clean

If everything goes fine then congratulations to you, you have just successfully built and installed the GCC from the source! But wait, how to invoke the newly installed GCC to compile my C++11 program? Try type

$ gcc --version

and what you see is definitely still the old version. Now you have two options: First, to replace the old GCC with the new one entirely. I don’t think GCC itself will cause any compatibility problems as a compiler, so this option is 100% viable. Second, leave your system environment untouched just in case that things go wrong, and use the newly installed GCC as a seperate compiler when needed. I personally prefer the second option because it keeps everything neat and let you switch between compilers, so I will go with that one. Whenever you need to use the new GCC (version 4.7.0 in this example), just set up the environmental variables as follows before you invoke your Makefile or run gcc commands:

$ export LD_LIBRARY_PATH=/usr/um/gcc-4.7.0/lib:/usr/um/gcc-4.7.0/lib64:$LD_LIBRARY_PATH
$ export PATH=/usr/um/gcc-4.7.0/bin:$PATH
$ export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu

Alternatively, you can do this by including the following lines at the very beginning of your Makefile:

PATH := /usr/um/gcc-4.7.0/bin:$(PATH)
LD_LIBRARY_PATH := /usr/um/gcc-4.7.0/lib:/usr/um/gcc-4.7.0/lib64:$(LD_LIBRARY_PATH)
LIBRARY_PATH := /usr/lib/x86_64-linux-gnu

However somehow it won’t work on some machine for bizzare reasons… I will try to figure that out later. Anyway, setting the env vars in terminal directly works fine and GCC will work. Try using the unique GCC 4.7 flag -std=c++11 for g++ to check if the new version is working correctly. The LIBRARY_PATH variable must be set correctly otherwise your code will compile but won’t link.

Enjoy the new GCC! From now on you should be able to update your GCC whenever a new version is released 🙂