SGI: Development

HOWTO: Building GCC 4.6.3 on IRIX

GCC has one of the crappiest build processes ever devised by man, so I made this howto to help people build it as pleasantly as possible.

You will need about 4GB of disk space. It takes about 2.5 hours to build everything on a 16-processor Origin 3400 (8x 500MHz + 8x 400MHz, 16GB of RAM).
Most of that time is spent in "genattrtab", which is _glacially_ slow and should be rewritten. The rest of that time is spent by gmake re-running "configure" for the 2873517th time. There is also some compiling :)

You may skip the "gmake -j16 check" step while building gmp, mpfr, and mpc.

If you are building this on a machine with a different number of processors, replace every "gmake -j16" below with "gmake -j<your_number_of_cpus_here>".

You will need GCC 4.3.2 from Nekoware, or something newer to build this; GCC 3.x won't do. Binutils also need the 'texinfo' package for some reason.


Anyway, let's begin.


0. Make a build directory:
Code:
mkdir build-gcc && cd build-gcc

You can delete this directory after installation is complete.


1. Download prerequisites:
Code:
curl -O ftp://ftp.gmplib.org/pub/gmp-5.0.5/gmp-5.0.5.tar.bz2
curl -O http://ftp.gnu.org/gnu/binutils/binutils-2.18.tar.bz2
curl -O http://www.mpfr.org/mpfr-current/mpfr-3.1.1.tar.bz2
curl -O http://www.multiprecision.org/mpc/download/mpc-1.0.1.tar.gz
curl -O ftp://gcc.gnu.org/pub/gcc/infrastructure/ppl-0.11.tar.gz
curl -O ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-ppl-0.15.11.tar.gz
curl -O ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-4.6.3/gcc-4.6.3.tar.bz2



2. Extract packages:

This will take a while, make yourself some coffee :)
Code:
tar jxf gmp-5.0.5.tar.bz2 && tar jxf binutils-2.18.tar.bz2 && tar jxf mpfr-3.1.1.tar.bz2 && tar zxf mpc-1.0.1.tar.gz && tar zxf ppl-0.11.tar.gz && tar zxf cloog-ppl-0.15.11.tar.gz && tar jxf gcc-4.6.3.tar.bz2


You can now delete the archives to save disk space:
Code:
rm *.tar.bz2 *.tar.gz



3. Build gmp:
Code:
cd gmp-5.0.5
./configure --disable-shared --enable-static --prefix=/opt/gcc-4.6.3 --enable-cxx CPPFLAGS=-fexceptions
gmake -j16
gmake -j16 check
sudo gmake install
gmake clean



4. Build mpfr:
Code:
cd ../mpfr-3.1.1
./configure --disable-shared --enable-static --prefix=/opt/gcc-4.6.3 --with-gmp=/opt/gcc-4.6.3
gmake -j16
gmake -j16 check
sudo gmake install
gmake clean



5. Build mpc:
Code:
cd ../mpc-1.0.1
./configure --disable-shared --enable-static --prefix=/opt/gcc-4.6.3 --with-gmp=/opt/gcc-4.6.3 --with-mpfr=/opt/gcc-4.6.3
gmake -j16
gmake -j16 check
sudo gmake install
gmake clean



6. Build PPL:
Code:
cd ../ppl-0.11
./configure --disable-shared --enable-static --prefix=/opt/gcc-4.6.3 --with-gmp-prefix=/opt/gcc-4.6.3 --without-java --disable-watchdog --disable-ppl_lcdd --disable-ppl_lpsol --disable-ppl_pips CPPFLAGS=-fexceptions

The configure script thinks we have support for getopt_long, but we don't. Correct that error manually by editing config.h and src/ppl.hh.dist -- comment out the lines containing "HAVE_GETOPT_H". You also have to delete the line with D["HAVE_GETOPT_H"]=" 1" in config.status .

