Thursday, 8 September 2011

Building GCC

A colleague has suggested that I write up building FSF GCC with GNAT for Mac OS X; these are the notes.

Build environment

I'm building on a 15" Macbook Pro with a 2.4 GHz Intel Core 2 Duo processor and 4 GB of RAM, running Mac OS X Lion 10.7.1 with Xcode 4.1. FSF GCC Ada requires a working GNAT compiler. I started with GNAT GPL 2011, which I installed at /opt/gnat-gpl-2011, so I adjust my PATH to make this compiler the default choice:
$ PATH=/opt/gnat-gpl-2011/bin:$PATH

Support libraries

GCC depends on several support libraries. The minimum set is By default, these libraries build as shared libraries. I don't feel this is such a good idea, because:
  • if you copy the built compiler to anyone. you must remember to copy the shared libraries it depends on too;
  • other applications on your machine may depend on older versions of the new libraries, and may have problems if you accidentally invoke them.

Source, build layout

I decided to build the support libraries in a ~/tmp/gcc-support directory.

Building GMP 5.0.2

I unpacked gmp-5.0.2.tar.bz2 into ~/tmp/gcc-support. Then,
$ cd gmp-5.0.2
$ ./configure \
  --prefix=$HOME/tmp/gcc-support \
  --disable-shared
This chose the build and host system types as core2-apple-darwin11.1.0. Then,
$ make
$ make check
All the tests passed, but I noticed these warnings during the test build:
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in ___gmpn_divexact_1 from /Users/simon/tmp/gcc-support/gmp-5.0.2/.libs/libgmp.a(dive_1.o). To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie
There's a thread about this at gmplib.org. I wasn't quite sure that the library had been built as 64-bit, but lipo says yes:
$ lipo -detailed_info .libs/libgmp.a
input file .libs/libgmp.a is not a fat file
Non-fat file: .libs/libgmp.a is architecture: x86_64
I finished off with
$ make install

Building MPFR 3.0.1

I unpacked mpfr-3.0.1.tar.bz2 into ~/tmp/gcc-support. Then,
$ cd mpfr-3.0.1
$ ./configure \
  --prefix=$HOME/tmp/gcc-support \
  --disable-shared \
  --with-gmp=$HOME/tmp/gcc-support
(note, we have to say where GMP is to be found). Then,
$ make
$ make check
(all tests passed), followed by
$ make install

Building MPC 0.9

I unpacked mpc-0.9.tar.gz into ~/tmp/gcc-support. Then,
$ cd mpc-0.9
$ ./configure \
  --prefix=$HOME/tmp/gcc-support \
  --disable-shared \
  --with-gmp=$HOME/tmp/gcc-support \
  --with-mpfr=$HOME/tmp/gcc-support
(we have to say where both GMP and MPFR are to be found.) Then,
$ make
$ make check
(all tests passed), followed by
$ make install

Downloading and building GCC

I downloaded GCC 4.6.1; the core, Ada, G++, Fortran and the test suite. I unpacked the lot at ~/tmp:
$ cd ~/tmp
$ tar jxvf ~/Downloads/Ada/gcc-4.6/gcc-core-4.6.1.tar.bz2
$ tar jtvf ~/Downloads/Ada/gcc-4.6/gcc-ada-4.6.1.tar.bz2
$ tar jxvf ~/Downloads/Ada/gcc-4.6/gcc-ada-4.6.1.tar.bz2
$ tar jxvf ~/Downloads/Ada/gcc-4.6/gcc-g++-4.6.1.tar.bz2
$ tar jxvf ~/Downloads/Ada/gcc-4.6/gcc-fortran-4.6.1.tar.bz2
$ tar jxvf ~/Downloads/Ada/gcc-4.6/gcc-testsuite-4.6.1.tar.bz2
then created a build directory:
$ mkdir gcc-build
$ cd gcc-build/
and configured (note, the reason for the setting of --prefix is to keep different versions of compilers separate. Nothing so infuriating as accidentally overwriting your only compiler with a non-doing version!):
$ ../gcc-4.6.1/configure \
  --prefix=/opt/gcc-4.6.1 \
  --disable-multilib \
  --enable-languages=c,ada,c++,fortran \
  --with-gmp=$HOME/tmp/gcc-support \
  --with-mpfr=$HOME/tmp/gcc-support \
  --with-mpc=$HOME/tmp/gcc-support \
  --build=x86_64-apple-darwin11
