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.
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 CLANG_TOOLS_EXTRA_DIR
="${CLANG_DIR}/tools/extra"
19 COMPILER_RT_DIR
="${LLVM_DIR}/projects/compiler-rt"
20 ANDROID_NDK_DIR
="${LLVM_DIR}/../android_tools/ndk"
21 STAMP_FILE
="${LLVM_BUILD_DIR}/cr_build_revision"
23 # ${A:-a} returns $A if it's set, a else.
24 LLVM_REPO_URL
=${LLVM_URL:-https://llvm.org/svn/llvm-project}
26 # Die if any command dies.
31 # Parse command line options.
37 chrome_tools
="plugins"
39 if [[ "${OS}" = "Darwin" ]]; then
43 while [[ $# > 0 ]]; do
62 if [[ $# == 0 ]]; then
63 echo "--with-chrome-tools requires an argument."
69 echo "usage: $0 [--force-local-build] [--mac-only] [--run-tests] "
70 echo "--bootstrap: First build clang with CC, then with itself."
71 echo "--force-local-build: Don't try to download prebuilt binaries."
72 echo "--mac-only: Do initial download only on Mac systems."
73 echo "--run-tests: Run tests after building. Only for local builds."
74 echo "--without-android: Don't build ASan Android runtime library."
75 echo "--with-chrome-tools: Select which chrome tools to build." \
76 "Defaults to plugins."
77 echo " Example: --with-chrome-tools 'plugins empty-string'"
85 # --mac-only prevents the initial download on non-mac systems, but if clang has
86 # already been downloaded in the past, this script keeps it up to date even if
87 # --mac-only is passed in and the system isn't a mac. People who don't like this
88 # can just delete their third_party/llvm-build directory.
89 if [[ -n "$mac_only" ]] && [[ "${OS}" != "Darwin" ]] &&
90 [[ ! ( "$GYP_DEFINES" =~ .
*(clang|tsan|asan
)=1.
* ) ]] &&
91 ! [[ -d "${LLVM_BUILD_DIR}" ]]; then
95 # Xcode and clang don't get along when predictive compilation is enabled.
96 # http://crbug.com/96315
97 if [[ "${OS}" = "Darwin" ]] && xcodebuild
-version |
grep -q 'Xcode 3.2' ; then
99 if [[ "${GYP_GENERATORS}" != "make" ]] && \
100 [ "$(defaults read "${XCONF}" EnablePredictiveCompilation)" != "0" ]; then
103 echo "You're using Xcode3 and you have 'Predictive Compilation' enabled."
104 echo "This does not work well with clang (http://crbug.com/96315)."
105 echo "Disable it in Preferences->Building (lower right), or run"
106 echo " defaults write ${XCONF} EnablePredictiveCompilation -boolean NO"
107 echo "while Xcode is not running."
111 SUB_VERSION
=$
(xcodebuild
-version |
sed -Ene 's/Xcode 3\.2\.([0-9]+)/\1/p')
112 if [[ "${SUB_VERSION}" < 6 ]]; then
114 echo " YOUR LD IS BUGGY!"
115 echo "Please upgrade Xcode to at least 3.2.6."
121 # Check if there's anything to be done, exit early if not.
122 if [[ -f "${STAMP_FILE}" ]]; then
123 PREVIOUSLY_BUILT_REVISON
=$
(cat "${STAMP_FILE}")
124 if [[ -z "$force_local_build" ]] && \
125 [[ "${PREVIOUSLY_BUILT_REVISON}" = "${CLANG_REVISION}" ]]; then
126 echo "Clang already at ${CLANG_REVISION}"
130 # To always force a new build if someone interrupts their build half way.
131 rm -f "${STAMP_FILE}"
133 # Clobber pch files, since they only work with the compiler version that
134 # created them. Also clobber .o files, to make sure everything will be built
135 # with the new compiler.
136 if [[ "${OS}" = "Darwin" ]]; then
137 XCODEBUILD_DIR
="${THIS_DIR}/../../../xcodebuild"
139 # Xcode groups .o files by project first, configuration second.
140 if [[ -d "${XCODEBUILD_DIR}" ]]; then
141 echo "Clobbering .o files for Xcode build"
142 find "${XCODEBUILD_DIR}" -name '*.o' -exec rm {} +
146 MAKE_DIR
="${THIS_DIR}/../../../out"
148 for CONFIG
in Debug Release
; do
149 if [[ -d "${MAKE_DIR}/${CONFIG}/obj.target" ||
150 -d "${MAKE_DIR}/${CONFIG}/obj.host" ]]; then
151 echo "Clobbering ${CONFIG} PCH and .o files for make build"
152 if [[ -d "${MAKE_DIR}/${CONFIG}/obj.target" ]]; then
153 find "${MAKE_DIR}/${CONFIG}/obj.target" -name '*.gch' -exec rm {} +
154 find "${MAKE_DIR}/${CONFIG}/obj.target" -name '*.o' -exec rm {} +
156 if [[ -d "${MAKE_DIR}/${CONFIG}/obj.host" ]]; then
157 find "${MAKE_DIR}/${CONFIG}/obj.host" -name '*.o' -exec rm {} +
161 # ninja puts its output below ${MAKE_DIR} as well.
162 if [[ -d "${MAKE_DIR}/${CONFIG}/obj
" ]]; then
163 echo "Clobbering
${CONFIG} PCH and .o files
for ninja build
"
164 find "${MAKE_DIR}/${CONFIG}/obj" -name '*.gch' -exec rm {} +
165 find "${MAKE_DIR}/${CONFIG}/obj" -name '*.o' -exec rm {} +
166 find "${MAKE_DIR}/${CONFIG}/obj" -name '*.o.d' -exec rm {} +
169 if [[ "${OS}" = "Darwin" ]]; then
170 if [[ -d "${XCODEBUILD_DIR}/${CONFIG}/SharedPrecompiledHeaders" ]]; then
171 echo "Clobbering ${CONFIG} PCH files for Xcode build"
172 rm -rf "${XCODEBUILD_DIR}/${CONFIG}/SharedPrecompiledHeaders"
177 # Clobber NaCl toolchain stamp files, see http://crbug.com/159793
178 if [[ -d "${MAKE_DIR}" ]]; then
179 find "${MAKE_DIR}" -name 'stamp.untar' -exec rm {} +
181 if [[ "${OS}" = "Darwin" ]]; then
182 if [[ -d "${XCODEBUILD_DIR}" ]]; then
183 find "${XCODEBUILD_DIR}" -name 'stamp.untar' -exec rm {} +
187 if [[ -z "$force_local_build" ]]; then
188 # Check if there's a prebuilt binary and if so just fetch that. That's faster,
189 # and goma relies on having matching binary hashes on client and server too.
190 CDS_URL
=https
://commondatastorage.googleapis.com
/chromium-browser-clang
191 CDS_FILE
="clang-${CLANG_REVISION}.tgz"
192 CDS_OUT_DIR
=$
(mktemp
-d -t clang_download.XXXXXX
)
193 CDS_OUTPUT
="${CDS_OUT_DIR}/${CDS_FILE}"
194 if [ "${OS}" = "Linux" ]; then
195 CDS_FULL_URL
="${CDS_URL}/Linux_x64/${CDS_FILE}"
196 elif [ "${OS}" = "Darwin" ]; then
197 CDS_FULL_URL
="${CDS_URL}/Mac/${CDS_FILE}"
199 echo Trying to download prebuilt clang
200 if which curl
> /dev
/null
; then
201 curl
-L --fail "${CDS_FULL_URL}" -o "${CDS_OUTPUT}" || \
202 rm -rf "${CDS_OUT_DIR}"
203 elif which wget
> /dev
/null
; then
204 wget
"${CDS_FULL_URL}" -O "${CDS_OUTPUT}" || rm -rf "${CDS_OUT_DIR}"
206 echo "Neither curl nor wget found. Please install one of these."
209 if [ -f "${CDS_OUTPUT}" ]; then
210 rm -rf "${LLVM_BUILD_DIR}/Release+Asserts"
211 mkdir
-p "${LLVM_BUILD_DIR}/Release+Asserts"
212 tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}/Release+Asserts"
213 echo clang
"${CLANG_REVISION}" unpacked
214 echo "${CLANG_REVISION}" > "${STAMP_FILE}"
215 rm -rf "${CDS_OUT_DIR}"
218 echo Did not
find prebuilt clang
at r
"${CLANG_REVISION}", building
222 if [[ -n "${with_android}" ]] && ! [[ -d "${ANDROID_NDK_DIR}" ]]; then
223 echo "Android NDK not found at ${ANDROID_NDK_DIR}"
224 echo "The Android NDK is needed to build a Clang whose -fsanitize=address"
225 echo "works on Android. See "
226 echo "http://code.google.com/p/chromium/wiki/AndroidBuildInstructions for how"
227 echo "to install the NDK, or pass --without-android."
231 echo Getting LLVM r
"${CLANG_REVISION}" in "${LLVM_DIR}"
232 if ! svn co
--force "${LLVM_REPO_URL}/llvm/trunk@${CLANG_REVISION}" \
234 echo Checkout failed
, retrying
236 svn co
--force "${LLVM_REPO_URL}/llvm/trunk@${CLANG_REVISION}" "${LLVM_DIR}"
239 echo Getting clang r
"${CLANG_REVISION}" in "${CLANG_DIR}"
240 svn co
--force "${LLVM_REPO_URL}/cfe/trunk@${CLANG_REVISION}" "${CLANG_DIR}"
242 echo Getting compiler-rt r
"${CLANG_REVISION}" in "${COMPILER_RT_DIR}"
243 svn co
--force "${LLVM_REPO_URL}/compiler-rt/trunk@${CLANG_REVISION}" \
250 if [[ "${OS}" = "Linux" ]]; then
251 NUM_JOBS
="$(grep -c "^processor
" /proc/cpuinfo)"
252 elif [ "${OS}" = "Darwin" ]; then
253 NUM_JOBS
="$(sysctl -n hw.ncpu)"
256 # Build bootstrap clang if requested.
257 if [[ -n "${bootstrap}" ]]; then
258 echo "Building bootstrap compiler"
259 mkdir
-p "${LLVM_BOOTSTRAP_DIR}"
260 cd "${LLVM_BOOTSTRAP_DIR}"
261 if [[ ! -f .
/config.status
]]; then
262 # The bootstrap compiler only needs to be able to build the real compiler,
263 # so it needs no cross-compiler output support. In general, the host
264 # compiler should be as similar to the final compiler as possible, so do
265 # keep --disable-threads & co.
268 --enable-targets=host-only \
273 MACOSX_DEPLOYMENT_TARGET
=10.5 make -j"${NUM_JOBS}"
275 if [[ -n "${run_tests}" ]]; then
279 export CC
="${PWD}/${LLVM_BOOTSTRAP_DIR}/Release+Asserts/bin/clang"
280 export CXX
="${PWD}/${LLVM_BOOTSTRAP_DIR}/Release+Asserts/bin/clang++"
281 echo "Building final compiler"
284 # Build clang (in a separate directory).
285 # The clang bots have this path hardcoded in built/scripts/slave/compile.py,
286 # so if you change it you also need to change these links.
287 mkdir
-p "${LLVM_BUILD_DIR}"
288 cd "${LLVM_BUILD_DIR}"
289 if [[ ! -f .
/config.status
]]; then
298 MACOSX_DEPLOYMENT_TARGET
=10.5 make -j"${NUM_JOBS}"
301 if [[ -n "${with_android}" ]]; then
302 # Make a standalone Android toolchain.
303 ${ANDROID_NDK_DIR}/build
/tools
/make-standalone-toolchain.sh \
304 --platform=android-14 \
305 --install-dir="${LLVM_BUILD_DIR}/android-toolchain" \
306 --system=linux-x86_64 \
309 # Build ASan runtime for Android.
310 # Note: LLVM_ANDROID_TOOLCHAIN_DIR is not relative to PWD, but to where we
311 # build the runtime, i.e. third_party/llvm/projects/compiler-rt.
312 cd "${LLVM_BUILD_DIR}"
313 make -C tools
/clang
/runtime
/ \
314 LLVM_ANDROID_TOOLCHAIN_DIR
="../../../llvm-build/android-toolchain"
318 # Build Chrome-specific clang tools. Paths in this list should be relative to
320 # For each tool directory, copy it into the clang tree and use clang's build
321 # system to compile it.
322 for CHROME_TOOL_DIR
in ${chrome_tools}; do
323 TOOL_SRC_DIR
="${THIS_DIR}/../${CHROME_TOOL_DIR}"
324 TOOL_DST_DIR
="${LLVM_DIR}/tools/clang/tools/chrome-${CHROME_TOOL_DIR}"
325 TOOL_BUILD_DIR
="${LLVM_BUILD_DIR}/tools/clang/tools/chrome-${CHROME_TOOL_DIR}"
326 rm -rf "${TOOL_DST_DIR}"
327 cp -R "${TOOL_SRC_DIR}" "${TOOL_DST_DIR}"
328 rm -rf "${TOOL_BUILD_DIR}"
329 mkdir
-p "${TOOL_BUILD_DIR}"
330 cp "${TOOL_SRC_DIR}/Makefile" "${TOOL_BUILD_DIR}"
331 MACOSX_DEPLOYMENT_TARGET
=10.5 make -j"${NUM_JOBS}" -C "${TOOL_BUILD_DIR}"
334 if [[ -n "$run_tests" ]]; then
336 PLUGIN_SRC_DIR
="${THIS_DIR}/../plugins"
337 "${PLUGIN_SRC_DIR}/tests/test.sh" "${LLVM_BUILD_DIR}/Release+Asserts"
338 cd "${LLVM_BUILD_DIR}"
343 # After everything is done, log success for this revision.
344 echo "${CLANG_REVISION}" > "${STAMP_FILE}"