Code:
gmake -j16
sudo gmake install
sudo gmake clean



7. Build CLooG-PPL:
Code:
cd ../cloog-ppl-0.15.11
./configure --disable-shared --enable-static --prefix=/opt/gcc-4.6.3 --with-gmp=/opt/gcc-4.6.3 --with-ppl=/opt/gcc-4.6.3
gmake -j16
sudo gmake install
gmake clean



8. Build binutils:
Code:
cd .. && mkdir bu-objs && cd bu-objs

../binutils-2.18/configure --prefix=/opt/gcc-4.6.3 --with-gmp=/opt/gcc-4.6.3 --with-mpfr=/opt/gcc-4.6.3 --with-mpc=/opt/gcc-4.6.3 --disable-libssp --disable-nls --disable-werror --without-docdir

gmake -j16
sudo gmake install
gmake clean



9. Build gcc:
Code:
cd .. && mkdir gcc-objs && cd gcc-objs

../gcc-4.6.3/configure --prefix=/opt/gcc-4.6.3 --with-gmp=/opt/gcc-4.6.3 --with-mpfr=/opt/gcc-4.6.3 --with-mpc=/opt/gcc-4.6.3 --with-cloog=/opt/gcc-4.6.3 --with-ppl=/opt/gcc-4.6.3 --with-as=/opt/gcc-4.6.3/bin/as --with-ld=/opt/gcc-4.6.3/bin/ld --with-gnu-as --with-gnu-ld --with-host-libstdcxx=/usr/nekoware/gcc-4.3/lib32/libstdc++.a --disable-libssp --disable-nls --disable-lto --disable-shared --enable-static --enable-threads=posix --enable-libgomp --enable-languages=c,c++,fortran,objc,obj-c++ --with-arch=mips4 --with-abi=n32

gmake -j16
sudo gmake install


You may now delete the build directory:
Code:
cd ../..
rm -rf build-gcc



10. Free up lots of space:

This reduces the size of the install directory from almost 600MB to 175MB.