The make failed; looking at gcc/config.log, it seems there's a problem involving the use of compilers built on Snow Leopard to build a compiler on Lion.
configure:5860: checking size of long long configure:5865: gcc -o conftest -g -fkeep-inline-functions conftest.c >&5 Undefined symbols for architecture x86_64:"___builtin___stpncpy_chk", referenced from:___inline_stpncpy_chk in ccgrb5E9.o ld: symbol(s) not found for architecture x86_64
After a bit of experimentation, it turns out that removing -fkeep-inline-functions at least would allow this configuration test to run; patch here. Unfortunately, when I then run make, it ends:
gnatbind -C -nostdinc -I- -I. -Iada -I../../gcc-4.6.1/gcc/ada -I../../gcc-4.6.1/gcc/ada/gcc-interface -o ada/b_gnat1.c -n ada/gnat1drv.ali
gnatbind: invalid switch: -C
and it turns out that GCC 4.6 uses the deprecated gnatbind -C switch (generate main program in C) which is not supported at all in GNAT GPL 2011.
There would be no problem with GCC 4.7, since the offending Makefile has been updated, but at the time of writing (6 September 2011) GCC 4.7 is still under active revision.
So the only option is to start again, using a GCC 4.5- or 4.6-based compiler. Fortunately, there's one available (it also includes AUnit, GNATcoll, XML/Ada - but who's counting!) The compiler path is now
$ PATH=/opt/gcc-4.6.0-x86_64/bin:$PATH
Configure as before, and build:
$ ../gcc-4.6.1/configure \
  --prefix=/opt/gcc-4.6.1 \
  --disable-multilib \
  --enable-languages=c,ada,c++,fortran \
  --with-gmp=$HOME/tmp/gcc-support \
  --with-mpfr=$HOME/tmp/gcc-support \
  --with-mpc=$HOME/tmp/gcc-support \
  --build=x86_64-apple-darwin11$ make
... which succeeded after 1h46m.

Testing

You need to install Dejagnu, and put its runtest on your path. I have dejagnu-1.4.4 installed in /opt/gnu, so I say
$ PATH=/opt/gnu/bin:$PATH
From previous experience, it can take a very long time indeed to run the full test suite, even locking up the machine to the point of needing a power cycle. So it can make sense to run the individual test suites.
$ make check-ada

   === acats Summary ===
   # of expected passes 2321
   # of unexpected failures 0
   === gnat Summary ===
   # of expected passes 871
   # of expected failures 10
   # of unsupported tests 2
$ make check-c
(this was using more and more swap; I killed it)
$ make check-c++

   === g++ Summary ===
   # of expected passes 25757
   # of unexpected failures 7
   # of expected failures 163
   # of unresolved testcases 7
   # of unsupported tests 365
   === libstdc++ Summary ===
   # of expected passes 7034
   # of expected failures 82
   # of unsupported tests 653
$ make check-fortran

   === gfortran Summary ===
   # of expected passes 38443
   # of expected failures 41
   # of unsupported tests 69

Installation

$ sudo make install
... and now all you need to do is to put /opt/gcc-4.6.1/bin at the front of your PATH, and you're using the new compiler.

3 comments:

  1. Create symbolic links in the gcc directory for mpc, mpfr and gmp so you don't have to configure and compile separately.

    ReplyDelete
  2. The symlinks need to be at the top level (e.g., .../gcc-4.6.1/gmp).

    Pleased to see that this builds static libraries, which meets one of my qualms.

    Pleased also to see that you can say for example 'make check-gmp'.

    Evidently this approach also works round the PIE warnings.

    So, thanks very much!

    ReplyDelete
  3. Thank you for those very informative and clear compilation instructions.

    ReplyDelete