Tuesday 13 August 2013

Compiling old versions of gcc

I wanted to compile up an old version of gcc (2.95.3) for another project which I might blog about in the future, I assumed this would not be too difficult, however it turned out more troublesome than I had thought.

I have on my Linux system gcc4 compiler and to use this to compile the source of version 2.95.3 a few tweaks have to be made. I should also mention as a remindeer to read and understand the output/errors they can save some time. I would have got to the solution sooner if I had matched up the error with some information I already had.

I unpacked gcc 2.95.3 source to a directory and then created a separate directory to build into (as recommended), I have also created a separate directory to install finished binaries into so as not to mess up my current system (also doing this as a non-root user).

First attempt to compile (from within my build directory) using the following options
../gcc-2.95.3/configure --prefix=<new bin directory> --enable-languages=c,c++ --enable-threads=posix --enable-shared --disable-nls --host=i386-pc-linux-gnu --target=i386-pc-linux-gnu

I only want support for c and c++, posix threads are enabled, I have disable NLS as I do not need it and I am specifying I want to create a compiler for 32bit.

This attempt fails to compile (due to two issues, but originally I concentrated on one and wasted a lot of time).
The first issue I noted was the errors from the assembler such as
Error: invalid instruction suffix for `push'
Error: invalid instruction suffix for `pop'

This suggested I had an architecture issue, so I spent a lot of time looking for the solution to this and ignored the following problem (which later on I realsied needed fixing too).

/usr/include/bits/pthreadtypes.h:99: warning: unnamed struct/union that defines no instances

This version of gcc does not support the unnamed union definition that appears in one of the header files on my system, more about how to solve this one later.

While trying to track down solutions for the architecture problem I believed I was facing above, I came across a blog entry here, which seemed to document a similar issue about invalid instructions.
The fix given was to add "--32" to the gcc assembler spec options in the header file gcc/config/svr4.h 

Second attempt to build having added the above entry, again compiling in my build directory with the following options

../gcc-2.95.3/configure --prefix=<new bin directory> --enable-languages=c,c++ --enable-threads=posix --enable-shared --disable-nls --host=i386-pc-linux-gnu --target=i386-pc-linux-gnu

This also failed to compile and returned

In file included from /usr/include/sys/types.h:271,
                 from /usr/include/stdlib.h:320,
                 from ../../gcc-2.95.3/gcc/frame.c:42:
/usr/include/bits/pthreadtypes.h:99: warning: unnamed struct/union that defines no instances
../../gcc-2.95.3/gcc/frame.c:55: extra brace group at end of initializer
../../gcc-2.95.3/gcc/frame.c:55: (near initialization for `object_mutex.__data')
../../gcc-2.95.3/gcc/frame.c:55: warning: excess elements in struct initializer
../../gcc-2.95.3/gcc/frame.c:55: warning: (near initialization for `object_mutex.__data')

This is what I noted earlier and spent ages on other possible problems ignoring this one and again this I had already found on the blog entry here, and is due to an unnamed union definition. The solution to this is just to make a copy of the header file, add a name to the unnamed union and then get gcc to include it.
The makefile that needs modifying is gcc/Makefile.in, the directory containing the modified header file is included before any others.

This now successfully compiled on the next attempt and I was able to use this to compile 32bit binaries.

In between each attempt I issued "make distclean" to ensure a clean directory in which to do the builds.