Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | # |
| 3 | # Compiles and installs a Linux/x86_64 -> Linux/ARM crosstool based on LLVM and |
| 4 | # LLVM-GCC-4.2 using SVN snapshots in provided tarballs. |
| 5 | |
| 6 | set -o nounset |
| 7 | set -o errexit |
| 8 | |
| 9 | echo -n "Welcome to LLVM Linux/X86_64 -> Linux/ARM crosstool " |
| 10 | echo "builder/installer; some steps will require sudo privileges." |
| 11 | |
Misha Brukman | f881ae0 | 2009-07-09 15:24:04 +0000 | [diff] [blame] | 12 | readonly INSTALL_ROOT="${INSTALL_ROOT:-/usr/local/crosstool}" |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 13 | # Both $USER and root *must* have read/write access to this dir. |
| 14 | readonly SCRATCH_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/llvm-project.XXXXXX") |
| 15 | readonly SRC_ROOT="${SCRATCH_ROOT}/src" |
| 16 | readonly OBJ_ROOT="${SCRATCH_ROOT}/obj" |
| 17 | |
| 18 | readonly CROSS_HOST="x86_64-unknown-linux-gnu" |
| 19 | readonly CROSS_TARGET="arm-none-linux-gnueabi" |
Misha Brukman | e034393 | 2009-07-06 18:29:03 +0000 | [diff] [blame] | 20 | readonly CROSS_MARCH="${CROSS_MARCH:-armv6}" |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 21 | |
| 22 | readonly CODE_SOURCERY="${INSTALL_ROOT}/codesourcery" |
| 23 | readonly CODE_SOURCERY_PKG_PATH="${CODE_SOURCERY_PKG_PATH:-${HOME}/codesourcery}" |
Misha Brukman | 00c1073 | 2009-06-12 02:04:47 +0000 | [diff] [blame] | 24 | readonly CODE_SOURCERY_HTTP="http://www.codesourcery.com/sgpp/lite/arm/portal/package1787/public" |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 25 | readonly CODE_SOURCERY_PKG="arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2" |
| 26 | readonly CODE_SOURCERY_ROOT="${CODE_SOURCERY}/arm-2007q3" |
| 27 | readonly CODE_SOURCERY_BIN="${CODE_SOURCERY_ROOT}/bin" |
| 28 | # Make sure ${CROSS_TARGET}-* binutils are in command path |
| 29 | export PATH="${CODE_SOURCERY_BIN}:${PATH}" |
| 30 | |
| 31 | readonly CROSS_TARGET_AS="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-as" |
| 32 | readonly CROSS_TARGET_LD="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-ld" |
| 33 | |
| 34 | readonly SYSROOT="${CODE_SOURCERY_ROOT}/${CROSS_TARGET}/libc" |
| 35 | |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 36 | readonly LLVM_PKG_PATH="${LLVM_PKG_PATH:-${HOME}/llvm-project/snapshots}" |
| 37 | |
Misha Brukman | f881ae0 | 2009-07-09 15:24:04 +0000 | [diff] [blame] | 38 | # Latest SVN revisions known to be working in this configuration. |
| 39 | readonly LLVM_DEFAULT_REV="74530" |
| 40 | readonly LLVMGCC_DEFAULT_REV="74535" |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 41 | |
| 42 | readonly LLVM_PKG="llvm-${LLVM_SVN_REV:-${LLVM_DEFAULT_REV}}.tar.bz2" |
| 43 | readonly LLVM_SRC_DIR="${SRC_ROOT}/llvm" |
| 44 | readonly LLVM_OBJ_DIR="${OBJ_ROOT}/llvm" |
Misha Brukman | f881ae0 | 2009-07-09 15:24:04 +0000 | [diff] [blame] | 45 | readonly LLVM_INSTALL_DIR="${INSTALL_ROOT}/${CROSS_TARGET}/llvm" |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 46 | |
Misha Brukman | f881ae0 | 2009-07-09 15:24:04 +0000 | [diff] [blame] | 47 | readonly LLVMGCC_PKG="llvm-gcc-4.2-${LLVMGCC_SVN_REV:-${LLVMGCC_DEFAULT_REV}}.tar.bz2" |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 48 | readonly LLVMGCC_SRC_DIR="${SRC_ROOT}/llvm-gcc-4.2" |
| 49 | readonly LLVMGCC_OBJ_DIR="${OBJ_ROOT}/llvm-gcc-4.2" |
Misha Brukman | f881ae0 | 2009-07-09 15:24:04 +0000 | [diff] [blame] | 50 | readonly LLVMGCC_INSTALL_DIR="${INSTALL_ROOT}/${CROSS_TARGET}/llvm-gcc-4.2" |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 51 | |
Misha Brukman | f881ae0 | 2009-07-09 15:24:04 +0000 | [diff] [blame] | 52 | readonly MAKE_OPTS="${MAKE_OPTS:--j2}" |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 53 | |
| 54 | # Params: |
| 55 | # $1: directory to be created |
| 56 | # $2: optional mkdir command prefix, e.g. "sudo" |
| 57 | createDir() { |
| 58 | if [[ ! -e $1 ]]; then |
| 59 | ${2:-} mkdir -p $1 |
| 60 | elif [[ -e $1 && ! -d $1 ]]; then |
| 61 | echo "$1 exists but is not a directory; exiting." |
| 62 | exit 3 |
| 63 | fi |
| 64 | } |
| 65 | |
| 66 | sudoCreateDir() { |
| 67 | createDir $1 sudo |
| 68 | sudo chown ${USER} $1 |
| 69 | } |
| 70 | |
| 71 | # Prints out and runs the command, but without logging -- intended for use with |
| 72 | # lightweight commands that don't have useful output to parse, e.g. mkdir, tar, |
| 73 | # etc. |
| 74 | runCommand() { |
| 75 | local message="$1" |
| 76 | shift |
| 77 | echo "=> $message" |
| 78 | echo "==> Running: $*" |
| 79 | $* |
| 80 | } |
| 81 | |
| 82 | runAndLog() { |
| 83 | local message="$1" |
| 84 | local log_file="$2" |
| 85 | shift 2 |
| 86 | echo "=> $message; log in $log_file" |
| 87 | echo "==> Running: $*" |
| 88 | # Pop-up a terminal with the output of the current command? |
| 89 | # e.g.: xterm -e /bin/bash -c "$* >| tee $log_file" |
| 90 | $* &> $log_file |
| 91 | if [[ $? != 0 ]]; then |
| 92 | echo "Error occurred: see most recent log file for details." |
| 93 | exit |
| 94 | fi |
| 95 | } |
| 96 | |
| 97 | installCodeSourcery() { |
Misha Brukman | e034393 | 2009-07-06 18:29:03 +0000 | [diff] [blame] | 98 | # Unpack the tarball, creating the CodeSourcery dir, if necessary. |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 99 | if [[ ! -d ${CODE_SOURCERY_ROOT} ]]; then |
Misha Brukman | e034393 | 2009-07-06 18:29:03 +0000 | [diff] [blame] | 100 | sudoCreateDir ${CODE_SOURCERY} |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 101 | cd ${CODE_SOURCERY} |
Misha Brukman | 00c1073 | 2009-06-12 02:04:47 +0000 | [diff] [blame] | 102 | if [[ -e ${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG} ]]; then |
| 103 | runCommand "Unpacking CodeSourcery in ${CODE_SOURCERY}" \ |
| 104 | tar jxf ${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG} |
| 105 | else |
| 106 | echo -n "CodeSourcery tarball not found in " |
| 107 | echo "${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG}" |
| 108 | echo -n "Fix the path or download it from " |
| 109 | echo "${CODE_SOURCERY_HTTP}/${CROSS_TARGET}/${CODE_SOURCERY_PKG}" |
| 110 | exit |
| 111 | fi |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 112 | else |
Misha Brukman | e034393 | 2009-07-06 18:29:03 +0000 | [diff] [blame] | 113 | echo "CodeSourcery install dir already exists; skipping." |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 114 | fi |
| 115 | |
| 116 | # Verify our CodeSourcery toolchain installation. |
| 117 | if [[ ! -d "${SYSROOT}" ]]; then |
| 118 | echo -n "Error: CodeSourcery does not contain libc for ${CROSS_TARGET}: " |
| 119 | echo "${SYSROOT} not found." |
| 120 | exit |
| 121 | fi |
| 122 | |
| 123 | for tool in ${CROSS_TARGET_AS} ${CROSS_TARGET_LD}; do |
| 124 | if [[ ! -e $tool ]]; then |
| 125 | echo "${tool} not found; exiting." |
| 126 | exit |
| 127 | fi |
| 128 | done |
| 129 | } |
| 130 | |
| 131 | installLLVM() { |
Misha Brukman | e034393 | 2009-07-06 18:29:03 +0000 | [diff] [blame] | 132 | if [[ -d ${LLVM_INSTALL_DIR} ]]; then |
| 133 | echo "LLVM install dir ${LLVM_INSTALL_DIR} exists; skipping." |
| 134 | return |
| 135 | fi |
| 136 | |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 137 | sudoCreateDir ${LLVM_INSTALL_DIR} |
| 138 | |
| 139 | # Unpack LLVM tarball; should create the directory "llvm". |
| 140 | cd ${SRC_ROOT} |
| 141 | runCommand "Unpacking LLVM" tar jxf ${LLVM_PKG_PATH}/${LLVM_PKG} |
| 142 | |
| 143 | # Configure, build, and install LLVM. |
| 144 | createDir ${LLVM_OBJ_DIR} |
| 145 | cd ${LLVM_OBJ_DIR} |
| 146 | runAndLog "Configuring LLVM" ${LLVM_OBJ_DIR}/llvm-configure.log \ |
| 147 | ${LLVM_SRC_DIR}/configure \ |
| 148 | --disable-jit \ |
| 149 | --enable-optimized \ |
| 150 | --prefix=${LLVM_INSTALL_DIR} \ |
| 151 | --target=${CROSS_TARGET} \ |
| 152 | --with-llvmgccdir=${LLVMGCC_INSTALL_DIR} |
| 153 | runAndLog "Building LLVM" ${LLVM_OBJ_DIR}/llvm-build.log \ |
| 154 | make ${MAKE_OPTS} |
| 155 | runAndLog "Installing LLVM" ${LLVM_OBJ_DIR}/llvm-install.log \ |
| 156 | make ${MAKE_OPTS} install |
| 157 | } |
| 158 | |
| 159 | installLLVMGCC() { |
Misha Brukman | e034393 | 2009-07-06 18:29:03 +0000 | [diff] [blame] | 160 | if [[ -d ${LLVMGCC_INSTALL_DIR} ]]; then |
| 161 | echo "LLVM-GCC install dir ${LLVMGCC_INSTALL_DIR} exists; skipping." |
| 162 | return |
| 163 | fi |
| 164 | |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 165 | sudoCreateDir ${LLVMGCC_INSTALL_DIR} |
| 166 | |
| 167 | # Unpack LLVM-GCC tarball; should create the directory "llvm-gcc-4.2". |
| 168 | cd ${SRC_ROOT} |
| 169 | runCommand "Unpacking LLVM-GCC" tar jxf ${LLVM_PKG_PATH}/${LLVMGCC_PKG} |
| 170 | |
| 171 | # Configure, build, and install LLVM-GCC. |
| 172 | createDir ${LLVMGCC_OBJ_DIR} |
| 173 | cd ${LLVMGCC_OBJ_DIR} |
| 174 | runAndLog "Configuring LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-configure.log \ |
| 175 | ${LLVMGCC_SRC_DIR}/configure \ |
| 176 | --enable-languages=c,c++ \ |
| 177 | --enable-llvm=${LLVM_INSTALL_DIR} \ |
| 178 | --prefix=${LLVMGCC_INSTALL_DIR} \ |
| 179 | --program-prefix=llvm- \ |
| 180 | --target=${CROSS_TARGET} \ |
Misha Brukman | e034393 | 2009-07-06 18:29:03 +0000 | [diff] [blame] | 181 | --with-arch=${CROSS_MARCH} \ |
| 182 | --with-as=${CROSS_TARGET_AS} \ |
| 183 | --with-ld=${CROSS_TARGET_LD} \ |
Misha Brukman | cb6f9c8 | 2009-06-12 01:55:57 +0000 | [diff] [blame] | 184 | --with-sysroot=${SYSROOT} |
| 185 | runAndLog "Building LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-build.log \ |
| 186 | make |
| 187 | runAndLog "Installing LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-install.log \ |
| 188 | make install |
| 189 | } |
| 190 | |
| 191 | echo "Building in ${SCRATCH_ROOT}; installing in ${INSTALL_ROOT}" |
| 192 | |
| 193 | createDir ${SRC_ROOT} |
| 194 | createDir ${OBJ_ROOT} |
| 195 | |
| 196 | installCodeSourcery |
| 197 | installLLVM |
| 198 | installLLVMGCC |
| 199 | |
| 200 | echo "Done." |