blob: d01df8c92a0a0f0655151e5743ae72ebd2a69c3e [file] [log] [blame]
#!/bin/bash
# Copyright (c) 2012 The Native Client Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This script is intended to build a mipsel-linux-gnu cross compilation
# toolchain that runs on x86 linux and generates code for a little-endian,
# hard-float, mips32 target.
######################################################################
# Config
######################################################################
set -o nounset
set -o errexit
readonly SCRIPT_DIR=$(dirname $0)
readonly MAKE_OPTS="-j8"
readonly ARCH="mips32"
readonly GMP_URL="http://ftp.gnu.org/gnu/gmp/gmp-6.1.1.tar.bz2"
readonly GMP_SHA1SUM="757d672e66d8e0afe60ca04735ab11c00d9346e4"
readonly MPFR_URL="http://ftp.gnu.org/gnu/mpfr/mpfr-3.1.4.tar.bz2"
readonly MPFR_SHA1SUM="e3b0af77f18505184410d621fe0aae179e229dba"
readonly MPC_URL="http://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz"
readonly MPC_SHA1SUM="b8be66396c726fdc36ebb0f692ed8a8cca3bcc66"
readonly GCC_URL="http://ftp.gnu.org/gnu/gcc/gcc-4.9.0/gcc-4.9.0.tar.bz2"
readonly GCC_SHA1SUM="fbde8eb49f2b9e6961a870887cf7337d31cd4917"
readonly BINUTILS_URL="http://ftp.gnu.org/gnu/binutils/binutils-2.26.tar.bz2"
readonly BINUTILS_SHA1SUM="a637508cffeb2323b14bc8dd65378819768ad4ff"
readonly KERNEL_URL="http://www.linux-mips.org/pub/linux/mips/kernel/v3.x/linux-3.18.3.tar.gz"
readonly KERNEL_SHA1SUM="66c390838cc3401135be534135fe72813e92378b"
readonly GLIBC_URL="http://ftp.gnu.org/gnu/glibc/glibc-2.19.tar.bz2"
readonly GLIBC_SHA1SUM="382f4438a7321dc29ea1a3da8e7852d2c2b3208c"
readonly INSTALL_ROOT=$(pwd)/toolchain/linux_x86/mips_trusted
readonly TMP=$(pwd)/toolchain/tmp/crosstool-trusted
readonly BUILD_DIR=${TMP}/build
readonly JAIL_MIPS32=${INSTALL_ROOT}/sysroot
readonly CROSS_TARBALL="mipsel_toolchain_sysroot"
######################################################################
# Helper
######################################################################
Banner() {
echo "######################################################################"
echo $*
echo "######################################################################"
}
SubBanner() {
echo "......................................................................"
echo $*
echo "......................................................................"
}
Usage() {
echo
echo "$0"
echo
}
DownloadOrCopy() {
local url=$1
local filename="${TMP}/${url##*/}"
local filetype="${url%%:*}"
if [ "${filename}" == "" ]; then
echo "Unknown error occured. Aborting."
exit 1
fi
if [[ "${filetype}" == "http" || ${filetype} == "https" ]] ; then
if [ ! -f "${filename}" ]; then
SubBanner "downloading from ${url} -> ${filename}"
wget ${url} -O ${filename}
fi
else
SubBanner "copying from ${url}"
cp ${url} ${filename}
fi
}
DownloadOrCopyAndVerify() {
local url=$1
local checksum=$2
local filename="${TMP}/${url##*/}"
local filetype="${url%%:*}"
if [ "${filename}" == "" ]; then
echo "Unknown error occured. Aborting."
exit 1
fi
if [[ "${filetype}" == "http" || ${filetype} == "https" ]] ; then
if [ ! -f "${filename}" ]; then
SubBanner "downloading from ${url} -> ${filename}"
wget ${url} -O ${filename}
fi
if [ "${checksum}" != "nochecksum" ]; then
if [ "$(sha1sum ${filename} | cut -d ' ' -f 1)" != "${checksum}" ]; then
echo "${filename} sha1sum failed. Deleting file and aborting."
rm -f ${filename}
exit 1
fi
fi
else
SubBanner "copying from ${url}"
cp ${url} ${filename}
fi
}
######################################################################
#
######################################################################
# Some sanity checks to make sure this script is run from the right place
# with the right tools.
SanityCheck() {
Banner "Sanity Checks"
if ! mkdir -p "${INSTALL_ROOT}" ; then
echo "ERROR: ${INSTALL_ROOT} can't be created."
exit -1
fi
for tool in wget ; do
if ! which ${tool} ; then
echo "Required binary $tool not found."
echo "Exiting."
exit 1
fi
done
}
ClearInstallDir() {
Banner "clearing dirs in ${INSTALL_ROOT}"
rm -rf ${INSTALL_ROOT}/*
mkdir -p ${JAIL_MIPS32}
}
ClearBuildDir() {
Banner "clearing dirs in ${BUILD_DIR}"
rm -rf ${BUILD_DIR}/*
}
CreateTarBall() {
local tarball=$1
Banner "creating tar ball ${tarball}"
tar cfz ${tarball}.tgz -C ${INSTALL_ROOT} .
}
# Download the toolchain source tarballs or use a local copy when available.
DownloadOrCopyAndInstallToolchain() {
Banner "Installing toolchain"
tarball="${TMP}/${GCC_URL##*/}"
DownloadOrCopyAndVerify ${GCC_URL} ${GCC_SHA1SUM}
SubBanner "extracting from ${tarball}"
tar jxf ${tarball} -C ${TMP}
pushd ${TMP}/gcc-*
local tarball="${TMP}/${GMP_URL##*/}"
DownloadOrCopyAndVerify ${GMP_URL} ${GMP_SHA1SUM}
SubBanner "extracting from ${tarball}"
tar jxf ${tarball}
local filename=`ls | grep gmp\-`
rm -f gmp
ln -s ${filename} gmp
# Fix gmp configure problem with flex.
sed -i "s/m4-not-needed/m4/" gmp/configure
local tarball="${TMP}/${MPFR_URL##*/}"
DownloadOrCopyAndVerify ${MPFR_URL} ${MPFR_SHA1SUM}
SubBanner "extracting from ${tarball}"
tar jxf ${tarball}
local filename=`ls | grep mpfr\-`
rm -f mpfr
ln -s ${filename} mpfr
local tarball="${TMP}/${MPC_URL##*/}"
DownloadOrCopyAndVerify ${MPC_URL} ${MPC_SHA1SUM}
SubBanner "extracting from ${tarball}"
tar zxf ${tarball}
local filename=`ls | grep mpc\-`
rm -f mpc
ln -s ${filename} mpc
popd
local tarball="${TMP}/${BINUTILS_URL##*/}"
DownloadOrCopyAndVerify ${BINUTILS_URL} ${BINUTILS_SHA1SUM}
SubBanner "extracting from ${tarball}"
tar jxf ${tarball} -C ${TMP}
tarball="${TMP}/${KERNEL_URL##*/}"
DownloadOrCopyAndVerify ${KERNEL_URL} ${KERNEL_SHA1SUM}
SubBanner "extracting from ${tarball}"
tar zxf ${tarball} -C ${TMP}
tarball="${TMP}/${GLIBC_URL##*/}"
DownloadOrCopyAndVerify ${GLIBC_URL} ${GLIBC_SHA1SUM}
SubBanner "extracting from ${tarball}"
tar jxf ${tarball} -C ${TMP}
Banner "Preparing the code"
# Fix a minor syntax issue in tc-mips.c.
local OLD_TEXT="as_warn_where (fragp->fr_file, fragp->fr_line, msg);"
local NEW_TEXT="as_warn_where (fragp->fr_file, fragp->fr_line, \"%s\", msg);"
local FILE_NAME="${TMP}/binutils-2.26/gas/config/tc-mips.c"
sed -i "s/${OLD_TEXT}/${NEW_TEXT}/g" "${FILE_NAME}"
export PATH=${INSTALL_ROOT}/bin:$PATH
Banner "Building binutils"
rm -rf ${BUILD_DIR}/binutils/
mkdir -p ${BUILD_DIR}/binutils/
pushd ${BUILD_DIR}/binutils/
SubBanner "Configuring"
${TMP}/binutils-2.26/configure \
--prefix=${INSTALL_ROOT} \
--target=mipsel-linux-gnu \
--with-sysroot=${JAIL_MIPS32}
SubBanner "Make"
make ${MAKE_OPTS} all-binutils all-gas all-ld
SubBanner "Install"
make ${MAKE_OPTS} install-binutils install-gas install-ld
popd
Banner "Building GCC (initial)"
rm -rf ${BUILD_DIR}/gcc/initial
mkdir -p ${BUILD_DIR}/gcc/initial
pushd ${BUILD_DIR}/gcc/initial
SubBanner "Configuring"
${TMP}/gcc-4.9.0/configure \
--prefix=${INSTALL_ROOT} \
--disable-libssp \
--disable-libgomp \
--disable-libmudflap \
--disable-fixed-point \
--disable-decimal-float \
--with-mips-plt \
--with-endian=little \
--with-arch=${ARCH} \
--enable-languages=c \
--with-newlib \
--without-headers \
--disable-shared \
--disable-threads \
--disable-libquadmath \
--disable-libatomic \
--target=mipsel-linux-gnu
SubBanner "Make"
make ${MAKE_OPTS} all
SubBanner "Install"
make ${MAKE_OPTS} install
popd
Banner "Installing Linux kernel headers"
pushd ${TMP}/linux-3.18.3
make headers_install ARCH=mips INSTALL_HDR_PATH=${JAIL_MIPS32}/usr
popd
Banner "Building GLIBC"
rm -rf ${BUILD_DIR}/glibc/final
mkdir -p ${BUILD_DIR}/glibc/final
pushd ${BUILD_DIR}/glibc/final
BUILD_CC=gcc \
AR=mipsel-linux-gnu-ar \
RANLIB=mipsel-linux-gnu-ranlibi \
CC=mipsel-linux-gnu-gcc \
CXX=mipsel-linux-gnu-g++ \
${TMP}/glibc-2.19/configure \
--prefix=/usr \
--enable-add-ons \
--host=mipsel-linux-gnu \
--disable-profile \
--without-gd \
--without-cvs \
--build=i686-pc-linux-gnu \
--with-headers=${JAIL_MIPS32}/usr/include
SubBanner "Make"
make ${MAKE_OPTS} all
SubBanner "Install"
make ${MAKE_OPTS} install install_root=${JAIL_MIPS32}
popd
Banner "Building GCC (final)"
rm -rf ${BUILD_DIR}/gcc/final
mkdir -p ${BUILD_DIR}/gcc/final
pushd ${BUILD_DIR}/gcc/final
${TMP}/gcc-4.9.0/configure \
--prefix=${INSTALL_ROOT} \
--disable-libssp \
--disable-libgomp \
--disable-libmudflap \
--disable-fixed-point \
--disable-decimal-float \
--with-mips-plt \
--with-endian=little \
--with-arch=${ARCH} \
--target=mipsel-linux-gnu \
--enable-__cxa_atexit \
--enable-languages=c,c++ \
--with-sysroot=${JAIL_MIPS32}
SubBanner "Make"
make ${MAKE_OPTS} all
SubBanner "Install"
make ${MAKE_OPTS} install
popd
}
# ----------------------------------------------------------------------
# mips32 deb files to complete our code sourcery jail
# ----------------------------------------------------------------------
readonly REPO_DEBIAN=http://ftp.debian.org/debian
readonly MIPS32_PACKAGES=${REPO_DEBIAN}/dists/jessie/main/binary-mipsel/Packages.xz
readonly BASE_PACKAGELIST_MIPS32=${SCRIPT_DIR}/packagelist.jessie.mipsel.base
readonly EXTRA_PACKAGELIST_MIPS32=${SCRIPT_DIR}/packagelist.jessie.mipsel.extra
readonly TMP_BASE_PKG_MIPS32=${TMP}/packagelist.generated.jessie.mipsel.base
readonly TMP_EXTRA_PKG_MIPS32=${TMP}/packagelist.generated.jessie.mipsel.extra
GeneratePackageLists() {
local packages=
local TMP_PACKAGELIST=
Banner "Generating Cobalt package lists for mips32"
rm -f ${TMP}/Packages.bz2
DownloadOrCopy ${MIPS32_PACKAGES}
xzcat ${TMP}/Packages.xz\
| egrep '^(Package:|Filename:)' > ${TMP}/Packages_mipsel
echo -n > ${TMP_EXTRA_PKG_MIPS32}
TMP_PACKAGELIST=${TMP_EXTRA_PKG_MIPS32}
packages=$(cat ${EXTRA_PACKAGELIST_MIPS32})
for pkg in ${packages} ; do
echo ${pkg}
grep -A 1 "${pkg}\$" ${TMP}/Packages_mipsel\
| egrep -o "pool/.*" >> ${TMP_PACKAGELIST}
done
}
InstallMissingLibraries() {
local DEP_FILES_NEEDED_MIPS32=
DEP_FILES_NEEDED_MIPS32=$(cat ${TMP_EXTRA_PKG_MIPS32})
for file in ${DEP_FILES_NEEDED_MIPS32} ; do
local package="${TMP}/${file##*/}"
Banner "installing ${file}"
DownloadOrCopy ${REPO_DEBIAN}/${file}
SubBanner "extracting to ${JAIL_MIPS32}"
dpkg --fsys-tarfile ${package}\
| tar -xvf - -C ${JAIL_MIPS32}
done
}
# Workaround for missing headers since pkg-config is not working correctly.
FixIncludes() {
Banner "Fixing includes"
pushd ${JAIL_MIPS32}/usr/include/glib-2.0
ln -s ../../lib/glib-2.0/include/glibconfig.h .
popd
pushd ${JAIL_MIPS32}/usr/include/gtk-2.0
ln -s ../../lib/gtk-2.0/include/gdkconfig.h .
popd
pushd ${JAIL_MIPS32}/usr/include/dbus-1.0/dbus
ln -s ../../../lib/dbus-1.0/include/dbus/dbus-arch-deps.h .
popd
pushd ${JAIL_MIPS32}/usr/include
cp ./mipsel-linux-gnu/sys/* ./sys/
mkdir -p bits
cp ./mipsel-linux-gnu/bits/* ./bits/
mkdir -p gnu
cp ./mipsel-linux-gnu/gnu/* ./gnu/
mkdir -p asm
cp ./mipsel-linux-gnu/asm/* ./asm/
cp ./mipsel-linux-gnu/openssl/* ./openssl/
popd
}
FixLinks() {
Banner "Fixing links"
pushd ${JAIL_MIPS32}/lib/
mv mipsel-linux-gnu/* .
rm -rf mipsel-linux-gnu
ln -s . mipsel-linux-gnu
popd
pushd ${JAIL_MIPS32}/usr/lib/
mkdir -p pkgconfig
mv mipsel-linux-gnu/pkgconfig/* pkgconfig/
rm -rf mipsel-linux-gnu/pkgconfig
cp -r mipsel-linux-gnu/* .
rm -rf mipsel-linux-gnu
ln -s . mipsel-linux-gnu
popd
mkdir -p ${JAIL_MIPS32}/usr/share
pushd ${JAIL_MIPS32}/usr/share/
mkdir -p pkgconfig
popd
pushd ${JAIL_MIPS32}/usr/lib/
rm -f libgcc_s.so*
ln -s ../../../mipsel-linux-gnu/lib/libgcc_s.so.1 .
ln -s libgcc_s.so.1 libgcc_s.so
popd
}
FixLibs() {
Banner "Fixing libraries"
readonly liblist="libanl.co \
libBrokenLocale.so \
libbz2.so \
libcap.so \
libcidn.so \
libcom_err.so \
libcrypt.so \
libdbus-1.so \
libdl.so \
libexpat.so \
libglib-2.0.so \
libgpg-error.so \
libkeyutils.so \
libnsl.so \
libnss_compat.so\
libnss_dns.so \
libnss_files.so \
libnss_hesiod.so\
libnss_nisplus.so\
libnss_nis.so \
libpamc.so \
libpam_misc.so \
libpam.so \
libpci.so \
libpcre.so \
libpng12.so \
libresolv.so \
librt.so \
libthread_db.so \
libutil.so \
libudev.so \
libz.so"
readonly liblist2="libpng12.so.0"
pushd ${JAIL_MIPS32}/usr/lib/
for library in ${liblist}; do
rm -f ${library}
ln -s ../../lib/${library}.[0123] ${library}
done
for library2 in ${liblist2}; do
rm -f ${library2}
ln -s ../../lib/${library2} ${library2}
done
rm -f libpython2.7.a
ln -s ./python2.7/config-mipsel-linux-gnu/libpython2.7.a libpython2.7.a
rm -f libm.so
ln -s ../../lib/libm.so.6 libm.so
popd
}
######################################################################
# Main
######################################################################
mkdir -p ${TMP}
SanityCheck
ClearInstallDir
ClearBuildDir
DownloadOrCopyAndInstallToolchain
GeneratePackageLists
InstallMissingLibraries
FixLinks
FixLibs
FixIncludes
CreateTarBall ${CROSS_TARBALL}