Code:
sudo rm -r /opt/gcc-4.6.3/share/doc /opt/gcc-4.6.3/share/aclocal /opt/gcc-4.6.3/share/man/man3 /opt/gcc-4.6.3/share/man/man7 /opt/gcc-4.6.3/share/man/man1/ppl-config.1 /opt/gcc-4.6.3/share/info /opt/gcc-4.6.3/info /opt/gcc-4.6.3/lib/*.{a,la} /opt/gcc-4.6.3/bin/ppl-config

sudo strip -s /opt/gcc-4.6.3/bin/* /opt/gcc-4.6.3/mips-sgi-irix6.5/bin/* /opt/gcc-4.6.3/libexec/gcc/mips-sgi-irix6.5/4.6.3/* /opt/gcc-4.6.3/libexec/gcc/mips-sgi-irix6.5/4.6.3/install-tools/fixincl



That's all, folks :)
The wiki has a How To section.

Just a thought.

R.

_________________
死の神はりんごだけ食べる

アレゲはアレゲ以上のなにものでもなさげ -- アレゲ研究家

:Tezro: :Tezro: :Onyx2R: :Onyx2RE: :Onyx2: :O3x04R: :O3x0: :O200: :Octane: :Octane2: :O2: :O2: :Indigo2IMP: :PI: :PI: :1600SW: :1600SW: :Indy: :Indy: :Indy: :Indy: :Indy:
:hpserv: J5600, 2 x Mac, 3 x SUN, Alpha DS20E, Alpha 800 5/550, 3 x RS/6000, Amiga 4000 VideoToaster, Amiga4000 -030, 733MHz Sam440 AmigaOS 4.1 update 1. Tandem Himalaya S-Series Nonstop S72000 ServerNet.

Sold: :Indy: :Indy: :Indy: :Indigo:

Cortex ---> http://www.facebook.com/pages/Cortex-th ... 11?sk=info
Minnie ---> http://www.facebook.com/pages/Minnie-th ... 02?sk=info
Book ----> http://pymblesoftware.com/book/
Github ---> https://github.com/pymblesoftware
Visit http://www.pymblesoftware.com
Search for "Pymble", "InstaElf", "CryWhy" or "Cricket Score Sheet" in the iPad App store or search for "Pymble" or "CryWhy" in the iPhone App store.
PymbleSoftware wrote:
The wiki has a How To section.

I know, but this is just an intermediary step. My original goal was to compile 4.7.2 and I intend to post the howto for that on the wiki (as well as here) when it's finished.
If you're compiling 4.7.? anyway, could you please make nekoware packages? It's only a tiny bit of additional work, aside from building with a different prefix ( /usr/nekoware/gcc-4.7) and runing find /usr/nekoware before make install and another find and a script afterwards, it's really just writing the releasenotes...
canavan wrote:
If you're compiling 4.7.? anyway, could you please make nekoware packages?

I could probably find the time to do that next weekend, however, the 4.7.2 compile isn't looking too good at the moment.

This happens during stage1, while gcc 4.7.2 is building libstdc++ with itself (xgcc):
Code:
../../../../gcc-4.7.2/libstdc++-v3/libsupc++/vec.cc: In function 'void __cxxabiv1::__cxa_vec_delete2(void*, std::size_t, std::size_t, __cxxabiv1::__cxa_cdtor_type, void (*)(void*))':
../../../../gcc-4.7.2/libstdc++-v3/libsupc++/vec.cc:323:3: internal compiler error: in maybe_record_trace_start, at dwarf2cfi.c:2231
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
gmake[5]: *** [vec.lo] Error 1


I can work around that by opening ../gcc-4.7.2/libstdc++-v3/libsupc++/vec.cc and changing lines 292 and 325 to:
Code:
extern "C" void __attribute__((optimize("O1")))

(this lowers the optimization level for those functions to -O1 from the default -O2), but then the same error happens in ../gcc-4.7.2/libstdc++-v3/src/c++98/strstream.cc (in the function starting at line 320) and then again in a generated header somewhere in the build directory ...

GCC was configured as follows:
Code:
../gcc-4.7.2/configure --prefix=/opt/gcc-4.7.2 --with-gmp=/opt/gcc-4.7.2 --with-mpfr=/opt/gcc-4.7.2 --with-mpc=/opt/gcc-4.7.2 --with-cloog=/opt/gcc-4.7.2 --with-ppl=/opt/gcc-4.7.2 --with-as=/opt/gcc-4.7.2/bin/as --with-ld=/opt/gcc-4.7.2/bin/ld --with-gnu-as --with-gnu-ld --with-host-libstdcxx=/opt/gcc-4.6.3/lib32/libstdc++.a --disable-libssp --disable-nls --disable-lto --disable-shared --enable-static --enable-threads=posix --enable-libgomp --enable-obsolete --enable-languages=c,c++,fortran,objc,obj-c++ --with-arch=mips4 --with-abi=n32

The prerequisites have been configured as written in the howto above, except with the prefix set to /opt/gcc-4.7.2.

Conclusion:
The optimizer in GCC 4.7.2 is broken at -O2, so there's not much I can do to fix this.
Even if I were to manually change the optimization level for each function this error appears in (or force -O1 for the entire libstdc++), the finished compiler would probably have the same problem and would therefore be useless for any practical work :(

I will try building the SVN version either tomorrow or on Saturday, but I don't have high expectations for this one ...
Two things:

1) Always run the testsuite (' make check '). It takes twice as long as the actual GCC bootstrap but at least you know what you've got before it miscompiles half your source code.

2) Don't use GNU ld on IRIX 6.x. It works fine for 'old' ELF (IRIX 5.x, or O32 ABI), but is rather broken for N32/64 IRIX ABIs. As Rainer Orth once told me:
Quote:
I've avoided GNU ld on all platforms like the plague.
Or bootstrap once with and once without GNU ld. The testsuite results will speak for themselves. So: configure with --without-gnu-ld --with-ld=/usr/bin/ld

I don't recall GCC 4.7. 0 being broken at -O2, in fact you need to bootstrap almost every GCC 4.x at -O2 or the binaries are so big you end up with multi-GOT misery. Not sure I ever built 4.7.2.

Otherwise, 'strip' from GNU binutils is broken so you'd best delete it.

You can disable some runtime checks in the compiler to speed it up a bit with --enable-checking=release

You need an Ada compiler to bootstrap the Ada language. I have Ada enabled GCC binaries for IRIX 5.3, 6.2 and 6.5 for those willing to try.

If you want to build the Java compiler you should build the Java libraries too: --enable-libgcj --enable-java-awt=xlib .

An all-language (C,C++,Ada,Fortran,Java,ObjC,ObjC++) GCC with triple ABI runtimes takes about 8 hours to bootstrap and check on my 8-way O350.

_________________
Now this is a deep dark secret, so everybody keep it quiet :)
It turns out that when reset, the WD33C93 defaults to a SCSI ID of 0, and it was simpler to leave it that way... -- Dave Olson, in comp.sys.sgi

Currently in commercial service: Image :Onyx2: (2x) :O3x02L:
In the museum : almost every MIPS/IRIX system.
Wanted : GM1 board for Professional Series GT graphics (030-0076-003, 030-0076-004)
Thanks for the tips, jan-jaap!

I omitted Ada and Java on purpose, since I have no use for them :)
I can build the Java frontend if anyone needs it for the Nekoware package (but please let me know before Saturday).

GNU ld from 2.18 seems to be working for simple things, but you're right, I should have run the testsuite.

You mentioned that 4.7.0 works OK, so I will try building 4.7.1 now.
4.7.2 crashes with the error in my previous post, which looks unrelated to binutils.

I also noticed that GCC on IRIX has been obsoleted, this is bad. There was a thread on this a while ago and I got the impression that someone provided the testing hardware, so that this wouldn't happen. Did something go wrong with that?

A few gotchas I've encountered, in case someone else reads this and wants to try doing things differently:
  • the in-tree build (i.e. building gcc and all its prerequisites from the gcc directory) is broken
  • latest binutils are broken -- programs segfault immediately (though it might only be ld's fault)
  • you must use the exact versions of ppl and cloog-ppl mentioned above, newer versions won't work
  • the documentation on GCC's website is for the SVN version (download the package and read the docs in there, the prerequisites are very different)

There's probably more, but this is all I can remember at the moment.
I'm using binutils 2.22 (well, binutils minus GNU ld and strip). Works for me.

Oh, when I said bootstrap at -O2, I meant pass STAGE1_CFLAGS=-O2 to 'make'.

There are many intricacies to building a compiler toolchain. As you found out, GCC has many dependencies. If you build the dependencies (or binutils with shared BFD) with GCC, they will depend on libgcc_s.so, creating a circular dependency. A misconfigured compiler can thus leave you without functional toolchain suitable of recovering. I maintain a separate 'bootstrap' compiler outside $PATH with all dependencies linked in statically to avoid this, and, in general, build any DSOs with MIPSpro to avoid libgcc_s.so.

IRIX obsoletion has been postponed a couple of times but in the end there just weren't enough people to fix bugs and run regression tests on a regular basis. It will be a while before software requires GCC >= 4.8

_________________
Now this is a deep dark secret, so everybody keep it quiet :)
It turns out that when reset, the WD33C93 defaults to a SCSI ID of 0, and it was simpler to leave it that way... -- Dave Olson, in comp.sys.sgi

Currently in commercial service: Image :Onyx2: (2x) :O3x02L:
In the museum : almost every MIPS/IRIX system.
Wanted : GM1 board for Professional Series GT graphics (030-0076-003, 030-0076-004)
4.7.1 is currently compiling and it looks good so far (it got much further than 4.7.2 before) :)

jan-jaap wrote:
There are many intricacies to building a compiler toolchain. As you found out, GCC has many dependencies. If you build the dependencies (or binutils with shared BFD) with GCC, they will depend on libgcc_s.so, creating a circular dependency. A misconfigured compiler can thus leave you without functional toolchain suitable of recovering. I maintain a separate 'bootstrap' compiler outside $PATH with all dependencies linked in statically to avoid this, and, in general, build any DSOs with MIPSpro to avoid libgcc_s.so.

I've built all dependencies with "--disable-shared --enable-static" (gcc as well) to avoid such problems.

The final Nekoware package will also have the dependencies linked in statically, since GCC is way too sensitive about certain library versions (ppl and cloog-ppl) and I think a few MB of disk space are a reasonable tradeoff for having things just work :)

Quote:
IRIX obsoletion has been postponed a couple of times but in the end there just weren't enough people to fix bugs and run regression tests on a regular basis. It will be a while before software requires GCC >= 4.8

Oh well.


EDIT: Build successful :D

There seems to be a problem with OpenMP, though, omp_get_num_procs() always returns 1, which is wrong. Setting the number of threads manually with omp_set_num_threads() or OMP_NUM_THREADS works as it should.

OK, so my schedule for next weekend is:
  • see if I can fix the number of CPUs detection code in libgomp
  • build latest binutils again
  • build 4.7.1 and its prereqs with the 4.7.1 that I built today
  • run the testsuite
  • write another howto
  • make a Nekoware package

If somebody needs the Java frontend, please let me know by Saturday, or I will build the package without Java support.
A short update:

4.7.1 with latest binutils (minus ld) compiles OK, it's currently running the testsuite with no failed tests so far.
I didn't touch the OpenMP bug, since it's not in libgomp and I didn't feel like going through gcc's spaghetti code to search for it. The workaround is to just set OMP_NUM_THREADS environment variable to the number of CPUs your machine has before running your OpenMP programs (you can do this in your shell's .profile).

Tomorrow I'll try to find the time to make a Nekoware package. Since this will be my first package, any tips are welcome :)
Read the wiki article http://www.nekochan.net/wiki/Packaging_Software make sure you check the releasenotes and dist files of older versions of the same software, and if you're lazy, try the two scripts i've posted here viewtopic.php?f=11&t=16723208&p=7321579 (but I suspect idbify.sh won't get the subsystems right since you're installing directly into /usr/nekoware.
Thanks, but the forum says "The selected attachment does not exist anymore." for the .tar with your scripts :(

However, I played around with swpkg a bit and it looks fairly straightforward. I've added all the files and set everything up.
It's a bit easier in this case, since everything is contained in a single directory and there are no external dependencies because all prerequisites are linked in statically (gcc needs a really old version of ppl and would break if you upgraded it, so it makes more sense to link it in statically -- I did the same for the other prerequisites, as upgrading them could have the same effect).
I didn't separate the files into .eoe, .lib, and .hdr subsystems, since they depend on each other and installing them separately would make no sense; the current gcc package does the same.

The Origin will have to be powered down now, so I'm going to interrupt the testsuite and continue the objc* tests next weekend. Then I will include the test results in the release notes, make the final package, and test it on a few other machines.
ShadeOfBlue wrote:
There seems to be a problem with OpenMP, though, omp_get_num_procs() always returns 1, which is wrong. Setting the number of threads manually with omp_set_num_threads() or OMP_NUM_THREADS works as it should.


Graphics Magick has the same problem, Bob Friesenhahn (sp ?) might have some input on that. Also tripped over this while looking for something else, don't know if there are any clues hidden in there but ...

http://www.cfd-online.com/Forums/openfo ... -irix.html
hamei wrote:
Graphics Magick has the same problem, Bob Friesenhahn (sp ?) might have some input on that. Also tripped over this while looking for something else, don't know if there are any clues hidden in there but ...

http://www.cfd-online.com/Forums/openfo ... -irix.html

That one is for MPI, which is a different library :)

This only affects OpenMP programs built with GCC, MIPSpro-compiled ones work as they should.

I've looked at libgomp again and found the error ... It's in libgomp/config/posix/proc.c.
On IRIX, _SC_NPROCESSORS_ONLN is called _SC_NPROC_ONLN. It's a really easy fix, don't know how I missed that earlier :oops:

I'll rebuild gcc and rerun all the tests next weekend.

If only their antiquated testing framework executed the tests in parallel ... It's not 1960 anymore :roll:
A little update:

I've patched libgomp to properly detect the number of CPUs in the machine. The libgomp testsuite passes without any errors and my OpenMP programs also work as they should :)

Here's the patch:
Code:
diff -urnp libgomp-orig/config/posix/proc.c libgomp/config/posix/proc.c
*** libgomp-orig/config/posix/proc.c    Sat Dec  8 14:57:52 2012
--- libgomp/config/posix/proc.c Sat Dec  8 14:58:43 2012
***************
*** 38,43 ****
--- 38,48 ----
#endif


+ #ifdef __sgi
+ #define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN
+ #endif
+
+
/* At startup, determine the default number of threads.  It would seem
this should be related to the number of cpus online.  */



