Upstream version 9.38.198.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="${NACL_ROOT}/src/third_party"
97
98 # Git sources
99 readonly PNACL_GIT_ROOT="${NACL_ROOT}/toolchain_build/src"
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}/pnacl-gcc"
103 readonly TC_SRC_NEWLIB="${PNACL_GIT_ROOT}/pnacl-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     mkdir -p ${BINUTILS_INSTALL_DIR}/${SO_DIR}
1641     for lib in ${BINUTILS_INSTALL_DIR}/*/${BINUTILS_TARGET}/lib/lib*${SO_EXT}
1642     do
1643       echo "moving ${lib}"
1644       mv ${lib} ${BINUTILS_INSTALL_DIR}/${SO_DIR}
1645     done
1646   fi
1647
1648   # NOTE: this needs to come AFTER the moving of the shared libs
1649   # TODO(robertm): this needs to be augmented for mac and windows
1650   echo "remove unused (remaining) binutils static libs and headers"
1651   rm -rf "${BINUTILS_INSTALL_DIR}/i686-pc-linux-gnu" \
1652          "${BINUTILS_INSTALL_DIR}/x86_64-unknown-linux-gnu"
1653
1654   spopd
1655 }
1656
1657 #+-------------------------------------------------------------------------
1658 #+ binutils-liberty      - Build native binutils libiberty
1659 binutils-liberty() {
1660   local srcdir="${TC_SRC_BINUTILS}"
1661
1662   assert-dir "${srcdir}" "You need to checkout binutils."
1663
1664   if binutils-liberty-needs-configure; then
1665     binutils-liberty-clean
1666     binutils-liberty-configure
1667   else
1668     SkipBanner "BINUTILS-LIBERTY" "configure"
1669   fi
1670
1671   if binutils-liberty-needs-make; then
1672     binutils-liberty-make
1673   else
1674     SkipBanner "BINUTILS-LIBERTY" "make"
1675   fi
1676 }
1677
1678 binutils-liberty-needs-configure() {
1679   [ ! -f "${TC_BUILD_BINUTILS_LIBERTY}/config.status" ]
1680   return $?
1681 }
1682
1683 #+ binutils-liberty-clean    - Clean binutils-liberty
1684 binutils-liberty-clean() {
1685   StepBanner "BINUTILS-LIBERTY" "Clean"
1686   local objdir="${TC_BUILD_BINUTILS_LIBERTY}"
1687   rm -rf ${objdir}
1688 }
1689
1690 #+ binutils-liberty-configure - Configure binutils-liberty
1691 binutils-liberty-configure() {
1692   StepBanner "BINUTILS-LIBERTY" "Configure"
1693
1694   local srcdir="${TC_SRC_BINUTILS}"
1695   local objdir="${TC_BUILD_BINUTILS_LIBERTY}"
1696
1697   mkdir -p "${objdir}"
1698   spushd "${objdir}"
1699   RunWithLog binutils.liberty.configure \
1700       env -i \
1701       PATH="${PATH}" \
1702       CC="${CC}" \
1703       CXX="${CXX}" \
1704       ${srcdir}/configure
1705   spopd
1706 }
1707
1708 binutils-liberty-needs-make() {
1709   local srcdir="${TC_SRC_BINUTILS}"
1710   local objdir="${TC_BUILD_BINUTILS_LIBERTY}"
1711
1712   ts-modified "$srcdir" "$objdir"
1713   return $?
1714 }
1715
1716 #+ binutils-liberty-make - Make binutils-liberty
1717 binutils-liberty-make() {
1718   StepBanner "BINUTILS-LIBERTY" "Make"
1719   local srcdir="${TC_SRC_BINUTILS}"
1720   local objdir="${TC_BUILD_BINUTILS_LIBERTY}"
1721   spushd "${objdir}"
1722
1723   ts-touch-open "${objdir}"
1724
1725   RunWithLog binutils.liberty.make \
1726       env -i \
1727       PATH="${PATH}" \
1728       CC="${CC}" \
1729       CXX="${CXX}" \
1730       make ${MAKE_OPTS_HOST} all-libiberty
1731
1732   ts-touch-commit "${objdir}"
1733
1734   spopd
1735 }
1736
1737 #########################################################################
1738 #     CLIENT BINARIES (SANDBOXED)
1739 #########################################################################
1740
1741 check-arch() {
1742   local arch=$1
1743   for valid_arch in i686 x86_64 armv7 universal ; do
1744     if [ "${arch}" == "${valid_arch}" ] ; then
1745       return
1746     fi
1747   done
1748
1749   Fatal "ERROR: Unsupported arch [$1]. Must be: i686, x86_64, armv7, universal"
1750 }
1751
1752 llvm-sb-setup() {
1753   local arch=$1
1754   LLVM_SB_LOG_PREFIX="llvm.sb.${arch}"
1755   LLVM_SB_OBJDIR="$(GetTranslatorBuildDir ${arch})/llvm-sb"
1756
1757   # The SRPC headers are included directly from the nacl tree, as they are
1758   # not in the SDK. libsrpc should have already been built by the
1759   # build.sh sdk-private-libs step.
1760   # This is always statically linked.
1761   # The LLVM sandboxed build uses the normally-disallowed external
1762   # function __nacl_get_arch().  Allow that for now.
1763   local flags="-static -I$(GetAbsolutePath ${NACL_ROOT}/..) \
1764     --pnacl-disable-abi-check "
1765
1766   LLVM_SB_CONFIGURE_ENV=(
1767     AR="${PNACL_AR}" \
1768     AS="${PNACL_AS}" \
1769     CC="${PNACL_CC} ${flags}" \
1770     CXX="${PNACL_CXX} ${flags}" \
1771     LD="${PNACL_LD} ${flags}" \
1772     NM="${PNACL_NM}" \
1773     RANLIB="${PNACL_RANLIB}")
1774 }
1775
1776 #+-------------------------------------------------------------------------
1777 #+ llvm-sb <arch>- Build and install llvm tools (sandboxed)
1778 llvm-sb() {
1779   local arch=$1
1780   check-arch ${arch}
1781   llvm-sb-setup ${arch}
1782   StepBanner "LLVM-SB" "Sandboxed pnacl-llc [${arch}]"
1783   local srcdir="${TC_SRC_LLVM}"
1784   assert-dir "${srcdir}" "You need to checkout llvm."
1785
1786   if llvm-sb-needs-configure ${arch} ; then
1787     llvm-sb-clean ${arch}
1788     llvm-sb-configure ${arch}
1789   else
1790     SkipBanner "LLVM-SB" "configure ${arch}"
1791   fi
1792
1793   llvm-sb-make ${arch}
1794   llvm-sb-install ${arch}
1795 }
1796
1797 llvm-sb-needs-configure() {
1798   [ ! -f "${LLVM_SB_OBJDIR}/config.status" ]
1799   return $?
1800 }
1801
1802 # llvm-sb-clean          - Clean llvm tools (sandboxed)
1803 llvm-sb-clean() {
1804   local arch=$1
1805   StepBanner "LLVM-SB" "Clean ${arch}"
1806   local objdir="${LLVM_SB_OBJDIR}"
1807
1808   rm -rf "${objdir}"
1809   mkdir -p "${objdir}"
1810 }
1811
1812 # llvm-sb-configure - Configure llvm tools (sandboxed)
1813 llvm-sb-configure() {
1814   local arch=$1
1815
1816   StepBanner "LLVM-SB" "Configure ${arch}"
1817   local srcdir="${TC_SRC_LLVM}"
1818   local objdir="${LLVM_SB_OBJDIR}"
1819   local installdir="$(GetTranslatorInstallDir ${arch})"
1820   local targets=""
1821   # For LLVM, "x86" brings in both i686 and x86_64.
1822   case ${arch} in
1823     i686) targets=x86 ;;
1824     x86_64) targets=x86 ;;
1825     armv7) targets=arm ;;
1826     universal) targets=x86,arm ;;
1827   esac
1828
1829   spushd "${objdir}"
1830   # TODO(jvoung): remove ac_cv_func_getrusage=no once newlib has getrusage
1831   # in its headers.  Otherwise, configure thinks that we can link in
1832   # getrusage (stub is in libnacl), but we can't actually compile code
1833   # that uses ::getrusage because it's not in headers:
1834   # https://code.google.com/p/nativeclient/issues/detail?id=3657
1835   RunWithLog \
1836       ${LLVM_SB_LOG_PREFIX}.configure \
1837       env -i \
1838       PATH="/usr/bin:/bin" \
1839       ${srcdir}/configure \
1840         "${LLVM_SB_CONFIGURE_ENV[@]}" \
1841         --prefix=${installdir} \
1842         --host=nacl \
1843         --enable-targets=${targets} \
1844         --disable-assertions \
1845         --enable-pic=no \
1846         --enable-static \
1847         --enable-shared=no \
1848         --disable-jit \
1849         --enable-optimized \
1850         --target=${CROSS_TARGET_ARM} \
1851         llvm_cv_link_use_export_dynamic=no \
1852         ac_cv_func_getrusage=no
1853   spopd
1854 }
1855
1856 # llvm-sb-make - Make llvm tools (sandboxed)
1857 llvm-sb-make() {
1858   local arch=$1
1859   StepBanner "LLVM-SB" "Make ${arch}"
1860   local objdir="${LLVM_SB_OBJDIR}"
1861
1862   spushd "${objdir}"
1863   ts-touch-open "${objdir}"
1864
1865   local tools_to_build="pnacl-llc"
1866   local export_dyn_env="llvm_cv_link_use_export_dynamic=no"
1867   local isjit=0
1868   RunWithLog ${LLVM_SB_LOG_PREFIX}.make \
1869       env -i PATH="/usr/bin:/bin" \
1870       ONLY_TOOLS="${tools_to_build}" \
1871       NACL_SANDBOX=1 \
1872       KEEP_SYMBOLS=1 \
1873       VERBOSE=1 \
1874       ${export_dyn_env} \
1875       make ${MAKE_OPTS} tools-only
1876
1877   ts-touch-commit "${objdir}"
1878
1879   spopd
1880 }
1881
1882 # llvm-sb-install - Install llvm tools (sandboxed)
1883 llvm-sb-install() {
1884   local arch=$1
1885   StepBanner "LLVM-SB" "Install ${arch}"
1886
1887   local toolname="pnacl-llc"
1888   local installdir="$(GetTranslatorInstallDir ${arch})"/bin
1889   mkdir -p "${installdir}"
1890   spushd "${installdir}"
1891   local objdir="${LLVM_SB_OBJDIR}"
1892   cp -f "${objdir}"/Release*/bin/${toolname} .
1893   mv -f ${toolname} ${toolname}.pexe
1894   local arches=${arch}
1895   if [[ "${arch}" == "universal" ]]; then
1896     arches="${SBTC_ARCHES_ALL}"
1897   elif [[ "${arch}" == "i686" ]]; then
1898     # LLVM does not separate the i686 and x86_64 backends.
1899     # Translate twice to get both nexes.
1900     arches="i686 x86_64"
1901   fi
1902   translate-sb-tool ${toolname} "${arches}"
1903   install-sb-tool ${toolname} "${arches}"
1904   spopd
1905 }
1906
1907 # translate-sb-tool <toolname> <arches>
1908 #
1909 # Translate <toolname>.pexe to <toolname>.<arch>.nexe in the current directory.
1910 translate-sb-tool() {
1911   local toolname=$1
1912   local arches=$2
1913   local pexe="${toolname}.pexe"
1914   if ${PNACL_PRUNE}; then
1915     # Only strip debug, to preserve symbol names for testing. This is okay
1916     # because we strip the native nexe later anyway.
1917     # So, why bother stripping here at all?
1918     # It does appear to affect the size of the nexe:
1919     # http://code.google.com/p/nativeclient/issues/detail?id=3305
1920     ${PNACL_STRIP} --strip-debug "${pexe}"
1921   fi
1922
1923   local tarch
1924   for tarch in ${arches}; do
1925     local nexe="${toolname}.${tarch}.nexe"
1926     StepBanner "TRANSLATE" \
1927                "Translating ${toolname}.pexe to ${tarch} (background)"
1928     # NOTE: we are using --noirt to build without a segment gap
1929     # since we aren't loading the IRT for the translator nexes.
1930     #
1931     # Compiling with -ffunction-sections, -fdata-sections, --gc-sections
1932     # helps reduce the size a bit. If you want to use --gc-sections to test out:
1933     # http://code.google.com/p/nativeclient/issues/detail?id=1591
1934     # you will need to do a build without these flags.
1935     "${PNACL_TRANSLATE}" -ffunction-sections -fdata-sections --gc-sections \
1936       --allow-llvm-bitcode-input --noirt -arch ${tarch} "${pexe}" -o "${nexe}" &
1937     QueueLastProcess
1938   done
1939   StepBanner "TRANSLATE" "Waiting for translation processes to finish"
1940   QueueWait
1941
1942   # Test that certain symbols have been pruned before stripping.
1943   if [ "${toolname}" == "pnacl-llc" ]; then
1944     for tarch in ${arches}; do
1945       local nexe="${toolname}.${tarch}.nexe"
1946       local llvm_host_glob="${LLVM_INSTALL_DIR}/lib/libLLVM*so"
1947       python "${PNACL_ROOT}/prune_test.py" "${PNACL_NM}" \
1948         "${llvm_host_glob}" "${nexe}"
1949     done
1950   fi
1951
1952   if ${PNACL_PRUNE}; then
1953     # Strip the nexes.
1954     for tarch in ${arches}; do
1955       local nexe="${toolname}.${tarch}.nexe"
1956       ${PNACL_STRIP} "${nexe}"
1957     done
1958   fi
1959   StepBanner "TRANSLATE" "Done."
1960 }
1961
1962 # install-sb-tool <toolname> <arches>
1963 #
1964 # Install <toolname>.<arch>.nexe from the current directory
1965 # into the right location (as <toolname>.nexe)
1966 install-sb-tool() {
1967   local toolname="$1"
1968   local arches="$2"
1969   local tarch
1970   for tarch in ${arches}; do
1971     local installbin="$(GetTranslatorInstallDir ${tarch})"/bin
1972     mkdir -p "${installbin}"
1973     mv -f ${toolname}.${tarch}.nexe "${installbin}"/${toolname}.nexe
1974     if ${PNACL_BUILDBOT}; then
1975       spushd "${installbin}"
1976       local tag="${toolname}_${tarch}_size"
1977       print-tagged-tool-sizes "${tag}" "$(pwd)/${toolname}.nexe"
1978       spopd
1979     fi
1980   done
1981 }
1982
1983 GetTranslatorBuildDir() {
1984   local arch="$1"
1985   echo "${TC_BUILD}/translator-${arch//_/-}"
1986 }
1987
1988 GetTranslatorInstallDir() {
1989   local arch="$1"
1990   echo "${INSTALL_TRANSLATOR}"/${arch}
1991 }
1992
1993 ### Sandboxed version of gold.
1994
1995 #+-------------------------------------------------------------------------
1996 #+ binutils-gold-sb - Build and install gold (sandboxed)
1997 #+                    This is the replacement for the old
1998 #+                    final sandboxed linker which was bfd based.
1999 #+                    It has nothing to do with the bitcode linker
2000 #+                    which is also gold based.
2001 binutils-gold-sb() {
2002   local arch=$1
2003   check-arch ${arch}
2004   StepBanner "GOLD-NATIVE-SB" "(libiberty + gold) ${arch}"
2005
2006   local srcdir="${TC_SRC_BINUTILS}"
2007   assert-dir "${srcdir}" "You need to checkout gold."
2008
2009   binutils-gold-sb-clean ${arch}
2010   binutils-gold-sb-configure ${arch}
2011   binutils-gold-sb-make ${arch}
2012   binutils-gold-sb-install ${arch}
2013 }
2014
2015 # binutils-gold-sb-clean - Clean gold
2016 binutils-gold-sb-clean() {
2017   local arch=$1
2018   StepBanner "GOLD-NATIVE-SB" "Clean ${arch}"
2019   local objdir="$(GetTranslatorBuildDir ${arch})/binutils-gold-sb"
2020
2021   rm -rf "${objdir}"
2022   mkdir -p "${objdir}"
2023 }
2024
2025 # binutils-gold-sb-configure - Configure binutils for gold (unsandboxed)
2026 binutils-gold-sb-configure() {
2027   local arch=$1
2028   local srcdir="${TC_SRC_BINUTILS}"
2029   local objdir="$(GetTranslatorBuildDir ${arch})/binutils-gold-sb"
2030   local installbin="$(GetTranslatorInstallDir ${arch})/bin"
2031
2032   # The SRPC headers are included directly from the nacl tree, as they are
2033   # not in the SDK. libsrpc should have already been built by the
2034   # build.sh sdk-private-libs step
2035   # The Gold sandboxed build uses the normally-disallowed external
2036   # function __nacl_get_arch().  Allow that for now.
2037   #
2038   local flags="-static -I$(GetAbsolutePath ${NACL_ROOT}/..) \
2039     -fno-exceptions -O3 --pnacl-disable-abi-check "
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   if [ "$arch" = "x86-32-nonsfi" ]; then
2438     ${cc_cmd} -c entry_linux.c -o "${tmpdir}"/entry_linux.o
2439     ${cc_cmd} -c entry_linux_x86_32.S -o "${tmpdir}"/entry_linux_asm.o
2440   elif [ "$arch" = "arm-nonsfi" ]; then
2441     ${cc_cmd} -c entry_linux.c -o "${tmpdir}"/entry_linux.o
2442     ${cc_cmd} -c entry_linux_arm.S -o "${tmpdir}"/entry_linux_asm.o
2443   fi
2444
2445   # Some of the support code lives in third_party/ because it's based on code
2446   # from other open-source projects.
2447   ${cc_cmd} \
2448     -c "${NACL_SRC_THIRD_PARTY}/pnacl_native_newlib_subset/string.c" \
2449     -std=c99 -o "${tmpdir}"/string.o
2450   # Pull in the no-errno __ieee754_fmod from newlib and rename it to fmod.
2451   # This is to support the LLVM frem instruction.
2452   ${cc_cmd} \
2453     -c "${TC_SRC_NEWLIB}/newlib/libm/math/e_fmod.c" \
2454     -I"${TC_SRC_NEWLIB}/newlib/libm/common/" \
2455     -D__ieee754_fmod=fmod \
2456     -std=c99 -o "${tmpdir}"/e_fmod.o
2457   ${cc_cmd} \
2458     -c "${TC_SRC_NEWLIB}/newlib/libm/math/ef_fmod.c" \
2459     -I"${TC_SRC_NEWLIB}/newlib/libm/common/" \
2460     -D__ieee754_fmodf=fmodf \
2461     -std=c99 -o "${tmpdir}"/ef_mod.o
2462
2463   # For ARM, also compile aeabi_read_tp.S
2464   if  [ ${arch} == arm ] ; then
2465     ${cc_cmd} -c aeabi_read_tp.S -o "${tmpdir}"/aeabi_read_tp.o
2466   fi
2467   spopd
2468
2469   ${PNACL_AR} rc "${destdir}"/libcrt_platform.a "${tmpdir}"/*.o
2470 }
2471
2472 libs-support-unsandboxed() {
2473   if ${BUILD_PLATFORM_LINUX} || ${BUILD_PLATFORM_MAC}; then
2474     local arch="x86-32-${BUILD_PLATFORM}"
2475     StepBanner "LIBS-SUPPORT (${arch})" "Install unsandboxed_irt.o"
2476     local destdir="${INSTALL_LIB_NATIVE}"${arch}
2477     mkdir -p ${destdir}
2478     # The NaCl headers insist on having a platform macro such as
2479     # NACL_LINUX defined, but nonsfi/irt/irt_interfaces.c does not
2480     # itself use any of these macros, so defining NACL_LINUX here even
2481     # on non-Linux systems is OK.
2482     gcc -m32 -O2 -Wall -Werror -I${NACL_ROOT}/.. -c \
2483         -DNACL_LINUX=1 -DDEFINE_MAIN \
2484         ${NACL_ROOT}/src/nonsfi/irt/irt_interfaces.c \
2485         -o ${destdir}/unsandboxed_irt.o
2486     gcc -m32 -O2 -Wall -Werror -I${NACL_ROOT}/.. -c \
2487         ${NACL_ROOT}/src/untrusted/irt/irt_query_list.c \
2488         -o ${destdir}/irt_query_list.o
2489   fi
2490 }
2491
2492
2493 # Build the dummy "libpnacl_irt_shim.a", which is useful for building
2494 # commandline programs.  It cannot be used to build PPAPI programs
2495 # because it does not actually shim the PPAPI interfaces.
2496 # The library is named the same as the real PPAPI shim to ensure that
2497 # the commandlines are the same.
2498 # This must be built after newlib(), since it uses headers like <stdint.h>.
2499 dummy-irt-shim() {
2500   local arch=$1
2501   local destdir="${INSTALL_LIB_NATIVE}"${arch}
2502   local label="DUMMY-IRT-SHIM (${arch})"
2503   mkdir -p "${destdir}"
2504
2505   local flags="--pnacl-allow-native --pnacl-allow-translate -Wall -Werror"
2506   local cc_cmd="${PNACL_CC} -arch ${arch} ${flags}"
2507
2508   spushd "${PNACL_SUPPORT}"
2509   StepBanner "${label}" "Install libpnacl_irt_shim_dummy.a"
2510   local tmpdir="${TC_BUILD}/dummy-irt-shim"
2511   rm -rf "${tmpdir}"
2512   mkdir -p "${tmpdir}"
2513   ${cc_cmd} -c dummy_shim_entry.c -o "${tmpdir}"/dummy_shim_entry.o
2514   spopd
2515
2516   ${PNACL_AR} rc "${destdir}"/libpnacl_irt_shim_dummy.a "${tmpdir}"/*.o
2517 }
2518
2519 #########################################################################
2520 #     < SDK >
2521 #########################################################################
2522 SCONS_ARGS=(MODE=nacl
2523             -j${PNACL_CONCURRENCY}
2524             bitcode=1
2525             disable_nosys_linker_warnings=1
2526             naclsdk_validate=0
2527             --verbose)
2528
2529 SDK_IS_SETUP=false
2530 sdk-setup() {
2531   if ${SDK_IS_SETUP} && [ $# -eq 0 ]; then
2532     return 0
2533   fi
2534   SDK_IS_SETUP=true
2535
2536   SDK_INSTALL_ROOT="${INSTALL_ROOT}/sdk"
2537   SDK_INSTALL_LIB="${SDK_INSTALL_ROOT}/lib"
2538   SDK_INSTALL_INCLUDE="${SDK_INSTALL_ROOT}/include"
2539 }
2540
2541 sdk() {
2542   sdk-setup "$@"
2543   StepBanner "SDK"
2544   sdk-clean
2545   sdk-headers
2546   sdk-libs
2547   sdk-verify
2548 }
2549
2550 #+ sdk-clean             - Clean sdk stuff
2551 sdk-clean() {
2552   sdk-setup "$@"
2553   StepBanner "SDK" "Clean"
2554   rm -rf "${SDK_INSTALL_ROOT}"
2555
2556   # clean scons obj dirs
2557   rm -rf "${SCONS_OUT}"/nacl-*-pnacl*
2558 }
2559
2560 sdk-headers() {
2561   sdk-setup "$@"
2562   mkdir -p "${SDK_INSTALL_INCLUDE}"
2563
2564   local extra_flags=""
2565   local neutral_platform="x86-32"
2566
2567   StepBanner "SDK" "Install headers"
2568   spushd "${NACL_ROOT}"
2569   RunWithLog "sdk.headers" \
2570       ./scons \
2571       "${SCONS_ARGS[@]}" \
2572       ${extra_flags} \
2573       platform=${neutral_platform} \
2574       pnacl_newlib_dir="${INSTALL_ROOT}" \
2575       install_headers \
2576       includedir="$(PosixToSysPath "${SDK_INSTALL_INCLUDE}")"
2577   spopd
2578 }
2579
2580 sdk-libs() {
2581   sdk-setup "$@"
2582   StepBanner "SDK" "Install libraries"
2583   mkdir -p "${SDK_INSTALL_LIB}"
2584
2585   local extra_flags=""
2586   local neutral_platform="x86-32"
2587
2588   spushd "${NACL_ROOT}"
2589   RunWithLog "sdk.libs.bitcode" \
2590       ./scons \
2591       "${SCONS_ARGS[@]}" \
2592       ${extra_flags} \
2593       platform=${neutral_platform} \
2594       pnacl_newlib_dir="${INSTALL_ROOT}" \
2595       install_lib \
2596       libdir="$(PosixToSysPath "${SDK_INSTALL_LIB}")"
2597   spopd
2598 }
2599
2600 # This builds lib*_private.a, to allow building the llc and ld nexes without
2601 # the IRT and without the segment gap.
2602 sdk-private-libs() {
2603   sdk-setup "$@"
2604   StepBanner "SDK" "Private (non-IRT) libs"
2605   spushd "${NACL_ROOT}"
2606
2607   local neutral_platform="x86-32"
2608   RunWithLog "sdk.libs_private.bitcode" \
2609     ./scons \
2610     -j${PNACL_CONCURRENCY} \
2611     bitcode=1 \
2612     platform=${neutral_platform} \
2613     pnacl_newlib_dir="${INSTALL_ROOT}" \
2614     --verbose \
2615     libnacl_sys_private \
2616     libpthread_private \
2617     libnacl_dyncode_private \
2618     libplatform \
2619     libimc \
2620     libimc_syscalls \
2621     libsrpc \
2622     libgio
2623
2624   local out_dir_prefix="${SCONS_OUT}"/nacl-x86-32-pnacl-pexe-clang
2625   local outdir="${out_dir_prefix}"/lib
2626   mkdir -p "${SDK_INSTALL_LIB}"
2627   cp "${outdir}"/lib*_private.a \
2628      "${outdir}"/lib{platform,imc,imc_syscalls,srpc,gio}.a "${SDK_INSTALL_LIB}"
2629   spopd
2630 }
2631
2632 sdk-verify() {
2633   sdk-setup "$@"
2634   StepBanner "SDK" "Verify"
2635
2636   # Verify bitcode libraries
2637   verify-bitcode-dir "${SDK_INSTALL_LIB}"
2638 }
2639
2640 newlib-nacl-headers-clean() {
2641   # Clean the include directory and revert it to its pure state
2642   if [ -d "${TC_SRC_NEWLIB}" ]; then
2643     rm -rf "${NEWLIB_INCLUDE_DIR}"
2644     # If the script is interrupted right here,
2645     # then NEWLIB_INCLUDE_DIR will not exist, and the repository
2646     # will be in a bad state. This will be fixed during the next
2647     # invocation by newlib-nacl-headers.
2648
2649     spushd "$(dirname "${NEWLIB_INCLUDE_DIR}")"
2650     RunWithLog "newlib-nacl-headers-clean" \
2651       ${GIT} checkout "$(basename "${NEWLIB_INCLUDE_DIR}")"
2652     spopd
2653   fi
2654 }
2655
2656 #+ newlib-nacl-headers   - Install NaCl headers to newlib
2657 newlib-nacl-headers() {
2658   StepBanner "newlib-nacl-headers" "Adding nacl headers to newlib"
2659
2660   assert-dir "${TC_SRC_NEWLIB}" "Newlib is not checked out"
2661
2662   # Make sure the headers directory has no local changes
2663   newlib-nacl-headers-check
2664   newlib-nacl-headers-clean
2665
2666   # Install the headers
2667   "${EXPORT_HEADER_SCRIPT}" \
2668       "${NACL_SYS_HEADERS}" \
2669       "${NEWLIB_INCLUDE_DIR}"
2670
2671   # Record the header install time
2672   ts-touch "${NACL_HEADERS_TS}"
2673 }
2674
2675 #+ newlib-nacl-headers-check - Make sure the newlib nacl headers haven't
2676 #+                             been modified since the last install.
2677 newlib-nacl-headers-check() {
2678   # The condition where NEWLIB_INCLUDE_DIR does not exist may have been
2679   # caused by an incomplete call to newlib-nacl-headers-clean().
2680   # Let it pass this check so that the clean will be able to finish.
2681   # See the comment in newlib-nacl-headers-clean()
2682   if ! [ -d "${TC_SRC_NEWLIB}" ] ||
2683      ! [ -d "${NEWLIB_INCLUDE_DIR}" ]; then
2684     return 0
2685   fi
2686
2687   # Already clean?
2688   if ! git-has-changes "${NEWLIB_INCLUDE_DIR}" ; then
2689     return 0
2690   fi
2691
2692   if ts-dir-changed "${NACL_HEADERS_TS}" "${NEWLIB_INCLUDE_DIR}"; then
2693     echo ""
2694     echo "*******************************************************************"
2695     echo "*                            ERROR                                *"
2696     echo "*      The NewLib include directory has local modifications       *"
2697     echo "*******************************************************************"
2698     echo "* The NewLib include directory should not be modified directly.   *"
2699     echo "* Instead, modifications should be done from:                     *"
2700     echo "*   src/trusted/service_runtime/include                           *"
2701     echo "*                                                                 *"
2702     echo "* To destroy the local changes to newlib, run:                    *"
2703     echo "*  pnacl/build.sh newlib-nacl-headers-clean                       *"
2704     echo "*******************************************************************"
2705     echo ""
2706     if ${PNACL_BUILDBOT} ; then
2707       newlib-nacl-headers-clean
2708     else
2709       exit -1
2710     fi
2711   fi
2712 }
2713
2714
2715 #+-------------------------------------------------------------------------
2716 #@ driver                - Install driver scripts.
2717 driver() {
2718   StepBanner "DRIVER"
2719   driver-install
2720 }
2721
2722 # install python scripts and redirector shell/batch scripts
2723 driver-install-python() {
2724   local destdir="$1"
2725   shift
2726   local pydir="${destdir}/pydir"
2727
2728   StepBanner "DRIVER" "Installing driver adaptors to ${destdir}"
2729   rm -rf "${destdir}"
2730   mkdir -p "${destdir}"
2731   mkdir -p "${pydir}"
2732
2733   spushd "${DRIVER_DIR}"
2734
2735   # Copy python scripts
2736   cp $@ driver_log.py driver_env.py driver_temps.py \
2737     *tools.py filetype.py loader.py nativeld.py "${pydir}"
2738
2739   # Install redirector shell/batch scripts
2740   for name in $@; do
2741     local dest="${destdir}/${name/.py}"
2742     # In some situations cygwin cp messes up the permissions of the redirector
2743     # shell/batch scripts. Using cp -a seems to make sure it preserves them.
2744     cp -a redirect.sh "${dest}"
2745     chmod +x "${dest}"
2746     if ${BUILD_PLATFORM_WIN}; then
2747       cp -a redirect.bat "${dest}".bat
2748     fi
2749   done
2750   spopd
2751 }
2752
2753 feature-version-file-install() {
2754   local install_root=$1
2755   # Scons tests can check this version number to decide whether to
2756   # enable tests for toolchain bug fixes or new features.  This allows
2757   # tests to be enabled on the toolchain buildbots/trybots before the
2758   # new toolchain version is rolled into the pinned version (i.e. before
2759   # the tests would pass on the main NaCl buildbots/trybots).
2760   #
2761   # If you are adding a test that depends on a toolchain change, you
2762   # can increment this version number manually.
2763   echo 6 > "${install_root}/FEATURE_VERSION"
2764 }
2765
2766 # The driver is a simple python script which changes its behavior
2767 # depending on the name it is invoked as.
2768 driver-install() {
2769   local bindir=bin
2770   # On Linux we ship a fat toolchain with 2 sets of binaries defaulting to
2771   # x86-32 (mostly because of the 32 bit chrome bots). So the default
2772   # bin dir is 32, and the bin64 driver runs the 64 bit binaries
2773   if ${HOST_ARCH_X8664} && ${BUILD_PLATFORM_LINUX}; then
2774     bindir="bin64"
2775     # We want to be able to locally test a toolchain on 64 bit hosts without
2776     # building it twice and without extra env vars. So if a 32 bit toolchain
2777     # has not already been built, just symlink the bin dirs together.
2778     if [[ ! -d "${INSTALL_BIN}" ]]; then
2779       mkdir -p "${INSTALL_ROOT}"
2780       ln -s ${bindir} "${INSTALL_BIN}"
2781     fi
2782   fi
2783
2784   # This directory (the ${INSTALL_ROOT}/${bindir} part)
2785   # should be kept in sync with INSTALL_BIN et al.
2786   local destdir="${INSTALL_ROOT}/${bindir}"
2787
2788   driver-install-python "${destdir}" "pnacl-*.py"
2789
2790   # Tell the driver the library mode and host arch
2791   echo """HAS_FRONTEND=1
2792 HOST_ARCH=${HOST_ARCH}""" > "${destdir}"/driver.conf
2793
2794   # On windows, copy the cygwin DLLs needed by the driver tools
2795   if ${BUILD_PLATFORM_WIN}; then
2796     StepBanner "DRIVER" "Copying cygwin libraries"
2797     local deps="gcc_s-1 iconv-2 win1 intl-8 stdc++-6 z"
2798     for name in ${deps}; do
2799       cp "/bin/cyg${name}.dll" "${destdir}"
2800     done
2801   fi
2802
2803   # Install a REV file so that "pnacl-clang --version" knows the version
2804   # of the drivers themselves.
2805   DumpAllRevisions > "${destdir}/REV"
2806
2807   feature-version-file-install ${INSTALL_ROOT}
2808 }
2809
2810 #@ driver-install-translator - Install driver scripts for translator component
2811 driver-install-translator() {
2812   local destdir="${INSTALL_TRANSLATOR}/bin"
2813
2814   driver-install-python "${destdir}" pnacl-translate.py
2815
2816   echo """HAS_FRONTEND=0""" > "${destdir}"/driver.conf
2817
2818   feature-version-file-install ${INSTALL_TRANSLATOR}
2819 }
2820
2821 ######################################################################
2822 ######################################################################
2823 #
2824 #                           HELPER FUNCTIONS
2825 #
2826 #             (These should not generally be used directly)
2827 #
2828 ######################################################################
2829 ######################################################################
2830
2831 DumpAllRevisions() {
2832   one-line-rev-info ${NACL_ROOT}
2833   for d in ${PNACL_GIT_ROOT}/*/ ; do
2834     one-line-rev-info $d
2835   done
2836 }
2837
2838 ######################################################################
2839 ######################################################################
2840 #     < VERIFY >
2841 ######################################################################
2842 ######################################################################
2843
2844 # Note: we could replace this with a modified version of tools/elf_checker.py
2845 #       if we do not want to depend on binutils
2846 readonly NACL_OBJDUMP=${BINUTILS_INSTALL_DIR}/bin/${REAL_CROSS_TARGET}-objdump
2847
2848 # Usage: VerifyArchive <checker> <pattern> <filename>
2849 ExtractAndCheck() {
2850   local checker="$1"
2851   local pattern="$2"
2852   local archive="$3"
2853   local tmp="/tmp/ar-verify-${RANDOM}"
2854   rm -rf ${tmp}
2855   mkdir -p ${tmp}
2856   cp "${archive}" "${tmp}"
2857   spushd ${tmp}
2858   ${PNACL_AR} x $(basename ${archive})
2859   # extract all the files
2860   local count=0
2861   for i in ${pattern} ; do
2862     if [ ! -e "$i" ]; then
2863       # we may also see the unexpanded pattern here if there is no match
2864       continue
2865     fi
2866     count=$((count+1))
2867     ${checker} $i
2868   done
2869   echo "PASS  (${count} files)"
2870   rm -rf "${tmp}"
2871   spopd
2872 }
2873
2874 IsLinkerScript() {
2875   local fname="$1"
2876   local type="$(file --brief --mime-type "${fname}")"
2877   case "$type" in
2878     text/x-c)
2879       # A linker script with C comments looks like C to "file".
2880       return 0
2881       ;;
2882     text/plain)
2883       return 0
2884       ;;
2885   esac
2886   return 1
2887 }
2888
2889 # Usage: VerifyLinkerScript <filename>
2890 VerifyLinkerScript() {
2891   local archive="$1"
2892   # Use preprocessor to strip the C-style comments.
2893   ${PNACL_PP} -xc "${archive}" | awk -v archive="$(basename ${archive})" '
2894     BEGIN { status = 0 }
2895     NF == 0 || $1 == "#" { next }
2896     $1 == "INPUT" && $2 == "(" && $NF == ")" { next }
2897     {
2898       print "FAIL - unexpected linker script(?) contents:", archive
2899       status = 1
2900       exit(status)
2901     }
2902     END { if (status == 0) print "PASS  (trivial linker script)" }
2903 ' || exit -1
2904 }
2905
2906 # Usage: VerifyArchive <checker> <pattern> <filename>
2907 VerifyArchive() {
2908   local checker="$1"
2909   local pattern="$2"
2910   local archive="$3"
2911   echo -n "verify $(basename "${archive}"): "
2912   if IsLinkerScript "${archive}"; then
2913     VerifyLinkerScript "${archive}"
2914   else
2915     ExtractAndCheck "$checker" "$pattern" "$archive"
2916   fi
2917 }
2918
2919 #
2920 # verify-object-llvm <obj>
2921 #
2922 #   Verifies that a given .o file is bitcode and free of ASMSs
2923 verify-object-llvm() {
2924   if ${PNACL_DIS} "$1" -o - | grep asm ; then
2925     echo
2926     echo "ERROR asm in $1"
2927     echo
2928     exit -1
2929   fi
2930   if [ ${PIPESTATUS[0]} -ne 0 ]; then
2931     exit -1
2932   fi
2933 }
2934
2935
2936 check-elf-abi() {
2937   # Temporarily disable ELF abi check until DEPS roll
2938   return 0
2939
2940   local arch_info="$(${NACL_OBJDUMP} -f $1)"
2941   if ! grep -q $2 <<< ${arch_info} ; then
2942     echo "ERROR $1 - bad file format: $2 vs ${arch_info}\n"
2943     echo ${arch_info}
2944     exit -1
2945   fi
2946 }
2947
2948
2949 # verify-object-arm <obj>
2950 #
2951 #   Ensure that the ARCH properties are what we expect, this is a little
2952 #   fragile and needs to be updated when tools change
2953 verify-object-arm() {
2954   check-elf-abi $1 "elf32-littlearm"
2955   # llvm-mc does not automatically insert these tags (unlike gnu-as).
2956   # So we exclude llvm-mc generated object files for now
2957   if [[ $1 == aeabi_read_tp.o || $1 == setjmp.o ]] ; then
2958     return
2959   fi
2960   arch_info="$("${PNACL_READELF}" -A "$1")"
2961   #TODO(robertm): some refactoring and cleanup needed
2962   if ! grep -q "Tag_FP_arch: VFPv3" <<< ${arch_info} ; then
2963     echo "ERROR $1 - bad Tag_FP_arch"
2964     #TODO(robertm): figure out what the right thing to do is here, c.f.
2965     # http://code.google.com/p/nativeclient/issues/detail?id=966
2966     "${PNACL_READELF}" -A $1 | grep  Tag_FP_arch
2967     exit -1
2968   fi
2969
2970   if ! grep -q "Tag_CPU_arch: v7" <<< ${arch_info} ; then
2971     echo "FAIL bad $1 Tag_CPU_arch"
2972     "${PNACL_READELF}" -A $1 | grep Tag_CPU_arch
2973     exit -1
2974   fi
2975
2976   if ! grep -q "Tag_Advanced_SIMD_arch: NEONv1" <<< ${arch_info} ; then
2977     echo "FAIL bad $1 Tag_Advanced_SIMD_arch"
2978     "${PNACL_READELF}" -A $1 | grep Tag_Advanced_SIMD_arch
2979   fi
2980
2981   # Check that the file uses the ARM hard-float ABI (where VFP
2982   # registers D0-D7 (s0-s15) are used to pass arguments and results).
2983   if ! grep -q "Tag_ABI_VFP_args: VFP registers" <<< ${arch_info} ; then
2984     echo "FAIL bad $1 Tag_ABI_VFP_args"
2985     "${PNACL_READELF}" -A $1 | grep Tag_ABI_VFP_args
2986   fi
2987 }
2988
2989
2990 # verify-object-x86-32 <obj>
2991 #
2992 verify-object-x86-32() {
2993   check-elf-abi $1 "elf32-i386"
2994 }
2995
2996 # verify-object-x86-64 <obj>
2997 #
2998 verify-object-x86-64() {
2999   check-elf-abi $1 "elf64-x86-64"
3000 }
3001
3002 #+ verify-bitcode-dir    - Verify that the files in a directory are bitcode.
3003 verify-bitcode-dir() {
3004   local dir="$1"
3005   # This avoids errors when * finds no matches.
3006   shopt -s nullglob
3007   SubBanner "VERIFY: ${dir}"
3008   for i in "${dir}"/*.a ; do
3009     verify-archive-llvm "$i"
3010   done
3011   for i in "${dir}"/*.bc ; do
3012     echo -n "verify $(basename "$i"): "
3013     verify-object-llvm "$i"
3014     echo "PASS (bitcode)"
3015   done
3016   for i in "${dir}"/*.o ; do
3017     Fatal "Native object file $i inside bitcode directory"
3018   done
3019   shopt -u nullglob
3020 }
3021
3022
3023 #+ verify-native-dir     - Verify that files in a directory are native for arch.
3024 verify-native-dir() {
3025   local arch="$1"
3026   local dir="$2"
3027
3028   SubBanner "VERIFY: ${dir}"
3029
3030   # This avoids errors when * finds no matches.
3031   shopt -s nullglob
3032   for i in "${dir}"/*.o ; do
3033     verify-object-${arch} "$i"
3034   done
3035
3036   for i in "${dir}"/*.a ; do
3037     verify-archive-${arch} "$i"
3038   done
3039
3040   for i in "${dir}"/*.bc "${dir}"/*.pso ; do
3041     Fatal "Bitcode file $i found inside native directory"
3042   done
3043   shopt -u nullglob
3044 }
3045
3046 #
3047 # verify-archive-llvm <archive>
3048 # Verifies that a given archive is bitcode and free of ASMSs
3049 #
3050 verify-archive-llvm() {
3051   # Currently all the files are .o in the llvm archives.
3052   # Eventually more and more should be .bc.
3053   VerifyArchive verify-object-llvm '*.bc *.o' "$@"
3054 }
3055
3056 #
3057 # verify-archive-arm <archive>
3058 # Verifies that a given archive is a proper arm achive
3059 #
3060 verify-archive-arm() {
3061   VerifyArchive verify-object-arm '*.o *.ons' "$@"
3062 }
3063
3064 #
3065 # verify-archive-x86-32 <archive>
3066 # Verifies that a given archive is a proper x86-32 achive
3067 #
3068 verify-archive-x86-32() {
3069   VerifyArchive verify-object-x86-32 '*.o *.ons' "$@"
3070 }
3071
3072 #
3073 # verify-archive-x86-64 <archive>
3074 # Verifies that a given archive is a proper x86-64 achive
3075 #
3076 verify-archive-x86-64() {
3077   VerifyArchive verify-object-x86-64 '*.o *.ons' "$@"
3078 }
3079
3080 #@-------------------------------------------------------------------------
3081 #+ verify                - Verifies that the pnacl-untrusted ELF files
3082 #+                         are of the correct architecture.
3083 verify() {
3084   StepBanner "VERIFY"
3085   verify-bitcode
3086   verify-native
3087 }
3088
3089 verify-bitcode() {
3090   verify-bitcode-dir "${INSTALL_LIB}"
3091 }
3092
3093 verify-native() {
3094   local arch
3095   for arch in arm x86-32 x86-64; do
3096     verify-native-dir ${arch} "${INSTALL_LIB_NATIVE}${arch}"
3097   done
3098 }
3099
3100 #+ verify-triple-build <arch>
3101 #+     Verify that the sandboxed translator produces an identical
3102 #+     translation of itself (pnacl-llc.pexe) as the unsandboxed translator.
3103 #+     (NOTE: This function is experimental/untested)
3104 verify-triple-build() {
3105   local arch=$1
3106   StepBanner "VERIFY" "Verifying triple build for ${arch}"
3107
3108   local bindir="$(GetTranslatorInstallDir ${arch})/bin"
3109   local llc_nexe="${bindir}/pnacl-llc.nexe"
3110   local llc_pexe="${bindir}/pnacl-llc.pexe"
3111   assert-file "${llc_nexe}" "sandboxed llc for ${arch} does not exist"
3112   assert-file "${llc_pexe}" "pnacl-llc.pexe does not exist"
3113
3114   local flags="--pnacl-sb --pnacl-driver-verbose"
3115
3116   if [ ${arch} == "arm" ] ; then
3117     # Use emulator if we are not on ARM
3118     local hostarch=$(uname -m)
3119     if ! [[ "${BUILD_ARCH}" =~ arm ]]; then
3120       flags+=" --pnacl-use-emulator"
3121     fi
3122   fi
3123
3124   local triple_install_dir="$(GetTranslatorInstallDir ${arch})/triple-build"
3125   mkdir -p ${triple_install_dir}
3126   local new_llc_nexe="${triple_install_dir}/pnacl-llc.rebuild.nexe"
3127   mkdir -p "${triple_install_dir}"
3128   StepBanner "VERIFY" "Translating ${llc_pexe} using sandboxed tools (${arch})"
3129   local sb_translator="${INSTALL_TRANSLATOR}/bin/pnacl-translate"
3130   RunWithLog "verify.triple.build" \
3131     "${sb_translator}" ${flags} -arch ${arch} "${llc_pexe}" -o "${new_llc_nexe}"
3132
3133   if ! cmp --silent "${llc_nexe}" "${new_llc_nexe}" ; then
3134     Banner "TRIPLE BUILD VERIFY FAILED"
3135     echo "Expected these files to be identical, but they are not:"
3136     echo "  ${archllc}"
3137     echo "  ${newllc}"
3138     exit -1
3139   fi
3140   StepBanner "VERIFY" "Verified ${arch} OK"
3141 }
3142
3143 ######################################################################
3144 ######################################################################
3145 #
3146 # UTILITIES
3147 #
3148 ######################################################################
3149 ######################################################################
3150
3151 #@-------------------------------------------------------------------------
3152 #@ show-config
3153 show-config() {
3154   Banner "Config Settings:"
3155   echo "PNACL_BUILDBOT:    ${PNACL_BUILDBOT}"
3156   echo "PNACL_CONCURRENCY: ${PNACL_CONCURRENCY}"
3157   echo "PNACL_DEBUG:       ${PNACL_DEBUG}"
3158   echo "PNACL_PRUNE:       ${PNACL_PRUNE}"
3159   echo "PNACL_VERBOSE:     ${PNACL_VERBOSE}"
3160   echo "INSTALL_ROOT:      ${INSTALL_ROOT}"
3161   Banner "Your Environment:"
3162   env | grep PNACL
3163   Banner "uname info for builder:"
3164   uname -a
3165 }
3166
3167 #@ help                  - Usage information.
3168 help() {
3169   Usage
3170 }
3171
3172 #@ help-full             - Usage information including internal functions.
3173 help-full() {
3174   Usage2
3175 }
3176
3177 has-trusted-toolchain() {
3178   if [ -f ${TOOLCHAIN_BASE}/arm_trusted/ld_script_arm_trusted ]; then
3179     return 0
3180   else
3181     return 1
3182   fi
3183 }
3184
3185 check-for-trusted() {
3186   if ! ${PNACL_BUILD_ARM} ; then
3187     return
3188   fi
3189
3190   if ! has-trusted-toolchain; then
3191     echo '*******************************************************************'
3192     echo '*   The ARM trusted toolchain does not appear to be installed yet *'
3193     echo '*   It is needed to run ARM tests.                                *'
3194     echo '*                                                                 *'
3195     echo '*   To download and install the trusted toolchain, run:           *'
3196     echo '*                                                                 *'
3197     echo '*       $ pnacl/build.sh download-trusted                         *'
3198     echo '*                                                                 *'
3199     echo '*   To compile the trusted toolchain, use:                        *'
3200     echo '*                                                                 *'
3201     echo '*       $ tools/llvm/trusted-toolchain-creator.sh trusted_sdk     *'
3202     echo '*               (warning: this takes a while)                     *'
3203     echo '*******************************************************************'
3204
3205     # If building on the bots, do not continue since it needs to run ARM tests.
3206     if ${PNACL_BUILDBOT} ; then
3207       echo "Building on bots --> need ARM trusted toolchain to run tests!"
3208       exit -1
3209     elif trusted-tc-confirm ; then
3210       echo "Continuing without ARM trusted toolchain"
3211       PNACL_BUILD_ARM=false
3212     else
3213       echo "Okay, stopping."
3214       exit -1
3215     fi
3216   fi
3217 }
3218
3219 trusted-tc-confirm() {
3220   echo
3221   echo "Do you wish to continue without the ARM trusted TC (skip ARM testing)?"
3222   echo ""
3223   confirm-yes "Continue"
3224   return $?
3225 }
3226
3227 DebugRun() {
3228   if ${PNACL_DEBUG} || ${PNACL_BUILDBOT}; then
3229     "$@"
3230   fi
3231 }
3232
3233 ######################################################################
3234 # Generate chromium perf bot logs for tracking the size of a binary.
3235 #
3236 print-tagged-tool-sizes() {
3237   local tag="$1"
3238   local binary="$2"
3239
3240   # size output look like:
3241   #    text   data     bss     dec    hex  filename
3242   #  354421  16132  168920  539473  83b51  .../tool
3243   local sizes=($(${PNACL_SIZE} -B "${binary}" | grep '[0-9]\+'))
3244   echo "RESULT ${tag}: text= ${sizes[0]} bytes"
3245   echo "RESULT ${tag}: data= ${sizes[1]} bytes"
3246   echo "RESULT ${tag}: bss= ${sizes[2]} bytes"
3247   echo "RESULT ${tag}: total= ${sizes[3]} bytes"
3248
3249   local file_size=($(du --bytes "${binary}"))
3250   echo "RESULT ${tag}: file_size= ${file_size[0]} bytes"
3251 }
3252
3253 ######################################################################
3254 ######################################################################
3255 #
3256 #                           < TIME STAMPING >
3257 #
3258 ######################################################################
3259 ######################################################################
3260
3261 ts-dir-changed() {
3262   local tsfile="$1"
3263   local dir="$2"
3264
3265   if [ -f "${tsfile}" ]; then
3266     local MODIFIED=$(find "${dir}" -type f -newer "${tsfile}")
3267     [ ${#MODIFIED} -gt 0 ]
3268     ret=$?
3269   else
3270     true
3271     ret=$?
3272   fi
3273   return $ret
3274 }
3275
3276 # Check if the source for a given build has been modified
3277 ts-modified() {
3278   local srcdir="$1"
3279   local objdir="$2"
3280   local tsfile="${objdir}/${TIMESTAMP_FILENAME}"
3281
3282   ts-dir-changed "${tsfile}" "${srcdir}"
3283   return $?
3284 }
3285
3286 ts-touch() {
3287   local tsfile="$1"
3288   touch "${tsfile}"
3289 }
3290
3291 # Record the time when make begins, but don't yet
3292 # write that to the timestamp file.
3293 # (Just in case make fails)
3294
3295 ts-touch-open() {
3296   local objdir="$1"
3297   local tsfile="${objdir}/${TIMESTAMP_FILENAME}"
3298   local tsfile_open="${objdir}/${TIMESTAMP_FILENAME}_OPEN"
3299
3300   rm -f "${tsfile}"
3301   touch "${tsfile_open}"
3302 }
3303
3304
3305 # Write the timestamp. (i.e. make has succeeded)
3306
3307 ts-touch-commit() {
3308   local objdir="$1"
3309   local tsfile="${objdir}/${TIMESTAMP_FILENAME}"
3310   local tsfile_open="${objdir}/${TIMESTAMP_FILENAME}_OPEN"
3311
3312   mv -f "${tsfile_open}" "${tsfile}"
3313 }
3314
3315
3316 # ts-newer-than dirA dirB
3317 # Compare the make timestamps in both object directories.
3318 # returns true (0) if dirA is newer than dirB
3319 # returns false (1) otherwise.
3320 #
3321 # This functions errs on the side of returning 0, since
3322 # that forces a rebuild anyway.
3323
3324 ts-newer-than() {
3325   local objdir1="$1"
3326   local objdir2="$2"
3327
3328   local tsfile1="${objdir1}/${TIMESTAMP_FILENAME}"
3329   local tsfile2="${objdir2}/${TIMESTAMP_FILENAME}"
3330
3331   if [ ! -d "${objdir1}" ]; then return 0; fi
3332   if [ ! -d "${objdir2}" ]; then return 0; fi
3333
3334   if [ ! -f "${tsfile1}" ]; then return 0; fi
3335   if [ ! -f "${tsfile2}" ]; then return 0; fi
3336
3337   local MODIFIED=$(find "${tsfile1}" -newer "${tsfile2}")
3338   if [ ${#MODIFIED} -gt 0 ]; then
3339     return 0
3340   fi
3341   return 1
3342 }
3343
3344
3345 # Don't define any functions after this or they won't show up in completions
3346 function-completions() {
3347   if [ $# = 0 ]; then set -- ""; fi
3348   compgen -A function -- $1
3349   exit 0
3350 }
3351
3352 ######################################################################
3353 ######################################################################
3354 #
3355 #                               < MAIN >
3356 #
3357 ######################################################################
3358 ######################################################################
3359
3360 mkdir -p "${INSTALL_ROOT}"
3361
3362 if [ $# = 0 ]; then set -- help; fi  # Avoid reference to undefined $1.
3363
3364 # Accept one -- argument for some compatibility with google3
3365 if [ $1 = "--tab_completion_word" ]; then
3366   set -- function-completions $2
3367 fi
3368
3369 if [ "$(type -t $1)" != "function" ]; then
3370   #Usage
3371   echo "ERROR: unknown function '$1'." >&2
3372   echo "For help, try:"
3373   echo "    $0 help"
3374   exit 1
3375 fi
3376
3377 "$@"