Simon Heimlicher

Simon Heimlicher's Homepage

Compile GCC 4.4.7 on RHEL 5

The current Matlab release, R2012b, only supports GCC 4.4 for compiling MEX functions on Linux.

On compute nodes, the installed GCC may be too old, but compiling a new version is not that hard.

The following script works for me on a Red Hat Enterprise Linux 5 machine. Note that these instructions build GCC with shared libraries (the default), which means that in general you cannot move GCC around without consequences. Since this configuration is aimed at compute nodes, only the current architecture will be supported; if you wish to change that, remove the line that says --disable-multilib from the call to configure at the bottom of the script.

I highly recommend to use stow as a very lightweight way to manage your self-compiled software.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/usr/bin/env zsh
# Download and compile GCC 4.4

set -ue

# Set minimal PATH to make sure we compile with the system compiler
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
# Use bash as the shell for everything GNU
export CONFIG_SHELL=/bin/bash

# Set to true for verbose output
VERBOSE=${VERBOSE:=false}

out () { printf "\n%b\n\n" "$@" >&2 }
fail () { printf "\n%b\n\n" " $@ " >&2; exit 1 }

DSTROOT=${DSTROOT:=$HOME/local}
PKGROOT=${PKGROOT:=$DSTROOT/pkg}
SCRATCH=${SCRATCH:-$HOME/scratch}
SRCDIR=${SRCDIR:=$SCRATCH/gcc/src}
BUILDDIR=${BUILDDIR:=$SCRATCH/gcc/build}

GCC_URL=http://mirror.switch.ch/ftp/mirror/gnu/gcc/gcc-4.4.7/gcc-4.4.7.tar.bz2

GCC_PREREQUISITE_URLS=(
ftp://gcc.gnu.org/pub/gcc/infrastructure/gmp-4.3.2.tar.bz2
ftp://gcc.gnu.org/pub/gcc/infrastructure/mpfr-2.4.2.tar.bz2
ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-0.8.1.tar.gz
http://www.mr511.de/software/libelf-0.8.13.tar.gz
)

out "DSTROOT='$DSTROOT'
PKGROOT='$PKGROOT'
SRCDIR='$SRCDIR'
BUILDDIR='$BUILDDIR'"

runcmd() {
  RUN_RET=0
  RUN_CWD='.'
  RUN_FORCE=false
  o_cwd=''; o_force=''
  zparseopts -D -K -- c:=o_cwd f=o_force -cwd:=o_cwd -force=o_force
  if [[ $# -eq 0 ]]; then
      print "Usage: runcmd [-f] <command line to run>" >&2
      return 1
  fi
  if [[ -n $o_cwd ]]; then RUN_CWD=$o_cwd[2]; fi
  if [[ -n $o_force ]]; then RUN_FORCE=true; fi
  cmdline=$@
  if $VERBOSE; then
      print "Running\n    ${(@)cmdline}\nRUN_FORCE=$RUN_FORCE RUN_CWD=$RUN_CWD" >&2
  fi
  ( set +ue; cd $RUN_CWD && print ${(@)cmdline} | $CONFIG_SHELL -sue; )
  RUN_RET=$?
  if [[ $RUN_RET -ne 0 ]]; then
      if $RUN_FORCE; then
          print "\n### $cmdline\nexit $RUN_RET in CWD=$RUN_CWD\n" >&2
      else
          print "\n\n### $cmdline\nexit $RUN_RET in CWD=$RUN_CWD\nAbort." >&2
          exit $RUN_RET
      fi
  fi
  return $RUN_RET
}

prepare_pkg () {
  local srcdir=$1
  local url=$2
  local pkgvers=${${url##*/}%.(tar*|zip)}
  local pkg=${pkgvers%-*}
  local vers=${pkgvers#*-}
  local suffix=${${url##*/}##*.}
  out "Fetching $pkgvers from $url"
  case $suffix in
      gz)
      runcmd -c $srcdir curl -L $url \| tar xz
      ;;
      bz2|tbz)
      runcmd -c $srcdir curl -L $url \| tar xj
      ;;
      zip)
      runcmd -c $srcdir curl -L $url \| funzip
      ;;
      *)
      fail "Unknown archive format: $url"
      ;;
  esac
  if [[ ! -d $srcdir/$pkgvers ]]; then
      fail "Extraction of download from $url failed"
  fi
  runcmd -c $srcdir ln -sf $pkgvers $pkg
}

if $VERBOSE; then
  printf "Using system compiler: '%s'" $(which gcc)
  gcc --version
fi

out "Making directories \n$DSTROOT\n$PKGROOT\n$SRCDIR\n$BUILDDIR"

runcmd mkdir -p $DSTROOT $PKGROOT $SRCDIR $BUILDDIR

GCC_PKG=${${GCC_URL##*/}%.(tar*|zip)}
GCC_SRC=$SRCDIR/$GCC_PKG
GCC_PREFIX=$PKGROOT/$GCC_PKG
GCC_BUILD=$BUILDDIR/$GCC_PKG-build

if [[ -d $GCC_SRC ]]; then
  out "Using GCC downloaded at $GCC_SRC"
else
  out "Downloading GCC"
  prepare_pkg $SRCDIR $GCC_URL
fi

out "Downloading prerequisites"
for pkg ($GCC_PREREQUISITE_URLS); do
  prepare_pkg $GCC_SRC $pkg
done

if [[ -d $GCC_BUILD ]]; then
  out "Running 'make distclean' in $GCC_BUILD"
  runcmd -c $GCC_BUILD -f make distclean
else
  out "Making GCC build directory $GCC_BUILD"
  runcmd mkdir -p $GCC_BUILD
fi

out "Configuring GCC"
runcmd -c $GCC_BUILD $GCC_SRC/configure --prefix=$GCC_PREFIX \
--enable-languages=c,c++,fortran \
--enable-threads=posix \
--enable-tls \
--enable-libgomp \
--enable-lto \
--enable-shared \
--enable-static \
--disable-nls \
--disable-multilib \
--with-fpmath=sse

out "Compiling GCC"
runcmd -c $GCC_BUILD make -j 8 all

out "Installing GCC"
runcmd -c $GCC_BUILD make -j 8 install

if which stow &>/dev/null; then
  out "Using 'stow' to symlink GCC from $GCC_PKG"
  runcmd -c $PKGROOT stow $GCC_PKG
else
  out "Package manager 'stow' not found. GCC is installed in $GCC_PREFIX"
fi

print "All done"

If all goes well, your new GCC is now installed in $PKGROOT/gcc-4.4.7. If stow was found,d symlinks will have been created one level up from $PKGROOT in subdirectories bin, lib, include, etc.

Comments