Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 #!/usr/bin/env bash
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 # This script will check out llvm and clang into third_party/llvm and build it.
8 # Do NOT CHANGE this if you don't know what you're doing -- see
9 # https://code.google.com/p/chromium/wiki/UpdatingClang
10 # Reverting problematic clang rolls is safe, though.
11 CLANG_REVISION=163674
13 THIS_DIR="$(dirname "${0}")"
14 LLVM_DIR="${THIS_DIR}/../../../third_party/llvm"
15 LLVM_BUILD_DIR="${LLVM_DIR}/../llvm-build"
16 LLVM_BOOTSTRAP_DIR="${LLVM_DIR}/../llvm-bootstrap"
17 CLANG_DIR="${LLVM_DIR}/tools/clang"
18 COMPILER_RT_DIR="${LLVM_DIR}/projects/compiler-rt"
19 STAMP_FILE="${LLVM_BUILD_DIR}/cr_build_revision"
21 # ${A:-a} returns $A if it's set, a else.
22 LLVM_REPO_URL=${LLVM_URL:-https://llvm.org/svn/llvm-project}
24 # Die if any command dies.
25 set -e
27 OS="$(uname -s)"
29 # Parse command line options.
30 force_local_build=
31 mac_only=
32 run_tests=
33 bootstrap=
34 while [[ $# > 0 ]]; do
35 case $1 in
36 --bootstrap)
37 bootstrap=yes
38 ;;
39 --force-local-build)
40 force_local_build=yes
41 ;;
42 --mac-only)
43 mac_only=yes
44 ;;
45 --run-tests)
46 run_tests=yes
47 ;;
48 --help)
49 echo "usage: $0 [--force-local-build] [--mac-only] [--run-tests] "
50 echo "--bootstrap: First build clang with CC, then with itself."
51 echo "--force-local-build: Don't try to download prebuilt binaries."
52 echo "--mac-only: Do initial download only on Mac systems."
53 echo "--run-tests: Run tests after building. Only for local builds."
54 exit 1
55 ;;
56 esac
57 shift
58 done
60 # --mac-only prevents the initial download on non-mac systems, but if clang has
61 # already been downloaded in the past, this script keeps it up to date even if
62 # --mac-only is passed in and the system isn't a mac. People who don't like this
63 # can just delete their third_party/llvm-build directory.
64 if [[ -n "$mac_only" ]] && [[ "${OS}" != "Darwin" ]] &&
65 [[ "$GYP_DEFINES" != *clang=1* ]] && ! [[ -d "${LLVM_BUILD_DIR}" ]]; then
66 exit 0
67 fi
69 # Xcode and clang don't get along when predictive compilation is enabled.
70 # http://crbug.com/96315
71 if [[ "${OS}" = "Darwin" ]] && xcodebuild -version | grep -q 'Xcode 3.2' ; then
72 XCONF=com.apple.Xcode
73 if [[ "${GYP_GENERATORS}" != "make" ]] && \
74 [ "$(defaults read "${XCONF}" EnablePredictiveCompilation)" != "0" ]; then
75 echo
76 echo " HEARKEN!"
77 echo "You're using Xcode3 and you have 'Predictive Compilation' enabled."
78 echo "This does not work well with clang (http://crbug.com/96315)."
79 echo "Disable it in Preferences->Building (lower right), or run"
80 echo " defaults write ${XCONF} EnablePredictiveCompilation -boolean NO"
81 echo "while Xcode is not running."
82 echo
83 fi
85 SUB_VERSION=$(xcodebuild -version | sed -Ene 's/Xcode 3\.2\.([0-9]+)/\1/p')
86 if [[ "${SUB_VERSION}" < 6 ]]; then
87 echo
88 echo " YOUR LD IS BUGGY!"
89 echo "Please upgrade Xcode to at least 3.2.6."
90 echo
91 fi
92 fi
95 # Check if there's anything to be done, exit early if not.
96 if [[ -f "${STAMP_FILE}" ]]; then
97 PREVIOUSLY_BUILT_REVISON=$(cat "${STAMP_FILE}")
98 if [[ -z "$force_local_build" ]] && \
99 [[ "${PREVIOUSLY_BUILT_REVISON}" = "${CLANG_REVISION}" ]]; then
100 echo "Clang already at ${CLANG_REVISION}"
101 exit 0
102 fi
103 fi
104 # To always force a new build if someone interrupts their build half way.
105 rm -f "${STAMP_FILE}"
107 # Clobber pch files, since they only work with the compiler version that
108 # created them. Also clobber .o files, to make sure everything will be built
109 # with the new compiler.
110 if [[ "${OS}" = "Darwin" ]]; then
111 XCODEBUILD_DIR="${THIS_DIR}/../../../xcodebuild"
113 # Xcode groups .o files by project first, configuration second.
114 if [[ -d "${XCODEBUILD_DIR}" ]]; then
115 echo "Clobbering .o files for Xcode build"
116 find "${XCODEBUILD_DIR}" -name '*.o' -exec rm {} +
117 fi
118 fi
120 if [ -f "${THIS_DIR}/../../../WebKit.gyp" ]; then
121 # We're inside a WebKit checkout.
122 # TODO(thakis): try to unify the directory layout of the xcode- and
123 # make-based builds. http://crbug.com/110455
124 MAKE_DIR="${THIS_DIR}/../../../../../../out"
125 else
126 # We're inside a Chromium checkout.
127 MAKE_DIR="${THIS_DIR}/../../../out"
128 fi
130 for CONFIG in Debug Release; do
131 if [[ -d "${MAKE_DIR}/${CONFIG}/obj.target" ||
132 -d "${MAKE_DIR}/${CONFIG}/obj.host" ]]; then
133 echo "Clobbering ${CONFIG} PCH and .o files for make build"
134 if [[ -d "${MAKE_DIR}/${CONFIG}/obj.target" ]]; then
135 find "${MAKE_DIR}/${CONFIG}/obj.target" -name '*.gch' -exec rm {} +
136 find "${MAKE_DIR}/${CONFIG}/obj.target" -name '*.o' -exec rm {} +
137 fi
138 if [[ -d "${MAKE_DIR}/${CONFIG}/obj.host" ]]; then
139 find "${MAKE_DIR}/${CONFIG}/obj.host" -name '*.o' -exec rm {} +
140 fi
141 fi
143 # ninja puts its output below ${MAKE_DIR} as well.
144 if [[ -d "${MAKE_DIR}/${CONFIG}/obj" ]]; then
145 echo "Clobbering ${CONFIG} PCH and .o files for ninja build"
146 find "${MAKE_DIR}/${CONFIG}/obj" -name '*.gch' -exec rm {} +
147 find "${MAKE_DIR}/${CONFIG}/obj" -name '*.o' -exec rm {} +
148 find "${MAKE_DIR}/${CONFIG}/obj" -name '*.o.d' -exec rm {} +
149 fi
151 if [[ "${OS}" = "Darwin" ]]; then
152 if [[ -d "${XCODEBUILD_DIR}/${CONFIG}/SharedPrecompiledHeaders" ]]; then
153 echo "Clobbering ${CONFIG} PCH files for Xcode build"
154 rm -rf "${XCODEBUILD_DIR}/${CONFIG}/SharedPrecompiledHeaders"
155 fi
156 fi
157 done
159 if [[ -z "$force_local_build" ]]; then
160 # Check if there's a prebuilt binary and if so just fetch that. That's faster,
161 # and goma relies on having matching binary hashes on client and server too.
162 CDS_URL=https://commondatastorage.googleapis.com/chromium-browser-clang
163 CDS_FILE="clang-${CLANG_REVISION}.tgz"
164 CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX)
165 CDS_OUTPUT="${CDS_OUT_DIR}/${CDS_FILE}"
166 if [ "${OS}" = "Linux" ]; then
167 CDS_FULL_URL="${CDS_URL}/Linux_x64/${CDS_FILE}"
168 elif [ "${OS}" = "Darwin" ]; then
169 CDS_FULL_URL="${CDS_URL}/Mac/${CDS_FILE}"
170 fi
171 echo Trying to download prebuilt clang
172 if which curl > /dev/null; then
173 curl -L --fail "${CDS_FULL_URL}" -o "${CDS_OUTPUT}" || \
174 rm -rf "${CDS_OUT_DIR}"
175 elif which wget > /dev/null; then
176 wget "${CDS_FULL_URL}" -O "${CDS_OUTPUT}" || rm -rf "${CDS_OUT_DIR}"
177 else
178 echo "Neither curl nor wget found. Please install one of these."
179 exit 1
180 fi
181 if [ -f "${CDS_OUTPUT}" ]; then
182 rm -rf "${LLVM_BUILD_DIR}/Release+Asserts"
183 mkdir -p "${LLVM_BUILD_DIR}/Release+Asserts"
184 tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}/Release+Asserts"
185 echo clang "${CLANG_REVISION}" unpacked
186 echo "${CLANG_REVISION}" > "${STAMP_FILE}"
187 rm -rf "${CDS_OUT_DIR}"
188 exit 0
189 else
190 echo Did not find prebuilt clang at r"${CLANG_REVISION}", building
191 fi
192 fi
194 echo Getting LLVM r"${CLANG_REVISION}" in "${LLVM_DIR}"
195 if ! svn co --force "${LLVM_REPO_URL}/llvm/trunk@${CLANG_REVISION}" \
196 "${LLVM_DIR}"; then
197 echo Checkout failed, retrying
198 rm -rf "${LLVM_DIR}"
199 svn co --force "${LLVM_REPO_URL}/llvm/trunk@${CLANG_REVISION}" "${LLVM_DIR}"
200 fi
202 echo Getting clang r"${CLANG_REVISION}" in "${CLANG_DIR}"
203 svn co --force "${LLVM_REPO_URL}/cfe/trunk@${CLANG_REVISION}" "${CLANG_DIR}"
205 echo Getting compiler-rt r"${CLANG_REVISION}" in "${COMPILER_RT_DIR}"
206 svn co --force "${LLVM_REPO_URL}/compiler-rt/trunk@${CLANG_REVISION}" \
207 "${COMPILER_RT_DIR}"
209 # Echo all commands.
210 set -x
212 NUM_JOBS=3
213 if [[ "${OS}" = "Linux" ]]; then
214 NUM_JOBS="$(grep -c "^processor" /proc/cpuinfo)"
215 elif [ "${OS}" = "Darwin" ]; then
216 NUM_JOBS="$(sysctl -n hw.ncpu)"
217 fi
219 # Build bootstrap clang if requested.
220 if [[ -n "${bootstrap}" ]]; then
221 echo "Building bootstrap compiler"
222 mkdir -p "${LLVM_BOOTSTRAP_DIR}"
223 cd "${LLVM_BOOTSTRAP_DIR}"
224 if [[ ! -f ./config.status ]]; then
225 # The bootstrap compiler only needs to be able to build the real compiler,
226 # so it needs no cross-compiler output support. In general, the host
227 # compiler should be as similar to the final compiler as possible, so do
228 # keep --disable-threads & co.
229 ../llvm/configure \
230 --enable-optimized \
231 --enable-targets=host-only \
232 --disable-threads \
233 --disable-pthreads \
234 --without-llvmgcc \
235 --without-llvmgxx
236 MACOSX_DEPLOYMENT_TARGET=10.5 make -j"${NUM_JOBS}"
237 fi
238 if [[ -n "${run_tests}" ]]; then
239 make check-all
240 fi
241 cd -
242 export CC="${PWD}/${LLVM_BOOTSTRAP_DIR}/Release+Asserts/bin/clang"
243 export CXX="${PWD}/${LLVM_BOOTSTRAP_DIR}/Release+Asserts/bin/clang++"
244 echo "Building final compiler"
245 fi
247 # Build clang (in a separate directory).
248 # The clang bots have this path hardcoded in built/scripts/slave/compile.py,
249 # so if you change it you also need to change these links.
250 mkdir -p "${LLVM_BUILD_DIR}"
251 cd "${LLVM_BUILD_DIR}"
252 if [[ ! -f ./config.status ]]; then
253 ../llvm/configure \
254 --enable-optimized \
255 --disable-threads \
256 --disable-pthreads \
257 --without-llvmgcc \
258 --without-llvmgxx
259 fi
261 MACOSX_DEPLOYMENT_TARGET=10.5 make -j"${NUM_JOBS}"
262 cd -
264 # Build plugin.
265 # Copy it into the clang tree and use clang's build system to compile the
266 # plugin.
267 PLUGIN_SRC_DIR="${THIS_DIR}/../plugins"
268 PLUGIN_DST_DIR="${LLVM_DIR}/tools/clang/tools/chrome-plugin"
269 PLUGIN_BUILD_DIR="${LLVM_BUILD_DIR}/tools/clang/tools/chrome-plugin"
270 rm -rf "${PLUGIN_DST_DIR}"
271 cp -R "${PLUGIN_SRC_DIR}" "${PLUGIN_DST_DIR}"
272 rm -rf "${PLUGIN_BUILD_DIR}"
273 mkdir -p "${PLUGIN_BUILD_DIR}"
274 cp "${PLUGIN_SRC_DIR}/Makefile" "${PLUGIN_BUILD_DIR}"
275 MACOSX_DEPLOYMENT_TARGET=10.5 make -j"${NUM_JOBS}" -C "${PLUGIN_BUILD_DIR}"
277 if [[ -n "$run_tests" ]]; then
278 # Run a few tests.
279 "${PLUGIN_SRC_DIR}/tests/test.sh" "${LLVM_BUILD_DIR}/Release+Asserts"
280 cd "${LLVM_BUILD_DIR}"
281 make check-all
282 cd -
283 fi
285 # After everything is done, log success for this revision.
286 echo "${CLANG_REVISION}" > "${STAMP_FILE}"