# Build

How to build GCC from source.

Tested with: version 5.1.0 on Ubuntu 14.04 in a 2013 computer.

Summary local build:

    sudo apt-get build-dep gcc
    # Required to compile gnat.
    sudo apt-get install gnat-4.8
    git clone git://gcc.gnu.org/git/gcc.git
    cd gcc
    # No annotated tags... so no describe.
    git checkout gcc-5_1_0-release
    ./contrib/download_prerequisites
    mkdir build
    cd build
    # C and C++ only.
    ../configure --enable-languages=c,c++ --prefix="$(pwd)/install"
    # Add a suffix to the executable names:
    # --program-suffix="-4.7"
    # All languages.
    # ../configure --enable-languages=all --prefix="$(pwd)/install"
    # Wait hours.
    make -j$(nproc)

    # Wait hours.
    #make check

    # Install executables to /usr/local/bin
    # There are also many other installed files under /usr/local.
    make install

    # Use it.
    ./install/bin/gcc -v
    # sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.9

Or install locally for interactive testing:

    make install DESTDIR="$(pwd)/../install"
    cd ../install/usr/local/bin/
    ./gcc -v

Or configure to always install locally:

    ./configure --prefix="$(pwd)/../install"
    # ...
    make install
    cd ../install/usr/local/bin/
    ./gcc -v

If you modify just the `gcc/` directory, you can `cd gcc; make; make install` to touch only that directory.

