summaryrefslogtreecommitdiff
path: root/utils/crosstool/ARM/build-install-linux.sh
blob: f3f8df96630cf4154cf1cadebca9e8d7e6f1fe5b (plain)
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."