17a017c6fSMisha Brukman#!/bin/bash 27a017c6fSMisha Brukman# 37a017c6fSMisha Brukman# Compiles and installs a Linux/x86_64 -> Linux/ARM crosstool based on LLVM and 47a017c6fSMisha Brukman# LLVM-GCC-4.2 using SVN snapshots in provided tarballs. 57a017c6fSMisha Brukman 67a017c6fSMisha Brukmanset -o nounset 77a017c6fSMisha Brukmanset -o errexit 87a017c6fSMisha Brukman 97a017c6fSMisha Brukmanecho -n "Welcome to LLVM Linux/X86_64 -> Linux/ARM crosstool " 107a017c6fSMisha Brukmanecho "builder/installer; some steps will require sudo privileges." 117a017c6fSMisha Brukman 12*3008068cSMisha Brukmanreadonly INSTALL_ROOT="${INSTALL_ROOT:-/usr/local/crosstool}" 137a017c6fSMisha Brukman# Both $USER and root *must* have read/write access to this dir. 147a017c6fSMisha Brukmanreadonly SCRATCH_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/llvm-project.XXXXXX") 157a017c6fSMisha Brukmanreadonly SRC_ROOT="${SCRATCH_ROOT}/src" 167a017c6fSMisha Brukmanreadonly OBJ_ROOT="${SCRATCH_ROOT}/obj" 177a017c6fSMisha Brukman 187a017c6fSMisha Brukmanreadonly CROSS_HOST="x86_64-unknown-linux-gnu" 197a017c6fSMisha Brukmanreadonly CROSS_TARGET="arm-none-linux-gnueabi" 2007748203SMisha Brukmanreadonly CROSS_MARCH="${CROSS_MARCH:-armv6}" 217a017c6fSMisha Brukman 227a017c6fSMisha Brukmanreadonly CODE_SOURCERY="${INSTALL_ROOT}/codesourcery" 237a017c6fSMisha Brukmanreadonly CODE_SOURCERY_PKG_PATH="${CODE_SOURCERY_PKG_PATH:-${HOME}/codesourcery}" 2415b8bc18SMisha Brukmanreadonly CODE_SOURCERY_HTTP="http://www.codesourcery.com/sgpp/lite/arm/portal/package1787/public" 257a017c6fSMisha Brukmanreadonly CODE_SOURCERY_PKG="arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2" 267a017c6fSMisha Brukmanreadonly CODE_SOURCERY_ROOT="${CODE_SOURCERY}/arm-2007q3" 277a017c6fSMisha Brukmanreadonly CODE_SOURCERY_BIN="${CODE_SOURCERY_ROOT}/bin" 287a017c6fSMisha Brukman# Make sure ${CROSS_TARGET}-* binutils are in command path 297a017c6fSMisha Brukmanexport PATH="${CODE_SOURCERY_BIN}:${PATH}" 307a017c6fSMisha Brukman 317a017c6fSMisha Brukmanreadonly CROSS_TARGET_AS="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-as" 327a017c6fSMisha Brukmanreadonly CROSS_TARGET_LD="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-ld" 337a017c6fSMisha Brukman 347a017c6fSMisha Brukmanreadonly SYSROOT="${CODE_SOURCERY_ROOT}/${CROSS_TARGET}/libc" 357a017c6fSMisha Brukman 367a017c6fSMisha Brukmanreadonly LLVM_PKG_PATH="${LLVM_PKG_PATH:-${HOME}/llvm-project/snapshots}" 377a017c6fSMisha Brukman 38*3008068cSMisha Brukman# Latest SVN revisions known to be working in this configuration. 39*3008068cSMisha Brukmanreadonly LLVM_DEFAULT_REV="74530" 40*3008068cSMisha Brukmanreadonly LLVMGCC_DEFAULT_REV="74535" 417a017c6fSMisha Brukman 427a017c6fSMisha Brukmanreadonly LLVM_PKG="llvm-${LLVM_SVN_REV:-${LLVM_DEFAULT_REV}}.tar.bz2" 437a017c6fSMisha Brukmanreadonly LLVM_SRC_DIR="${SRC_ROOT}/llvm" 447a017c6fSMisha Brukmanreadonly LLVM_OBJ_DIR="${OBJ_ROOT}/llvm" 45*3008068cSMisha Brukmanreadonly LLVM_INSTALL_DIR="${INSTALL_ROOT}/${CROSS_TARGET}/llvm" 467a017c6fSMisha Brukman 47*3008068cSMisha Brukmanreadonly LLVMGCC_PKG="llvm-gcc-4.2-${LLVMGCC_SVN_REV:-${LLVMGCC_DEFAULT_REV}}.tar.bz2" 487a017c6fSMisha Brukmanreadonly LLVMGCC_SRC_DIR="${SRC_ROOT}/llvm-gcc-4.2" 497a017c6fSMisha Brukmanreadonly LLVMGCC_OBJ_DIR="${OBJ_ROOT}/llvm-gcc-4.2" 50*3008068cSMisha Brukmanreadonly LLVMGCC_INSTALL_DIR="${INSTALL_ROOT}/${CROSS_TARGET}/llvm-gcc-4.2" 517a017c6fSMisha Brukman 52*3008068cSMisha Brukmanreadonly MAKE_OPTS="${MAKE_OPTS:--j2}" 537a017c6fSMisha Brukman 547a017c6fSMisha Brukman# Params: 557a017c6fSMisha Brukman# $1: directory to be created 567a017c6fSMisha Brukman# $2: optional mkdir command prefix, e.g. "sudo" 577a017c6fSMisha BrukmancreateDir() { 587a017c6fSMisha Brukman if [[ ! -e $1 ]]; then 597a017c6fSMisha Brukman ${2:-} mkdir -p $1 607a017c6fSMisha Brukman elif [[ -e $1 && ! -d $1 ]]; then 617a017c6fSMisha Brukman echo "$1 exists but is not a directory; exiting." 627a017c6fSMisha Brukman exit 3 637a017c6fSMisha Brukman fi 647a017c6fSMisha Brukman} 657a017c6fSMisha Brukman 667a017c6fSMisha BrukmansudoCreateDir() { 677a017c6fSMisha Brukman createDir $1 sudo 687a017c6fSMisha Brukman sudo chown ${USER} $1 697a017c6fSMisha Brukman} 707a017c6fSMisha Brukman 717a017c6fSMisha Brukman# Prints out and runs the command, but without logging -- intended for use with 727a017c6fSMisha Brukman# lightweight commands that don't have useful output to parse, e.g. mkdir, tar, 737a017c6fSMisha Brukman# etc. 747a017c6fSMisha BrukmanrunCommand() { 757a017c6fSMisha Brukman local message="$1" 767a017c6fSMisha Brukman shift 777a017c6fSMisha Brukman echo "=> $message" 787a017c6fSMisha Brukman echo "==> Running: $*" 797a017c6fSMisha Brukman $* 807a017c6fSMisha Brukman} 817a017c6fSMisha Brukman 827a017c6fSMisha BrukmanrunAndLog() { 837a017c6fSMisha Brukman local message="$1" 847a017c6fSMisha Brukman local log_file="$2" 857a017c6fSMisha Brukman shift 2 867a017c6fSMisha Brukman echo "=> $message; log in $log_file" 877a017c6fSMisha Brukman echo "==> Running: $*" 887a017c6fSMisha Brukman # Pop-up a terminal with the output of the current command? 897a017c6fSMisha Brukman # e.g.: xterm -e /bin/bash -c "$* >| tee $log_file" 907a017c6fSMisha Brukman $* &> $log_file 917a017c6fSMisha Brukman if [[ $? != 0 ]]; then 927a017c6fSMisha Brukman echo "Error occurred: see most recent log file for details." 937a017c6fSMisha Brukman exit 947a017c6fSMisha Brukman fi 957a017c6fSMisha Brukman} 967a017c6fSMisha Brukman 977a017c6fSMisha BrukmaninstallCodeSourcery() { 9807748203SMisha Brukman # Unpack the tarball, creating the CodeSourcery dir, if necessary. 997a017c6fSMisha Brukman if [[ ! -d ${CODE_SOURCERY_ROOT} ]]; then 10007748203SMisha Brukman sudoCreateDir ${CODE_SOURCERY} 1017a017c6fSMisha Brukman cd ${CODE_SOURCERY} 10215b8bc18SMisha Brukman if [[ -e ${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG} ]]; then 1037a017c6fSMisha Brukman runCommand "Unpacking CodeSourcery in ${CODE_SOURCERY}" \ 1047a017c6fSMisha Brukman tar jxf ${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG} 1057a017c6fSMisha Brukman else 10615b8bc18SMisha Brukman echo -n "CodeSourcery tarball not found in " 10715b8bc18SMisha Brukman echo "${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG}" 10815b8bc18SMisha Brukman echo -n "Fix the path or download it from " 10915b8bc18SMisha Brukman echo "${CODE_SOURCERY_HTTP}/${CROSS_TARGET}/${CODE_SOURCERY_PKG}" 11015b8bc18SMisha Brukman exit 11115b8bc18SMisha Brukman fi 11215b8bc18SMisha Brukman else 11307748203SMisha Brukman echo "CodeSourcery install dir already exists; skipping." 1147a017c6fSMisha Brukman fi 1157a017c6fSMisha Brukman 1167a017c6fSMisha Brukman # Verify our CodeSourcery toolchain installation. 1177a017c6fSMisha Brukman if [[ ! -d "${SYSROOT}" ]]; then 1187a017c6fSMisha Brukman echo -n "Error: CodeSourcery does not contain libc for ${CROSS_TARGET}: " 1197a017c6fSMisha Brukman echo "${SYSROOT} not found." 1207a017c6fSMisha Brukman exit 1217a017c6fSMisha Brukman fi 1227a017c6fSMisha Brukman 1237a017c6fSMisha Brukman for tool in ${CROSS_TARGET_AS} ${CROSS_TARGET_LD}; do 1247a017c6fSMisha Brukman if [[ ! -e $tool ]]; then 1257a017c6fSMisha Brukman echo "${tool} not found; exiting." 1267a017c6fSMisha Brukman exit 1277a017c6fSMisha Brukman fi 1287a017c6fSMisha Brukman done 1297a017c6fSMisha Brukman} 1307a017c6fSMisha Brukman 1317a017c6fSMisha BrukmaninstallLLVM() { 13207748203SMisha Brukman if [[ -d ${LLVM_INSTALL_DIR} ]]; then 13307748203SMisha Brukman echo "LLVM install dir ${LLVM_INSTALL_DIR} exists; skipping." 13407748203SMisha Brukman return 13507748203SMisha Brukman fi 13607748203SMisha Brukman 1377a017c6fSMisha Brukman sudoCreateDir ${LLVM_INSTALL_DIR} 1387a017c6fSMisha Brukman 1397a017c6fSMisha Brukman # Unpack LLVM tarball; should create the directory "llvm". 1407a017c6fSMisha Brukman cd ${SRC_ROOT} 1417a017c6fSMisha Brukman runCommand "Unpacking LLVM" tar jxf ${LLVM_PKG_PATH}/${LLVM_PKG} 1427a017c6fSMisha Brukman 1437a017c6fSMisha Brukman # Configure, build, and install LLVM. 1447a017c6fSMisha Brukman createDir ${LLVM_OBJ_DIR} 1457a017c6fSMisha Brukman cd ${LLVM_OBJ_DIR} 1467a017c6fSMisha Brukman runAndLog "Configuring LLVM" ${LLVM_OBJ_DIR}/llvm-configure.log \ 1477a017c6fSMisha Brukman ${LLVM_SRC_DIR}/configure \ 1487a017c6fSMisha Brukman --disable-jit \ 1497a017c6fSMisha Brukman --enable-optimized \ 1507a017c6fSMisha Brukman --prefix=${LLVM_INSTALL_DIR} \ 1517a017c6fSMisha Brukman --target=${CROSS_TARGET} \ 1527a017c6fSMisha Brukman --with-llvmgccdir=${LLVMGCC_INSTALL_DIR} 1537a017c6fSMisha Brukman runAndLog "Building LLVM" ${LLVM_OBJ_DIR}/llvm-build.log \ 1547a017c6fSMisha Brukman make ${MAKE_OPTS} 1557a017c6fSMisha Brukman runAndLog "Installing LLVM" ${LLVM_OBJ_DIR}/llvm-install.log \ 1567a017c6fSMisha Brukman make ${MAKE_OPTS} install 1577a017c6fSMisha Brukman} 1587a017c6fSMisha Brukman 1597a017c6fSMisha BrukmaninstallLLVMGCC() { 16007748203SMisha Brukman if [[ -d ${LLVMGCC_INSTALL_DIR} ]]; then 16107748203SMisha Brukman echo "LLVM-GCC install dir ${LLVMGCC_INSTALL_DIR} exists; skipping." 16207748203SMisha Brukman return 16307748203SMisha Brukman fi 16407748203SMisha Brukman 1657a017c6fSMisha Brukman sudoCreateDir ${LLVMGCC_INSTALL_DIR} 1667a017c6fSMisha Brukman 1677a017c6fSMisha Brukman # Unpack LLVM-GCC tarball; should create the directory "llvm-gcc-4.2". 1687a017c6fSMisha Brukman cd ${SRC_ROOT} 1697a017c6fSMisha Brukman runCommand "Unpacking LLVM-GCC" tar jxf ${LLVM_PKG_PATH}/${LLVMGCC_PKG} 1707a017c6fSMisha Brukman 1717a017c6fSMisha Brukman # Configure, build, and install LLVM-GCC. 1727a017c6fSMisha Brukman createDir ${LLVMGCC_OBJ_DIR} 1737a017c6fSMisha Brukman cd ${LLVMGCC_OBJ_DIR} 1747a017c6fSMisha Brukman runAndLog "Configuring LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-configure.log \ 1757a017c6fSMisha Brukman ${LLVMGCC_SRC_DIR}/configure \ 1767a017c6fSMisha Brukman --enable-languages=c,c++ \ 1777a017c6fSMisha Brukman --enable-llvm=${LLVM_INSTALL_DIR} \ 1787a017c6fSMisha Brukman --prefix=${LLVMGCC_INSTALL_DIR} \ 1797a017c6fSMisha Brukman --program-prefix=llvm- \ 1807a017c6fSMisha Brukman --target=${CROSS_TARGET} \ 18107748203SMisha Brukman --with-arch=${CROSS_MARCH} \ 18207748203SMisha Brukman --with-as=${CROSS_TARGET_AS} \ 18307748203SMisha Brukman --with-ld=${CROSS_TARGET_LD} \ 1847a017c6fSMisha Brukman --with-sysroot=${SYSROOT} 1857a017c6fSMisha Brukman runAndLog "Building LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-build.log \ 1867a017c6fSMisha Brukman make 1877a017c6fSMisha Brukman runAndLog "Installing LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-install.log \ 1887a017c6fSMisha Brukman make install 1897a017c6fSMisha Brukman} 1907a017c6fSMisha Brukman 1917a017c6fSMisha Brukmanecho "Building in ${SCRATCH_ROOT}; installing in ${INSTALL_ROOT}" 1927a017c6fSMisha Brukman 1937a017c6fSMisha BrukmancreateDir ${SRC_ROOT} 1947a017c6fSMisha BrukmancreateDir ${OBJ_ROOT} 1957a017c6fSMisha Brukman 1967a017c6fSMisha BrukmaninstallCodeSourcery 1977a017c6fSMisha BrukmaninstallLLVM 1987a017c6fSMisha BrukmaninstallLLVMGCC 1997a017c6fSMisha Brukman 2007a017c6fSMisha Brukmanecho "Done." 201