blob: 900bb349e5c62c1514db370f41b28b82ddb96880 [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 MTI_PREBUILT_URL="https://codescape.mips.com/components/toolchain/2017.10-07/Codescape.GNU.Tools.Package.2017.10-07.for.MIPS.MTI.Linux.CentOS-5.x86_64.tar.gz"
readonly MTI_PREBUILT_SHA1SUM="c3e21b47b9d7e9c1f617c1a5e1a8255fdb97efb6"
######################################################################
# Helper
######################################################################
Banner() {
echo "######################################################################"
echo $*
echo "######################################################################"
}
SubBanner() {
echo "......................................................................"
echo $*
echo "......................................................................"
}
Usage() {
echo
echo "$0 <clang|gcc_4-9|gcc_mti_6-3>"
echo
echo "clang - Creates sysroot based on Debian Jessie with addition of GCC 4.9 libs"
echo "gcc_4-9 - Builds GCC 4.9 toolchain and creates sysroot based on Debian Jessie"
echo "gcc_mti_6-3 - Downloads prebuilt MTI GCC 6.3 toolchain and creates sysroot based on Debian Stretch"
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} .
}
CreateMTITarBall() {
local tarball=$1
Banner "Creating tar ball ${tarball}"
cp -r ${INSTALL_ROOT}"/sysroot/." $(pwd)"/toolchain/codescape/sysroot/mipsel-r2-hard/"
tar cfz ${tarball}.tgz -C $(pwd)"/toolchain/codescape/" .
}
# 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
}
DownloadMTI() {
Banner "Downloading MTI toolchain"
mkdir -p ${TMP}"/codescape"
tarball="${TMP}/${MTI_PREBUILT_URL##*/}"
DownloadOrCopyAndVerify ${MTI_PREBUILT_URL} ${MTI_PREBUILT_SHA1SUM}
SubBanner "Extracting from ${tarball}"
tar xvf ${tarball} -C ${TMP}"/codescape"
mkdir -p $(pwd)"/toolchain/codescape/mti"
mkdir -p $(pwd)"/toolchain/codescape/sysroot/mipsel-r2-hard"
SubBanner "Removing uneeded libs"
mti=${TMP}"/codescape/mips-mti-linux-gnu/2017.10-07"
rm -rf ${mti}"/sysroot"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/micromipsel-r2-hard-nan2008"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/micromipsel-r2-soft"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/mipsel-r1-hard"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/mipsel-r2-hard-nan2008"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/mipsel-r2-hard-nan2008-uclibc"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/mipsel-r2-hard-uclibc"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/mipsel-r2-soft"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/mips-r2-hard"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/mips-r2-hard-nan2008"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/mips-r2-hard-nan2008-uclibc"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/mips-r2-hard-uclibc"
rm -rf ${mti}"/lib/gcc/mips-mti-linux-gnu/6.3.0/mips-r2-soft"
rm -rf ${mti}"/lib64"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/micromipsel-r2-hard-nan2008"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/micromipsel-r2-soft"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/mipsel-r1-hard"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/mipsel-r2-hard-nan2008"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/mipsel-r2-hard-nan2008-uclibc"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/mipsel-r2-hard-uclibc"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/mipsel-r2-soft"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/mips-r2-hard"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/mips-r2-hard-nan2008"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/mips-r2-hard-nan2008-uclibc"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/mips-r2-hard-uclibc"
rm -rf ${mti}"/mips-mti-linux-gnu/lib/mips-r2-soft"
SubBanner "Copying toolchain"
cp -r ${TMP}"/codescape/mips-mti-linux-gnu/2017.10-07/." $(pwd)"/toolchain/codescape/mti/"
}
# ----------------------------------------------------------------------
# mips32 deb files to complete our code sourcery jail
# ----------------------------------------------------------------------
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
}
GCCCleanup() {
Banner "Removing uneeded GCC tools for clang build"
rm -rf ${INSTALL_ROOT}"/bin"
rm -rf ${INSTALL_ROOT}"/include"
rm -rf ${INSTALL_ROOT}"/libexec"
rm -rf ${INSTALL_ROOT}"/share"
}
CleanUp() {
Banner "Removing temporary files"
rm -rf $(pwd)/toolchain/*
}
######################################################################
# Main
######################################################################
if [[ $# -eq 0 ]] ; then
echo "You must specify a mode on the commandline:"
echo
Usage
exit -1
elif [[ $1 == "clang" || $1 == "gcc_4-9" ]] ; then
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
mkdir -p ${TMP}
SanityCheck
ClearInstallDir
ClearBuildDir
DownloadOrCopyAndInstallToolchain
GeneratePackageLists
InstallMissingLibraries
FixLinks
FixLibs
FixIncludes
if [[ $1 == "clang" ]] ; then
GCCCleanup
CreateTarBall "mipsel_clang_jessie_sysroot"
elif [[ $1 == "gcc_4-9" ]] ; then
CreateTarBall "mipsel_gcc_4-9_jessie_sysroot"
fi
CleanUp
elif [[ $1 == "gcc_mti_6-3" ]] ; then
readonly REPO_DEBIAN=http://ftp.debian.org/debian
readonly MIPS32_PACKAGES=${REPO_DEBIAN}/dists/stretch/main/binary-mipsel/Packages.xz
readonly BASE_PACKAGELIST_MIPS32=${SCRIPT_DIR}/packagelist.stretch.mipsel.base
readonly EXTRA_PACKAGELIST_MIPS32=${SCRIPT_DIR}/packagelist.stretch.mipsel.extra
readonly TMP_BASE_PKG_MIPS32=${TMP}/packagelist.generated.stretch.mipsel.base
readonly TMP_EXTRA_PKG_MIPS32=${TMP}/packagelist.generated.stretch.mipsel.extra
mkdir -p ${TMP}
SanityCheck
ClearInstallDir
DownloadMTI
GeneratePackageLists
InstallMissingLibraries
FixLinks
FixLibs
FixIncludes
CreateMTITarBall "mipsel_gcc_mti_6-3_stretch_sysroot"
CleanUp
else
Usage
exit -1
fi