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