build-install-linux.sh 6.2 KB

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