Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client / pnacl / build.sh
1 #!/bin/bash
2 # Copyright (c) 2012 The Native Client 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.
5 #
6 #@                 PNaCl toolchain build script
7 #@-------------------------------------------------------------------
8 #@ This script builds the ARM and PNaCl untrusted toolchains.
9 #@ It MUST be run from the native_client/ directory.
10 ######################################################################
11 # Directory Layout Description
12 ######################################################################
13 #
14 # All directories are relative to BASE which is
15 # On Linux: native_client/toolchain/linux_x86/pnacl_newlib/
16 # On Mac: native_client/toolchain/mac_x86/pnacl_newlib/
17 # On Windows: native_client/toolchain/win_x86/pnacl_newlib/
18 #
19 ######################################################################
20
21 set -o nounset
22 set -o errexit
23
24 PWD_ON_ENTRY="$(pwd)"
25 # The script is located in "native_client/pnacl/".
26 # Set pwd to pnacl/
27 cd "$(dirname "$0")"
28 if [[ $(basename "$(pwd)") != "pnacl" ]] ; then
29   echo "ERROR: cannot find pnacl/ directory"
30   exit -1
31 fi
32
33 source scripts/common-tools.sh
34
35 readonly PNACL_ROOT="$(pwd)"
36 readonly NACL_ROOT="$(GetAbsolutePath ..)"
37 readonly SCONS_OUT="${NACL_ROOT}/scons-out"
38
39 SetScriptPath "${PNACL_ROOT}/build.sh"
40 SetLogDirectory "${PNACL_ROOT}/build/log"
41
42 readonly TOOLCHAIN_BUILD="${NACL_ROOT}/toolchain_build/toolchain_build_pnacl.py"
43
44 # For different levels of make parallelism change this in your env
45 readonly PNACL_CONCURRENCY=${PNACL_CONCURRENCY:-8}
46 # Concurrency for builds using the host's system compiler (which might be goma)
47 readonly PNACL_CONCURRENCY_HOST=${PNACL_CONCURRENCY_HOST:-${PNACL_CONCURRENCY}}
48 PNACL_PRUNE=${PNACL_PRUNE:-false}
49 PNACL_BUILD_ARM=true
50 PNACL_BUILD_MIPS=${PNACL_BUILD_MIPS:-false}
51
52 if ${BUILD_PLATFORM_MAC} || ${BUILD_PLATFORM_WIN}; then
53   # We don't yet support building ARM tools for mac or windows.
54   PNACL_BUILD_ARM=false
55   PNACL_BUILD_MIPS=false
56 fi
57
58 # PNaCl builds libc++/libc++abi as well as libstdc++, allowing users to
59 # choose which to use through the -stdlib=XXX command-line argument.
60 #
61 # The following strings are used for banner names as well as file and
62 # folder names. These names are created by the libraries themselves, and
63 # expected by their dependents. Changing them would be ill-advised.
64 readonly LIB_CXX_NAME="libc++"
65 readonly LIB_STDCPP_NAME="libstdc++"
66
67 # TODO(pdox): Decide what the target should really permanently be
68 readonly CROSS_TARGET_ARM=arm-none-linux-gnueabi
69 readonly BINUTILS_TARGET=arm-pc-nacl
70 readonly REAL_CROSS_TARGET=le32-nacl
71 readonly NACL64_TARGET=x86_64-nacl
72
73 readonly DRIVER_DIR="${PNACL_ROOT}/driver"
74 readonly ARM_ARCH=armv7-a
75 readonly ARM_FPU=vfp
76
77 readonly TOOLCHAIN_ROOT="${NACL_ROOT}/toolchain"
78 readonly TOOLCHAIN_BASE="${TOOLCHAIN_ROOT}/${SCONS_BUILD_PLATFORM}_x86"
79
80 readonly NNACL_NEWLIB_ROOT="${TOOLCHAIN_BASE}/nacl_x86_newlib"
81 readonly NNACL_ARM_NEWLIB_ROOT="${TOOLCHAIN_BASE}/nacl_arm_newlib"
82
83 readonly PNACL_MAKE_OPTS="${PNACL_MAKE_OPTS:-}"
84 readonly MAKE_OPTS="-j${PNACL_CONCURRENCY} VERBOSE=1 ${PNACL_MAKE_OPTS}"
85 readonly MAKE_OPTS_HOST="-j${PNACL_CONCURRENCY_HOST} VERBOSE=1 ${PNACL_MAKE_OPTS}"
86
87 readonly NONEXISTENT_PATH="/going/down/the/longest/road/to/nowhere"
88
89 # For speculative build status output. ( see status function )
90 # Leave this blank, it will be filled during processing.
91 SPECULATIVE_REBUILD_SET=""
92
93 readonly PNACL_SUPPORT="${PNACL_ROOT}/support"
94
95 readonly THIRD_PARTY="${NACL_ROOT}"/../third_party
96 readonly NACL_SRC_THIRD_PARTY_MOD="${NACL_ROOT}/src/third_party_mod"
97
98 # Git sources
99 readonly PNACL_GIT_ROOT="${PNACL_ROOT}/git"
100 readonly TC_SRC_BINUTILS="${PNACL_GIT_ROOT}/binutils"
101 readonly TC_SRC_LLVM="${PNACL_GIT_ROOT}/llvm"
102 readonly TC_SRC_GCC="${PNACL_GIT_ROOT}/gcc"
103 readonly TC_SRC_NEWLIB="${PNACL_GIT_ROOT}/nacl-newlib"
104 readonly TC_SRC_LIBSTDCPP="${TC_SRC_GCC}/${LIB_STDCPP_NAME}-v3"
105 readonly TC_SRC_COMPILER_RT="${PNACL_GIT_ROOT}/compiler-rt"
106 readonly TC_SRC_CLANG="${PNACL_GIT_ROOT}/clang"
107 readonly TC_SRC_LIBCXX="${PNACL_GIT_ROOT}/libcxx"
108
109 readonly SERVICE_RUNTIME_SRC="${NACL_ROOT}/src/trusted/service_runtime"
110 readonly EXPORT_HEADER_SCRIPT="${SERVICE_RUNTIME_SRC}/export_header.py"
111 readonly NACL_SYS_HEADERS="${SERVICE_RUNTIME_SRC}/include"
112 readonly NEWLIB_INCLUDE_DIR="${TC_SRC_NEWLIB}/newlib/libc/sys/nacl"
113
114 # The location of each project. These should be absolute paths.
115 readonly TC_BUILD="${PNACL_ROOT}/build"
116 readonly TC_BUILD_LLVM="${TC_BUILD}/llvm_${HOST_ARCH}"
117 readonly TC_BUILD_BINUTILS="${TC_BUILD}/binutils_${HOST_ARCH}"
118 readonly TC_BUILD_BINUTILS_LIBERTY="${TC_BUILD}/binutils-liberty"
119 TC_BUILD_NEWLIB="${TC_BUILD}/newlib"
120 readonly TC_BUILD_COMPILER_RT="${TC_BUILD}/compiler_rt"
121 readonly TC_BUILD_GCC="${TC_BUILD}/gcc"
122 readonly NACL_HEADERS_TS="${TC_BUILD}/nacl.sys.timestamp"
123
124 readonly TIMESTAMP_FILENAME="make-timestamp"
125
126 # PNaCl toolchain installation directories (absolute paths)
127 readonly INSTALL_ROOT="${TOOLCHAIN_BASE}/pnacl_newlib"
128 readonly INSTALL_BIN="${INSTALL_ROOT}/bin"
129
130 # Bitcode lib directories (including static bitcode libs)
131 INSTALL_LIB="${INSTALL_ROOT}/lib"
132
133 # Native nacl lib directories
134 # The pattern `${INSTALL_LIB_NATIVE}${arch}' is used in many places.
135 readonly INSTALL_LIB_NATIVE="${INSTALL_ROOT}/lib-"
136 readonly INSTALL_LIB_ARM="${INSTALL_LIB_NATIVE}arm"
137 readonly INSTALL_LIB_X8632="${INSTALL_LIB_NATIVE}x86-32"
138 readonly INSTALL_LIB_X8664="${INSTALL_LIB_NATIVE}x86-64"
139 readonly INSTALL_LIB_MIPS32="${INSTALL_LIB_NATIVE}mips32"
140
141 # PNaCl client-translators (sandboxed) binary locations
142 readonly INSTALL_TRANSLATOR="${TOOLCHAIN_BASE}/pnacl_translator"
143
144
145 # The INSTALL_HOST directory has host binaries and libs which
146 # are part of the toolchain (e.g. llvm and binutils).
147 # There are also tools-x86 and tools-arm which have host binaries which
148 # are not part of the toolchain but might be useful in the SDK, e.g.
149 # arm sel_ldr and x86-hosted arm/mips validators.
150 readonly INSTALL_HOST="${INSTALL_ROOT}/host_${HOST_ARCH}"
151
152 # Component installation directories
153 readonly LLVM_INSTALL_DIR="${INSTALL_HOST}"
154 readonly BINUTILS_INSTALL_DIR="${INSTALL_HOST}"
155 readonly BFD_PLUGIN_DIR="${BINUTILS_INSTALL_DIR}/lib/bfd-plugins"
156 readonly FAKE_INSTALL_DIR="${INSTALL_HOST}/fake"
157 NEWLIB_INSTALL_DIR="${INSTALL_ROOT}/usr"
158
159 # Location of the PNaCl tools defined for configure invocations.
160 readonly PNACL_CC="${INSTALL_BIN}/pnacl-clang"
161 readonly PNACL_CXX="${INSTALL_BIN}/pnacl-clang++"
162 readonly PNACL_LD="${INSTALL_BIN}/pnacl-ld"
163 readonly PNACL_PP="${INSTALL_BIN}/pnacl-clang -E"
164 readonly PNACL_AR="${INSTALL_BIN}/pnacl-ar"
165 readonly PNACL_RANLIB="${INSTALL_BIN}/pnacl-ranlib"
166 readonly PNACL_AS="${INSTALL_BIN}/pnacl-as"
167 readonly PNACL_DIS="${INSTALL_BIN}/pnacl-dis"
168 readonly PNACL_FINALIZE="${INSTALL_BIN}/pnacl-finalize"
169 readonly PNACL_NM="${INSTALL_BIN}/pnacl-nm"
170 readonly PNACL_TRANSLATE="${INSTALL_BIN}/pnacl-translate"
171 readonly PNACL_READELF="${INSTALL_BIN}/pnacl-readelf"
172 readonly PNACL_SIZE="${BINUTILS_INSTALL_DIR}/bin/${REAL_CROSS_TARGET}-size"
173 readonly PNACL_STRIP="${INSTALL_BIN}/pnacl-strip"
174 readonly ILLEGAL_TOOL="${INSTALL_BIN}"/pnacl-illegal
175
176 GetNNaClTool() {
177   local arch=$1
178   case ${arch} in
179     x86-32) echo ${NNACL_NEWLIB_ROOT}/bin/i686-nacl-gcc ;;
180     x86-64) echo ${NNACL_NEWLIB_ROOT}/bin/x86_64-nacl-gcc ;;
181     arm) echo ${NNACL_ARM_NEWLIB_ROOT}/bin/arm-nacl-gcc ;;
182     mips32)
183       # No NNaCl for mips
184       echo -n "${PNACL_CC} -arch mips32 --pnacl-bias=mips32 "
185       echo "--pnacl-allow-translate --pnacl-allow-native" ;;
186     *) Fatal "Unexpected argument to GetNNaClTool: $*" ;;
187   esac
188 }
189
190 # For a production (release) build, we want the sandboxed
191 # translator to only contain the code needed to handle
192 # its own architecture. For example, the translator shipped with
193 # an X86-32 browser would only be able to translate to X86-32 code.
194 # This is so that the translator binary is as small as possible.
195 #
196 # If SBTC_PRODUCTION is true, then the translators are built
197 # separately, one for each architecture, so that each translator
198 # can only target its own architecture.
199 #
200 # If SBTC_PRODUCTION is false, then we instead use PNaCl to
201 # build a `fat` translator which can target all supported
202 # architectures. This translator is built as a .pexe
203 # which can then be translated to each individual architecture.
204 SBTC_PRODUCTION=${SBTC_PRODUCTION:-true}
205
206 # Which arches to build for our sandboxed toolchain.
207 SBTC_ARCHES_ALL=${SBTC_ARCHES_ALL:-"armv7 i686 x86_64"}
208
209 get-sbtc-llvm-arches() {
210 # For LLVM i686 brings in both i686 and x86_64.  De-dupe that.
211   echo ${SBTC_ARCHES_ALL} \
212     | sed 's/x86_64/i686/' | sed 's/i686\(.*\)i686/i686\1/'
213 }
214 SBTC_ARCHES_LLVM=$(get-sbtc-llvm-arches)
215
216
217 CC=${CC:-gcc}
218 CXX=${CXX:-g++}
219 AR=${AR:-ar}
220 RANLIB=${RANLIB:-ranlib}
221
222 if ${HOST_ARCH_X8632}; then
223   # These are simple compiler wrappers to force 32bit builds
224   CC="${PNACL_ROOT}/scripts/mygcc32"
225   CXX="${PNACL_ROOT}/scripts/myg++32"
226 fi
227
228 # Set up some environment variables to build flavored bitcode libs
229 setup-biased-bitcode-env() {
230   local arch=$1
231   # Do this to avoid .S files in newlib that clang doesn't like
232   NEWLIB_TARGET="${REAL_CROSS_TARGET}"
233   TC_BUILD_NEWLIB="${TC_BUILD}/newlib-${arch}"
234   LIB_CPP_BUILD="${TC_BUILD}/c++-stdlib-newlib-${arch}"
235   case ${arch} in
236     portable)
237       BIASED_BC_CFLAGS=""
238       NEWLIB_INSTALL_DIR="${INSTALL_ROOT}/usr"
239       INSTALL_LIB="${INSTALL_ROOT}/lib"
240       LIB_CPP_INSTALL_DIR="${INSTALL_ROOT}/usr"
241       ;;
242     arm)
243       BIASED_BC_CFLAGS="--target=armv7-unknown-nacl-gnueabihf -mfloat-abi=hard"
244       NEWLIB_INSTALL_DIR="${INSTALL_ROOT}/usr-bc-${arch}"
245       INSTALL_LIB="${INSTALL_ROOT}/lib-bc-${arch}"
246       LIB_CPP_INSTALL_DIR="${INSTALL_ROOT}/usr-bc-${arch}"
247       ;;
248     x86-32)
249       BIASED_BC_CFLAGS="--target=i686-unknown-nacl"
250       NEWLIB_INSTALL_DIR="${INSTALL_ROOT}/usr-bc-${arch}"
251       INSTALL_LIB="${INSTALL_ROOT}/lib-bc-${arch}"
252       LIB_CPP_INSTALL_DIR="${INSTALL_ROOT}/usr-bc-${arch}"
253       ;;
254     x86-64)
255       BIASED_BC_CFLAGS="--target=x86_64-unknown-nacl"
256       NEWLIB_INSTALL_DIR="${INSTALL_ROOT}/usr-bc-${arch}"
257       INSTALL_LIB="${INSTALL_ROOT}/lib-bc-${arch}"
258       LIB_CPP_INSTALL_DIR="${INSTALL_ROOT}/usr-bc-${arch}"
259       ;;
260     mips32)
261       # MIPS doesn't use biased bitcode.
262       BIASED_BC_CFLAGS=""
263       NEWLIB_INSTALL_DIR="${INSTALL_ROOT}/usr-bc-${arch}"
264       INSTALL_LIB="${INSTALL_ROOT}/lib-bc-${arch}"
265       LIB_CPP_INSTALL_DIR="${INSTALL_ROOT}/usr-bc-${arch}"
266       ;;
267     *)
268       echo "Newlib architecture not implemented yet"
269       exit 1
270   esac
271 }
272
273 setup-lib-cpp-env() {
274   # NOTE: we do not expect the assembler or linker to be used for libs
275   #       hence the use of ILLEGAL_TOOL.
276
277   STD_ENV_FOR_LIB_CPP=(
278     CC_FOR_BUILD="${CC}"
279     CC="${PNACL_CC}"
280     CXX="${PNACL_CXX}"
281     RAW_CXX_FOR_TARGET="${PNACL_CXX}"
282     LD="${ILLEGAL_TOOL}"
283     CFLAGS="-g -O2 -mllvm -inline-threshold=5 ${BIASED_BC_CFLAGS}"
284     CXXFLAGS="-g -O2 -mllvm -inline-threshold=5 ${BIASED_BC_CFLAGS}"
285     CFLAGS_FOR_TARGET="-g -O2 -mllvm -inline-threshold=5 ${BIASED_BC_CFLAGS}"
286     CXXFLAGS_FOR_TARGET="-g -O2 -mllvm -inline-threshold=5 ${BIASED_BC_CFLAGS}"
287     CC_FOR_TARGET="${PNACL_CC}"
288     GCC_FOR_TARGET="${PNACL_CC}"
289     CXX_FOR_TARGET="${PNACL_CXX}"
290     AR="${PNACL_AR}"
291     AR_FOR_TARGET="${PNACL_AR}"
292     NM_FOR_TARGET="${PNACL_NM}"
293     RANLIB="${PNACL_RANLIB}"
294     RANLIB_FOR_TARGET="${PNACL_RANLIB}"
295     AS_FOR_TARGET="${ILLEGAL_TOOL}"
296     LD_FOR_TARGET="${ILLEGAL_TOOL}"
297     OBJDUMP_FOR_TARGET="${ILLEGAL_TOOL}" )
298 }
299
300 setup-newlib-env() {
301   local arch=$1
302   setup-biased-bitcode-env ${arch}
303
304   STD_ENV_FOR_NEWLIB=(
305     # TODO(robertm): get rid of '-allow-asm' here once we have a way of
306     # distinguishing "good" from "bad" asms.
307     CFLAGS_FOR_TARGET="-allow-asm -g -O2 -mllvm -inline-threshold=5 ${BIASED_BC_CFLAGS}"
308     CXXFLAGS_FOR_TARGET="-allow-asm -g -O2 -mllvm -inline-threshold=5 ${BIASED_BC_CFLAGS}"
309     CC_FOR_TARGET="${PNACL_CC}"
310     GCC_FOR_TARGET="${PNACL_CC}"
311     CXX_FOR_TARGET="${PNACL_CXX}"
312     AR_FOR_TARGET="${PNACL_AR}"
313     NM_FOR_TARGET="${PNACL_NM}"
314     RANLIB_FOR_TARGET="${PNACL_RANLIB}"
315     READELF_FOR_TARGET="${PNACL_READELF}"
316     OBJDUMP_FOR_TARGET="${ILLEGAL_TOOL}"
317     AS_FOR_TARGET="${ILLEGAL_TOOL}"
318     LD_FOR_TARGET="${ILLEGAL_TOOL}"
319     STRIP_FOR_TARGET="${ILLEGAL_TOOL}" )
320 }
321
322 # The gold plugin that we use is documented at
323 # http://llvm.org/docs/GoldPlugin.html
324 # Despite its name it is actually used by both gold and bfd. The changes to
325 # this file to enable its use are:
326 # * Build shared
327 # * --enable-gold and --enable-plugin when building binutils
328 # * --with-binutils-include when building binutils
329 # * linking the plugin in bfd-plugins
330
331 ######################################################################
332 ######################################################################
333 #
334 #                     < USER ACCESSIBLE FUNCTIONS >
335 #
336 ######################################################################
337 ######################################################################
338
339 # Convert a path given on the command-line to an absolute path.
340 # This takes into account the fact that we changed directories at the
341 # beginning of this script. PWD_ON_ENTRY is used to remember the
342 # initial working directory.
343 ArgumentToAbsolutePath() {
344   local relpath="$1"
345   local savepwd="$(pwd)"
346   cd "${PWD_ON_ENTRY}"
347   GetAbsolutePath "${relpath}"
348   cd "${savepwd}"
349 }
350
351 #@ sync-sources          - check out repos needed to build toolchain
352 sync-sources() {
353   StepBanner "SYNC SOURCES"
354   python ${TOOLCHAIN_BUILD} --legacy-repo-sync
355   newlib-nacl-headers
356 }
357
358 git-sync() {
359   local gitbase="${PNACL_GIT_ROOT}"
360   # Disable depot tools auto-update for these invocations. (It
361   # will still get updated when it is invoked at the start of each build,
362   # and we don't want it updating from cygwin here)
363   export DEPOT_TOOLS_UPDATE=0
364
365   mkdir -p "${gitbase}"
366   cp "${PNACL_ROOT}"/gclient_template "${gitbase}/.gclient"
367
368   if ! [ -d "${gitbase}/dummydir" ]; then
369     spushd "${gitbase}"
370     ${GCLIENT} update --verbose -j1
371     spopd
372   fi
373
374   newlib-nacl-headers-clean
375   cp "${PNACL_ROOT}"/DEPS "${gitbase}"/dummydir
376   spushd "${gitbase}"
377   ${GCLIENT} update --verbose -j1
378   spopd
379
380   # Copy nacl headers into newlib tree.
381   newlib-nacl-headers
382 }
383
384 gerrit-upload() {
385   # Upload to gerrit code review
386   # (Note: normally we use Rietveld code review. This is only useful if
387   # e.g. we want external users to use gerrit instead of rietveld so we can
388   # easily merge their commits without giving them direct access). But
389   # this at least documents the specifics of uploading to our repo
390   # TODO(dschuff): Find a good way to persist the user's login. maybe
391   # do something like what depot tools does
392   if ! [ -f ~/.gerrit_username ]; then
393     echo "Enter your gerrit username: "
394     read user
395     echo "Saving gerrit username (${user}) to ~/.gerrit_username"
396     echo ${user} > ~/.gerrit_username
397   else
398     local user=$(cat ~/.gerrit_username)
399   fi
400   cd "${TC_SRC_LLVM}"
401   git push ssh://${user}@gerrit.chromium.org:29418/native_client/pnacl-llvm \
402     HEAD:refs/for/master
403 }
404
405 #@-------------------------------------------------------------------------
406
407 #@ download-trusted      - Download and Install trusted SDKs (arm,x86-32,x86-64)
408 #@                         (your untrusted build will not be modified)
409 download-trusted() {
410   StepBanner "DOWNLOAD-TRUSTED" "Downloading trusted toolchains"
411   local installdir="${INSTALL_ROOT}"
412   local tmpdir="${installdir}-backup"
413   local dldir="${installdir}-downloaded"
414
415   rm -rf "${dldir}"
416
417   if [ -d "${tmpdir}" ]; then
418     echo "ERROR: It is not expected that directory '${tmpdir}' exists."
419     echo "       Please delete it if you don't need it"
420     exit -1
421   fi
422
423   if [ -d "${installdir}" ]; then
424     mv "${installdir}" "${tmpdir}"
425   fi
426
427   download-toolchains
428
429   if [ -d "${installdir}" ]; then
430     mv "${installdir}" "${dldir}"
431   fi
432
433   if [ -d "${tmpdir}" ]; then
434     mv "${tmpdir}" "${installdir}"
435   fi
436 }
437
438 #@-------------------------------------------------------------------------
439
440 #@ download-toolchains   - Download and Install all SDKs (arm,x86-32,x86-64)
441
442 download-toolchains() {
443   ${GCLIENT} runhooks --force --verbose
444 }
445
446 #@ libs                  - install native libs and build bitcode libs
447 libs() {
448   libs-clean
449   # MIPS32 doesn't use biased bitcode.
450   for arch in portable arm x86-32 x86-64; do
451     newlib ${arch}
452   done
453   libs-support
454   for arch in arm x86-32 x86-64 mips32 arm-nonsfi x86-32-nonsfi; do
455     dummy-irt-shim ${arch}
456   done
457   compiler-rt-all
458   libgcc_eh-all
459   # MIPS32 doesn't use biased bitcode.
460   for arch in portable arm x86-32 x86-64; do
461     lib-cpp ${LIB_CXX_NAME} ${arch}
462     lib-cpp ${LIB_STDCPP_NAME} ${arch}
463   done
464 }
465
466 #@ everything            - Build and install untrusted SDK. no translator
467 everything() {
468   sync-sources
469   build-all
470 }
471
472 #@ build-all does everything AFTER getting the sources
473 build-all() {
474   mkdir -p "${INSTALL_ROOT}"
475   # This is needed to build misc-tools and run ARM tests.
476   # We check this early so that there are no surprises later, and we can
477   # handle all user interaction early.
478   check-for-trusted
479
480   clean-install
481
482   clean-logs
483
484   build-host
485
486   driver
487
488   libs
489
490   # NOTE: we delay the tool building till after the sdk is essentially
491   #      complete, so that sdk sanity checks don't fail
492   misc-tools
493   cp "${PNACL_ROOT}/README" "${INSTALL_ROOT}"
494   verify
495
496   if ${PNACL_PRUNE}; then
497     prune
498   fi
499 }
500
501 #@ Build just the host binaries
502 build-host() {
503   binutils
504   llvm
505   if ${PNACL_PRUNE}; then
506     prune-host
507   fi
508 }
509
510 #@ everything-translator   - Build and install untrusted SDK AND translator
511 everything-translator() {
512   everything
513   translator-all
514   driver-install-translator
515 }
516
517 #+ translator-clean-all  - Clean all translator install/build directories
518 translator-clean-all() {
519   StepBanner "TRANSLATOR" "Clean all"
520   rm -rf "${TC_BUILD}"/translator*
521   rm -rf "${INSTALL_TRANSLATOR}"*
522 }
523
524 #@ translator-all   -  Build and install all of the translators.
525 translator-all() {
526   StepBanner \
527     "SANDBOXED TC [prod=${SBTC_PRODUCTION}] [arches=${SBTC_ARCHES_ALL}]"
528
529   # Build the SDK if it not already present.
530   sdk
531   # Also build private libs to allow building nexes without the IRT
532   # segment gap.  Specifically, only the sandboxed translator nexes
533   # are built without IRT support to gain address space and reduce
534   # swap file usage. Also libsrpc and its dependencies are now considered
535   # private libs because they are not in the real SDK
536   sdk-private-libs
537
538   binutils-liberty
539   if ${SBTC_PRODUCTION}; then
540     # Build each architecture separately.
541     local arch
542     for arch in ${SBTC_ARCHES_LLVM} ; do
543       llvm-sb ${arch}
544     done
545     for arch in ${SBTC_ARCHES_ALL} ; do
546       binutils-gold-sb ${arch}
547     done
548   else
549     # Using arch `universal` builds the sandboxed tools from a single
550     # .pexe which support all targets.
551     llvm-sb universal
552     binutils-gold-sb universal
553     if ${PNACL_PRUNE}; then
554       # The universal pexes have already been translated.
555       # They don't need to stick around.
556       rm -rf "$(GetTranslatorInstallDir universal)"
557     fi
558   fi
559
560   # Copy native libs to translator install dir.
561   cp -a ${INSTALL_LIB_NATIVE}* ${INSTALL_TRANSLATOR}
562
563   driver-install-translator
564
565   if ${PNACL_PRUNE}; then
566     sdk-clean newlib
567   fi
568 }
569
570
571 #+ translator-prune    Remove leftover files like pexes from pnacl_translator
572 #+                     build and from translator-archive-pexes.
573 translator-prune() {
574   find "${INSTALL_TRANSLATOR}" -name "*.pexe" -exec "rm" {} +
575 }
576
577
578 #+ translator-clean <arch> -
579 #+     Clean one translator install/build
580 translator-clean() {
581   local arch=$1
582   StepBanner "TRANSLATOR" "Clean ${arch}"
583   rm -rf "$(GetTranslatorInstallDir ${arch})"
584   rm -rf "$(GetTranslatorBuildDir ${arch})"
585 }
586
587 #@ all                   - Alias for 'everything'
588 all() {
589   everything
590 }
591
592 #@ status                - Show status of build directories
593 status() {
594   # TODO(robertm): this is currently broken
595   StepBanner "BUILD STATUS"
596
597   status-helper "BINUTILS"             binutils
598   status-helper "LLVM"                 llvm
599
600   status-helper "NEWLIB"               newlib
601   status-helper "C++ Standard Library" lib-cpp
602 }
603
604 status-helper() {
605   local title="$1"
606   local mod="$2"
607
608   if ${mod}-needs-configure; then
609     StepBanner "$title" "NEEDS FULL REBUILD"
610     speculative-add "${mod}"
611   elif ${mod}-needs-make; then
612     StepBanner "$title" "NEEDS MAKE (INCREMENTAL)"
613     speculative-add "${mod}"
614   else
615     StepBanner "$title" "OK (UP TO DATE)"
616   fi
617 }
618
619 speculative-add() {
620   local mod="$1"
621   SPECULATIVE_REBUILD_SET="${SPECULATIVE_REBUILD_SET} ${mod}"
622 }
623
624 speculative-check() {
625   local mod="$1"
626   local search=$(echo "${SPECULATIVE_REBUILD_SET}" | grep -F "$mod")
627   [ ${#search} -gt 0 ]
628   return $?
629 }
630
631
632
633 #@ clean                 - Clean the build and install directories.
634 clean() {
635   StepBanner "CLEAN" "Cleaning build, log, and install directories."
636
637   clean-logs
638   clean-build
639   clean-install
640   clean-scons
641 }
642
643 #@ fast-clean            - Clean everything except LLVM.
644 fast-clean() {
645   local did_backup=false
646   local backup_dir="${PNACL_ROOT}/fast-clean-llvm-backup"
647
648   if [ -d "${TC_BUILD_LLVM}" ]; then
649     rm -rf "${backup_dir}"
650     mv "${TC_BUILD_LLVM}" "${backup_dir}"
651     did_backup=true
652   fi
653
654   clean
655
656   if ${did_backup} ; then
657     mkdir -p "${TC_BUILD}"
658     mv "${backup_dir}" "${TC_BUILD_LLVM}"
659   fi
660 }
661
662 #+ clean-scons           - Clean scons-out directory
663 clean-scons() {
664   rm -rf "${SCONS_OUT}"
665 }
666
667 #+ clean-build           - Clean all build directories
668 clean-build() {
669   rm -rf "${TC_BUILD}"
670 }
671
672 #+ clean-install         - Clean install directories
673 clean-install() {
674   rm -rf "${INSTALL_ROOT}"
675 }
676
677 #+ libs-clean            - Removes the library directories
678 libs-clean() {
679   StepBanner "LIBS-CLEAN" "Cleaning ${INSTALL_ROOT}/libs-*"
680   rm -rf "${INSTALL_LIB}"/*
681   rm -rf "${INSTALL_LIB_NATIVE}"*
682 }
683
684
685 #@-------------------------------------------------------------------------
686
687 prune-host() {
688   echo "stripping binaries (binutils)"
689   strip "${BINUTILS_INSTALL_DIR}"/bin/*
690
691   echo "stripping binaries (llvm)"
692   if ! strip "${LLVM_INSTALL_DIR}"/bin/* ; then
693     echo "NOTE: some failures during stripping are expected"
694   fi
695
696   echo "removing unused clang shared lib"
697   rm -rf "${LLVM_INSTALL_DIR}"/${SO_DIR}/*clang${SO_EXT}
698
699   echo "removing unused binutils binaries"
700   rm -rf "${LLVM_INSTALL_DIR}"/bin/le32-nacl-elfedit
701   rm -rf "${LLVM_INSTALL_DIR}"/bin/le32-nacl-gprof
702   rm -rf "${LLVM_INSTALL_DIR}"/bin/le32-nacl-objcopy
703
704   echo "removing unused LLVM/Clang binaries"
705   rm -rf "${LLVM_INSTALL_DIR}"/bin/bc-wrap
706   rm -rf "${LLVM_INSTALL_DIR}"/bin/bugpoint
707   rm -rf "${LLVM_INSTALL_DIR}"/bin/c-index-test
708   rm -rf "${LLVM_INSTALL_DIR}"/bin/clang-*
709   rm -rf "${LLVM_INSTALL_DIR}"/bin/llc
710   rm -rf "${LLVM_INSTALL_DIR}"/bin/lli
711   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-ar
712   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-bcanalyzer
713   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-config
714   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-cov
715   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-diff
716   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-dwarfdump
717   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-extract
718   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-mcmarkup
719   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-prof
720   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-ranlib
721   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-readobj
722   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-rtdyld
723   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-size
724   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-stress
725   rm -rf "${LLVM_INSTALL_DIR}"/bin/llvm-symbolizer
726   rm -rf "${LLVM_INSTALL_DIR}"/bin/macho-dump
727   rm -rf "${LLVM_INSTALL_DIR}"/bin/pso-stub
728   rm -rf "${LLVM_INSTALL_DIR}"/bin/*-tblgen
729
730   echo "removing llvm & clang headers"
731   rm -rf "${LLVM_INSTALL_DIR}"/include
732
733   echo "removing docs/ and share/"
734   rm -rf "${LLVM_INSTALL_DIR}"/docs
735   rm -rf "${LLVM_INSTALL_DIR}"/share
736
737   echo "removing unused libs"
738   rm -rf "${LLVM_INSTALL_DIR}"/lib/*.a
739   rm -rf "${LLVM_INSTALL_DIR}"/lib/bfd-plugins
740   rm -rf "${LLVM_INSTALL_DIR}"/lib/BugpointPasses.so
741   rm -rf "${LLVM_INSTALL_DIR}"/lib/LLVMHello.so
742 }
743
744 #+ prune                 - Prune toolchain
745 prune() {
746   StepBanner "PRUNE" "Pruning toolchain"
747   local dir_size_before=$(get_dir_size_in_mb ${INSTALL_ROOT})
748
749   SubBanner "Size before: ${INSTALL_ROOT} ${dir_size_before}MB"
750
751   prune-host
752
753   echo "removing .pyc files"
754   rm -f "${INSTALL_BIN}"/pydir/*.pyc
755
756   local dir_size_after=$(get_dir_size_in_mb "${INSTALL_ROOT}")
757   SubBanner "Size after: ${INSTALL_ROOT} ${dir_size_after}MB"
758 }
759
760 #+ tarball <filename>    - Produce tarball file
761 tarball() {
762   if [ ! -n "${1:-}" ]; then
763     echo "Error: tarball needs a tarball name." >&2
764     exit 1
765   fi
766   local tarball="$(ArgumentToAbsolutePath "$1")"
767   StepBanner "TARBALL" "Creating tar ball ${tarball}"
768   tar zcf "${tarball}" -C "${INSTALL_ROOT}" .
769   ls -l ${tarball}
770 }
771
772 translator-tarball() {
773   if [ ! -n "${1:-}" ]; then
774     echo "Error: tarball needs a tarball name." >&2
775     exit 1
776   fi
777   local tarball="$(ArgumentToAbsolutePath "$1")"
778   StepBanner "TARBALL" "Creating translator tar ball ${tarball}"
779   tar zcf "${tarball}" -C "${INSTALL_TRANSLATOR}" .
780 }
781
782 #########################################################################
783 #                              < LLVM >
784 #########################################################################
785
786
787 #+-------------------------------------------------------------------------
788 #+ llvm                  - Configure, build and install LLVM.
789
790 llvm() {
791   StepBanner "LLVM (${HOST_ARCH} HOST)"
792
793   local srcdir="${TC_SRC_LLVM}"
794
795   assert-dir "${srcdir}" "You need to checkout LLVM."
796
797   if llvm-needs-configure; then
798     llvm-clean
799     llvm-configure
800   else
801     SkipBanner "LLVM" "configure"
802   fi
803
804   if llvm-needs-make; then
805     llvm-make
806   else
807     SkipBanner "LLVM" "make"
808   fi
809
810   llvm-install
811 }
812
813 #+ llvm-clean            - Clean LLVM completely
814 llvm-clean() {
815   StepBanner "LLVM" "Clean"
816   local objdir="${TC_BUILD_LLVM}"
817   rm -rf ${objdir}
818   mkdir -p ${objdir}
819 }
820
821 #+ llvm-link-clang       - Add tools/clang symlink into llvm directory
822 llvm-link-clang() {
823   rm -f "${TC_SRC_LLVM}"/tools/clang
824   # Symbolic link named : ${TC_SRC_LLVM}/tools/clang
825   # Needs to point to   : ${TC_SRC_CLANG}
826   ln -sf "${TC_SRC_CLANG}" "${TC_SRC_LLVM}"/tools/clang
827 }
828
829 #+ llvm-unlink-clang     - Remove tools/clang symlink from llvm directory
830 llvm-unlink-clang() {
831   if [ -d "${TC_SRC_LLVM}" ]; then
832     rm -f "${TC_SRC_LLVM}"/tools/clang
833   fi
834 }
835
836 # Default case - Optimized configure
837 LLVM_EXTRA_OPTIONS="--enable-optimized"
838
839 #+ llvm-configure        - Run LLVM configure
840 llvm-configure() {
841   StepBanner "LLVM" "Configure"
842
843   local srcdir="${TC_SRC_LLVM}"
844   local objdir="${TC_BUILD_LLVM}"
845
846   mkdir -p "${objdir}"
847   spushd "${objdir}"
848
849   # Some components like ARMDisassembler may time out when built with -O3.
850   # If we ever start using MSVC, we may also need to tone down the opt level
851   # (see the settings in the CMake file for those components).
852   local llvm_extra_opts=${LLVM_EXTRA_OPTIONS}
853   if ${BUILD_PLATFORM_MAC}; then
854     llvm_extra_opts="${LLVM_EXTRA_OPTIONS} --with-optimize-option=-O2"
855   fi
856
857   llvm-link-clang
858   # The --with-binutils-include is to allow llvm to build the gold plugin
859   # re: --enable-targets  "x86" brings in both i686 and x86_64.
860   #
861   # Disabling zlib features for now to reduce set of shared lib deps.
862   # This may disable things like compressed debug info:
863   # https://code.google.com/p/nativeclient/issues/detail?id=3592
864   #
865   # Disabling terminfo removes a dependency on libtinfo on Linux which
866   # is awkward mostly because it would require a multilib x86-32 copy
867   # of libtinfo installed.  This just disables output colouring.
868   local binutils_include="${TC_SRC_BINUTILS}/include"
869   RunWithLog "llvm.configure" \
870       env -i PATH="${PATH}" \
871              MAKE_OPTS=${MAKE_OPTS_HOST} \
872              CC="${CC}" \
873              CXX="${CXX}" \
874              ${srcdir}/configure \
875              --enable-shared \
876              --disable-zlib \
877              --disable-terminfo \
878              --disable-jit \
879              --with-binutils-include=${binutils_include} \
880              --enable-targets=x86,arm,mips \
881              --prefix="${LLVM_INSTALL_DIR}" \
882              --program-prefix= \
883              ${llvm_extra_opts}
884
885
886   spopd
887 }
888
889 #+ llvm-configure-ninja - Configure with cmake for ninja build
890 # Not used by default. Call manually. Pass build type (Release or Debug)
891 # as an argument; The default is Release.
892 llvm-configure-ninja() {
893   StepBanner "LLVM" "Configure (Cmake-ninja)"
894
895   local srcdir="${TC_SRC_LLVM}"
896   local objdir="${TC_BUILD_LLVM}"
897   local buildtype="${1:-Release}"
898
899   mkdir -p "${objdir}"
900   spushd "${objdir}"
901
902   llvm-link-clang
903   local binutils_include="${TC_SRC_BINUTILS}/include"
904   # Disabling zlib features for now to reduce set of shared lib deps.
905   # This may disable things like compressed debug info:
906   # https://code.google.com/p/nativeclient/issues/detail?id=3592
907   RunWithLog "llvm.configure.cmake" \
908     env \
909       cmake -G Ninja \
910       -DCMAKE_BUILD_TYPE=${buildtype} \
911       -DCMAKE_INSTALL_PREFIX="${LLVM_INSTALL_DIR}" \
912       -DCMAKE_INSTALL_RPATH='$ORIGIN/../lib' \
913       -DBUILD_SHARED_LIBS=ON \
914       -DLLVM_TARGETS_TO_BUILD="X86;ARM;Mips" \
915       -DLLVM_ENABLE_ASSERTIONS=ON \
916       -ULLVM_ENABLE_ZLIB \
917       -DLLVM_ENABLE_TERMINFO=OFF \
918       -DLLVM_BUILD_TESTS=ON \
919       -DLLVM_APPEND_VC_REV=ON \
920       -DLLVM_BINUTILS_INCDIR="${binutils_include}" \
921       ${srcdir}
922   spopd
923 }
924
925 #+ llvm-configure-dbg        - Run LLVM configure
926 #  Not used by default. Call manually.
927 llvm-configure-dbg() {
928   StepBanner "LLVM" "Configure With Debugging"
929   LLVM_EXTRA_OPTIONS="--disable-optimized \
930         --enable-debug-runtime \
931         --enable-assertions "
932   llvm-configure
933 }
934
935
936 llvm-needs-configure() {
937   [ ! -f "${TC_BUILD_LLVM}/config.status" \
938     -a ! -f "${TC_BUILD_LLVM}/build.ninja" ]
939   return $?
940 }
941
942 llvm-needs-make() {
943   local objdir="${TC_BUILD_LLVM}"
944   ts-modified "${TC_SRC_LLVM}" "${objdir}" ||
945     ts-modified "${TC_SRC_CLANG}" "${objdir}"
946   return $?
947 }
948
949 #+ llvm-make             - Run LLVM 'make'
950 llvm-make() {
951   StepBanner "LLVM" "Make"
952
953   local srcdir="${TC_SRC_LLVM}"
954   local objdir="${TC_BUILD_LLVM}"
955   llvm-link-clang
956
957   spushd "${objdir}"
958
959   ts-touch-open "${objdir}"
960
961   if [ -f "${TC_BUILD_LLVM}/build.ninja" ]; then
962     if [ -f "${TC_BUILD_LLVM}/config.status" ]; then
963       echo "ERROR: Found multiple build system files in ${TC_BUILD_LLVM}"
964       exit 1
965     fi
966     echo "Using ninja"
967     ninja
968   else
969     RunWithLog llvm.make \
970       env -i PATH="${PATH}" \
971       MAKE_OPTS="${MAKE_OPTS_HOST}" \
972       NACL_SANDBOX=0 \
973       CC="${CC}" \
974       CXX="${CXX}" \
975       make ${MAKE_OPTS_HOST} all
976   fi
977
978   ts-touch-commit  "${objdir}"
979
980   spopd
981 }
982
983 #+ llvm-install          - Install LLVM
984 llvm-install() {
985   StepBanner "LLVM" "Install"
986
987   spushd "${TC_BUILD_LLVM}"
988   llvm-link-clang
989   if [ -f "${TC_BUILD_LLVM}/build.ninja" ]; then
990     echo "Using ninja"
991     RunWithLog llvm.install ninja install
992   else
993     RunWithLog llvm.install \
994       env -i PATH=/usr/bin/:/bin \
995       MAKE_OPTS="${MAKE_OPTS}" \
996       NACL_SANDBOX=0 \
997       CC="${CC}" \
998       CXX="${CXX}" \
999       make ${MAKE_OPTS} install
1000   fi
1001   spopd
1002
1003   # This is really part of libgcc_eh, but gets blown away by the ninja build.
1004   install-unwind-header
1005 }
1006
1007 #########################################################################
1008 #########################################################################
1009 #     < LIBGCC_EH >
1010 #########################################################################
1011 #########################################################################
1012
1013 libgcc_eh-all() {
1014   StepBanner "LIBGCC_EH (from GCC 4.6)"
1015
1016   libgcc_eh arm
1017   libgcc_eh mips32
1018   libgcc_eh x86-32
1019   libgcc_eh x86-64
1020 }
1021
1022 libgcc_eh-setup() {
1023   local arch=$1
1024   local flags=$2
1025   # For x86 we use nacl-gcc to build libgcc_eh because of some issues with
1026   # LLVM's handling of the gcc intrinsics used in the library. See
1027   # https://code.google.com/p/nativeclient/issues/detail?id=1933
1028   # and http://llvm.org/bugs/show_bug.cgi?id=8541
1029   # For ARM, LLVM does work and we use it to avoid dealing with the fact that
1030   # arm-nacl-gcc uses different libgcc support functions than PNaCl.
1031   if [ ${arch} == "arm" ]; then
1032     LIBGCC_EH_ENV=(
1033       CC="${PNACL_CC} ${flags} -arch ${arch} --pnacl-bias=${arch} \
1034          --pnacl-allow-translate --pnacl-allow-native" \
1035       AR="${PNACL_AR}" \
1036       NM="${PNACL_NM}" \
1037       RANLIB="${PNACL_RANLIB}")
1038   else
1039     LIBGCC_EH_ENV=(
1040       CC="$(GetNNaClTool ${arch}) ${flags}" \
1041       AR="${PNACL_AR}" \
1042       NM="${PNACL_NM}" \
1043       RANLIB="${PNACL_RANLIB}")
1044   fi
1045 }
1046
1047 libgcc_eh() {
1048   local arch=$1
1049
1050   local objdir="${TC_BUILD}/libgcc_eh-${arch}-newlib"
1051   local subdir="${objdir}/fake-target/libgcc"
1052   local installdir="${INSTALL_LIB_NATIVE}${arch}"
1053   local label="(${arch} libgcc_eh.a)"
1054
1055   mkdir -p "${installdir}"
1056   rm -rf "${installdir}"/libgcc_eh*
1057   rm -rf "${objdir}"
1058
1059   # Setup fake gcc build directory.
1060   mkdir -p "${objdir}"/gcc
1061   cp -a "${PNACL_ROOT}"/scripts/libgcc-newlib.mvars \
1062         "${objdir}"/gcc/libgcc.mvars
1063   cp -a "${PNACL_ROOT}"/scripts/libgcc-tconfig.h "${objdir}"/gcc/tconfig.h
1064   touch "${objdir}"/gcc/tm.h
1065
1066   install-unwind-header
1067
1068   mkdir -p "${subdir}"
1069   spushd "${subdir}"
1070   local flags=""
1071   flags+=" -DENABLE_RUNTIME_CHECKING"
1072
1073   libgcc_eh-setup ${arch} "${flags}"
1074
1075   StepBanner "LIBGCC_EH" "Configure ${label}"
1076   RunWithLog libgcc.${arch}.configure \
1077     env -i \
1078       PATH="/usr/bin:/bin" \
1079       /bin/sh \
1080       "${TC_SRC_GCC}"/libgcc/configure \
1081         "${LIBGCC_EH_ENV[@]}" \
1082         --prefix="${FAKE_INSTALL_DIR}" \
1083         --enable-shared \
1084         --host=i686-nacl
1085         # --enable-shared is needed because the EH functions end
1086         # up in libgcc.a if shared libs are disabled.
1087         #
1088         # The "--host" field is needed to enable cross-compiling.
1089         # It introduces extra configuration files in libgcc/config, but these
1090         # appear to affect libgcc, not libgcc_eh.
1091         # TODO(pdox): Create a fake target to get rid of i686 here.
1092
1093   StepBanner "LIBGCC_EH" "Make ${label}"
1094   RunWithLog libgcc.${arch}.make make libgcc_eh.a
1095   spopd
1096
1097   StepBanner "LIBGCC_EH" "Install ${label}"
1098   cp ${subdir}/libgcc_eh.a "${installdir}"
1099 }
1100
1101 install-unwind-header() {
1102   # TODO(pdox):
1103   # We need to establish an unwind ABI, since this is part of the ABI
1104   # exposed to the bitcode by the translator. This header should not vary
1105   # across compilers or C libraries.
1106   local install="/usr/bin/install -c -m 644"
1107   ${install} ${TC_SRC_GCC}/gcc/unwind-generic.h \
1108              ${LLVM_INSTALL_DIR}/lib/clang/3.4/include/unwind.h
1109 }
1110
1111 #########################################################################
1112 #########################################################################
1113 #     < COMPILER-RT >
1114 #########################################################################
1115 #########################################################################
1116
1117 compiler-rt-all() {
1118   StepBanner "COMPILER-RT (LIBGCC)"
1119   compiler-rt arm
1120   compiler-rt mips32
1121   compiler-rt x86-32
1122   compiler-rt x86-64
1123   compiler-rt arm-nonsfi
1124   compiler-rt x86-32-nonsfi
1125 }
1126
1127
1128 #+ compiler-rt           - build/install llvm's replacement for libgcc.a
1129 compiler-rt() {
1130   local arch=$1
1131   local src="${TC_SRC_COMPILER_RT}/lib"
1132   local objdir="${TC_BUILD_COMPILER_RT}-${arch}"
1133   local installdir="${INSTALL_LIB_NATIVE}${arch}"
1134   StepBanner "compiler rt" "build (${arch})"
1135
1136   rm -rf "${objdir}"
1137   mkdir -p "${objdir}"
1138
1139   spushd "${objdir}"
1140   RunWithLog libgcc.${arch}.make \
1141       make -j ${PNACL_CONCURRENCY} -f ${src}/Makefile-pnacl libgcc.a \
1142         CC="${PNACL_CC}" \
1143         AR="${PNACL_AR}" \
1144         "SRC_DIR=${src}" \
1145         "CFLAGS=-arch ${arch} -DPNACL_${arch} --pnacl-allow-translate -O3"
1146
1147   StepBanner "compiler rt" "install (${arch})"
1148   mkdir -p "${installdir}"
1149   cp libgcc.a "${installdir}"
1150   spopd
1151 }
1152
1153 #########################################################################
1154 #########################################################################
1155 #                          < LIBSTDC++/LIBC++ >
1156 #########################################################################
1157 #########################################################################
1158
1159 check-lib-cpp() {
1160   local lib=$1
1161   if [ ${lib} != ${LIB_CXX_NAME} ] && [ ${lib} != ${LIB_STDCPP_NAME} ]; then
1162     echo "ERROR: Unsupported C++ Standard Library '${lib}'. Choose one of: ${LIB_CXX_NAME}, ${LIB_STDCPP_NAME}"
1163     exit -1
1164   fi
1165 }
1166
1167 LIB_CPP_IS_SETUP=false
1168 lib-cpp-setup() {
1169   if ${LIB_CPP_IS_SETUP} && [ $# -eq 0 ]; then
1170     return 0
1171   fi
1172   local arch=$1
1173   setup-biased-bitcode-env ${arch}
1174   LIB_CPP_IS_SETUP=true
1175 }
1176
1177 lib-cpp() {
1178   local lib=$1
1179   local arch=$2
1180   check-lib-cpp "${lib}"
1181   lib-cpp-setup "${arch}"
1182   StepBanner "C++ Standard Library" "(BITCODE $*)"
1183
1184   if lib-cpp-needs-configure "${lib}" "${arch}"; then
1185     lib-cpp-clean "${lib}"
1186     lib-cpp-configure "${lib}" "${arch}"
1187   else
1188     StepBanner "${lib}" "configure"
1189   fi
1190
1191   if lib-cpp-needs-make "${lib}" "${arch}"; then
1192     lib-cpp-make "${lib}" "${arch}"
1193   else
1194     SkipBanner "${lib}" "make"
1195   fi
1196
1197   lib-cpp-install "${lib}" "${arch}"
1198   LIB_CPP_IS_SETUP=false
1199 }
1200
1201 #+ lib-cpp-clean - clean libc++/libstdc++ in bitcode
1202 lib-cpp-clean() {
1203   local lib=$1
1204   StepBanner "${lib}" "Clean"
1205   rm -rf ${TC_BUILD}/${lib}*
1206 }
1207
1208 lib-cpp-needs-configure() {
1209   local lib=$1
1210   local arch=$2
1211   lib-cpp-setup "${arch}"
1212   local objdir="${LIB_CPP_BUILD}-${lib}"
1213   ts-newer-than "${TC_BUILD_LLVM}" "${objdir}" && return 0
1214   [ ! -f "${objdir}/config.status" ]
1215   return $?
1216 }
1217
1218 lib-cpp-configure() {
1219   local lib=$1
1220   local arch=$2
1221   lib-cpp-setup "${arch}"
1222   StepBanner "${lib}" "Configure"
1223   local objdir="${LIB_CPP_BUILD}-${lib}"
1224   local subdir="${objdir}/pnacl-target"
1225   local flags=""
1226   mkdir -p "${subdir}"
1227   spushd "${subdir}"
1228
1229   flags+="--with-newlib --disable-shared --disable-rpath"
1230
1231   setup-lib-cpp-env
1232
1233   if [ ${lib} == ${LIB_CXX_NAME} ]; then
1234     local srcdir="${TC_SRC_LIBCXX}"
1235     # HAS_THREAD_LOCAL is used by libc++abi's exception storage, the
1236     # fallback is pthread otherwise.
1237     local cflags="-g -O2 -mllvm -inline-threshold=5 ${BIASED_BC_CFLAGS} \
1238       -DHAS_THREAD_LOCAL=1"
1239     # LLVM's lit is used to test libc++. run.py serves as a shell that
1240     # translates pexe->nexe and executes in sel_ldr. The libc++ test
1241     # suite needs to be told to use pnacl-clang++'s "system library",
1242     # which happens to be libc++ when the -stdlib parameter is used.
1243     # The target architecture is set through the PNACL_RUN_ARCH
1244     # environment variable (``-arch env``).
1245     local litargs="--verbose"
1246     litargs+=" --param shell_prefix='${NACL_ROOT}/run.py -arch env --retries=1'"
1247     litargs+=" --param exe_suffix='.pexe'"
1248     litargs+=" --param use_system_lib=true"
1249     litargs+=" --param link_flags='-std=gnu++11 --pnacl-exceptions=sjlj'"
1250     # TODO(jfb) CMAKE_???_COMPILER_WORKS can be removed once the PNaCl
1251     #           driver scripts stop confusing cmake for libc++. See:
1252     #           https://code.google.com/p/nativeclient/issues/detail?id=3661
1253     RunWithLog libcxx.configure \
1254       env \
1255       cmake -G "Unix Makefiles" \
1256       -DCMAKE_CXX_COMPILER_WORKS=1 \
1257       -DCMAKE_C_COMPILER_WORKS=1 \
1258       -DCMAKE_SYSTEM_NAME=nacl \
1259       -DCMAKE_INSTALL_PREFIX="${LIB_CPP_INSTALL_DIR}" \
1260       -DCMAKE_BUILD_TYPE=Release \
1261       -DCMAKE_C_COMPILER="${PNACL_CC}" \
1262       -DCMAKE_CXX_COMPILER="${PNACL_CXX}" \
1263       -DCMAKE_AR="${PNACL_AR}" \
1264       -DCMAKE_NM="${PNACL_NM}" \
1265       -DCMAKE_RANLIB="${PNACL_RANLIB}" \
1266       -DCMAKE_LD="${ILLEGAL_TOOL}" \
1267       -DCMAKE_AS="${ILLEGAL_TOOL}" \
1268       -DCMAKE_OBJDUMP="${ILLEGAL_TOOL}" \
1269       -DCMAKE_C_FLAGS="-std=gnu11 ${cflags}" \
1270       -DCMAKE_CXX_FLAGS="-std=gnu++11 ${cflags}" \
1271       -DLIT_EXECUTABLE="${TC_SRC_LLVM}/utils/lit/lit.py" \
1272       -DLLVM_LIT_ARGS="${litargs}" \
1273       -DLIBCXX_ENABLE_CXX0X=0 \
1274       -DLIBCXX_ENABLE_SHARED=0 \
1275       -DLIBCXX_CXX_ABI=libcxxabi \
1276       -DLIBCXX_LIBCXXABI_INCLUDE_PATHS="${TC_SRC_LIBCXX}/../libcxxabi/include" \
1277       ${flags} \
1278       ${srcdir}
1279   else
1280     local srcdir="${TC_SRC_LIBSTDCPP}"
1281     RunWithLog libstdcpp.configure \
1282       env -i PATH=/usr/bin/:/bin \
1283       "${STD_ENV_FOR_LIB_CPP[@]}" \
1284       "${srcdir}"/configure \
1285       --host="${CROSS_TARGET_ARM}" \
1286       --prefix="${LIB_CPP_INSTALL_DIR}" \
1287       --enable-cxx-flags="-D__SIZE_MAX__=4294967295" \
1288       --disable-multilib \
1289       --disable-linux-futex \
1290       --disable-libstdcxx-time \
1291       --disable-sjlj-exceptions \
1292       --disable-libstdcxx-pch \
1293       ${flags}
1294   fi
1295   spopd
1296 }
1297
1298 lib-cpp-needs-make() {
1299   local lib=$1
1300   local arch=$2
1301   lib-cpp-setup "${arch}"
1302   local srcdir="${TC_SRC_LIBSTDCPP}" && \
1303     [ ${lib} == ${LIB_CXX_NAME} ] && srcdir="${TC_SRC_LIBCXX}"
1304   local objdir="${LIB_CPP_BUILD}-${lib}"
1305
1306   ts-modified "${srcdir}" "${objdir}"
1307   return $?
1308 }
1309
1310 lib-cpp-make() {
1311   local lib=$1
1312   local arch=$2
1313   lib-cpp-setup "${arch}"
1314   StepBanner "${lib}" "Make"
1315   local objdir="${LIB_CPP_BUILD}-${lib}"
1316
1317   ts-touch-open "${objdir}"
1318
1319   spushd "${objdir}/pnacl-target"
1320   setup-lib-cpp-env
1321   RunWithLog "${lib}.make" \
1322     env -i PATH=/usr/bin/:/bin \
1323     make \
1324     "${STD_ENV_FOR_LIB_CPP[@]}" \
1325     ${MAKE_OPTS}
1326   spopd
1327
1328   ts-touch-commit "${objdir}"
1329 }
1330
1331 lib-cpp-install() {
1332   local lib=$1
1333   local arch=$2
1334   lib-cpp-setup "${arch}"
1335   StepBanner "${lib}" "Install"
1336   local objdir="${LIB_CPP_BUILD}-${lib}"
1337
1338   spushd "${objdir}/pnacl-target"
1339
1340   # Clean the existing installation
1341   local include_dir=""
1342   if [ ${lib} == ${LIB_CXX_NAME} ]; then
1343     include_dir="v[0-9]"
1344   else
1345     include_dir="[0-9].[0-9].[0-9]"
1346   fi
1347   rm -rf "${LIB_CPP_INSTALL_DIR}"/include/c++/"${include_dir}"
1348   rm -rf "${LIB_CPP_INSTALL_DIR}"/lib/"${lib}"*
1349
1350   # install headers (=install-data)
1351   # for good measure make sure we do not keep any old headers
1352   setup-lib-cpp-env
1353   if [ ${lib} == ${LIB_CXX_NAME} ]; then
1354     RunWithLog "${lib}.install" \
1355       make \
1356       "${STD_ENV_FOR_LIB_CPP[@]}" \
1357       ${MAKE_OPTS} install
1358   else
1359     RunWithLog "${lib}.install" \
1360       make \
1361       "${STD_ENV_FOR_LIB_CPP[@]}" \
1362       ${MAKE_OPTS} install-data
1363   fi
1364
1365   # Install bitcode library
1366   mkdir -p "${LIB_CPP_INSTALL_DIR}/lib"
1367   if [ ${lib} == ${LIB_CXX_NAME} ]; then
1368     cp "${objdir}/pnacl-target/lib/${LIB_CXX_NAME}.a" \
1369       "${LIB_CPP_INSTALL_DIR}/lib"
1370   else
1371     cp "${objdir}/pnacl-target/src/.libs/${LIB_STDCPP_NAME}.a" \
1372       "${LIB_CPP_INSTALL_DIR}/lib"
1373   fi
1374   spopd
1375
1376   # libstdc++ installs a file with an abnormal name: "libstdc++*-gdb.py"
1377   # The asterisk may be due to a bug in libstdc++ Makefile/configure.
1378   # This causes problems on the Windows bot (during cleanup, toolchain
1379   # directory delete fails due to the bad character).
1380   # Rename it to get rid of the asterisk.
1381   if [ ${lib} == ${LIB_STDCPP_NAME} ]; then
1382     spushd "${LIB_CPP_INSTALL_DIR}/lib"
1383     mv -f ${LIB_STDCPP_NAME}'*'-gdb.py ${LIB_STDCPP_NAME}-gdb.py
1384     spopd
1385   fi
1386 }
1387
1388 #########################################################################
1389 #########################################################################
1390 #                          < Tools >
1391 #########################################################################
1392 #########################################################################
1393
1394 build-validator() {
1395   local arch=$1
1396   StepBanner "MISC-TOOLS" "Building validator ("${arch}")"
1397   spushd "${NACL_ROOT}"
1398   RunWithLog ${arch}_ncval_core \
1399     ./scons MODE=opt-host \
1400     sysinfo=0 \
1401     ${arch}-ncval-core
1402   cp ${SCONS_OUT}/opt-linux-x86-32/obj/src/trusted/\
1403 validator_${arch}/${arch}-ncval-core ${INSTALL_ROOT}/tools-x86
1404   spopd
1405 }
1406
1407 #+ misc-tools            - Build and install sel_ldr and validator for ARM.
1408 misc-tools() {
1409   if ${PNACL_BUILD_ARM} ; then
1410     StepBanner "MISC-TOOLS" "Building sel_ldr (arm)"
1411
1412     # TODO(robertm): revisit some of these options
1413     spushd "${NACL_ROOT}"
1414     RunWithLog arm_sel_ldr \
1415       ./scons MODE=opt-host \
1416       platform=arm \
1417       naclsdk_validate=0 \
1418       sysinfo=0 \
1419       -j${PNACL_CONCURRENCY} \
1420       sel_ldr
1421     rm -rf  "${INSTALL_ROOT}/tools-arm"
1422     mkdir "${INSTALL_ROOT}/tools-arm"
1423     local sconsdir="${SCONS_OUT}/opt-${SCONS_BUILD_PLATFORM}-arm"
1424     cp "${sconsdir}/obj/src/trusted/service_runtime/sel_ldr" \
1425        "${INSTALL_ROOT}/tools-arm"
1426     spopd
1427   else
1428     StepBanner "MISC-TOOLS" "Skipping arm sel_ldr (No trusted arm toolchain)"
1429   fi
1430
1431   # TODO(petarj): It would be nice to build MIPS sel_ldr on builbots later.
1432   if [ "${PNACL_BUILD_MIPS}" == "true" ] ; then
1433     StepBanner "MISC-TOOLS" "Building sel_ldr (mips32)"
1434     spushd "${NACL_ROOT}"
1435     RunWithLog mips32_sel_ldr \
1436       ./scons MODE=opt-host \
1437       platform=mips32 \
1438       naclsdk_validate=0 \
1439       sysinfo=0 \
1440       -j${PNACL_CONCURRENCY} \
1441       sel_ldr
1442     rm -rf  "${INSTALL_ROOT}/tools-mips32"
1443     mkdir "${INSTALL_ROOT}/tools-mips32"
1444     local sconsdir="scons-out/opt-${SCONS_BUILD_PLATFORM}-mips32"
1445     cp "${sconsdir}/obj/src/trusted/service_runtime/sel_ldr" \
1446        "${INSTALL_ROOT}/tools-mips32"
1447     spopd
1448   else
1449     StepBanner "MISC-TOOLS" "Skipping mips sel_ldr (No trusted mips toolchain)"
1450   fi
1451
1452   if ${BUILD_PLATFORM_LINUX} ; then
1453     rm -rf  "${INSTALL_ROOT}/tools-x86"
1454     mkdir "${INSTALL_ROOT}/tools-x86"
1455     for target in arm mips; do
1456       build-validator $target
1457     done
1458   else
1459     for target in arm mips; do
1460       StepBanner "MISC-"${target} "Skipping " ${target} " validator (Not yet supported on Mac)"
1461     done
1462   fi
1463 }
1464
1465 #########################################################################
1466 #     < BINUTILS >
1467 #########################################################################
1468
1469 #+-------------------------------------------------------------------------
1470 #+ binutils          - Build and install binutils (cross-tools)
1471 binutils() {
1472   StepBanner "BINUTILS (${HOST_ARCH} HOST)"
1473
1474   local srcdir="${TC_SRC_BINUTILS}"
1475
1476   assert-dir "${srcdir}" "You need to checkout binutils."
1477
1478   if binutils-needs-configure; then
1479     binutils-clean
1480     binutils-configure
1481   else
1482     SkipBanner "BINUTILS" "configure"
1483   fi
1484
1485   if binutils-needs-make; then
1486     binutils-make
1487   else
1488     SkipBanner "BINUTILS" "make"
1489   fi
1490   binutils-install
1491 }
1492
1493 #+ binutils-clean    - Clean binutils
1494 binutils-clean() {
1495   StepBanner "BINUTILS" "Clean"
1496   local objdir="${TC_BUILD_BINUTILS}"
1497   rm -rf ${objdir}
1498 }
1499
1500 #+ binutils-configure- Configure binutils for ARM
1501 binutils-configure() {
1502   StepBanner "BINUTILS" "Configure"
1503
1504   local srcdir="${TC_SRC_BINUTILS}"
1505   local objdir="${TC_BUILD_BINUTILS}"
1506
1507   # enable multiple targets so that we can use the same ar with all .o files
1508   local targ="arm-pc-nacl,i686-pc-nacl,x86_64-pc-nacl,mipsel-pc-nacl"
1509   mkdir -p "${objdir}"
1510   spushd "${objdir}"
1511
1512   # The linux escaping is horrible but apparently the only way of doing this:
1513   # c.f.:  http://sourceware.org/ml/binutils/2009-05/msg00252.html
1514   # all we try to do here is to add "$ORIGIN/../lib to "rpath".
1515   # If you ever touch this please make sure that rpath is correct via:
1516   # objdump -p ${TOOLCHAIN_BASE}/pnacl_newlib/host/bin/le32-nacl-ld.gold
1517   # objdump -p ${TOOLCHAIN_BASE}/pnacl_newlib/host/bin/le32-nacl-objdump
1518   if ${BUILD_PLATFORM_LINUX} ; then
1519       local flags='-Xlinker -rpath -Xlinker '"'"'$\\$$\$$\\$$\$$ORIGIN/../lib'"'"
1520       local shared='yes'
1521       local zlib='--without-zlib'
1522   else
1523       # The shared build for binutils on mac is currently disabled.
1524       # A mac-expert needs to look at this but
1525       # It seems that on mac the linker is storing "full" library paths into
1526       # the dynamic image, e.g, for the llc dynamic image we see  paths like:
1527       # @executable_path/../lib/libLLVM-3.3svn.dylib
1528       # This only works if at linktime the libraries are already at
1529       # @executable_path/../lib which is not the case for mac
1530       #local flags="-Xlinker -rpath -Xlinker '@executable_path/../lib'"
1531       local flags=''
1532       local shared='no'
1533       local zlib=''
1534   fi
1535   # The --enable-gold and --enable-plugins options are on so that we
1536   # can use gold's support for plugin to link PNaCl modules, and use
1537   # gold as the final linker. We do not use bfd ld, and it is disabled
1538   # in part because we do not have its MIPS support downstream.
1539
1540   # We llvm's mc for assembly so we no longer build gas
1541   RunWithLog binutils.configure \
1542       env -i \
1543       PATH="${PATH}" \
1544       CC="${CC}" \
1545       CXX="${CXX}" \
1546       LDFLAGS="${flags}" \
1547       ${srcdir}/configure \
1548           --prefix="${BINUTILS_INSTALL_DIR}" \
1549           --target=${BINUTILS_TARGET} \
1550           --program-prefix=${REAL_CROSS_TARGET}- \
1551           --enable-targets=${targ} \
1552           --enable-shared=${shared} \
1553           --enable-gold=default \
1554           --enable-ld=no \
1555           --disable-nls \
1556           --enable-plugins \
1557           --disable-werror \
1558           --without-gas \
1559           ${zlib} \
1560           --with-sysroot="${NONEXISTENT_PATH}"
1561   # There's no point in setting the correct path as sysroot, because we
1562   # want the toolchain to be relocatable. The driver will use ld command-line
1563   # option --sysroot= to override this value and set it to the correct path.
1564   # However, we need to include --with-sysroot during configure to get this
1565   # option. So fill in a non-sense, non-existent path.
1566
1567   spopd
1568 }
1569
1570 binutils-needs-configure() {
1571   [ ! -f "${TC_BUILD_BINUTILS}/config.status" ]
1572   return $?
1573 }
1574
1575 binutils-needs-make() {
1576   local srcdir="${TC_SRC_BINUTILS}"
1577   local objdir="${TC_BUILD_BINUTILS}"
1578   local ret=1
1579   ts-modified "$srcdir" "$objdir" && ret=0
1580   return ${ret}
1581 }
1582
1583 #+ binutils-make     - Make binutils for ARM
1584 binutils-make() {
1585   StepBanner "BINUTILS" "Make"
1586   local objdir="${TC_BUILD_BINUTILS}"
1587   spushd "${objdir}"
1588
1589   ts-touch-open "${objdir}"
1590
1591   if ${BUILD_PLATFORM_LINUX}; then
1592     RunWithLog binutils.make \
1593       env -i PATH="/usr/bin:/bin" \
1594       ac_cv_search_zlibVersion=no \
1595       make ${MAKE_OPTS_HOST}
1596   else
1597     local control_parallel=""
1598     if ${BUILD_PLATFORM_MAC}; then
1599       # Try to avoid parallel builds for Mac to see if it avoids flake.
1600       # http://code.google.com/p/nativeclient/issues/detail?id=2926
1601       control_parallel="-j1"
1602     fi
1603     RunWithLog binutils.make \
1604       env -i PATH="${PATH}" \
1605       make ${MAKE_OPTS_HOST} ${control_parallel}
1606   fi
1607
1608   ts-touch-commit "${objdir}"
1609
1610   spopd
1611 }
1612
1613 #+ binutils-install  - Install binutils for ARM
1614 binutils-install() {
1615   StepBanner "BINUTILS" "Install"
1616   local objdir="${TC_BUILD_BINUTILS}"
1617   spushd "${objdir}"
1618
1619   RunWithLog binutils.install \
1620     env -i PATH="/usr/bin:/bin" \
1621     make \
1622       install ${MAKE_OPTS}
1623
1624   # TODO(robertm): remove this once we manage to avoid building
1625   #                ld in the first place
1626   echo "pruning hack: ${BINUTILS_INSTALL_DIR}"
1627   rm -f "${BINUTILS_INSTALL_DIR}/bin/${REAL_CROSS_TARGET}-ld"
1628   rm -f "${BINUTILS_INSTALL_DIR}/bin/${REAL_CROSS_TARGET}-ld.bfd"
1629
1630   # Also remove "${BINUTILS_INSTALL_DIR}/${BINUTILS_TARGET}" which contains
1631   # duplicate binaries and unused linker scripts
1632   echo "remove unused ${BINUTILS_INSTALL_DIR}/${BINUTILS_TARGET}/"
1633   rm -rf "${BINUTILS_INSTALL_DIR}/${BINUTILS_TARGET}/"
1634
1635   # Move binutils shared libs to host/lib.
1636   # The first "*" expands to the host string, e.g.
1637   # x86_64-unknown-linux-gnu
1638   if ${BUILD_PLATFORM_LINUX} ; then
1639     echo "move shared libs to ${BINUTILS_INSTALL_DIR}/${SO_DIR}"
1640     for lib in ${BINUTILS_INSTALL_DIR}/*/${BINUTILS_TARGET}/lib/lib*${SO_EXT}
1641     do
1642       echo "moving ${lib}"
1643       mv ${lib} ${BINUTILS_INSTALL_DIR}/${SO_DIR}
1644     done
1645   fi
1646
1647   # NOTE: this needs to come AFTER the moving of the shared libs
1648   # TODO(robertm): this needs to be augmented for mac and windows
1649   echo "remove unused (remaining) binutils static libs and headers"
1650   rm -rf "${BINUTILS_INSTALL_DIR}/i686-pc-linux-gnu" \
1651          "${BINUTILS_INSTALL_DIR}/x86_64-unknown-linux-gnu"
1652
1653   spopd
1654 }
1655
1656 #+-------------------------------------------------------------------------
1657 #+ binutils-liberty      - Build native binutils libiberty
1658 binutils-liberty() {
1659   local srcdir="${TC_SRC_BINUTILS}"
1660
1661   assert-dir "${srcdir}" "You need to checkout binutils."
1662
1663   if binutils-liberty-needs-configure; then
1664     binutils-liberty-clean
1665     binutils-liberty-configure
1666   else
1667     SkipBanner "BINUTILS-LIBERTY" "configure"
1668   fi
1669
1670   if binutils-liberty-needs-make; then
1671     binutils-liberty-make
1672   else
1673     SkipBanner "BINUTILS-LIBERTY" "make"
1674   fi
1675 }
1676
1677 binutils-liberty-needs-configure() {
1678   [ ! -f "${TC_BUILD_BINUTILS_LIBERTY}/config.status" ]
1679   return $?
1680 }
1681
1682 #+ binutils-liberty-clean    - Clean binutils-liberty
1683 binutils-liberty-clean() {
1684   StepBanner "BINUTILS-LIBERTY" "Clean"
1685   local objdir="${TC_BUILD_BINUTILS_LIBERTY}"
1686   rm -rf ${objdir}
1687 }
1688
1689 #+ binutils-liberty-configure - Configure binutils-liberty
1690 binutils-liberty-configure() {
1691   StepBanner "BINUTILS-LIBERTY" "Configure"
1692
1693   local srcdir="${TC_SRC_BINUTILS}"
1694   local objdir="${TC_BUILD_BINUTILS_LIBERTY}"
1695
1696   mkdir -p "${objdir}"
1697   spushd "${objdir}"
1698   RunWithLog binutils.liberty.configure \
1699       env -i \
1700       PATH="${PATH}" \
1701       CC="${CC}" \
1702       CXX="${CXX}" \
1703       ${srcdir}/configure
1704   spopd
1705 }
1706
1707 binutils-liberty-needs-make() {
1708   local srcdir="${TC_SRC_BINUTILS}"
1709   local objdir="${TC_BUILD_BINUTILS_LIBERTY}"
1710
1711   ts-modified "$srcdir" "$objdir"
1712   return $?
1713 }
1714
1715 #+ binutils-liberty-make - Make binutils-liberty
1716 binutils-liberty-make() {
1717   StepBanner "BINUTILS-LIBERTY" "Make"
1718   local srcdir="${TC_SRC_BINUTILS}"
1719   local objdir="${TC_BUILD_BINUTILS_LIBERTY}"
1720   spushd "${objdir}"
1721
1722   ts-touch-open "${objdir}"
1723
1724   RunWithLog binutils.liberty.make \
1725       env -i \
1726       PATH="${PATH}" \
1727       CC="${CC}" \
1728       CXX="${CXX}" \
1729       make ${MAKE_OPTS_HOST} all-libiberty
1730
1731   ts-touch-commit "${objdir}"
1732
1733   spopd
1734 }
1735
1736 #########################################################################
1737 #     CLIENT BINARIES (SANDBOXED)
1738 #########################################################################
1739
1740 check-arch() {
1741   local arch=$1
1742   for valid_arch in i686 x86_64 armv7 universal ; do
1743     if [ "${arch}" == "${valid_arch}" ] ; then
1744       return
1745     fi
1746   done
1747
1748   Fatal "ERROR: Unsupported arch [$1]. Must be: i686, x86_64, armv7, universal"
1749 }
1750
1751 llvm-sb-setup() {
1752   local arch=$1
1753   LLVM_SB_LOG_PREFIX="llvm.sb.${arch}"
1754   LLVM_SB_OBJDIR="$(GetTranslatorBuildDir ${arch})/llvm-sb"
1755
1756   # The SRPC headers are included directly from the nacl tree, as they are
1757   # not in the SDK. libsrpc should have already been built by the
1758   # build.sh sdk-private-libs step.
1759   # This is always statically linked.
1760   # The LLVM sandboxed build uses the normally-disallowed external
1761   # function __nacl_get_arch().  Allow that for now.
1762   local flags="-static -I$(GetAbsolutePath ${NACL_ROOT}/..) \
1763     --pnacl-disable-abi-check "
1764
1765   LLVM_SB_CONFIGURE_ENV=(
1766     AR="${PNACL_AR}" \
1767     AS="${PNACL_AS}" \
1768     CC="${PNACL_CC} ${flags}" \
1769     CXX="${PNACL_CXX} ${flags}" \
1770     LD="${PNACL_LD} ${flags}" \
1771     NM="${PNACL_NM}" \
1772     RANLIB="${PNACL_RANLIB}")
1773 }
1774
1775 #+-------------------------------------------------------------------------
1776 #+ llvm-sb <arch>- Build and install llvm tools (sandboxed)
1777 llvm-sb() {
1778   local arch=$1
1779   check-arch ${arch}
1780   llvm-sb-setup ${arch}
1781   StepBanner "LLVM-SB" "Sandboxed pnacl-llc [${arch}]"
1782   local srcdir="${TC_SRC_LLVM}"
1783   assert-dir "${srcdir}" "You need to checkout llvm."
1784
1785   if llvm-sb-needs-configure ${arch} ; then
1786     llvm-sb-clean ${arch}
1787     llvm-sb-configure ${arch}
1788   else
1789     SkipBanner "LLVM-SB" "configure ${arch}"
1790   fi
1791
1792   llvm-sb-make ${arch}
1793   llvm-sb-install ${arch}
1794 }
1795
1796 llvm-sb-needs-configure() {
1797   [ ! -f "${LLVM_SB_OBJDIR}/config.status" ]
1798   return $?
1799 }
1800
1801 # llvm-sb-clean          - Clean llvm tools (sandboxed)
1802 llvm-sb-clean() {
1803   local arch=$1
1804   StepBanner "LLVM-SB" "Clean ${arch}"
1805   local objdir="${LLVM_SB_OBJDIR}"
1806
1807   rm -rf "${objdir}"
1808   mkdir -p "${objdir}"
1809 }
1810
1811 # llvm-sb-configure - Configure llvm tools (sandboxed)
1812 llvm-sb-configure() {
1813   local arch=$1
1814
1815   StepBanner "LLVM-SB" "Configure ${arch}"
1816   local srcdir="${TC_SRC_LLVM}"
1817   local objdir="${LLVM_SB_OBJDIR}"
1818   local installdir="$(GetTranslatorInstallDir ${arch})"
1819   local targets=""
1820   # For LLVM, "x86" brings in both i686 and x86_64.
1821   case ${arch} in
1822     i686) targets=x86 ;;
1823     x86_64) targets=x86 ;;
1824     armv7) targets=arm ;;
1825     universal) targets=x86,arm ;;
1826   esac
1827
1828   spushd "${objdir}"
1829   # TODO(jvoung): remove ac_cv_func_getrusage=no once newlib has getrusage
1830   # in its headers.  Otherwise, configure thinks that we can link in
1831   # getrusage (stub is in libnacl), but we can't actually compile code
1832   # that uses ::getrusage because it's not in headers:
1833   # https://code.google.com/p/nativeclient/issues/detail?id=3657
1834   RunWithLog \
1835       ${LLVM_SB_LOG_PREFIX}.configure \
1836       env -i \
1837       PATH="/usr/bin:/bin" \
1838       ${srcdir}/configure \
1839         "${LLVM_SB_CONFIGURE_ENV[@]}" \
1840         --prefix=${installdir} \
1841         --host=nacl \
1842         --enable-targets=${targets} \
1843         --disable-assertions \
1844         --enable-pic=no \
1845         --enable-static \
1846         --enable-shared=no \
1847         --disable-jit \
1848         --enable-optimized \
1849         --target=${CROSS_TARGET_ARM} \
1850         llvm_cv_link_use_export_dynamic=no \
1851         ac_cv_func_getrusage=no
1852   spopd
1853 }
1854
1855 # llvm-sb-make - Make llvm tools (sandboxed)
1856 llvm-sb-make() {
1857   local arch=$1
1858   StepBanner "LLVM-SB" "Make ${arch}"
1859   local objdir="${LLVM_SB_OBJDIR}"
1860
1861   spushd "${objdir}"
1862   ts-touch-open "${objdir}"
1863
1864   local tools_to_build="pnacl-llc"
1865   local export_dyn_env="llvm_cv_link_use_export_dynamic=no"
1866   local isjit=0
1867   RunWithLog ${LLVM_SB_LOG_PREFIX}.make \
1868       env -i PATH="/usr/bin:/bin" \
1869       ONLY_TOOLS="${tools_to_build}" \
1870       NACL_SANDBOX=1 \
1871       KEEP_SYMBOLS=1 \
1872       VERBOSE=1 \
1873       ${export_dyn_env} \
1874       make ${MAKE_OPTS} tools-only
1875
1876   ts-touch-commit "${objdir}"
1877
1878   spopd
1879 }
1880
1881 # llvm-sb-install - Install llvm tools (sandboxed)
1882 llvm-sb-install() {
1883   local arch=$1
1884   StepBanner "LLVM-SB" "Install ${arch}"
1885
1886   local toolname="pnacl-llc"
1887   local installdir="$(GetTranslatorInstallDir ${arch})"/bin
1888   mkdir -p "${installdir}"
1889   spushd "${installdir}"
1890   local objdir="${LLVM_SB_OBJDIR}"
1891   cp -f "${objdir}"/Release*/bin/${toolname} .
1892   mv -f ${toolname} ${toolname}.pexe
1893   local arches=${arch}
1894   if [[ "${arch}" == "universal" ]]; then
1895     arches="${SBTC_ARCHES_ALL}"
1896   elif [[ "${arch}" == "i686" ]]; then
1897     # LLVM does not separate the i686 and x86_64 backends.
1898     # Translate twice to get both nexes.
1899     arches="i686 x86_64"
1900   fi
1901   translate-sb-tool ${toolname} "${arches}"
1902   install-sb-tool ${toolname} "${arches}"
1903   spopd
1904 }
1905
1906 # translate-sb-tool <toolname> <arches>
1907 #
1908 # Translate <toolname>.pexe to <toolname>.<arch>.nexe in the current directory.
1909 translate-sb-tool() {
1910   local toolname=$1
1911   local arches=$2
1912   local pexe="${toolname}.pexe"
1913   if ${PNACL_PRUNE}; then
1914     # Only strip debug, to preserve symbol names for testing. This is okay
1915     # because we strip the native nexe later anyway.
1916     # So, why bother stripping here at all?
1917     # It does appear to affect the size of the nexe:
1918     # http://code.google.com/p/nativeclient/issues/detail?id=3305
1919     ${PNACL_STRIP} --strip-debug "${pexe}"
1920   fi
1921
1922   local tarch
1923   for tarch in ${arches}; do
1924     local nexe="${toolname}.${tarch}.nexe"
1925     StepBanner "TRANSLATE" \
1926                "Translating ${toolname}.pexe to ${tarch} (background)"
1927     # NOTE: we are using --noirt to build without a segment gap
1928     # since we aren't loading the IRT for the translator nexes.
1929     #
1930     # Compiling with -ffunction-sections, -fdata-sections, --gc-sections
1931     # helps reduce the size a bit. If you want to use --gc-sections to test out:
1932     # http://code.google.com/p/nativeclient/issues/detail?id=1591
1933     # you will need to do a build without these flags.
1934     "${PNACL_TRANSLATE}" -ffunction-sections -fdata-sections --gc-sections \
1935       --allow-llvm-bitcode-input --noirt -arch ${tarch} "${pexe}" -o "${nexe}" &
1936     QueueLastProcess
1937   done
1938   StepBanner "TRANSLATE" "Waiting for translation processes to finish"
1939   QueueWait
1940
1941   # Test that certain symbols have been pruned before stripping.
1942   if [ "${toolname}" == "pnacl-llc" ]; then
1943     for tarch in ${arches}; do
1944       local nexe="${toolname}.${tarch}.nexe"
1945       local llvm_host_glob="${LLVM_INSTALL_DIR}/lib/libLLVM*so"
1946       python "${PNACL_ROOT}/prune_test.py" "${PNACL_NM}" \
1947         "${llvm_host_glob}" "${nexe}"
1948     done
1949   fi
1950
1951   if ${PNACL_PRUNE}; then
1952     # Strip the nexes.
1953     for tarch in ${arches}; do
1954       local nexe="${toolname}.${tarch}.nexe"
1955       ${PNACL_STRIP} "${nexe}"
1956     done
1957   fi
1958   StepBanner "TRANSLATE" "Done."
1959 }
1960
1961 # install-sb-tool <toolname> <arches>
1962 #
1963 # Install <toolname>.<arch>.nexe from the current directory
1964 # into the right location (as <toolname>.nexe)
1965 install-sb-tool() {
1966   local toolname="$1"
1967   local arches="$2"
1968   local tarch
1969   for tarch in ${arches}; do
1970     local installbin="$(GetTranslatorInstallDir ${tarch})"/bin
1971     mkdir -p "${installbin}"
1972     mv -f ${toolname}.${tarch}.nexe "${installbin}"/${toolname}.nexe
1973     if ${PNACL_BUILDBOT}; then
1974       spushd "${installbin}"
1975       local tag="${toolname}_${tarch}_size"
1976       print-tagged-tool-sizes "${tag}" "$(pwd)/${toolname}.nexe"
1977       spopd
1978     fi
1979   done
1980 }
1981
1982 GetTranslatorBuildDir() {
1983   local arch="$1"
1984   echo "${TC_BUILD}/translator-${arch//_/-}"
1985 }
1986
1987 GetTranslatorInstallDir() {
1988   local arch="$1"
1989   echo "${INSTALL_TRANSLATOR}"/${arch}
1990 }
1991
1992 ### Sandboxed version of gold.
1993
1994 #+-------------------------------------------------------------------------
1995 #+ binutils-gold-sb - Build and install gold (sandboxed)
1996 #+                    This is the replacement for the old
1997 #+                    final sandboxed linker which was bfd based.
1998 #+                    It has nothing to do with the bitcode linker
1999 #+                    which is also gold based.
2000 binutils-gold-sb() {
2001   local arch=$1
2002   check-arch ${arch}
2003   StepBanner "GOLD-NATIVE-SB" "(libiberty + gold) ${arch}"
2004
2005   local srcdir="${TC_SRC_BINUTILS}"
2006   assert-dir "${srcdir}" "You need to checkout gold."
2007
2008   binutils-gold-sb-clean ${arch}
2009   binutils-gold-sb-configure ${arch}
2010   binutils-gold-sb-make ${arch}
2011   binutils-gold-sb-install ${arch}
2012 }
2013
2014 # binutils-gold-sb-clean - Clean gold
2015 binutils-gold-sb-clean() {
2016   local arch=$1
2017   StepBanner "GOLD-NATIVE-SB" "Clean ${arch}"
2018   local objdir="$(GetTranslatorBuildDir ${arch})/binutils-gold-sb"
2019
2020   rm -rf "${objdir}"
2021   mkdir -p "${objdir}"
2022 }
2023
2024 # binutils-gold-sb-configure - Configure binutils for gold (unsandboxed)
2025 binutils-gold-sb-configure() {
2026   local arch=$1
2027   local srcdir="${TC_SRC_BINUTILS}"
2028   local objdir="$(GetTranslatorBuildDir ${arch})/binutils-gold-sb"
2029   local installbin="$(GetTranslatorInstallDir ${arch})/bin"
2030
2031   # The SRPC headers are included directly from the nacl tree, as they are
2032   # not in the SDK. libsrpc should have already been built by the
2033   # build.sh sdk-private-libs step
2034   # The Gold sandboxed build uses the normally-disallowed external
2035   # function __nacl_get_arch().  Allow that for now.
2036   #
2037   # TODO(jfb) Gold currently only builds with libstdc++.
2038   local flags="-static -I$(GetAbsolutePath ${NACL_ROOT}/..) \
2039     -fno-exceptions -O3 --pnacl-disable-abi-check -stdlib=${LIB_STDCPP_NAME} "
2040   local configure_env=(
2041     AR="${PNACL_AR}" \
2042     AS="${PNACL_AS}" \
2043     CC="${PNACL_CC} ${flags}" \
2044     CXX="${PNACL_CXX} ${flags}" \
2045     CC_FOR_BUILD="${CC}" \
2046     CXX_FOR_BUILD="${CXX}" \
2047     LD="${PNACL_LD} ${flags}" \
2048     NM="${PNACL_NM}" \
2049     RANLIB="${PNACL_RANLIB}"
2050   )
2051   local gold_targets=""
2052   case ${arch} in
2053     i686)      gold_targets=i686-pc-nacl ;;
2054     x86_64)    gold_targets=x86_64-pc-nacl ;;
2055     armv7)     gold_targets=arm-pc-nacl ;;
2056     universal)
2057       gold_targets=i686-pc-nacl,x86_64-pc-nacl,arm-pc-nacl ;;
2058   esac
2059
2060   # gold always adds "target" to the enabled targets so we are
2061   # little careful to not build too much
2062   # Note: we are (ab)using target for both --host and --target
2063   #       which configure expects to be present
2064   local target
2065   if [ ${arch} == "universal" ] ; then
2066     target=i686-pc-nacl
2067   else
2068     target=${gold_targets}
2069   fi
2070
2071   StepBanner "GOLD-NATIVE-SB" "Configure (libiberty)"
2072   # Gold depends on liberty only for a few functions:
2073   # xrealloc, lbasename, etc.
2074   # we could remove these if necessary.
2075
2076   mkdir -p "${objdir}/libiberty"
2077   spushd "${objdir}/libiberty"
2078   StepBanner "GOLD-NATIVE-SB" "Dir [$(pwd)]"
2079   local log_prefix="binutils-gold.sb.${arch}"
2080   RunWithLog "${log_prefix}".configure \
2081     env -i \
2082     PATH="/usr/bin:/bin" \
2083     "${configure_env[@]}" \
2084     ${srcdir}/libiberty/configure --prefix="${installbin}" \
2085     --host=${target} \
2086     --target=${target}
2087   spopd
2088
2089   StepBanner "GOLD-NATIVE-SB" "Configure (gold) ${arch}"
2090   mkdir -p "${objdir}/gold"
2091   spushd "${objdir}/gold"
2092   StepBanner "GOLD-NATIVE-SB" "Dir [$(pwd)]"
2093   # Removed -Werror until upstream gold no longer has problems with new clang
2094   # warnings. http://code.google.com/p/nativeclient/issues/detail?id=2861
2095   # TODO(sehr,robertm): remove this when gold no longer has these.
2096   RunWithLog "${log_prefix}".configure \
2097     env -i \
2098     PATH="/usr/bin:/bin" \
2099     "${configure_env[@]}" \
2100     CXXFLAGS="" \
2101     CFLAGS="" \
2102     ac_cv_search_zlibVersion=no \
2103     ac_cv_header_sys_mman_h=no \
2104     ac_cv_func_mmap=no \
2105     ac_cv_func_mallinfo=no \
2106     ac_cv_prog_cc_g=no \
2107     ac_cv_prog_cxx_g=no \
2108     ${srcdir}/gold/configure --prefix="${installbin}" \
2109                                       --enable-targets=${gold_targets} \
2110                                       --host=${target} \
2111                                       --target=${target} \
2112                                       --disable-nls \
2113                                       --enable-plugins=no \
2114                                       --enable-naclsrpc=yes \
2115                                       --disable-werror \
2116                                       --with-sysroot="${NONEXISTENT_PATH}"
2117   # Note: the extra ac_cv settings:
2118   # * eliminate unnecessary use of zlib
2119   # * eliminate use of mmap
2120   # (those should not have much impact on the non-sandboxed
2121   # version but help in the sandboxed case)
2122   # We also disable debug (-g) because the bitcode files become too big
2123   # (with ac_cv_prog_cc_g).
2124
2125   # There's no point in setting the correct path as sysroot, because we
2126   # want the toolchain to be relocatable. The driver will use ld command-line
2127   # option --sysroot= to override this value and set it to the correct path.
2128   # However, we need to include --with-sysroot during configure to get this
2129   # option. So fill in a non-sense, non-existent path.
2130   spopd
2131 }
2132
2133 # binutils-gold-sb-make - Make binutils (sandboxed)
2134 binutils-gold-sb-make() {
2135   local arch=${1}
2136   local objdir="$(GetTranslatorBuildDir ${arch})/binutils-gold-sb"
2137   ts-touch-open "${objdir}/"
2138
2139   StepBanner "GOLD-NATIVE-SB" "Make (liberty) ${arch}"
2140   spushd "${objdir}/libiberty"
2141
2142   RunWithLog "binutils-gold.liberty.sb.${arch}".make \
2143       env -i PATH="/usr/bin:/bin" \
2144       make ${MAKE_OPTS}
2145   spopd
2146
2147   StepBanner "GOLD-NATIVE-SB" "Make (gold) ${arch}"
2148   spushd "${objdir}/gold"
2149   RunWithLog "binutils-gold.sb.${arch}".make \
2150       env -i PATH="/usr/bin:/bin" \
2151       make ${MAKE_OPTS} ld-new
2152   spopd
2153
2154   ts-touch-commit "${objdir}"
2155 }
2156
2157 # binutils-gold-sb-install - Install gold
2158 binutils-gold-sb-install() {
2159   local arch=$1
2160   local objdir="$(GetTranslatorBuildDir ${arch})/binutils-gold-sb"
2161   local installbin="$(GetTranslatorInstallDir ${arch})/bin"
2162
2163   StepBanner "GOLD-NATIVE-SB" "Install [${installbin}] ${arch}"
2164
2165   mkdir -p "${installbin}"
2166   spushd "${installbin}"
2167
2168   # Install just "ld"
2169   cp "${objdir}"/gold/ld-new ld.pexe
2170
2171   # Translate and install
2172   local arches=${arch}
2173   if [[ "${arch}" == "universal" ]]; then
2174     arches="${SBTC_ARCHES_ALL}"
2175   fi
2176   translate-sb-tool ld "${arches}"
2177   install-sb-tool ld "${arches}"
2178   spopd
2179 }
2180
2181
2182 #+-------------------------------------------------------------------------
2183 #########################################################################
2184 #     < NEWLIB-BITCODE >
2185 #########################################################################
2186
2187 #+ newlib - Build and install newlib in bitcode.
2188 newlib() {
2189   local arch=$1
2190   setup-newlib-env ${arch}
2191   StepBanner "NEWLIB (${arch})"
2192
2193   if newlib-needs-configure; then
2194     newlib-clean
2195     newlib-configure ${arch}
2196   else
2197     SkipBanner "NEWLIB" "configure"
2198   fi
2199
2200   if newlib-needs-make; then
2201     newlib-make ${arch}
2202   else
2203     SkipBanner "NEWLIB" "make"
2204   fi
2205
2206   newlib-install ${arch}
2207 }
2208
2209 #+ newlib-clean  - Clean bitcode newlib.
2210 newlib-clean() {
2211   StepBanner "NEWLIB" "Clean"
2212   rm -rf "${TC_BUILD_NEWLIB}"
2213 }
2214
2215 newlib-needs-configure() {
2216   ts-newer-than "${TC_BUILD_LLVM}" \
2217                 "${TC_BUILD_NEWLIB}" && return 0
2218
2219   [ ! -f "${TC_BUILD_NEWLIB}/config.status" ]
2220   return #?
2221 }
2222
2223 #+ newlib-configure - Configure bitcode Newlib
2224 newlib-configure() {
2225   local arch=$1
2226   setup-newlib-env ${arch}
2227   StepBanner "NEWLIB" "Configure (${NEWLIB_TARGET})"
2228
2229   local srcdir="${TC_SRC_NEWLIB}"
2230   local objdir="${TC_BUILD_NEWLIB}"
2231   mkdir -p "${objdir}"
2232   spushd "${objdir}"
2233
2234   RunWithLog "newlib.${arch}.configure" \
2235     env -i \
2236     PATH="/usr/bin:/bin" \
2237     "${STD_ENV_FOR_NEWLIB[@]}" \
2238     ${srcdir}/configure \
2239         --disable-multilib \
2240         --prefix="${NEWLIB_INSTALL_DIR}" \
2241         --disable-newlib-supplied-syscalls \
2242         --disable-texinfo \
2243         --disable-libgloss \
2244         --enable-newlib-iconv \
2245         --enable-newlib-iconv-from-encodings=UTF-8,UTF-16LE,UCS-4LE,UTF-16,UCS-4 \
2246         --enable-newlib-iconv-to-encodings=UTF-8,UTF-16LE,UCS-4LE,UTF-16,UCS-4 \
2247         --enable-newlib-io-long-long \
2248         --enable-newlib-io-long-double \
2249         --enable-newlib-io-c99-formats \
2250         --enable-newlib-mb \
2251         --target="${NEWLIB_TARGET}"
2252
2253   spopd
2254 }
2255
2256 newlib-needs-make() {
2257   local srcdir="${TC_SRC_NEWLIB}"
2258   local objdir="${TC_BUILD_NEWLIB}"
2259
2260   ts-modified "$srcdir" "$objdir"
2261   return $?
2262 }
2263
2264 #+ newlib-make           - Make bitcode Newlib
2265 newlib-make() {
2266   local arch=$1
2267   setup-newlib-env ${arch}
2268   StepBanner "NEWLIB" "Make"
2269   local srcdir="${TC_SRC_NEWLIB}"
2270   local objdir="${TC_BUILD_NEWLIB}"
2271
2272   ts-touch-open "${objdir}"
2273
2274   spushd "${objdir}"
2275   RunWithLog "newlib.${arch}.make" \
2276     env -i PATH="/usr/bin:/bin" \
2277     make \
2278       "${STD_ENV_FOR_NEWLIB[@]}" \
2279       ${MAKE_OPTS}
2280   spopd
2281
2282   ts-touch-commit "${objdir}"
2283
2284 }
2285
2286 #+ newlib-install        - Install Bitcode Newlib using build env.
2287 newlib-install() {
2288   local arch=$1
2289   setup-newlib-env ${arch}
2290   StepBanner "NEWLIB" "Install"
2291   local objdir="${TC_BUILD_NEWLIB}"
2292
2293   spushd "${objdir}"
2294
2295   # NOTE: we might be better off not using install, as we are already
2296   #       doing a bunch of copying of headers and libs further down
2297   RunWithLog newlib.install \
2298     env -i PATH="/usr/bin:/bin" \
2299       make \
2300       "${STD_ENV_FOR_NEWLIB[@]}" \
2301       install ${MAKE_OPTS}
2302   spopd
2303
2304   # Newlib installs files into usr/${NEWLIB_TARGET}/*
2305   # Get rid of the ${NEWLIB_TARGET}/ prefix.
2306   spushd "${NEWLIB_INSTALL_DIR}"
2307   mkdir -p lib include
2308   mv -f ${NEWLIB_TARGET}/lib/* lib
2309   rm -rf  include/sys include/machine
2310   mv -f ${NEWLIB_TARGET}/include/* include
2311   rmdir ${NEWLIB_TARGET}/lib
2312   rmdir ${NEWLIB_TARGET}/include
2313   rmdir ${NEWLIB_TARGET}
2314
2315   cp "${NACL_ROOT}/src/untrusted/pthread/pthread.h" \
2316     "${NACL_ROOT}/src/untrusted/pthread/semaphore.h" \
2317     include
2318   # Copy the nacl_random.h header, which is needed by the libc++ build. It
2319   # uses the IRT so should be safe to include in the toolchain tarball.
2320   mkdir include/nacl
2321   cp "${NACL_ROOT}/src/untrusted/nacl/nacl_random.h" \
2322     include/nacl
2323   spopd
2324 }
2325
2326 libs-support() {
2327   StepBanner "LIBS-SUPPORT"
2328   libs-support-newlib-crt1 portable
2329   libs-support-newlib-crt1 x86-64
2330   libs-support-bitcode portable
2331   libs-support-bitcode x86-64
2332
2333   local arch
2334   for arch in arm x86-32 x86-64 mips32 arm-nonsfi x86-32-nonsfi; do
2335     libs-support-native ${arch}
2336   done
2337
2338   libs-support-unsandboxed
2339 }
2340
2341 libs-support-newlib-crt1() {
2342   local arch=$1
2343   setup-biased-bitcode-env ${arch}
2344   mkdir -p "${INSTALL_LIB}"
2345   spushd "${PNACL_SUPPORT}/bitcode"
2346
2347   StepBanner "LIBS-SUPPORT-NEWLIB" \
2348              "Install crt1.x & crt1_for_eh.x (linker scripts)"
2349   # Two versions of crt1.x exist, for different scenarios (with and without EH).
2350   # See: https://code.google.com/p/nativeclient/issues/detail?id=3069
2351   cp crt1.x "${INSTALL_LIB}"/crt1.x
2352   cp crt1_for_eh.x "${INSTALL_LIB}"/crt1_for_eh.x
2353   spopd
2354 }
2355
2356 libs-support-bitcode() {
2357   local arch=$1
2358   setup-biased-bitcode-env ${arch}
2359   local build_dir="${TC_BUILD}/libs-support-bitcode-${arch}"
2360   local cc_cmd="${PNACL_CC} -Wall -Werror -O2 ${BIASED_BC_CFLAGS}"
2361
2362   mkdir -p "${build_dir}"
2363   spushd "${PNACL_SUPPORT}/bitcode"
2364   # Install crti.bc (empty _init/_fini)
2365   StepBanner "LIBS-SUPPORT" "Install ${arch} crti.bc"
2366   ${cc_cmd} -c crti.c -o "${build_dir}"/crti.bc
2367
2368   # Install crtbegin bitcode (__cxa_finalize for C++)
2369   StepBanner "LIBS-SUPPORT" "Install ${arch} crtbegin.bc"
2370   # NOTE: we do not have an "end" version of ththis
2371   ${cc_cmd} -c crtbegin.c -o "${build_dir}"/crtbegin.bc
2372
2373   # Install unwind_stubs.bc (stubs for _Unwind_* functions when libgcc_eh
2374   # is not included in the native link).
2375   StepBanner "LIBS-SUPPORT" "Install ${arch} unwind_stubs.bc"
2376   ${cc_cmd} -c unwind_stubs.c -o "${build_dir}"/unwind_stubs.bc
2377   StepBanner "LIBS-SUPPORT" "Install ${arch} sjlj_eh_redirect.bc"
2378   ${cc_cmd} -c sjlj_eh_redirect.c -o "${build_dir}"/sjlj_eh_redirect.bc
2379
2380   # Install libpnaclmm.a (__atomic_*).
2381   StepBanner "LIBS-SUPPORT" "Install ${arch} libpnaclmm.a"
2382   ${cc_cmd} -c pnaclmm.c -o "${build_dir}"/pnaclmm.bc
2383   ${PNACL_AR} rc "${build_dir}"/libpnaclmm.a "${build_dir}"/pnaclmm.bc
2384
2385   spopd
2386
2387   # Install to actual lib directories.
2388   spushd "${build_dir}"
2389   local files="crti.bc crtbegin.bc libpnaclmm.a unwind_stubs.bc sjlj_eh_redirect.bc"
2390   mkdir -p "${INSTALL_LIB}"
2391   cp -f ${files} "${INSTALL_LIB}"
2392   spopd
2393 }
2394
2395 libs-support-native() {
2396   local arch=$1
2397   local destdir="${INSTALL_LIB_NATIVE}"${arch}
2398   local label="LIBS-SUPPORT (${arch})"
2399   mkdir -p "${destdir}"
2400
2401   local flags="--pnacl-allow-native --pnacl-allow-translate -Wall -Werror"
2402   local cc_cmd="${PNACL_CC} -arch ${arch} --pnacl-bias=${arch} ${flags} \
2403       -I../../.. -O3"
2404
2405   spushd "${PNACL_SUPPORT}"
2406
2407   # NOTE: one of the reasons why we build these native is
2408   #       the shim library on x86-64
2409   #       c.f.: https://sites.google.com/a/google.com/nativeclient/project-pnacl/c-exception-handling
2410   # Compile crtbegin.o / crtend.o
2411   StepBanner "${label}" "Install crtbegin.o / crtend.o"
2412
2413   # Build two versions of crtbegin: one that relies on later linking with
2414   # libgcc_eh and one that doesn't.
2415   # See: https://code.google.com/p/nativeclient/issues/detail?id=3069
2416   ${cc_cmd} -c crtbegin.c -o "${destdir}"/crtbegin.o
2417   ${cc_cmd} -c crtbegin.c -DLINKING_WITH_LIBGCC_EH \
2418             -o "${destdir}"/crtbegin_for_eh.o
2419   ${cc_cmd} -c crtend.c -o "${destdir}"/crtend.o
2420
2421   # Make libcrt_platform.a
2422   StepBanner "${label}" "Install libcrt_platform.a"
2423   local tmpdir="${TC_BUILD}/libs-support-native"
2424   rm -rf "${tmpdir}"
2425   mkdir -p "${tmpdir}"
2426   ${cc_cmd} -c pnacl_irt.c -o "${tmpdir}"/pnacl_irt.o
2427   ${cc_cmd} -c relocate.c -o "${tmpdir}"/relocate.o
2428
2429   local setjmp_arch="$arch"
2430   if [ "$setjmp_arch" = "x86-32-nonsfi" ]; then
2431     setjmp_arch=x86-32
2432   elif [ "$setjmp_arch" = "arm-nonsfi" ]; then
2433     setjmp_arch=arm
2434   fi
2435   ${cc_cmd} -c setjmp_${setjmp_arch/-/_}.S -o "${tmpdir}"/setjmp.o
2436
2437   # Some of the support code lives in third_party/ because it's based on code
2438   # from other open-source projects.
2439   ${cc_cmd} \
2440     -c "${NACL_SRC_THIRD_PARTY_MOD}/pnacl_native_newlib_subset/string.c" \
2441     -std=c99 -o "${tmpdir}"/string.o
2442   # Pull in the no-errno __ieee754_fmod from newlib and rename it to fmod.
2443   # This is to support the LLVM frem instruction.
2444   ${cc_cmd} \
2445     -c "${TC_SRC_NEWLIB}/newlib/libm/math/e_fmod.c" \
2446     -I"${TC_SRC_NEWLIB}/newlib/libm/common/" \
2447     -D__ieee754_fmod=fmod \
2448     -std=c99 -o "${tmpdir}"/e_fmod.o
2449   ${cc_cmd} \
2450     -c "${TC_SRC_NEWLIB}/newlib/libm/math/ef_fmod.c" \
2451     -I"${TC_SRC_NEWLIB}/newlib/libm/common/" \
2452     -D__ieee754_fmodf=fmodf \
2453     -std=c99 -o "${tmpdir}"/ef_mod.o
2454
2455   # For ARM, also compile aeabi_read_tp.S
2456   if  [ ${arch} == arm ] ; then
2457     ${cc_cmd} -c aeabi_read_tp.S -o "${tmpdir}"/aeabi_read_tp.o
2458   fi
2459   spopd
2460
2461   ${PNACL_AR} rc "${destdir}"/libcrt_platform.a "${tmpdir}"/*.o
2462 }
2463
2464 libs-support-unsandboxed() {
2465   if ${BUILD_PLATFORM_LINUX} || ${BUILD_PLATFORM_MAC}; then
2466     local arch="x86-32-${BUILD_PLATFORM}"
2467     StepBanner "LIBS-SUPPORT (${arch})" "Install unsandboxed_irt.o"
2468     local destdir="${INSTALL_LIB_NATIVE}"${arch}
2469     mkdir -p ${destdir}
2470     # The NaCl headers insist on having a platform macro such as
2471     # NACL_LINUX defined, but nonsfi/irt/irt_interfaces.c does not
2472     # itself use any of these macros, so defining NACL_LINUX here even
2473     # on non-Linux systems is OK.
2474     gcc -m32 -O2 -Wall -Werror -I${NACL_ROOT}/.. -c \
2475         -DNACL_LINUX=1 -DDEFINE_MAIN \
2476         ${NACL_ROOT}/src/nonsfi/irt/irt_interfaces.c \
2477         -o ${destdir}/unsandboxed_irt.o
2478   fi
2479 }
2480
2481
2482 # Build the dummy "libpnacl_irt_shim.a", which is useful for building
2483 # commandline programs.  It cannot be used to build PPAPI programs
2484 # because it does not actually shim the PPAPI interfaces.
2485 # The library is named the same as the real PPAPI shim to ensure that
2486 # the commandlines are the same.
2487 # This must be built after newlib(), since it uses headers like <stdint.h>.
2488 dummy-irt-shim() {
2489   local arch=$1
2490   local destdir="${INSTALL_LIB_NATIVE}"${arch}
2491   local label="DUMMY-IRT-SHIM (${arch})"
2492   mkdir -p "${destdir}"
2493
2494   local flags="--pnacl-allow-native --pnacl-allow-translate -Wall -Werror"
2495   local cc_cmd="${PNACL_CC} -arch ${arch} ${flags}"
2496
2497   spushd "${PNACL_SUPPORT}"
2498   StepBanner "${label}" "Install libpnacl_irt_shim_dummy.a"
2499   local tmpdir="${TC_BUILD}/dummy-irt-shim"
2500   rm -rf "${tmpdir}"
2501   mkdir -p "${tmpdir}"
2502   ${cc_cmd} -c dummy_shim_entry.c -o "${tmpdir}"/dummy_shim_entry.o
2503   spopd
2504
2505   ${PNACL_AR} rc "${destdir}"/libpnacl_irt_shim_dummy.a "${tmpdir}"/*.o
2506 }
2507
2508 #########################################################################
2509 #     < SDK >
2510 #########################################################################
2511 SCONS_ARGS=(MODE=nacl
2512             -j${PNACL_CONCURRENCY}
2513             bitcode=1
2514             disable_nosys_linker_warnings=1
2515             naclsdk_validate=0
2516             --verbose)
2517
2518 SDK_IS_SETUP=false
2519 sdk-setup() {
2520   if ${SDK_IS_SETUP} && [ $# -eq 0 ]; then
2521     return 0
2522   fi
2523   SDK_IS_SETUP=true
2524
2525   SDK_INSTALL_ROOT="${INSTALL_ROOT}/sdk"
2526   SDK_INSTALL_LIB="${SDK_INSTALL_ROOT}/lib"
2527   SDK_INSTALL_INCLUDE="${SDK_INSTALL_ROOT}/include"
2528 }
2529
2530 sdk() {
2531   sdk-setup "$@"
2532   StepBanner "SDK"
2533   sdk-clean
2534   sdk-headers
2535   sdk-libs
2536   sdk-verify
2537 }
2538
2539 #+ sdk-clean             - Clean sdk stuff
2540 sdk-clean() {
2541   sdk-setup "$@"
2542   StepBanner "SDK" "Clean"
2543   rm -rf "${SDK_INSTALL_ROOT}"
2544
2545   # clean scons obj dirs
2546   rm -rf "${SCONS_OUT}"/nacl-*-pnacl*
2547 }
2548
2549 sdk-headers() {
2550   sdk-setup "$@"
2551   mkdir -p "${SDK_INSTALL_INCLUDE}"
2552
2553   local extra_flags=""
2554   local neutral_platform="x86-32"
2555
2556   StepBanner "SDK" "Install headers"
2557   spushd "${NACL_ROOT}"
2558   RunWithLog "sdk.headers" \
2559       ./scons \
2560       "${SCONS_ARGS[@]}" \
2561       ${extra_flags} \
2562       platform=${neutral_platform} \
2563       pnacl_newlib_dir="${INSTALL_ROOT}" \
2564       install_headers \
2565       includedir="$(PosixToSysPath "${SDK_INSTALL_INCLUDE}")"
2566   spopd
2567 }
2568
2569 sdk-libs() {
2570   sdk-setup "$@"
2571   StepBanner "SDK" "Install libraries"
2572   mkdir -p "${SDK_INSTALL_LIB}"
2573
2574   local extra_flags=""
2575   local neutral_platform="x86-32"
2576
2577   spushd "${NACL_ROOT}"
2578   RunWithLog "sdk.libs.bitcode" \
2579       ./scons \
2580       "${SCONS_ARGS[@]}" \
2581       ${extra_flags} \
2582       platform=${neutral_platform} \
2583       pnacl_newlib_dir="${INSTALL_ROOT}" \
2584       install_lib \
2585       libdir="$(PosixToSysPath "${SDK_INSTALL_LIB}")"
2586   spopd
2587 }
2588
2589 # This builds lib*_private.a, to allow building the llc and ld nexes without
2590 # the IRT and without the segment gap.
2591 sdk-private-libs() {
2592   sdk-setup "$@"
2593   StepBanner "SDK" "Private (non-IRT) libs"
2594   spushd "${NACL_ROOT}"
2595
2596   local neutral_platform="x86-32"
2597   RunWithLog "sdk.libs_private.bitcode" \
2598     ./scons \
2599     -j${PNACL_CONCURRENCY} \
2600     bitcode=1 \
2601     platform=${neutral_platform} \
2602     pnacl_newlib_dir="${INSTALL_ROOT}" \
2603     --verbose \
2604     libnacl_sys_private \
2605     libpthread_private \
2606     libnacl_dyncode_private \
2607     libplatform \
2608     libimc \
2609     libimc_syscalls \
2610     libsrpc \
2611     libgio
2612
2613   local out_dir_prefix="${SCONS_OUT}"/nacl-x86-32-pnacl-pexe-clang
2614   local outdir="${out_dir_prefix}"/lib
2615   mkdir -p "${SDK_INSTALL_LIB}"
2616   cp "${outdir}"/lib*_private.a \
2617      "${outdir}"/lib{platform,imc,imc_syscalls,srpc,gio}.a "${SDK_INSTALL_LIB}"
2618   spopd
2619 }
2620
2621 sdk-verify() {
2622   sdk-setup "$@"
2623   StepBanner "SDK" "Verify"
2624
2625   # Verify bitcode libraries
2626   verify-bitcode-dir "${SDK_INSTALL_LIB}"
2627 }
2628
2629 newlib-nacl-headers-clean() {
2630   # Clean the include directory and revert it to its pure state
2631   if [ -d "${TC_SRC_NEWLIB}" ]; then
2632     rm -rf "${NEWLIB_INCLUDE_DIR}"
2633     # If the script is interrupted right here,
2634     # then NEWLIB_INCLUDE_DIR will not exist, and the repository
2635     # will be in a bad state. This will be fixed during the next
2636     # invocation by newlib-nacl-headers.
2637
2638     spushd "$(dirname "${NEWLIB_INCLUDE_DIR}")"
2639     RunWithLog "newlib-nacl-headers-clean" \
2640       ${GIT} checkout "$(basename "${NEWLIB_INCLUDE_DIR}")"
2641     spopd
2642   fi
2643 }
2644
2645 #+ newlib-nacl-headers   - Install NaCl headers to newlib
2646 newlib-nacl-headers() {
2647   StepBanner "newlib-nacl-headers" "Adding nacl headers to newlib"
2648
2649   assert-dir "${TC_SRC_NEWLIB}" "Newlib is not checked out"
2650
2651   # Make sure the headers directory has no local changes
2652   newlib-nacl-headers-check
2653   newlib-nacl-headers-clean
2654
2655   # Install the headers
2656   "${EXPORT_HEADER_SCRIPT}" \
2657       "${NACL_SYS_HEADERS}" \
2658       "${NEWLIB_INCLUDE_DIR}"
2659
2660   # Record the header install time
2661   ts-touch "${NACL_HEADERS_TS}"
2662 }
2663
2664 #+ newlib-nacl-headers-check - Make sure the newlib nacl headers haven't
2665 #+                             been modified since the last install.
2666 newlib-nacl-headers-check() {
2667   # The condition where NEWLIB_INCLUDE_DIR does not exist may have been
2668   # caused by an incomplete call to newlib-nacl-headers-clean().
2669   # Let it pass this check so that the clean will be able to finish.
2670   # See the comment in newlib-nacl-headers-clean()
2671   if ! [ -d "${TC_SRC_NEWLIB}" ] ||
2672      ! [ -d "${NEWLIB_INCLUDE_DIR}" ]; then
2673     return 0
2674   fi
2675
2676   # Already clean?
2677   if ! git-has-changes "${NEWLIB_INCLUDE_DIR}" ; then
2678     return 0
2679   fi
2680
2681   if ts-dir-changed "${NACL_HEADERS_TS}" "${NEWLIB_INCLUDE_DIR}"; then
2682     echo ""
2683     echo "*******************************************************************"
2684     echo "*                            ERROR                                *"
2685     echo "*      The NewLib include directory has local modifications       *"
2686     echo "*******************************************************************"
2687     echo "* The NewLib include directory should not be modified directly.   *"
2688     echo "* Instead, modifications should be done from:                     *"
2689     echo "*   src/trusted/service_runtime/include                           *"
2690     echo "*                                                                 *"
2691     echo "* To destroy the local changes to newlib, run:                    *"
2692     echo "*  pnacl/build.sh newlib-nacl-headers-clean                       *"
2693     echo "*******************************************************************"
2694     echo ""
2695     if ${PNACL_BUILDBOT} ; then
2696       newlib-nacl-headers-clean
2697     else
2698       exit -1
2699     fi
2700   fi
2701 }
2702
2703
2704 #+-------------------------------------------------------------------------
2705 #@ driver                - Install driver scripts.
2706 driver() {
2707   StepBanner "DRIVER"
2708   driver-install
2709 }
2710
2711 # install python scripts and redirector shell/batch scripts
2712 driver-install-python() {
2713   local destdir="$1"
2714   shift
2715   local pydir="${destdir}/pydir"
2716
2717   StepBanner "DRIVER" "Installing driver adaptors to ${destdir}"
2718   rm -rf "${destdir}"
2719   mkdir -p "${destdir}"
2720   mkdir -p "${pydir}"
2721
2722   spushd "${DRIVER_DIR}"
2723
2724   # Copy python scripts
2725   cp $@ driver_log.py driver_env.py driver_temps.py \
2726     *tools.py filetype.py loader.py "${pydir}"
2727
2728   # Install redirector shell/batch scripts
2729   for name in $@; do
2730     local dest="${destdir}/${name/.py}"
2731     # In some situations cygwin cp messes up the permissions of the redirector
2732     # shell/batch scripts. Using cp -a seems to make sure it preserves them.
2733     cp -a redirect.sh "${dest}"
2734     chmod +x "${dest}"
2735     if ${BUILD_PLATFORM_WIN}; then
2736       cp -a redirect.bat "${dest}".bat
2737     fi
2738   done
2739   spopd
2740 }
2741
2742 feature-version-file-install() {
2743   # Scons tests can check this version number to decide whether to
2744   # enable tests for toolchain bug fixes or new features.  This allows
2745   # tests to be enabled on the toolchain buildbots/trybots before the
2746   # new toolchain version is rolled into TOOL_REVISIONS (i.e. before
2747   # the tests would pass on the main NaCl buildbots/trybots).
2748   #
2749   # If you are adding a test that depends on a toolchain change, you
2750   # can increment this version number manually.
2751   echo 5 > "${INSTALL_ROOT}/FEATURE_VERSION"
2752 }
2753
2754 # The driver is a simple python script which changes its behavior
2755 # depending on the name it is invoked as.
2756 driver-install() {
2757   local bindir=bin
2758   # On Linux we ship a fat toolchain with 2 sets of binaries defaulting to
2759   # x86-32 (mostly because of the 32 bit chrome bots). So the default
2760   # bin dir is 32, and the bin64 driver runs the 64 bit binaries
2761   if ${HOST_ARCH_X8664} && ${BUILD_PLATFORM_LINUX}; then
2762     bindir="bin64"
2763     # We want to be able to locally test a toolchain on 64 bit hosts without
2764     # building it twice and without extra env vars. So if a 32 bit toolchain
2765     # has not already been built, just symlink the bin dirs together.
2766     if [[ ! -d "${INSTALL_BIN}" ]]; then
2767       mkdir -p "${INSTALL_ROOT}"
2768       ln -s ${bindir} "${INSTALL_BIN}"
2769     fi
2770   fi
2771
2772   # This directory (the ${INSTALL_ROOT}/${bindir} part)
2773   # should be kept in sync with INSTALL_BIN et al.
2774   local destdir="${INSTALL_ROOT}/${bindir}"
2775
2776   driver-install-python "${destdir}" "pnacl-*.py"
2777
2778   # Tell the driver the library mode and host arch
2779   echo """HAS_FRONTEND=1
2780 HOST_ARCH=${HOST_ARCH}""" > "${destdir}"/driver.conf
2781
2782   # On windows, copy the cygwin DLLs needed by the driver tools
2783   if ${BUILD_PLATFORM_WIN}; then
2784     StepBanner "DRIVER" "Copying cygwin libraries"
2785     local deps="gcc_s-1 iconv-2 win1 intl-8 stdc++-6 z"
2786     for name in ${deps}; do
2787       cp "/bin/cyg${name}.dll" "${destdir}"
2788     done
2789   fi
2790
2791   # Install a REV file so that "pnacl-clang --version" knows the version
2792   # of the drivers themselves.
2793   DumpAllRevisions > "${destdir}/REV"
2794
2795   feature-version-file-install
2796 }
2797
2798 #@ driver-install-translator - Install driver scripts for translator component
2799 driver-install-translator() {
2800   local destdir="${INSTALL_TRANSLATOR}/bin"
2801
2802   driver-install-python "${destdir}" pnacl-translate.py pnacl-nativeld.py
2803
2804   echo """HAS_FRONTEND=0""" > "${destdir}"/driver.conf
2805 }
2806
2807 ######################################################################
2808 ######################################################################
2809 #
2810 #                           HELPER FUNCTIONS
2811 #
2812 #             (These should not generally be used directly)
2813 #
2814 ######################################################################
2815 ######################################################################
2816
2817 DumpAllRevisions() {
2818   one-line-rev-info ${NACL_ROOT}
2819   for d in ${PNACL_GIT_ROOT}/*/ ; do
2820     one-line-rev-info $d
2821   done
2822 }
2823
2824 ######################################################################
2825 ######################################################################
2826 #     < VERIFY >
2827 ######################################################################
2828 ######################################################################
2829
2830 # Note: we could replace this with a modified version of tools/elf_checker.py
2831 #       if we do not want to depend on binutils
2832 readonly NACL_OBJDUMP=${BINUTILS_INSTALL_DIR}/bin/${REAL_CROSS_TARGET}-objdump
2833
2834 # Usage: VerifyArchive <checker> <pattern> <filename>
2835 ExtractAndCheck() {
2836   local checker="$1"
2837   local pattern="$2"
2838   local archive="$3"
2839   local tmp="/tmp/ar-verify-${RANDOM}"
2840   rm -rf ${tmp}
2841   mkdir -p ${tmp}
2842   cp "${archive}" "${tmp}"
2843   spushd ${tmp}
2844   ${PNACL_AR} x $(basename ${archive})
2845   # extract all the files
2846   local count=0
2847   for i in ${pattern} ; do
2848     if [ ! -e "$i" ]; then
2849       # we may also see the unexpanded pattern here if there is no match
2850       continue
2851     fi
2852     count=$((count+1))
2853     ${checker} $i
2854   done
2855   echo "PASS  (${count} files)"
2856   rm -rf "${tmp}"
2857   spopd
2858 }
2859
2860 IsLinkerScript() {
2861   local fname="$1"
2862   local type="$(file --brief --mime-type "${fname}")"
2863   case "$type" in
2864     text/x-c)
2865       # A linker script with C comments looks like C to "file".
2866       return 0
2867       ;;
2868     text/plain)
2869       return 0
2870       ;;
2871   esac
2872   return 1
2873 }
2874
2875 # Usage: VerifyLinkerScript <filename>
2876 VerifyLinkerScript() {
2877   local archive="$1"
2878   # Use preprocessor to strip the C-style comments.
2879   ${PNACL_PP} -xc "${archive}" | awk -v archive="$(basename ${archive})" '
2880     BEGIN { status = 0 }
2881     NF == 0 || $1 == "#" { next }
2882     $1 == "INPUT" && $2 == "(" && $NF == ")" { next }
2883     {
2884       print "FAIL - unexpected linker script(?) contents:", archive
2885       status = 1
2886       exit(status)
2887     }
2888     END { if (status == 0) print "PASS  (trivial linker script)" }
2889 ' || exit -1
2890 }
2891
2892 # Usage: VerifyArchive <checker> <pattern> <filename>
2893 VerifyArchive() {
2894   local checker="$1"
2895   local pattern="$2"
2896   local archive="$3"
2897   echo -n "verify $(basename "${archive}"): "
2898   if IsLinkerScript "${archive}"; then
2899     VerifyLinkerScript "${archive}"
2900   else
2901     ExtractAndCheck "$checker" "$pattern" "$archive"
2902   fi
2903 }
2904
2905 #
2906 # verify-object-llvm <obj>
2907 #
2908 #   Verifies that a given .o file is bitcode and free of ASMSs
2909 verify-object-llvm() {
2910   if ${PNACL_DIS} "$1" -o - | grep asm ; then
2911     echo
2912     echo "ERROR asm in $1"
2913     echo
2914     exit -1
2915   fi
2916   if [ ${PIPESTATUS[0]} -ne 0 ]; then
2917     exit -1
2918   fi
2919 }
2920
2921
2922 check-elf-abi() {
2923   # Temporarily disable ELF abi check until DEPS roll
2924   return 0
2925
2926   local arch_info="$(${NACL_OBJDUMP} -f $1)"
2927   if ! grep -q $2 <<< ${arch_info} ; then
2928     echo "ERROR $1 - bad file format: $2 vs ${arch_info}\n"
2929     echo ${arch_info}
2930     exit -1
2931   fi
2932 }
2933
2934
2935 # verify-object-arm <obj>
2936 #
2937 #   Ensure that the ARCH properties are what we expect, this is a little
2938 #   fragile and needs to be updated when tools change
2939 verify-object-arm() {
2940   check-elf-abi $1 "elf32-littlearm"
2941   # llvm-mc does not automatically insert these tags (unlike gnu-as).
2942   # So we exclude llvm-mc generated object files for now
2943   if [[ $1 == aeabi_read_tp.o || $1 == setjmp.o ]] ; then
2944     return
2945   fi
2946   arch_info="$("${PNACL_READELF}" -A "$1")"
2947   #TODO(robertm): some refactoring and cleanup needed
2948   if ! grep -q "Tag_FP_arch: VFPv3" <<< ${arch_info} ; then
2949     echo "ERROR $1 - bad Tag_FP_arch"
2950     #TODO(robertm): figure out what the right thing to do is here, c.f.
2951     # http://code.google.com/p/nativeclient/issues/detail?id=966
2952     "${PNACL_READELF}" -A $1 | grep  Tag_FP_arch
2953     exit -1
2954   fi
2955
2956   if ! grep -q "Tag_CPU_arch: v7" <<< ${arch_info} ; then
2957     echo "FAIL bad $1 Tag_CPU_arch"
2958     "${PNACL_READELF}" -A $1 | grep Tag_CPU_arch
2959     exit -1
2960   fi
2961
2962   if ! grep -q "Tag_Advanced_SIMD_arch: NEONv1" <<< ${arch_info} ; then
2963     echo "FAIL bad $1 Tag_Advanced_SIMD_arch"
2964     "${PNACL_READELF}" -A $1 | grep Tag_Advanced_SIMD_arch
2965   fi
2966
2967   # Check that the file uses the ARM hard-float ABI (where VFP
2968   # registers D0-D7 (s0-s15) are used to pass arguments and results).
2969   if ! grep -q "Tag_ABI_VFP_args: VFP registers" <<< ${arch_info} ; then
2970     echo "FAIL bad $1 Tag_ABI_VFP_args"
2971     "${PNACL_READELF}" -A $1 | grep Tag_ABI_VFP_args
2972   fi
2973 }
2974
2975
2976 # verify-object-x86-32 <obj>
2977 #
2978 verify-object-x86-32() {
2979   check-elf-abi $1 "elf32-i386"
2980 }
2981
2982 # verify-object-x86-64 <obj>
2983 #
2984 verify-object-x86-64() {
2985   check-elf-abi $1 "elf64-x86-64"
2986 }
2987
2988 #+ verify-bitcode-dir    - Verify that the files in a directory are bitcode.
2989 verify-bitcode-dir() {
2990   local dir="$1"
2991   # This avoids errors when * finds no matches.
2992   shopt -s nullglob
2993   SubBanner "VERIFY: ${dir}"
2994   for i in "${dir}"/*.a ; do
2995     verify-archive-llvm "$i"
2996   done
2997   for i in "${dir}"/*.bc ; do
2998     echo -n "verify $(basename "$i"): "
2999     verify-object-llvm "$i"
3000     echo "PASS (bitcode)"
3001   done
3002   for i in "${dir}"/*.o ; do
3003     Fatal "Native object file $i inside bitcode directory"
3004   done
3005   shopt -u nullglob
3006 }
3007
3008
3009 #+ verify-native-dir     - Verify that files in a directory are native for arch.
3010 verify-native-dir() {
3011   local arch="$1"
3012   local dir="$2"
3013
3014   SubBanner "VERIFY: ${dir}"
3015
3016   # This avoids errors when * finds no matches.
3017   shopt -s nullglob
3018   for i in "${dir}"/*.o ; do
3019     verify-object-${arch} "$i"
3020   done
3021
3022   for i in "${dir}"/*.a ; do
3023     verify-archive-${arch} "$i"
3024   done
3025
3026   for i in "${dir}"/*.bc "${dir}"/*.pso ; do
3027     Fatal "Bitcode file $i found inside native directory"
3028   done
3029   shopt -u nullglob
3030 }
3031
3032 #
3033 # verify-archive-llvm <archive>
3034 # Verifies that a given archive is bitcode and free of ASMSs
3035 #
3036 verify-archive-llvm() {
3037   # Currently all the files are .o in the llvm archives.
3038   # Eventually more and more should be .bc.
3039   VerifyArchive verify-object-llvm '*.bc *.o' "$@"
3040 }
3041
3042 #
3043 # verify-archive-arm <archive>
3044 # Verifies that a given archive is a proper arm achive
3045 #
3046 verify-archive-arm() {
3047   VerifyArchive verify-object-arm '*.o *.ons' "$@"
3048 }
3049
3050 #
3051 # verify-archive-x86-32 <archive>
3052 # Verifies that a given archive is a proper x86-32 achive
3053 #
3054 verify-archive-x86-32() {
3055   VerifyArchive verify-object-x86-32 '*.o *.ons' "$@"
3056 }
3057
3058 #
3059 # verify-archive-x86-64 <archive>
3060 # Verifies that a given archive is a proper x86-64 achive
3061 #
3062 verify-archive-x86-64() {
3063   VerifyArchive verify-object-x86-64 '*.o *.ons' "$@"
3064 }
3065
3066 #@-------------------------------------------------------------------------
3067 #+ verify                - Verifies that the pnacl-untrusted ELF files
3068 #+                         are of the correct architecture.
3069 verify() {
3070   StepBanner "VERIFY"
3071   verify-bitcode
3072   verify-native
3073 }
3074
3075 verify-bitcode() {
3076   verify-bitcode-dir "${INSTALL_LIB}"
3077 }
3078
3079 verify-native() {
3080   local arch
3081   for arch in arm x86-32 x86-64; do
3082     verify-native-dir ${arch} "${INSTALL_LIB_NATIVE}${arch}"
3083   done
3084 }
3085
3086 #+ verify-triple-build <arch>
3087 #+     Verify that the sandboxed translator produces an identical
3088 #+     translation of itself (pnacl-llc.pexe) as the unsandboxed translator.
3089 #+     (NOTE: This function is experimental/untested)
3090 verify-triple-build() {
3091   local arch=$1
3092   StepBanner "VERIFY" "Verifying triple build for ${arch}"
3093
3094   local bindir="$(GetTranslatorInstallDir ${arch})/bin"
3095   local llc_nexe="${bindir}/pnacl-llc.nexe"
3096   local llc_pexe="${bindir}/pnacl-llc.pexe"
3097   assert-file "${llc_nexe}" "sandboxed llc for ${arch} does not exist"
3098   assert-file "${llc_pexe}" "pnacl-llc.pexe does not exist"
3099
3100   local flags="--pnacl-sb --pnacl-driver-verbose"
3101
3102   if [ ${arch} == "arm" ] ; then
3103     # Use emulator if we are not on ARM
3104     local hostarch=$(uname -m)
3105     if ! [[ "${BUILD_ARCH}" =~ arm ]]; then
3106       flags+=" --pnacl-use-emulator"
3107     fi
3108   fi
3109
3110   local triple_install_dir="$(GetTranslatorInstallDir ${arch})/triple-build"
3111   mkdir -p ${triple_install_dir}
3112   local new_llc_nexe="${triple_install_dir}/pnacl-llc.rebuild.nexe"
3113   mkdir -p "${triple_install_dir}"
3114   StepBanner "VERIFY" "Translating ${llc_pexe} using sandboxed tools (${arch})"
3115   local sb_translator="${INSTALL_TRANSLATOR}/bin/pnacl-translate"
3116   RunWithLog "verify.triple.build" \
3117     "${sb_translator}" ${flags} -arch ${arch} "${llc_pexe}" -o "${new_llc_nexe}"
3118
3119   if ! cmp --silent "${llc_nexe}" "${new_llc_nexe}" ; then
3120     Banner "TRIPLE BUILD VERIFY FAILED"
3121     echo "Expected these files to be identical, but they are not:"
3122     echo "  ${archllc}"
3123     echo "  ${newllc}"
3124     exit -1
3125   fi
3126   StepBanner "VERIFY" "Verified ${arch} OK"
3127 }
3128
3129 ######################################################################
3130 ######################################################################
3131 #
3132 # UTILITIES
3133 #
3134 ######################################################################
3135 ######################################################################
3136
3137 #@-------------------------------------------------------------------------
3138 #@ show-config
3139 show-config() {
3140   Banner "Config Settings:"
3141   echo "PNACL_BUILDBOT:    ${PNACL_BUILDBOT}"
3142   echo "PNACL_CONCURRENCY: ${PNACL_CONCURRENCY}"
3143   echo "PNACL_DEBUG:       ${PNACL_DEBUG}"
3144   echo "PNACL_PRUNE:       ${PNACL_PRUNE}"
3145   echo "PNACL_VERBOSE:     ${PNACL_VERBOSE}"
3146   echo "INSTALL_ROOT:      ${INSTALL_ROOT}"
3147   Banner "Your Environment:"
3148   env | grep PNACL
3149   Banner "uname info for builder:"
3150   uname -a
3151 }
3152
3153 #@ help                  - Usage information.
3154 help() {
3155   Usage
3156 }
3157
3158 #@ help-full             - Usage information including internal functions.
3159 help-full() {
3160   Usage2
3161 }
3162
3163 has-trusted-toolchain() {
3164   if [ -f ${TOOLCHAIN_BASE}/arm_trusted/ld_script_arm_trusted ]; then
3165     return 0
3166   else
3167     return 1
3168   fi
3169 }
3170
3171 check-for-trusted() {
3172   if ! ${PNACL_BUILD_ARM} ; then
3173     return
3174   fi
3175
3176   if ! has-trusted-toolchain; then
3177     echo '*******************************************************************'
3178     echo '*   The ARM trusted toolchain does not appear to be installed yet *'
3179     echo '*   It is needed to run ARM tests.                                *'
3180     echo '*                                                                 *'
3181     echo '*   To download and install the trusted toolchain, run:           *'
3182     echo '*                                                                 *'
3183     echo '*       $ pnacl/build.sh download-trusted                         *'
3184     echo '*                                                                 *'
3185     echo '*   To compile the trusted toolchain, use:                        *'
3186     echo '*                                                                 *'
3187     echo '*       $ tools/llvm/trusted-toolchain-creator.sh trusted_sdk     *'
3188     echo '*               (warning: this takes a while)                     *'
3189     echo '*******************************************************************'
3190
3191     # If building on the bots, do not continue since it needs to run ARM tests.
3192     if ${PNACL_BUILDBOT} ; then
3193       echo "Building on bots --> need ARM trusted toolchain to run tests!"
3194       exit -1
3195     elif trusted-tc-confirm ; then
3196       echo "Continuing without ARM trusted toolchain"
3197       PNACL_BUILD_ARM=false
3198     else
3199       echo "Okay, stopping."
3200       exit -1
3201     fi
3202   fi
3203 }
3204
3205 trusted-tc-confirm() {
3206   echo
3207   echo "Do you wish to continue without the ARM trusted TC (skip ARM testing)?"
3208   echo ""
3209   confirm-yes "Continue"
3210   return $?
3211 }
3212
3213 DebugRun() {
3214   if ${PNACL_DEBUG} || ${PNACL_BUILDBOT}; then
3215     "$@"
3216   fi
3217 }
3218
3219 ######################################################################
3220 # Generate chromium perf bot logs for tracking the size of a binary.
3221 #
3222 print-tagged-tool-sizes() {
3223   local tag="$1"
3224   local binary="$2"
3225
3226   # size output look like:
3227   #    text   data     bss     dec    hex  filename
3228   #  354421  16132  168920  539473  83b51  .../tool
3229   local sizes=($(${PNACL_SIZE} -B "${binary}" | grep '[0-9]\+'))
3230   echo "RESULT ${tag}: text= ${sizes[0]} bytes"
3231   echo "RESULT ${tag}: data= ${sizes[1]} bytes"
3232   echo "RESULT ${tag}: bss= ${sizes[2]} bytes"
3233   echo "RESULT ${tag}: total= ${sizes[3]} bytes"
3234 }
3235
3236 ######################################################################
3237 ######################################################################
3238 #
3239 #                           < TIME STAMPING >
3240 #
3241 ######################################################################
3242 ######################################################################
3243
3244 ts-dir-changed() {
3245   local tsfile="$1"
3246   local dir="$2"
3247
3248   if [ -f "${tsfile}" ]; then
3249     local MODIFIED=$(find "${dir}" -type f -newer "${tsfile}")
3250     [ ${#MODIFIED} -gt 0 ]
3251     ret=$?
3252   else
3253     true
3254     ret=$?
3255   fi
3256   return $ret
3257 }
3258
3259 # Check if the source for a given build has been modified
3260 ts-modified() {
3261   local srcdir="$1"
3262   local objdir="$2"
3263   local tsfile="${objdir}/${TIMESTAMP_FILENAME}"
3264
3265   ts-dir-changed "${tsfile}" "${srcdir}"
3266   return $?
3267 }
3268
3269 ts-touch() {
3270   local tsfile="$1"
3271   touch "${tsfile}"
3272 }
3273
3274 # Record the time when make begins, but don't yet
3275 # write that to the timestamp file.
3276 # (Just in case make fails)
3277
3278 ts-touch-open() {
3279   local objdir="$1"
3280   local tsfile="${objdir}/${TIMESTAMP_FILENAME}"
3281   local tsfile_open="${objdir}/${TIMESTAMP_FILENAME}_OPEN"
3282
3283   rm -f "${tsfile}"
3284   touch "${tsfile_open}"
3285 }
3286
3287
3288 # Write the timestamp. (i.e. make has succeeded)
3289
3290 ts-touch-commit() {
3291   local objdir="$1"
3292   local tsfile="${objdir}/${TIMESTAMP_FILENAME}"
3293   local tsfile_open="${objdir}/${TIMESTAMP_FILENAME}_OPEN"
3294
3295   mv -f "${tsfile_open}" "${tsfile}"
3296 }
3297
3298
3299 # ts-newer-than dirA dirB
3300 # Compare the make timestamps in both object directories.
3301 # returns true (0) if dirA is newer than dirB
3302 # returns false (1) otherwise.
3303 #
3304 # This functions errs on the side of returning 0, since
3305 # that forces a rebuild anyway.
3306
3307 ts-newer-than() {
3308   local objdir1="$1"
3309   local objdir2="$2"
3310
3311   local tsfile1="${objdir1}/${TIMESTAMP_FILENAME}"
3312   local tsfile2="${objdir2}/${TIMESTAMP_FILENAME}"
3313
3314   if [ ! -d "${objdir1}" ]; then return 0; fi
3315   if [ ! -d "${objdir2}" ]; then return 0; fi
3316
3317   if [ ! -f "${tsfile1}" ]; then return 0; fi
3318   if [ ! -f "${tsfile2}" ]; then return 0; fi
3319
3320   local MODIFIED=$(find "${tsfile1}" -newer "${tsfile2}")
3321   if [ ${#MODIFIED} -gt 0 ]; then
3322     return 0
3323   fi
3324   return 1
3325 }
3326
3327
3328 # Don't define any functions after this or they won't show up in completions
3329 function-completions() {
3330   if [ $# = 0 ]; then set -- ""; fi
3331   compgen -A function -- $1
3332   exit 0
3333 }
3334
3335 ######################################################################
3336 ######################################################################
3337 #
3338 #                               < MAIN >
3339 #
3340 ######################################################################
3341 ######################################################################
3342
3343 mkdir -p "${INSTALL_ROOT}"
3344
3345 if [ $# = 0 ]; then set -- help; fi  # Avoid reference to undefined $1.
3346
3347 # Accept one -- argument for some compatibility with google3
3348 if [ $1 = "--tab_completion_word" ]; then
3349   set -- function-completions $2
3350 fi
3351
3352 if [ "$(type -t $1)" != "function" ]; then
3353   #Usage
3354   echo "ERROR: unknown function '$1'." >&2
3355   echo "For help, try:"
3356   echo "    $0 help"
3357   exit 1
3358 fi
3359
3360 "$@"