## Modify, rebuild and rerun

    cat <<'EOS' | git apply -
    diff --git a/gcc/gcc-main.c b/gcc/gcc-main.c
    index 230ba48..01f87ef 100644
    --- a/gcc/gcc-main.c
    +++ b/gcc/gcc-main.c
    @@ -37,9 +37,12 @@ along with GCC; see the file COPYING3.  If not see

     extern int main (int, char **);

    +#include <stdlib.h>
    +
     int
     main (int argc, char **argv)
     {
    +  system("date > /tmp/gcc");
       driver d;

       return d.main (argc, argv);
    EOS

    cd build/gcc
    make -j5
    make -j5 install
    cd ../install/usr/local/bin/
    ./gcc -v
    cat /tmp/gcc

You *cannot* modify the *stdout* output with at `puts("hacked)`, or else the build will fail! This probably happens because `dumpspecs` is used on some part of the bootstrap process.

## Configure

<https://gcc.gnu.org/install/configure.html>

### download_prerequisites

In Ubuntu 14.04, missing dependencies GMP and others did not go away for me even though they were installed with `apt-get build-dep gcc` and `dpkg` says they are present. I needed `download_prerequisites`

<http://stackoverflow.com/questions/9253695/building-gcc-requires-gmp-4-2-mpfr-2-3-1-and-mpc-0-8-0>

Also `configure` does not detect a missing `flex`, but it seems required or else you get a missing `yylex` error: <http://stackoverflow.com/questions/4262531/trouble-building-gcc-4-6>

### Binutils and GCC

Binutils a requirement of GCC. For instance, Linux From Scratch first installs Binutils, then GCC, then recompiles both to bootstrap.

It appears that you can build both GCC and Binutils the same time: <http://stackoverflow.com/questions/1726042/recipe-for-compiling-binutils-gcc-together> This is called a combined build.

A compatibility matrix between GCC and Binutils can be found at: <http://wiki.osdev.org/Cross-Compiler_Successful_Builds>

### glibc and GCC

GCC depends on glibc. TODO does it depend on `stdlibc++`?

Linux From Scratch compiles it twice to bootstrap.

### Three systems

When you build GCC, you have to configure 3 systems:

- build: where GCC will be built
- host: the system that will run GCC
- target: the system that will run the code generated by the compiled GCC

<https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gccint/Configure-Terms.html#Configure-Terms>

### Compilation options

    ../src/configure CFLAGS='-O0 -g' CXXFLAGS='-O0 -g'

The default compilation uses `-O2`, so you might want to reduce that for better debugging in development.

### enable-languages

<https://gcc.gnu.org/install/configure.html>

By default, only some languages are built.

If you want to enable all languages, use:

    --enable-languages=all

### Gnat

### ADA

### gnat1

I am unable to to build and install it! <http://www.linuxfromscratch.org/blfs/view/svn/general/gcc-ada.html>

Apparently you need a super recent built GNAT as circular dependency, and that of Ubuntu 14.04 is not recent enough?

### gccgo

### Go

### go1

I am unable to to build and install it!

<https://golang.org/doc/install/gccgo>

## Build

Making a separate build directory is mandatory.

Took me 2 hours and a half on a and 5GB of disk.

To build only certain parts of GCC <http://stackoverflow.com/questions/14728652/how-to-make-a-light-build-of-gcc-with-language-supports-etc-pruned>:

    ../src/configure --enable-languages=c,c++

With `make -j5`, this took 1 hour.

See all configuration options with:

    ./configure --help

### bootstrap

### Build stages

By default, the build happens in 3 stages:

1. compile the compiler with the compiler of the `build` computer
2. use the compiled compiler to compile itself
3. repeat 2. and compare 2 and 3. Should be the same.

Configure the build to disable bootstrap and compile only once:

    ../src/configure --disable-bootstrap

TODO does it work without? Is bootstrap really necessary? How can stage 3 ever be different from stage 2?

## Tests

## check

- <https://gcc.gnu.org/install/test.html>
- <https://gcc.gnu.org/onlinedocs/gccint/C-Tests.html>

Requires:

    sudo apt-get install autogen runtest

Run all tests:

    make -k check

Run only certain tests:

    make -k check-gcc-c
    make -k check-gcc

Restrict to tests under a single directory `gcc/testsuite/gcc.dg`:

    make check-gcc RUNTESTFLAGS='dg.exp'

where `dg.exp` is a test script in that directory.

Run a single test:

    make check-gcc RUNTESTFLAGS='dg.exp=cast-1.c'

Where `cast-1.c` refers to `gcc/testsuite/gcc.dg/cast-1.c`

Run tests matching glob:

    make check-gcc RUNTESTFLAGS='dg.exp=cast-*.c'

Test output is very noisy, and does not return non zero on failure.

You should look for a line of type:

            === gcc Summary ===

    # of expected passes        16
    # of unexpected failures    2

for failures, or read the `.sum` file under `build/gcc/testsuite/gcc`.

Known failures exist in all versions, and are summarized at: <https://gcc.gnu.org/gcc-5/buildstat.html>

Executables are compiled under: `build/gcc/testsuite/gcc`. That also contains:

- a `.log` file with detailed test information
- a `.sum` file with summary pass / fail information

Tests are run with `runtest`, which uses `expect`:

- `runtest` is part of DejaGnu. Thus the `.dg` directories.
- `.exp` files are expect scripts

## Install

By default, generated files will be put under:

- `/usr/local/bin`: for front-end executables like `gcc`, `ld`
- `/usr/local/lib64`: for libraries like `libstdc++`
- `/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/5.1.0`: for backend executables like `cc1` and `collect2`

GCC knows how to find the correct internal executables like `cc1` even if they are not in your path. Configure path information must be hard-coded into it.

## Run what you've built

TODO what is the required glibc for each GCC?

C programs seemed to run directly:

    gcc hello_world.c
    ./hello_world

On Ubuntu 14.04, GCC 5.1, C++ programs needed `$LD_LIBRARY_PATH` to find the standard library `libstdc++.so` as it is not on the path by default:

    LD_LIBRARY_PATH="/usr/local/lib64:$LD_LIBRARY_PATH" ./cpp

## Uninstall

There is not top-level uninstall target that removes everything, but some subtrees do have the target.

- <http://stackoverflow.com/questions/25303928/how-to-uninstall-gcc-installed-from-source>

Remove installations from the `gcc/` tree:

    cd gcc
    sudo make uninstall

## Documentation

    make

builds `man` and `info` documentation by default:

    cd gcc/doc
    man ./gcc.1

Those are generated from the `.texi` inputs.

For the HTML docs, use:

    make html

    firefox/gcc/HTML/gcc-4.8.2/gcc/index.html

The website is not included in the source code, but on a separate repo:

    cvs -q -d :pserver:cvs@gcc.gnu.org:/cvs/gcc checkout -P wwwdocs
