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.
9 # Turn on/off debugging mode
10 readonly PNACL_DEBUG=${PNACL_DEBUG:-false}
12 # True if the scripts are running on the build bots.
13 readonly PNACL_BUILDBOT=${PNACL_BUILDBOT:-false}
15 # Dump all build output to stdout
16 readonly PNACL_VERBOSE=${PNACL_VERBOSE:-false}
18 readonly TIME_AT_STARTUP=$(date '+%s')
26 TC_LOG_ALL="${TC_LOG}/ALL"
29 ######################################################################
31 ######################################################################
33 BUILD_PLATFORM=$(uname | tr '[A-Z]' '[a-z]')
34 BUILD_PLATFORM_LINUX=false
35 BUILD_PLATFORM_MAC=false
36 BUILD_PLATFORM_WIN=false
38 if [ "${BUILD_PLATFORM}" == "linux" ] ; then
39 BUILD_PLATFORM_LINUX=true
40 SCONS_BUILD_PLATFORM=linux
41 BUILD_ARCH=${BUILD_ARCH:-$(uname -m)}
45 elif [[ "${BUILD_PLATFORM}" =~ cygwin_nt ]]; then
47 BUILD_PLATFORM_WIN=true
48 SCONS_BUILD_PLATFORM=win
49 # force 32 bit host because build is also 32 bit on windows.
50 HOST_ARCH=${HOST_ARCH:-x86_32}
51 BUILD_ARCH=${BUILD_ARCH:-x86_32}
54 SO_DIR=bin # On Windows, DLLs are placed in bin/
55 # because the dynamic loader searches %PATH%
56 elif [ "${BUILD_PLATFORM}" == "darwin" ] ; then
58 BUILD_PLATFORM_MAC=true
59 SCONS_BUILD_PLATFORM=mac
60 # On mac, uname -m is a lie. We always do 64 bit host builds, on
61 # 64 bit build machines
62 HOST_ARCH=${HOST_ARCH:-x86_64}
63 BUILD_ARCH=${BUILD_ARCH:-x86_64}
68 echo "Unknown system '${BUILD_PLATFORM}'"
72 readonly BUILD_PLATFORM
73 readonly BUILD_PLATFORM_LINUX
74 readonly BUILD_PLATFORM_MAC
75 readonly BUILD_PLATFORM_WIN
76 readonly SCONS_BUILD_PLATFORM
80 BUILD_ARCH_SHORT=${BUILD_ARCH}
81 BUILD_ARCH_X8632=false
82 BUILD_ARCH_X8664=false
85 if [ "${BUILD_ARCH}" == "x86_32" ] ||
86 [ "${BUILD_ARCH}" == "i386" ] ||
87 [ "${BUILD_ARCH}" == "i686" ] ; then
91 elif [ "${BUILD_ARCH}" == "x86_64" ] ; then
94 elif [ "${BUILD_ARCH}" == "armv7l" ] ; then
97 elif [ "${BUILD_ARCH}" == "mips32" ] ||
98 [ "${BUILD_ARCH}" == "mips" ] ; then
100 BUILD_ARCH_SHORT=mips
102 echo "Unknown build arch '${BUILD_ARCH}'"
106 readonly BUILD_ARCH_SHORT
107 readonly BUILD_ARCH_X8632
108 readonly BUILD_ARCH_X8664
109 readonly BUILD_ARCH_ARM
110 readonly BUILD_ARCH_MIPS
113 HOST_ARCH=${HOST_ARCH:-${BUILD_ARCH}}
114 HOST_ARCH_X8632=false
115 HOST_ARCH_X8664=false
118 if [ "${HOST_ARCH}" == "x86_32" ] ||
119 [ "${HOST_ARCH}" == "i386" ] ||
120 [ "${HOST_ARCH}" == "i686" ] ; then
123 elif [ "${HOST_ARCH}" == "x86_64" ] ; then
125 elif [ "${HOST_ARCH}" == "armv7l" ] ; then
127 elif [ "${HOST_ARCH}" == "mips32" ] ||
128 [ "${HOST_ARCH}" == "mips" ] ; then
131 echo "Unknown host arch '${HOST_ARCH}'"
135 readonly HOST_ARCH_X8632
136 readonly HOST_ARCH_X8664
137 readonly HOST_ARCH_ARM
138 readonly HOST_ARCH_MIPS
140 if [ "${BUILD_ARCH}" != "${HOST_ARCH}" ]; then
141 if ! { ${BUILD_ARCH_X8664} && ${HOST_ARCH_X8632}; }; then
142 echo "Cross builds other than build=x86_64 with host=x86_32 not supported"
147 if ${BUILD_PLATFORM_WIN}; then
148 readonly GCLIENT="gclient.bat"
149 readonly GIT="git.bat"
151 readonly SVN="svn.bat"
153 readonly GCLIENT="gclient"
159 # On Windows, scons expects Windows-style paths (C:\foo\bar)
160 # This function converts cygwin posix paths to Windows-style paths.
161 # On all other platforms, this function does nothing to the path.
164 if ${BUILD_PLATFORM_WIN}; then
165 cygpath -w "$(GetAbsolutePath "${path}")"
172 ######################################################################
173 # Git repository tools
174 ######################################################################
179 local status=$(${GIT} status --porcelain --untracked-files=no)
185 git-assert-no-changes() {
187 if git-has-changes "${dir}"; then
188 Banner "ERROR: Repository ${dir} has local changes"
193 ######################################################################
194 # Subversion repository tools
195 ######################################################################
200 local repo_rev=$(svn-get-revision "${dir}")
201 [ "${repo_rev}" == "${rev}" ]
205 #+ svn-get-revision <dir>
209 local rev=$(${SVN} info | grep 'Revision: ' | cut -b 11-)
210 if ! [[ "${rev}" =~ ^[0-9]+$ ]]; then
211 echo "Invalid revision number '${rev}' or invalid repository '${dir}'" 1>&2
218 #+ svn-checkout <url> <repodir> - Checkout an SVN repository
224 if [ ! -d "${dir}" ]; then
225 StepBanner "SVN-CHECKOUT" "Checking out ${url}"
226 RunWithLog "svn-checkout" ${SVN} co "${url}" "${dir}" -r "${rev}"
228 SkipBanner "SVN-CHECKOUT" "Using existing SVN repository for ${url}"
232 #+ svn-update <dir> <rev> - Update an SVN repository
238 "SVN repository $(basename "${dir}") doesn't exist."
241 if [[ "$rev" == "tip" ]]; then
242 RunWithLog "svn-update" ${SVN} update
244 RunWithLog "svn-update" ${SVN} update -r ${rev}
252 local STATUS=$(${SVN} status)
254 [ "${STATUS}" != "" ]
258 #+ svn-assert-no-changes <dir> - Assert an svn repo has no local changes
259 svn-assert-no-changes() {
261 if svn-has-changes "${dir}" ; then
262 local name=$(basename "${dir}")
263 Banner "ERROR: Repository ${name} has local changes"
269 ######################################################################
270 # vcs rev info helper
271 ######################################################################
276 git-one-line-rev-info() {
277 local commit=$(${GIT} log -n 1 | head -1 | get-field 2)
278 local url=$(egrep "^[^a-z]+url = " .git/config | head -1 | get-field 3)
279 # variable bypass does implicit whitespace strip
280 echo "[GIT] ${url}: ${commit}"
283 svn-one-line-rev-info() {
284 local url=$(${SVN} info | egrep 'URL:' | get-field 2)
285 local rev=$(${SVN} info | egrep 'Revision:' | get-field 2)
286 echo "[SVN] ${url}: ${rev}"
289 #+ one-line-rev-info <dir> - show one line summmary for
290 one-line-rev-info() {
293 svn-one-line-rev-info
294 elif [ -d .git ]; then
296 git-one-line-rev-info
298 echo "[$1] Unknown version control system"
303 ######################################################################
305 ######################################################################
307 #@ progress - Show build progress (open in another window)
309 StepBanner "PROGRESS WINDOW"
312 if [ -f "${TC_LOG_ALL}" ]; then
313 if tail --version > /dev/null; then
315 tail -s 0.05 --max-unchanged-stats=20 --follow=name "${TC_LOG_ALL}"
318 tail -F "${TC_LOG_ALL}"
325 #+ clean-logs - Clean all logs
332 LogEcho "-------------------------------------------------------------------"
333 LogEcho "ENTERING: $1"
334 pushd "$1" > /dev/null
339 LogEcho "LEAVING: $(pwd)"
341 LogEcho "-------------------------------------------------------------------"
342 LogEcho "ENTERING: $(pwd)"
347 echo "$*" >> "${TC_LOG_ALL}"
351 local log="${TC_LOG}/$1"
357 if ${PNACL_VERBOSE}; then
358 echo "RUNNING: " "$@" | tee "${log}" | tee -a "${TC_LOG_ALL}"
359 "$@" 2>&1 | tee "${log}" | tee -a "${TC_LOG_ALL}"
362 echo "RUNNING: " "$@" | tee -a "${TC_LOG_ALL}" &> "${log}"
363 "$@" 2>&1 | tee -a "${TC_LOG_ALL}" &> "${log}"
366 if [ ${ret} -ne 0 ]; then
372 echo "LOGFILE: ${log}"
376 if ${PNACL_BUILDBOT}; then
377 echo "BEGIN LOGFILE Contents."
379 echo "END LOGFILE Contents."
387 # Pretty print, respecting parameter grouping
389 local has_space=$(echo "$I" | grep " ")
390 if [ ${#has_space} -gt 0 ]; then
405 if [ ! -d "${dir}" ]; then
406 Banner "ERROR: ${msg}"
415 if [ ! -f "${fn}" ]; then
416 Banner "ERROR: ${fn} does not exist. ${msg}"
422 egrep "^#@" "${SCRIPT_PATH}" | cut -b 3-
426 egrep "^#(@|\+)" "${SCRIPT_PATH}" | cut -b 3-
431 echo " *********************************************************************"
437 echo " *********************************************************************"
442 if [ $# -eq 1 ]; then
444 echo "-------------------------------------------------------------------"
445 local padding=$(RepeatStr ' ' 28)
446 echo "${padding}${module}"
447 echo "-------------------------------------------------------------------"
450 local padding=$(RepeatStr ' ' $((20-${#module})) )
451 echo "[$(TimeStamp)] ${module}${padding}" "$@"
456 if date --version &> /dev/null ; then
458 date -d "now - ${TIME_AT_STARTUP}sec" '+%M:%S'
460 # Other 'date' (assuming BSD for now)
461 local time_now=$(date '+%s')
462 local time_delta=$[ ${time_now} - ${TIME_AT_STARTUP} ]
463 date -j -f "%s" "${time_delta}" "+%M:%S"
469 echo "----------------------------------------------------------------------"
471 echo "----------------------------------------------------------------------"
475 StepBanner "$1" "Skipping $2, already up to date."
483 while [ $count -gt 0 ]; do
499 local F=$(file -b "$1")
500 [[ "${F}" =~ "ELF" ]]
504 local F=$(file -b "$1")
505 [[ "${F}" =~ "Mach-O" ]]
509 local F=$(file -b "$1")
510 [[ "${F}" =~ "shell" ]]
513 get_dir_size_in_mb() {
514 du -msc "$1" | tail -1 | egrep -o "[0-9]+"
520 echo -n "${msg} [Y/N]? "
523 if [ "${YESNO}" == "N" ] || [ "${YESNO}" == "n" ]; then
526 if [ "${YESNO}" == "Y" ] || [ "${YESNO}" == "y" ]; then
532 # On Linux with GNU readlink, "readlink -f" would be a quick way
533 # of getting an absolute path, but MacOS has BSD readlink.
538 if [ -d "${relpath}" ]; then
542 reldir="$(dirname "${relpath}")"
543 relname="/$(basename "${relpath}")"
546 local absdir="$(cd "${reldir}" && pwd)"
547 echo "${absdir}${relname}"
551 # The Queue* functions provide a simple way of keeping track
552 # of multiple background processes in order to ensure that:
553 # 1) they all finish successfully (with return value 0), and
554 # 2) they terminate if the master process is killed/interrupted.
555 # (This is done using a bash "trap" handler)
564 # echo "Waiting for commands finish..."
567 # TODO(pdox): Right now, this abstraction is only used for
568 # paralellizing translations in the self-build. If we're going
569 # to use this for anything more complex, then throttling the
570 # number of active processes to exactly PNACL_CONCURRENCY would
571 # be a useful feature.
575 CT_WAIT_QUEUE+=" ${pid}"
576 if ! QueueConcurrent ; then
582 [ ${PNACL_CONCURRENCY} -gt 1 ]
586 for pid in ${CT_WAIT_QUEUE} ; do
592 # Add a trap so that if the user Ctrl-C's or kills
593 # this script while background processes are running,
594 # the background processes don't keep going.
595 trap 'QueueKill' SIGINT SIGTERM SIGHUP
598 echo "Killing queued processes: ${CT_WAIT_QUEUE}"
599 for pid in ${CT_WAIT_QUEUE} ; do
600 kill ${pid} &> /dev/null || true
607 [ "${CT_WAIT_QUEUE}" == "" ]