efa97a114bfeca37c35569df79ced1141ffac872
[oota-llvm.git] / utils / crosstool / ARM / build-install-linux.sh
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
12 readonly INSTALL_ROOT="${INSTALL_ROOT:-/usr/local}"
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"
20
21 readonly CODE_SOURCERY="${INSTALL_ROOT}/codesourcery"
22 readonly CODE_SOURCERY_PKG_PATH="${CODE_SOURCERY_PKG_PATH:-${HOME}/codesourcery}"
23 readonly CODE_SOURCERY_PKG="arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2"
24 readonly CODE_SOURCERY_ROOT="${CODE_SOURCERY}/arm-2007q3"
25 readonly CODE_SOURCERY_BIN="${CODE_SOURCERY_ROOT}/bin"
26 # Make sure ${CROSS_TARGET}-* binutils are in command path
27 export PATH="${CODE_SOURCERY_BIN}:${PATH}"
28
29 readonly CROSS_TARGET_AS="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-as"
30 readonly CROSS_TARGET_LD="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-ld"
31
32 readonly SYSROOT="${CODE_SOURCERY_ROOT}/${CROSS_TARGET}/libc"
33
34 readonly LLVM_PROJECT="${INSTALL_ROOT}/llvm-project"
35 readonly LLVM_INSTALL_ROOT="${LLVM_PROJECT}/${CROSS_HOST}/${CROSS_TARGET}"
36 readonly LLVM_PKG_PATH="${LLVM_PKG_PATH:-${HOME}/llvm-project/snapshots}"
37
38 # Latest SVN revision known to be working in this configuration.
39 readonly LLVM_DEFAULT_REV="70786"
40
41 readonly LLVM_PKG="llvm-${LLVM_SVN_REV:-${LLVM_DEFAULT_REV}}.tar.bz2"
42 readonly LLVM_SRC_DIR="${SRC_ROOT}/llvm"
43 readonly LLVM_OBJ_DIR="${OBJ_ROOT}/llvm"
44 readonly LLVM_INSTALL_DIR="${LLVM_INSTALL_ROOT}/llvm"
45
46 readonly LLVMGCC_PKG="llvm-gcc-4.2-${LLVMGCC_SVN_REV:-${LLVM_DEFAULT_REV}}.tar.bz2"
47 readonly LLVMGCC_SRC_DIR="${SRC_ROOT}/llvm-gcc-4.2"
48 readonly LLVMGCC_OBJ_DIR="${OBJ_ROOT}/llvm-gcc-4.2"
49 readonly LLVMGCC_INSTALL_DIR="${LLVM_INSTALL_ROOT}/llvm-gcc-4.2"
50
51 readonly 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.
55 verifyNotDir() {
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"
65 createDir() {
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
74 sudoCreateDir() {
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.
82 runCommand() {
83   local message="$1"
84   shift
85   echo "=> $message"
86   echo "==> Running: $*"
87   $*
88 }
89
90 runAndLog() {
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
105 installCodeSourcery() {
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
134 installLLVM() {
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
158 installLLVMGCC() {
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
185 echo "Building in ${SCRATCH_ROOT}; installing in ${INSTALL_ROOT}"
186
187 createDir ${SRC_ROOT}
188 createDir ${OBJ_ROOT}
189
190 installCodeSourcery
191 installLLVM
192 installLLVMGCC
193
194 echo "Done."