blob: efa97a114bfeca37c35569df79ced1141ffac872 [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"
20
21readonly CODE_SOURCERY="${INSTALL_ROOT}/codesourcery"
22readonly CODE_SOURCERY_PKG_PATH="${CODE_SOURCERY_PKG_PATH:-${HOME}/codesourcery}"
23readonly CODE_SOURCERY_PKG="arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2"
24readonly CODE_SOURCERY_ROOT="${CODE_SOURCERY}/arm-2007q3"
25readonly CODE_SOURCERY_BIN="${CODE_SOURCERY_ROOT}/bin"
26# Make sure ${CROSS_TARGET}-* binutils are in command path
27export PATH="${CODE_SOURCERY_BIN}:${PATH}"
28
29readonly CROSS_TARGET_AS="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-as"
30readonly CROSS_TARGET_LD="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-ld"
31
32readonly SYSROOT="${CODE_SOURCERY_ROOT}/${CROSS_TARGET}/libc"
33
34readonly LLVM_PROJECT="${INSTALL_ROOT}/llvm-project"
35readonly LLVM_INSTALL_ROOT="${LLVM_PROJECT}/${CROSS_HOST}/${CROSS_TARGET}"
36readonly LLVM_PKG_PATH="${LLVM_PKG_PATH:-${HOME}/llvm-project/snapshots}"
37
38# Latest SVN revision known to be working in this configuration.
39readonly LLVM_DEFAULT_REV="70786"
40
41readonly LLVM_PKG="llvm-${LLVM_SVN_REV:-${LLVM_DEFAULT_REV}}.tar.bz2"
42readonly LLVM_SRC_DIR="${SRC_ROOT}/llvm"
43readonly LLVM_OBJ_DIR="${OBJ_ROOT}/llvm"
44readonly LLVM_INSTALL_DIR="${LLVM_INSTALL_ROOT}/llvm"
45
46readonly LLVMGCC_PKG="llvm-gcc-4.2-${LLVMGCC_SVN_REV:-${LLVM_DEFAULT_REV}}.tar.bz2"
47readonly LLVMGCC_SRC_DIR="${SRC_ROOT}/llvm-gcc-4.2"
48readonly LLVMGCC_OBJ_DIR="${OBJ_ROOT}/llvm-gcc-4.2"
49readonly LLVMGCC_INSTALL_DIR="${LLVM_INSTALL_ROOT}/llvm-gcc-4.2"
50
51readonly MAKE_OPTS="-j2"
52
53# Verify we aren't going to install into an existing directory as this might
54# create problems as we won't have a clean install.
55verifyNotDir() {
56 if [[ -d $1 ]]; then
57 echo "Install dir $1 already exists; remove it to continue."
58 exit
59 fi
60}
61
62# Params:
63# $1: directory to be created
64# $2: optional mkdir command prefix, e.g. "sudo"
65createDir() {
66 if [[ ! -e $1 ]]; then
67 ${2:-} mkdir -p $1
68 elif [[ -e $1 && ! -d $1 ]]; then
69 echo "$1 exists but is not a directory; exiting."
70 exit 3
71 fi
72}
73
74sudoCreateDir() {
75 createDir $1 sudo
76 sudo chown ${USER} $1
77}
78
79# Prints out and runs the command, but without logging -- intended for use with
80# lightweight commands that don't have useful output to parse, e.g. mkdir, tar,
81# etc.
82runCommand() {
83 local message="$1"
84 shift
85 echo "=> $message"
86 echo "==> Running: $*"
87 $*
88}
89
90runAndLog() {
91 local message="$1"
92 local log_file="$2"
93 shift 2
94 echo "=> $message; log in $log_file"
95 echo "==> Running: $*"
96 # Pop-up a terminal with the output of the current command?
97 # e.g.: xterm -e /bin/bash -c "$* >| tee $log_file"
98 $* &> $log_file
99 if [[ $? != 0 ]]; then
100 echo "Error occurred: see most recent log file for details."
101 exit
102 fi
103}
104
105installCodeSourcery() {
106 # Create CodeSourcery dir, if necessary.
107 verifyNotDir ${CODE_SOURCERY}
108 sudoCreateDir ${CODE_SOURCERY}
109
110 # Unpack the tarball.
111 if [[ ! -d ${CODE_SOURCERY_ROOT} ]]; then
112 cd ${CODE_SOURCERY}
113 runCommand "Unpacking CodeSourcery in ${CODE_SOURCERY}" \
114 tar jxf ${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG}
115 else
116 echo "CodeSourcery install dir already exists."
117 fi
118
119 # Verify our CodeSourcery toolchain installation.
120 if [[ ! -d "${SYSROOT}" ]]; then
121 echo -n "Error: CodeSourcery does not contain libc for ${CROSS_TARGET}: "
122 echo "${SYSROOT} not found."
123 exit
124 fi
125
126 for tool in ${CROSS_TARGET_AS} ${CROSS_TARGET_LD}; do
127 if [[ ! -e $tool ]]; then
128 echo "${tool} not found; exiting."
129 exit
130 fi
131 done
132}
133
134installLLVM() {
135 verifyNotDir ${LLVM_INSTALL_DIR}
136 sudoCreateDir ${LLVM_INSTALL_DIR}
137
138 # Unpack LLVM tarball; should create the directory "llvm".
139 cd ${SRC_ROOT}
140 runCommand "Unpacking LLVM" tar jxf ${LLVM_PKG_PATH}/${LLVM_PKG}
141
142 # Configure, build, and install LLVM.
143 createDir ${LLVM_OBJ_DIR}
144 cd ${LLVM_OBJ_DIR}
145 runAndLog "Configuring LLVM" ${LLVM_OBJ_DIR}/llvm-configure.log \
146 ${LLVM_SRC_DIR}/configure \
147 --disable-jit \
148 --enable-optimized \
149 --prefix=${LLVM_INSTALL_DIR} \
150 --target=${CROSS_TARGET} \
151 --with-llvmgccdir=${LLVMGCC_INSTALL_DIR}
152 runAndLog "Building LLVM" ${LLVM_OBJ_DIR}/llvm-build.log \
153 make ${MAKE_OPTS}
154 runAndLog "Installing LLVM" ${LLVM_OBJ_DIR}/llvm-install.log \
155 make ${MAKE_OPTS} install
156}
157
158installLLVMGCC() {
159 verifyNotDir ${LLVMGCC_INSTALL_DIR}
160 sudoCreateDir ${LLVMGCC_INSTALL_DIR}
161
162 # Unpack LLVM-GCC tarball; should create the directory "llvm-gcc-4.2".
163 cd ${SRC_ROOT}
164 runCommand "Unpacking LLVM-GCC" tar jxf ${LLVM_PKG_PATH}/${LLVMGCC_PKG}
165
166 # Configure, build, and install LLVM-GCC.
167 createDir ${LLVMGCC_OBJ_DIR}
168 cd ${LLVMGCC_OBJ_DIR}
169 runAndLog "Configuring LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-configure.log \
170 ${LLVMGCC_SRC_DIR}/configure \
171 --enable-languages=c,c++ \
172 --enable-llvm=${LLVM_INSTALL_DIR} \
173 --prefix=${LLVMGCC_INSTALL_DIR} \
174 --program-prefix=llvm- \
175 --target=${CROSS_TARGET} \
176 --with-gnu-as=${CROSS_TARGET_AS} \
177 --with-gnu-ld=${CROSS_TARGET_LD} \
178 --with-sysroot=${SYSROOT}
179 runAndLog "Building LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-build.log \
180 make
181 runAndLog "Installing LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-install.log \
182 make install
183}
184
185echo "Building in ${SCRATCH_ROOT}; installing in ${INSTALL_ROOT}"
186
187createDir ${SRC_ROOT}
188createDir ${OBJ_ROOT}
189
190installCodeSourcery
191installLLVM
192installLLVMGCC
193
194echo "Done."