I hope that the comment below my fix is a joke :)

The rest of the testsuite is running now, but it's so damn slow, I'll probably have to continue it next week.
In case anyone has missed it, the finished package has been in /beta for about two weeks now: http://forums.nekochan.net/viewtopic.php?f=15&t=16727285 :)
ShadeOfBlue wrote:
In case anyone has missed it, the finished package has been in /beta for about two weeks now: http://forums.nekochan.net/viewtopic.php?f=15&t=16727285 :)

I'd love to check it out Shade , and thanks very much for creating this ... but if I had two compilers on my system I'd really screw up ! :oops:

I was thinking tho ... how much of the problem with compiling Fireflop is gcc-isms ? Would a gcc version be feasible ?
hamei wrote:
I'd love to check it out Shade , and thanks very much for creating this ... but if I had two compilers on my system I'd really screw up ! :oops:

This one installs under a separate directory (/usr/nekoware/gcc-4.7) and is completely self-contained. Nothing looks in that directory by default, so as long as you don't add it to your PATH, nothing bad should happen :)
Whenever you want to compile something with gcc, just append "CC=/usr/nekoware/gcc-4.7/bin/gcc CXX=/usr/nekoware/gcc-4.7/bin/g++" to the end of the configure command line and it should work.

The previous Nekoware gcc package (4.3) required setting LD_LIBRARYN32_PATH, but this one doesn't, since I've linked everything statically (it's a better choice in this case).
It should Just Work(tm) :mrgreen:

hamei wrote:
I was thinking tho ... how much of the problem with compiling Fireflop is gcc-isms ? Would a gcc version be feasible ?

I've never tried compiling Firefox, but I guess you could give it a shot. A gcc-compiled Firefox is still better than no Firefox at all :)
In most cases, the proper fix for LD_LIBRARYN32_PATH is linking with -Wl,-rpath -Wl,/usr/nekoware/...., but I suspect it won't make much of a difference in this case.
The reason I linked the prerequisites statically is that GCC is really touchy about their versions.
For example, it needs PPL 0.11, which is an ancient version (newest is 1.0), and CLooG-PPL 0.15.11 (also old). If you use newer versions, it won't work.

If I had created separate packages for such prerequisites and linked them dynamically, those packages could never be updated to newer versions because GCC would break. Maintaining obsolete versions just for GCC would be silly and this is why I linked them statically :)