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