How to build the GCC complier ?

The official document is here.

The prerequisites GMP, MPFR, and MPC can als be obtained here.

Also see here and here at LinuxFromScratch.org.

  • Build GMP (GNU Multiple Precision Arithmetic) library. It's important to build the library statically, i.e. when running the configure script, use
    configure --disable-shared --enable-static --prefix=/tmp/gcc

    Caveat: If you are building GCC on PowerPC/Linux (especially IBM POWER) make sure GMP is built in the same mode (32/64-bit) as your current GCC's default CPU mode. If your GCC by default generates 32-bit binaries, you must build GMP in 32-bit mode as well (if you need, use compiler option -m32 to enforce this.) If 32-bit mode is indeed the case (use file command on any binary your GCC generates, and you should see something like ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV)...) use the option

    ABI=32
    as the first argument to configure script. See here for more ABI build options for GMP.

    Make sure at the end of your GMP build, do make install.

  • Build MPFR (Multiple precision floating-point) library. It's important to build the library statically, i.e. when running the configure script, use
    configure --disable-shared --enable-static --prefix=/tmp/gcc --with-gmp=/tmp/gcc
    (MPFR depends on GMP)

    Caveat: As above, if you are building GCC on PowerPC/Linux, ensure MPFR is built in the same mode (32/64-bit) as your current GCC's default CPU mode. In the configure script or the Makefile, search for strings such as -m elf32ppclinux or -m elf64ppc.

    Make sure at the end, do make install

  • Build MPC (Multiple precision complex arithmetic) library. It's important to build the library statically, i.e. when running the configure script, use
    configure --disable-shared --enable-static --prefix=/tmp/gcc --with-gmp=/tmp/gcc --with-mpfr=/tmp/gcc
    (MPC depends on MPFR and GMP)

    Caveat: As above, if you are building GCC on PowerPC/Linux, ensure MPC is built in the same mode (32/64-bit) as your current GCC's default CPU mode. In the configure script or the Makefile, search for strings such as -m elf32ppclinux or -m elf64ppc.

    Make sure at the end, do make install

  • Build LibELF. This library is needed for LTO (Link-Time Optimization) It's important to build the library statically, i.e. when running the configure script, use
    configure --disable-shared --enable-static --prefix=/tmp/gcc

    Caveat: As above, if you are building GCC on PowerPC/Linux, ensure LibELF is built in the same mode (32/64-bit) as your current GCC's default CPU mode.

    Make sure at the end, do make install

  • Make sure the assembler as and linker ld are not too old. For example, old ld can produce errors like the following:
       /usr/src/packages/BUILD/glibc-2.3/cc/csu/crti.S:16: relocation truncated to fit: R_PPC_LOCAL24PC _GLOBAL_OFFSET_TABLE_+fffffffffffffffc
       c-lang.o(.text+0x4b90):
        In function `VEC_tree_base_quick_insert':../../gcc-4.4.4/gcc/tree.h:190: relocation truncated to fit: R_PPC_REL24 memmove@@GLIBC_2.0
       
    Assembler and linker can be found in GNU BinUtils.

    To see which ld is used during linking, invoke gcc with

    gcc -v -Wl,-v ...
  • Make sure make is not too old. It can be found here.
  • Download GCC source and unpack the tarball. Say the source is now under
    /tmp/gcc-4.x.y/
        

    It's better to use the GNU tar to avoid issues.

  • If you are building GCC on PowerPC/Linux, edit GCC's configure script and Makefiles, in particular, edit
        gcc-4.x.y/Makefile.in
        gcc-4.x.y/gcc/Makefile.in
        
    and change optimization flags from -O2 or -O1 to -O0. This will increase the chance of a successful build.
  • Find a scratch directory, say /scratch. Then
          cd /scratch
          /tmp/gcc-4.x.y/configure --prefix=/usr/local/ <other options>
        
    where <other options> are:

    • --enable-languages=c,c++,fortran
    • --enable-threads=posix
    • --enable-tls (for Thread Local Storage support)
    • --enable-libgomp (for OpenMP support)
    • --enable-lto (for Link-Time Optimization)
    • --disable-nls (no need for Native Language Support)
    • --disable-checking
    • --disable-multilib (if you only need build for 64-bit target)
    • --disable-shared (if you want to avoid later "GLIBCXX_3.4.9 not found"-type annoyances)
    • --disable-libstdcxx-pch (no need for C++ pre-compiled headers, which takes huge amount of disk space)
    • --disable-bootstrap (this option can speed up GCC build time, but use it only if your current GCC supports all the languages, i.e. C/C++/Fortran/Ada..etc)
    • --with-gmp=/tmp/gcc
    • --with-mpfr=/tmp/gcc
    • --with-mpc=/tmp/gcc
    • --with-libelf=/tmp/gcc
    • --with-fpmath=sse (on i386 and x86-64 targets, specify the compiler defaults to -msse2 and -mfpmath=sse for floating point arithmetic)
    • --with-ld=<your ld path> (points to your own ld. However, your Stage 1 build will not use this ld; instead, it still uses your system's default ld)
    • --with-as=<your as path> (points to your own as)

    If you are building GCC on PowerPC/Linux, also use the following options to increase the chance of a successful build:

    • --with-cpu=default32 (this one is crucial. The resulting GCC will still be able to build 64-bit binaries, but GCC itself should be built in 32-bit mode.)
    • --enable-__cxa_atexit (this allows use of __cxa_atexit, rather than atexit, to register C++ destructors for local statics and global objects. This option is essential for fully standards-compliant handling of destructors. It also affects the C++ ABI, and therefore results in C++ shared libraries and C++ programs that are interoperable with other Linux distributions.)
    • --with-long-double-128
    • --enable-secureplt (see here)
    • --with-system-zlib

    See here for other options.

  • GCC is built in three stages:
    1. Bootstrapping: Build only C compiler using the currently available C compiler. The result is called Stage-1 C compiler.
    2. Build GCC (C compiler, C++ compiler, Fortran compiler, support libraries, etc) using Stage-1 C compiler. The result is called Stage-2 GCC.
    3. Build GCC yet again using Stage-2 GCC. Compare the resulting binaries against Stage-2 GCC. If they are the same (which they should), done!

    To save time and disk space, one can build using

    gmake bootstrap2-lean -j 5
    bootstrap2 means running the first two stages only. lean means various stages are removed once they are no longer needed.

    See here for other build targets.

  • One possible issue during the build is certain configure script (e.g. libcpp's) complains "no usable dependency style found". To fix this, modify the configure script so the dependency is hard-coded as gcc3:
    am_cv_CC_dependencies_compiler_type=gcc3
  • Another possible issue during the build is certain configure script complains "cannot compute suffix of object files: cannot compile". The cause of error is as it says: cannot compile. You need to check whether all the intermediate binaries (xgcc, cc1, cc1plus, f951 etc) can run or not. They either need LD_LIBRARY_PATH set up, or they simply crash.

  • Depending on where the GCC binaries are installed, one might need to add libstdc++.so's directory to LD_LIBRARY_PATH environmental variable, or some of C++ code will not run (e.g. "GLIBCXX_3.4.9 not found" error).

    To see the current glibC++ version, do

    readelf -s /usr/lib/libstdc++.so.6 | grep GLIBCXX_3

    Alternatively, one can do use either compiler options:

    • -static-libgcc or -static-libstdc++, so the relevant libraries are linked statically.
    • -Wl,--rpath,<your installation path>/lib64, so the path is hard-coded in the generated binaries. One can also set the LD_RUN_PATH environmental variable to achieve the same effect.