#!/bin/sh
# This is my script for building a complete MinGW cross-compiler toolchain
# that runs under Linux to produce executables that run under Windows. It
# probably works (or can easily be adapted to work) under any unix system.
#
# It is based in large part on Sam Lantinga's script, which in turn was
# based partly on Ray Kelm's script, which in turn was built on
# Mo Dejong's script for doing the same, but with some added fixes.
#
# My changes:
# 1. Adapted the script to the new packaging of MinGW GCC, which is
# currently split into core and auxiliary components.
# 2. The script now determines the GCC and BINUTILS directory name
# directly from the tar file contents. This gets around common
# problems due to the directory names not always following the
# expected patterns.
# 3. Grouped together and simplified the macros that users need to
# define.
# 4. Made optional components truly optional -- leave the
# corresponding archive names blank and they will be ignored.
# 5. Included an option to purge the installation directory before
# installing the current cross-compiler.
#
# NOTE: If you choose a destination directory for the installation (set
# in the macro PREFIX) for which you do not have write access, you will
# need to run this script with root (or equivalent) privileges.
#
#
# Updated by Igor Mikolic-Torreira <igormt@alumni.caltech.edu>
#-----------------------------------------------------
#
# BEGIN USER SETTINGS
#
# You need to review and adjust the macros that follow
#
#-----------------------------------------------------
# Directory where cross-tools directory will be placed
TOPDIR=../../..
# Cross tools directory name under TOPDIR
CROSSTOOLS=cross-tools
# What flavor of GCC cross-compiler are we building? under CROSSTOOLS
TARGET=mingw32
cwd=`pwd`
cd ${TOPDIR}
# Make TOPDIR absolute
TOPDIR=`pwd`
cd ${cwd}/`dirname $0`
SCRIPTDIR=`pwd`
cd ${cwd}
BUILDDIR=${TOPDIR}/${CROSSTOOLS}
# Where does the cross-compiler go?
# This should be the directory into which your cross-compiler
# will be installed. Remember that if you set this to a directory
# that only root has write access to, you will need to run this
# script as root.
PREFIX=${BUILDDIR}/${TARGET}
mkdir -p ${BUILDDIR}
mkdir -p ${BUILDDIR}/${TARGET}
echo "Building cross tools in ${BUILDDIR} ..."
echo " "
# Purge anything and everything already in the $PREFIX
#(also known as the destination or installation) directory?
# Set to "Y" to purge, any other value omits the purge step.
PURGE_DIR="Y"
# Set the following to the files from the current MinGW release
# (or whichever MinGW release you wish to build and install)
# You need to set both the URL they will be downloaded from
# and the exact name of the individual component files.
MINGW_URL="http://superb-west.dl.sourceforge.net/sourceforge/mingw"
# GCC_CORE is required; the other components are optional.
# Set any you don't want to "". You need binutils,
# mingw runtime and w32api; do not ever set those to "".
GCC_CORE_ARCHIVE="gcc-core-3.4.5-20060117-1-src.tar.gz"
GCC_GPP_ARCHIVE="gcc-g++-3.4.5-20060117-1-src.tar.gz"
GCC_G77_ARCHIVE=""
GCC_OBJC_ARCHIVE=""
GCC_JAVA_ARCHIVE=""
GCC_ADA_ARCHIVE=""
GCC_PATCH=""
# GCC_G77_ARCHIVE="gcc-g77-3.4.2-20040916-1-src.tar.gz"
# GCC_OBJC_ARCHIVE="gcc-objc-3.4.2-20040916-1-src.tar.gz"
# GCC_JAVA_ARCHIVE="gcc-java-3.4.2-20040916-1-src.tar.gz"
BINUTILS_ARCHIVE="binutils-2.16.91-20060119-1-src.tar.gz"
MINGW_ARCHIVE="mingw-runtime-3.9.tar.gz"
W32API_ARCHIVE="w32api-3.7.tar.gz"
MINGW_UTILS_ARCHIVE="mingw-utils-0.3-src.tar.gz"
# These are the files from the SDL website
# These are optional, set them to "" if you don't want them)
SDL_URL="http://www.libsdl.org/extras/win32/common"
OPENGL_ARCHIVE="opengl-devel.tar.gz"
DIRECTX_ARCHIVE="directx-devel.tar.gz"
#-----------------------------------------------------
#
# END USER SETTINGS
#
# The remainder of the script should not neet any edits
#
#-----------------------------------------------------
# Make sure these are initialized as we want them
GCC_CORE=""
BINUTILS=""
GCC_LANGS="c"
# Set our build directory and where our sources will go
if [ "x$BUILDDIR" = "x" ]; then
# Default to the current directory
BUILDDIR=$(pwd)
fi
SRCDIR="$BUILDDIR/source"
# Need install directory first on the path so gcc can find binutils
PATH="$PREFIX/bin:$PATH"
#-----------------------------------------------------
#
# Functions that do most of the work
#
#-----------------------------------------------------
download_files()
{
# Download a file from a given url, only if it is not present
mkdir -p "$SRCDIR"
# Make sure wget is installed
if test "x`which wget`" = "x" ; then
echo "You need to install wget."
exit 1
fi
download_file "$GCC_CORE_ARCHIVE" "$MINGW_URL"
if [ "x$GCC_GPP_ARCHIVE" != "x" ]; then
download_file "$GCC_GPP_ARCHIVE" "$MINGW_URL"
fi
if [ "x$GCC_G77_ARCHIVE" != "x" ]; then
download_file "$GCC_G77_ARCHIVE" "$MINGW_URL"
fi
if [ "x$GCC_OBJC_ARCHIVE" != "x" ]; then
download_file "$GCC_OBJC_ARCHIVE" "$MINGW_URL"
fi
if [ "x$GCC_JAVA_ARCHIVE" != "x" ]; then
download_file "$GCC_JAVA_ARCHIVE" "$MINGW_URL"
fi
if [ "x$GCC_ADA_ARCHIVE" != "x" ]; then
download_file "$GCC_ADA_ARCHIVE" "$MINGW_URL"
fi
download_file "$BINUTILS_ARCHIVE" "$MINGW_URL"
download_file "$MINGW_ARCHIVE" "$MINGW_URL"
download_file "$W32API_ARCHIVE" "$MINGW_URL"
if [ "x$MINGW_UTILS_ARCHIVE" != "x" ]; then
download_file "$MINGW_UTILS_ARCHIVE" "$MINGW_URL"
fi
if [ "x$OPENGL_ARCHIVE" != "x" ]; then
download_file "$OPENGL_ARCHIVE" "$SDL_URL"
fi
if [ "x$DIRECTX_ARCHIVE" != "x" ]; then
download_file "$DIRECTX_ARCHIVE" "$SDL_URL"
fi
}
download_file()
{
cd "$SRCDIR"
if test ! -f $1 ; then
echo "Downloading $1"
wget "$2/$1"
if test ! -f $1 ; then
echo "Could not download $1"
exit 1
fi
else
echo "Found $1 in the srcdir $SRCDIR"
fi
cd "$BUILDDIR"
}
purge_existing_install()
{
echo "Purging the existing files in $PREFIX"
if cd "$PREFIX"; then
rm -rf *
fi
cd "$BUILDDIR"
}
install_libs()
{
echo "Installing cross libs and includes"
mkdir -p "$PREFIX/$TARGET"
cd "$PREFIX/$TARGET"
tar -xzf "$SRCDIR/$MINGW_ARCHIVE"
tar -xzf "$SRCDIR/$W32API_ARCHIVE"
if [ "x$OPENGL_ARCHIVE" != "x" ]; then
tar -xzf "$SRCDIR/$OPENGL_ARCHIVE"
fi
if [ "x$DIRECTX_ARCHIVE" != "x" ]; then
tar -xzf "$SRCDIR/$DIRECTX_ARCHIVE"
fi
cd "$BUILDDIR"
}
extract_binutils()
{
cd "$SRCDIR"
BINUTILS=`tar -tzf "$SRCDIR/$BINUTILS_ARCHIVE" | head -n 1`
if [ "x${BINUTILS}" != "x./" ]; then
rm -rf "$BINUTILS"
fi
echo "Extracting binutils"
tar -xzf "$SRCDIR/$BINUTILS_ARCHIVE"
cd "$BUILDDIR"
}
configure_binutils()
{
cd "$BUILDDIR"
rm -rf "binutils-$TARGET"
mkdir "binutils-$TARGET"
cd "binutils-$TARGET"
echo "Configuring binutils"
"$SRCDIR/$BINUTILS/configure" --prefix="$PREFIX" --target=$TARGET --disable-nls \
--with-gcc --with-gnu-as --with-gnu-ld --disable-shared 2>&1 > configure.log
cd "$BUILDDIR"
}
build_binutils()
{
cd "$BUILDDIR/binutils-$TARGET"
echo "Building binutils"
make CFLAGS="-O2 -fno-exceptions" LDFLAGS="-s" 2>&1 > make.log
if test $? -ne 0; then
echo "make of binutils failed - log available: binutils-$TARGET/make.log"
exit 1
fi
cd "$BUILDDIR"
}
install_binutils()
{
cd "$BUILDDIR/binutils-$TARGET"
echo "Installing binutils"
make install 2>&1 > make-install.log
if test $? -ne 0; then
echo "install of binutils failed - log available: binutils-$TARGET/make-install.log"
exit 1
fi
cd "$BUILDDIR"
}
extract_gcc()
{
cd "$SRCDIR"
GCC=`tar -tzf "$SRCDIR/$GCC_CORE_ARCHIVE" | head -n 1`
# rm -rf "$GCC"
echo "====== GCC ${GCC} ========="
echo "Extracting gcc"
tar -xzf "$SRCDIR/$GCC_CORE_ARCHIVE"
if [ "x$GCC_GPP_ARCHIVE" != "x" ]; then
GCC_LANGS=${GCC_LANGS}",c++"
tar -xzf "$SRCDIR/$GCC_GPP_ARCHIVE"
fi
if [ "x$GCC_G77_ARCHIVE" != "x" ]; then
GCC_LANGS=${GCC_LANGS}",f77"
tar -xzf "$SRCDIR/$GCC_G77_ARCHIVE"
fi
if [ "x$GCC_OBJC_ARCHIVE" != "x" ]; then
GCC_LANGS=${GCC_LANGS}",objc"
tar -xzf "$SRCDIR/$GCC_OBJC_ARCHIVE"
fi
if [ "x$GCC_JAVA_ARCHIVE" != "x" ]; then
GCC_LANGS=${GCC_LANGS}",java"
tar -xzf "$SRCDIR/$GCC_JAVA_ARCHIVE"
fi
if [ "x$GCC_ADA_ARCHIVE" != "x" ]; then
GCC_LANGS=${GCC_LANGS}",ada"
tar -xzf "$SRCDIR/$GCC_ADA_ARCHIVE"
fi
cd "$BUILDDIR"
}
patch_gcc()
{
if [ "$GCC_PATCH" != "" ]; then
echo "Patching gcc"
cd "$SRCDIR/$GCC"
patch -p1 < "$SRCDIR/$GCC_PATCH"
cd "$BUILDDIR"
fi
}
configure_gcc()
{
cd "$BUILDDIR"
rm -rf "gcc-$TARGET"
mkdir "gcc-$TARGET"
cd "gcc-$TARGET"
echo "Configuring gcc"
"$SRCDIR/$GCC/configure" -v \
--prefix="$PREFIX" --target=$TARGET \
--with-headers="$PREFIX/$TARGET/include" \
--with-gcc --with-gnu-ld --with-gnu-as \
--enable-threads --disable-nls --enable-languages=$GCC_LANGS \
--disable-win32-registry --disable-shared --enable-sjlj-exceptions --enable-libgcj \
--disable-java-awt --without-x --enable-java-gc=boehm --disable-libgcj-debug \
--enable-interpreter --enable-hash-synchronization --enable-libstdcxx-debug \
2>&1 > configure.log
cd "$BUILDDIR"
}
build_gcc()
{
cd "$BUILDDIR/gcc-$TARGET"
echo "Building gcc"
make CFLAGS="-O2" CXXFLAGS="-O2" GCJFLAGS="-O2" LDFLAGS="-s" DEBUG_FLAGS="-g0" 2>&1 > make.log
if test $? -ne 0; then
echo "make of gcc failed - log available: gcc-$TARGET/make.log"
exit 1
fi
if [ "x$GCC_ADA" != "x" ]; then
cd gcc
make "CFLAGS=-O2" "LDFLAGS=-s" gnatlib_and_tools 2>&1 > make-gnatlib.log
if test $? -ne 0; then
echo "make of gnatlib and tools failed - log available: gcc-$TARGET/make-gnatlib.log"
exit 1
fi
fi
cd "$BUILDDIR"
}
install_gcc()
{
cd "$BUILDDIR/gcc-$TARGET"
echo "Installing gcc"
make install 2>&1 > make-install.log
if test $? -ne 0; then
echo "install of gcc failed - log available: gcc-$TARGET/make-install.log"
exit 1
fi
cd "$BUILDDIR"
}
extract_mingw_utils()
{
cd "$SRCDIR"
MINGW_UTILS=`tar -tzf "$SRCDIR/$MINGW_UTILS_ARCHIVE" | head -n 1`
if [ "x${MINGW_UTILS}" != "x./" ]; then
rm -rf "$MINGW_UTILS"
fi
echo "Extracting mingw-utils"
tar -xzf "$SRCDIR/$MINGW_UTILS_ARCHIVE"
cd "$BUILDDIR"
}
patch_mingw_utils()
{
MINGW_UTILS=`tar -tzf "$SRCDIR/$MINGW_UTILS_ARCHIVE" | head -n 1`
cd "${SRCDIR}/${MINGW_UTILS}"
echo "Patching mingw-utils"
patch -p0 < ${SCRIPTDIR}/patches/mingw-utils.patch 2>&1 > patch.log
cd "$BUILDDIR"
}
configure_mingw_utils()
{
cd "$BUILDDIR"
rm -rf "mingw-utils"
mkdir "mingw-utils"
cd "mingw-utils"
echo "Configuring mingw-utils"
"$SRCDIR/$MINGW_UTILS/configure" --disable-nonportable --prefix="${PREFIX}/${TARGET}" 2>&1 > configure.log
cd "$BUILDDIR"
}
build_mingw_utils()
{
cd "$BUILDDIR/mingw-utils"
echo "Building mingw-utils"
make CFLAGS="-O2 -fno-exceptions" LDFLAGS="-s" 2>&1 > make.log
if test $? -ne 0; then
echo "make of mingw-utils failed - log available: mingw-utils/make.log"
exit 1
fi
cd "$BUILDDIR"
}
install_mingw_utils()
{
cd "$BUILDDIR/mingw-utils"
echo "Installing mingw-utils"
make install 2>&1 > make-install.log
if test $? -ne 0; then
echo "install of mingw-utils failed - log available: mingw-utils/make-install.log"
exit 1
fi
cd "$BUILDDIR"
}
final_tweaks()
{
echo "Finalizing installation"
# remove gcc build headers
rm -rf "$PREFIX/$TARGET/sys-include"
# Add extra binary links
if [ ! -f "$PREFIX/$TARGET/bin/objdump" ]; then
ln "$PREFIX/bin/$TARGET-objdump" "$PREFIX/$TARGET/bin/objdump"
fi
if [ ! -f "$PREFIX/$TARGET/bin/dllwrap" ]; then
ln "$PREFIX/bin/$TARGET-dllwrap" "$PREFIX/$TARGET/bin/dllwrap"
fi
# make cc and c++ symlinks to gcc and g++
if [ ! -f "$PREFIX/$TARGET/bin/g++" ]; then
ln "$PREFIX/bin/$TARGET-g++" "$PREFIX/$TARGET/bin/g++"
fi
if [ ! -f "$PREFIX/$TARGET/bin/cc" ]; then
ln -s "gcc" "$PREFIX/$TARGET/bin/cc"
fi
if [ ! -f "$PREFIX/$TARGET/bin/c++" ]; then
ln -s "g++" "$PREFIX/$TARGET/bin/c++"
fi
# strip all the binaries
ls "$PREFIX"/bin/* "$PREFIX/$TARGET"/bin/* | egrep -v '.dll$' | egrep -v 'gccbug$' |
while read file; do
strip "$file"
done
echo "Installation complete!"
}
#
# Main part of the script
#
download_files
if [ "x$PURGE_DIR" = "xY" ]; then
purge_existing_install
fi
install_libs
extract_binutils
configure_binutils
build_binutils
install_binutils
extract_gcc
patch_gcc
configure_gcc
build_gcc
install_gcc
if test -n "${MINGW_UTILS_ARCHIVE}"; then
extract_mingw_utils
patch_mingw_utils
configure_mingw_utils
build_mingw_utils
install_mingw_utils
fi
final_tweaks
#
# End
#
syntax highlighted by Code2HTML, v. 0.9.1