This post has already been read 3371 times!

redhat-linux-logo
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.

Stow 2.2.0

#!/bin/bash

DSTROOT=$HOME/local
PKGROOT=$DSTROOT/pkg
SCRATCH=/tmp/build
TMPROOT=$SCRATCH/root
mkdir -p $PKGROOT $TMPROOT

PKG=stow-2.2.0
cd $SCRATCH && curl http://ftp.gnu.org/gnu/stow/stow-latest.tar.bz2 | tar xjf -
cd $PKG
./configure --prefix=$PKGROOT/$PKG
make install

cd $PKGROOT
mkdir -p ../bin
ln -s $PKG/bin/stow ../bin

gccegg-65

Compile GCC 4.4.7(the GNU Compiler Collection) on RHEL 5

The GNU Compiler Collection includes front ends for C, C++, Objective-C, Fortran, Java, Ada, and Go, as well as libraries for these languages (libstdc++, libgcj,...). GCC was originally written as the compiler for the GNU operating system. The GNU system was developed to be 100% free software, free in the sense that it respects the user's freedom.

We strive to provide regular, high quality releases, which we want to work well on a variety of native and cross targets (including GNU/Linux), and encourage everyone to contribute changes or help testing GCC. Our sources are readily and freely available via SVN and weekly snapshots.

#!/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] " >&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 are closed.

Post Navigation