This procedure is predicated on using Ubuntu 12.04 LTS amd64 as the development OS and GCC version 4.6.3 packaged in that version of Ubuntu to bootstrap the GCC build itself. A key complication for the build process is that the multiarch changes being made to GCC to support improved cross-compilation functionality are not yet supported by out-of-the-box Debian based Linux distributions, like Ubuntu. The following link contains the details and the extra symbolic links needed to get the build to complete.
I have tried to build GCC 4.6.3 on Ubuntu 12.04 i386 (i.e. 32 bit) but with marginal success. The build process required a bit more patching than I normally like. With Ubuntu 12.04 64 bit, one set of initial modifications was all I needed to get the build to run from start to finish without intervention.
Step 1: Prepare VM (Optional)
I strongly suggest using a purpose-built VM for GCC development. Since GCC forms the foundation of a development environment, mixing GCC compiler development with development of other software elements could be ill advised. As described below, GCC doesn’t build seamlessly on Ubuntu, so isolating your GCC development system with the extra symbolic links added to build GCC will eliminate the risk of those changes to the environment affecting other projects sharing the same environment. Additionally, GCC has a very configurable build system and you may well end up experimenting with configurations that might not play well with other software you are building.
See: Building an Ubuntu 12.04 VM for Development for my short post on creating a development VM using ESXi.
Step 2: Install Required Build Support and Source Code Packages
If you wish to build GCC 4.8.0, read over the modifications section at the end of this post for the tweaks to this process for 4.8.0.
As my goal is to build a debug version of GCC for plugin development, I have no desire to build some of the dependencies from source. If you want to build debug versions of the libraries gcc depends upon, then follow the process outlined here. The information provided by Solarian Programmer on that link was quite helpful to me as I plowed through the build process. The most straightforward way to insure your environment has the right dependencies in place for the build is to get the ‘build-dep’ package for the GCC 4.7 series. Once the dependencies are in place, I pull the archive containing the GCC source and put it into a separate build directory in my home folder. Mirrors for GCC source may be found here: http://gcc.gnu.org/mirrors.html, choose one appropriate for your geography.
The script below captures my sequence of commands:
$ sudo apt-get build-dep gcc-4.7-base
$ mkdir gcc-build
$ cd gcc-build
$ mkdir 4.7.2
$ cd 4.7.2
$ wget 'your mirror here'/gcc-4.7.2.tar.bz2
$ tar -jxvf gcc-4.7.2.tar.bz2
Step 3 : Patch the OS for the Build :
Patching the OS for the GCC build requires defining a pair of symbolic links to insure the build system can find the right include files and libraries for the build:
$ cd /usr/include
$ ln -s x86_64-linux-gnu/* .
$ cd /usr/lib
$ sudo ln -s x86_64-linux-gnu/crt* .
You will get some ‘failed to create symbolic link’ messages when creating links in the include directory, these don’t appear to cause problems. I used elevated permissions to insure all the links in /usr/lib directory were created.
Step 4 : Configure and Build GCC
I typically create a build directory inside of the GCC version specific directory and build in it. This keeps all the source code and executables together in one directory structure and makes it easy to remove broken builds by simply removing the entire directory. There are a fair number of configuration options for the build; I run ‘gcc -v’ to get the configuration of the stock build for the platform and then pick the options that seem to make sense. For this build, be sure to add the –disable-multilib option to prevent the build system from trying to build the multi-arch versions of gcc. If you are interested in building gcc plugins, then also include the –enable-plugin configuration option.
If you plan on installing this debug build into an environment which already has a version of GCC installed, then you ought to use the –prefix and –program-suffix configuration options to distinguish your build from the stock build. Ubuntu 12.04 includes GCC 4.6.3 and it is not generally a good idea to replace the version of GCC that ships with an OS image; parts of the system may depend on that version of the compiler suite. The –prefix configuration option specifies the directory into which the newly built gcc suite should be installed. The –program-suffix option allows you to specify a label to be appended to all the executable files generated in the build. For example –program-suffix=-4.7.2 would result in the gcc executable being labelled ‘gcc-4.7.2’.
For make, the ‘-g3’ flag causes the compiler to emit the maximum level of debug information, including debugging of macros in gdb. The ‘-O0’ option turns off optimizations, as some optimizations result in changes to the AST tree that don’t map well to the source code for debugging. The ‘-j4’ option allows make to fork up to 4 child processes to parallelize the build. Stage1 builds the C compiler with the compiler packaged with the Ubuntu distribution, 4.6.3 in my case. Once the C compiler has been built, the rest of the gcc suite will be built with that compiler.
$ cd ~/gcc-build/4.7.2/gcc-4.7.2
$ mkdir build
$ cd build
$ ../configure --build=x86_64-linux-gnu --disable-multilib --prefix=/usr/gcc-4.7.2 --program-suffix=-4.7.2 --with-system-zlib --without-included-gettext --enable-threads=posix --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --disable-werror --with-arch-32=i686
$ make -j4 STAGE1_CFLAGS="-g3 -O0" all-stage1
$ make -j4 CXXFLAGS="-g3 -O0"
After issuing the last make command, you will have plenty of time to get a refreshing beverage while the build system churns away. When the build completes, you should have a complete gcc compiler suite built for debugging.
Step 5 : Install GCC
With the suite built, you have the choice of leaving the build directory alone and specifying the appropriate paths to the compiler, includes and libraries in the build tree or you can install the compiler into appropriate system directories. In the absence of specifying –prefix, the suite will install into /usr/local. If you have specified –prefix, then the suite will install into a tree rooted in the specified directory. For the example above, the suite would install below /user/gcc-4.7.2. The suite may be installed wit the following command.
$ sudo make install
The sudo command is needed if you will be installing into a system directory.
Modifications for GCC 4.8.0:
This approach works as-is for gcc 4.8.0; needless to say you must substitute ‘4.8.0’ for ‘4.7.2’ throughout the process. There is not yet a ‘build-dep’ package for ‘gcc-4.8-base’ but I found that using the package for ‘gcc-4.7-base’ works.
One issue you will encounter when using GCC 4.8.0 on an otherwise stock Ubuntu 12.04 is that GCC 4.8.0 now defaults to the DWARF-4 format for debugging info whereas the current version of gdb packaged with Ubuntu 12.04 (gdb version 7.4) expects DWARF-3 debugging information. You have two choices: 1) you can upgrade to gdb 7.5 or above as DWARF-4 is the default format for 7.5 and beyond or 2) add the compiler setting: ‘-gdwarf-3’ to your projects to force the compiler to emit DWARF-3 debugging information.
I found GCC 4.8.0 to work every bit as well as GCC 4.7.2 and 4.8.0 has a couple of nice C++ 11 enhancements, generalized attributes for example.