Ioannis E. VENETIS <venetis@mail.capsl.udel.edu> pointed out that GMP and MPFR were not used by gcc.
Turned out that none could use GMP and MPFR as the config option changed its name, but the change was not propagated to all users.
/trunk/scripts/build/binutils.sh | 2 1 1 0 +-
/trunk/scripts/build/debug/300-gdb.sh | 2 1 1 0 +-
/trunk/scripts/build/cc_gcc.sh | 6 3 3 0 +++---
3 files changed, 5 insertions(+), 5 deletions(-)
1 # This file contains some usefull common functions
2 # Copyright 2007 Yann E. MORIN
3 # Licensed under the GPL v2. See COPYING in the root of this package
5 # Prepare the fault handler
8 CT_DoLog ERROR "Build failed in step '${CT_STEP_MESSAGE[${CT_STEP_COUNT}]}'"
9 for((step=(CT_STEP_COUNT-1); step>1; step--)); do
10 CT_DoLog ERROR " called in step '${CT_STEP_MESSAGE[${step}]}'"
12 CT_DoLog ERROR "Error happened in '${BASH_SOURCE[1]}' in function '${FUNCNAME[1]}' (line unknown, sorry)"
13 for((depth=2; ${BASH_LINENO[$((${depth}-1))]}>0; depth++)); do
14 CT_DoLog ERROR " called from '${BASH_SOURCE[${depth}]}' at line # ${BASH_LINENO[${depth}-1]} in function '${FUNCNAME[${depth}]}'"
16 [ "${CT_LOG_TO_FILE}" = "y" ] && CT_DoLog ERROR "Look at '${CT_LOG_FILE}' for more info on this error."
22 # Install the fault handler
25 # Inherit the fault handler in subshells and functions
28 # Make pipes fail on the _first_ failed command
29 # Not supported on bash < 3.x, but we need it, so drop the obsoleting bash-2.x
32 # Don't hash commands' locations, and search every time it is requested.
33 # This is slow, but needed because of the static/shared core gcc which shall
34 # always match to shared if it exists, and only fallback to static if the
39 # - first of all, save stdout so we can see the live logs: fd #6
41 # - then point stdout to the log file (temporary for now)
42 tmp_log_file="${CT_TOP_DIR}/log.$$"
43 exec >>"${tmp_log_file}"
45 # The different log levels:
53 # A function to log what is happening
54 # Different log level are available:
55 # - ERROR: A serious, fatal error occurred
56 # - WARN: A non fatal, non serious error occurred, take your responsbility with the generated build
57 # - INFO: Informational messages
58 # - EXTRA: Extra informational messages
59 # - DEBUG: Debug messages
60 # - ALL: Component's build messages
61 # Usage: CT_DoLog <level> [message]
62 # If message is empty, then stdin will be logged.
64 local max_level LEVEL level cur_l cur_L
66 eval max_level="\${CT_LOG_LEVEL_${CT_LOG_LEVEL_MAX}}"
67 # Set the maximum log level to DEBUG if we have none
68 [ -z "${max_level}" ] && max_level=${CT_LOG_LEVEL_DEBUG}
71 eval level="\${CT_LOG_LEVEL_${LEVEL}}"
77 fi |( IFS="\n" # We want the full lines, even leading spaces
83 indent=$((2*CT_STEP_COUNT))
85 case "${CT_LOG_SEE_TOOLS_WARN},${line}" in
86 y,*"warning:"*) cur_L=WARN; cur_l=${CT_LOG_LEVEL_WARN};;
87 y,*"WARNING:"*) cur_L=WARN; cur_l=${CT_LOG_LEVEL_WARN};;
88 *"error:"*) cur_L=ERROR; cur_l=${CT_LOG_LEVEL_ERROR};;
89 *"make["?*"]:"*"Stop.") cur_L=ERROR; cur_l=${CT_LOG_LEVEL_ERROR};;
90 *) cur_L="${LEVEL}"; cur_l="${level}";;
92 # There will always be a log file (stdout, fd #1), be it /dev/null
93 printf "[%-5s]%*s%s%s\n" "${cur_L}" "${indent}" " " "${line}"
94 if [ ${cur_l} -le ${max_level} ]; then
95 # Only print to console (fd #6) if log level is high enough.
96 printf "\r[%-5s]%*s%s%s\n" "${cur_L}" "${indent}" " " "${line}" >&6
98 if [ "${CT_LOG_PROGRESS_BAR}" = "y" ]; then
99 printf "\r[%02d:%02d] %s " $((SECONDS/60)) $((SECONDS%60)) "${_prog_bar[$((_prog_bar_cpt/10))]}" >&6
100 _prog_bar_cpt=$(((_prog_bar_cpt+1)%40))
108 # Execute an action, and log its messages
109 # Usage: CT_DoExecLog <level> <[VAR=val...] command [parameters...]>
113 eval "$@" 2>&1 |CT_DoLog "${level}"
116 # Tail message to be logged whatever happens
117 # Usage: CT_DoEnd <level>
121 CT_STOP_DATE=$(CT_DoDate +%s%N)
122 CT_STOP_DATE_HUMAN=$(CT_DoDate +%Y%m%d.%H%M%S)
123 if [ "${level}" != "ERROR" ]; then
124 CT_DoLog "${level:-INFO}" "Build completed at ${CT_STOP_DATE_HUMAN}"
126 elapsed=$((CT_STOP_DATE-CT_STAR_DATE))
127 elapsed_min=$((elapsed/(60*1000*1000*1000)))
128 elapsed_sec=$(printf "%02d" $(((elapsed%(60*1000*1000*1000))/(1000*1000*1000))))
129 elapsed_csec=$(printf "%02d" $(((elapsed%(1000*1000*1000))/(10*1000*1000))))
130 CT_DoLog ${level:-INFO} "(elapsed: ${elapsed_min}:${elapsed_sec}.${elapsed_csec})"
133 # Abort the execution with an error message
134 # Usage: CT_Abort <message>
140 # Test a condition, and print a message if satisfied
141 # Usage: CT_Test <message> <tests>
146 test "$@" && CT_DoLog WARN "$m"
150 # Test a condition, and abort with an error message if satisfied
151 # Usage: CT_TestAndAbort <message> <tests>
155 test "$@" && CT_Abort "$m"
159 # Test a condition, and abort with an error message if not satisfied
160 # Usage: CT_TestAndAbort <message> <tests>
164 test "$@" || CT_Abort "$m"
168 # Test the presence of a tool, or abort if not found
169 # Usage: CT_HasOrAbort <tool>
171 CT_TestAndAbort "'${1}' not found and needed for successful toolchain build." -z ""$(CT_Which "${1}")
175 # Search a program: wrap "which" for those system where
176 # "which" verbosely says there is no match (Mdk are such
178 # Usage: CT_Which <filename>
180 which "$1" 2>/dev/null || true
183 # Get current date with nanosecond precision
184 # On those system not supporting nanosecond precision, faked with rounding down
185 # to the highest entire second
186 # Usage: CT_DoDate <fmt>
188 date "$1" |sed -r -e 's/%N$/000000000/;'
192 CT_STEP_MESSAGE[${CT_STEP_COUNT}]="<none>"
193 # Memorise a step being done so that any error is caught
194 # Usage: CT_DoStep <loglevel> <message>
196 local start=$(CT_DoDate +%s%N)
197 CT_DoLog "$1" "================================================================="
199 CT_STEP_COUNT=$((CT_STEP_COUNT+1))
200 CT_STEP_LEVEL[${CT_STEP_COUNT}]="$1"; shift
201 CT_STEP_START[${CT_STEP_COUNT}]="${start}"
202 CT_STEP_MESSAGE[${CT_STEP_COUNT}]="$1"
206 # End the step just being done
209 local stop=$(CT_DoDate +%s%N)
210 local duration=$(printf "%032d" $((stop-${CT_STEP_START[${CT_STEP_COUNT}]})) |sed -r -e 's/([[:digit:]]{2})[[:digit:]]{7}$/\.\1/; s/^0+//; s/^\./0\./;')
211 local elapsed=$(printf "%02d:%02d" $((SECONDS/60)) $((SECONDS%60)))
212 local level="${CT_STEP_LEVEL[${CT_STEP_COUNT}]}"
213 local message="${CT_STEP_MESSAGE[${CT_STEP_COUNT}]}"
214 CT_STEP_COUNT=$((CT_STEP_COUNT-1))
215 CT_DoLog "${level}" "${message}: done in ${duration}s (at ${elapsed})"
219 # Pushes into a directory, and pops back
221 pushd "$1" >/dev/null 2>&1
227 # Makes a path absolute
228 # Usage: CT_MakeAbsolutePath path
229 CT_MakeAbsolutePath() {
230 # Try to cd in that directory
236 # No such directory, fail back to guessing
239 *) echo "$(pwd)/$1";;
246 # Creates a temporary directory
247 # $1: variable to assign to
248 # Usage: CT_MktempDir foo
250 # Some mktemp do not allow more than 6 Xs
251 eval "$1"=$(mktemp -q -d "${CT_BUILD_DIR}/.XXXXXX")
252 CT_TestOrAbort "Could not make temporary directory" -n "${!1}" -a -d "${!1}"
255 # Echoes the specified string on stdout until the pipe breaks.
258 # Usage: CT_DoYes "" |make oldconfig
263 # Get the file name extension of a component
264 # Usage: CT_GetFileExtension <component_name-component_version>
265 # If found, echoes the extension to stdout
266 # If not found, echoes nothing on stdout.
267 CT_GetFileExtension() {
271 CT_Pushd "${CT_TARBALLS_DIR}"
272 # we need to also check for an empty extension for those very
273 # peculiar components that don't have one (such as sstrip from
275 for ext in .tar.gz .tar.bz2 .tgz .tar ''; do
276 if [ -f "${file}${ext}" ]; then
286 # Download an URL using wget
287 # Usage: CT_DoGetFileWget <URL>
289 # Need to return true because it is legitimate to not find the tarball at
290 # some of the provided URLs (think about snapshots, different layouts for
291 # different gcc versions, etc...)
292 # Some (very old!) FTP server might not support the passive mode, thus
294 # With automated download as we are doing, it can be very dangerous to use
295 # -c to continue the downloads. It's far better to simply overwrite the
297 # Some company networks have firewalls to connect to the internet, but it's
298 # not easy to detect them, and wget does not timeout by default while
299 # connecting, so force a global ${CT_CONNECT_TIMEOUT}-second timeout.
300 wget -T ${CT_CONNECT_TIMEOUT} -nc --progress=dot:binary --tries=3 --passive-ftp "$1" \
301 || wget -T ${CT_CONNECT_TIMEOUT} -nc --progress=dot:binary --tries=3 "$1" \
305 # Download an URL using curl
306 # Usage: CT_DoGetFileCurl <URL>
308 # Note: comments about wget method (above) are also valid here
309 # Plus: no good progress indicator is available with curl,
310 # so output is consigned to oblivion
311 curl --ftp-pasv -O --retry 3 "$1" --connect-timeout ${CT_CONNECT_TIMEOUT} >/dev/null \
312 || curl -O --retry 3 "$1" --connect-timeout ${CT_CONNECT_TIMEOUT} >/dev/null \
316 _wget=$(CT_Which wget)
317 _curl=$(CT_Which curl)
318 # Wrapper function to call one of curl or wget
319 # Usage: CT_DoGetFile <URL>
321 case "${_wget},${_curl}" in
322 ,) CT_DoError "Could find neither wget nor curl";;
323 ,*) CT_DoGetFileCurl "$1" 2>&1 |CT_DoLog ALL;;
324 *) CT_DoGetFileWget "$1" 2>&1 |CT_DoLog ALL;;
328 # Download the file from one of the URLs passed as argument
329 # Usage: CT_GetFile <filename> [extension] <url> [url ...]
337 .tar.bz2|.tar.gz|.tgz|.tar)
343 # Do we already have it?
344 ext=$(CT_GetFileExtension "${file}")
345 if [ -n "${ext}" ]; then
346 CT_DoLog DEBUG "Already have '${file}'"
350 CT_Pushd "${CT_TARBALLS_DIR}"
351 # We'd rather have a bzip2'ed tarball, then gzipped tarball, plain tarball,
352 # or, as a failover, a file without extension.
353 # Try local copy first, if it exists
354 for ext in ${first_ext} .tar.bz2 .tar.gz .tgz .tar ''; do
355 CT_DoLog DEBUG "Trying '${CT_LOCAL_TARBALLS_DIR}/${file}${ext}'"
356 if [ -r "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" -a \
357 "${CT_FORCE_DOWNLOAD}" != "y" ]; then
358 CT_DoLog EXTRA "Using '${file}' from local storage"
359 ln -sv "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" "${file}${ext}" |CT_DoLog ALL
364 CT_DoLog EXTRA "Retrieving '${file}' from network"
365 for ext in ${first_ext} .tar.bz2 .tar.gz .tgz .tar ''; do
366 # Try all urls in turn
368 CT_DoLog DEBUG "Trying '${url}/${file}${ext}'"
369 CT_DoGetFile "${url}/${file}${ext}"
370 if [ -f "${file}${ext}" ]; then
371 # No need to test if the file already exists because
372 # it does NOT. If it did exist, we'd have been stopped
373 # above, when looking for local copies.
374 if [ "${CT_SAVE_TARBALLS}" = "y" ]; then
375 CT_DoLog EXTRA "Saving '${file}' to local storage"
376 mv "${file}${ext}" "${CT_LOCAL_TARBALLS_DIR}" |CT_DoLog ALL
377 ln -sv "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" "${file}${ext}" |CT_DoLog ALL
385 CT_Abort "Could not download '${file}', and not present in '${CT_LOCAL_TARBALLS_DIR}'"
388 # Extract a tarball and patch the resulting sources if necessary.
389 # Some tarballs need to be extracted in specific places. Eg.: glibc addons
390 # must be extracted in the glibc directory; uCLibc locales must be extracted
391 # in the extra/locale sub-directory of uClibc.
392 CT_ExtractAndPatch() {
394 local base_file=$(echo "${file}" |cut -d - -f 1)
395 local ver_file=$(echo "${file}" |cut -d - -f 2-)
396 local official_patch_dir
397 local custom_patch_dir
399 local ext=$(CT_GetFileExtension "${file}")
400 CT_TestAndAbort "'${file}' not found in '${CT_TARBALLS_DIR}'" -z "${ext}"
401 local full_file="${CT_TARBALLS_DIR}/${file}${ext}"
403 CT_Pushd "${CT_SRC_DIR}"
405 # Add-ons need a little love, really.
408 CT_TestAndAbort "Trying to extract the C-library addon/locales '${file}' when C-library not yet extracted" ! -d "${CT_LIBC_FILE}"
411 [ -f ".${file}.extracted" ] && return 0
412 touch ".${file}.extracted"
415 CT_TestAndAbort "Trying to extract the C-library addon/locales '${file}' when C-library not yet extracted" ! -d "${CT_LIBC_FILE}"
416 cd "${CT_LIBC_FILE}/extra/locale"
418 [ -f ".${file}.extracted" ] && return 0
419 touch ".${file}.extracted"
423 # If the directory exists, then consider extraction and patching done
424 if [ -d "${file}" ]; then
425 CT_DoLog DEBUG "Already extracted '${file}'"
429 CT_DoLog EXTRA "Extracting '${file}'"
431 .tar.bz2) tar xvjf "${full_file}" |CT_DoLog ALL;;
432 .tar.gz|.tgz) tar xvzf "${full_file}" |CT_DoLog ALL;;
433 .tar) tar xvf "${full_file}" |CT_DoLog ALL;;
434 *) CT_Abort "Don't know how to handle '${file}': unknown extension" ;;
437 # Snapshots might not have the version number in the extracted directory
438 # name. This is also the case for some (odd) packages, such as D.U.M.A.
439 # Overcome this issue by symlink'ing the directory.
440 if [ ! -d "${file}" -a "${libc_addon}" != "y" ]; then
442 .tar.bz2) base=$(tar tjf "${full_file}" |head -n 1 |cut -d / -f 1 || true);;
443 .tar.gz|.tgz) base=$(tar tzf "${full_file}" |head -n 1 |cut -d / -f 1 || true);;
444 .tar) base=$(tar tf "${full_file}" |head -n 1 |cut -d / -f 1 || true);;
446 CT_TestOrAbort "There was a problem when extracting '${file}'" -d "${base}" -o "${base}" != "${file}"
447 ln -s "${base}" "${file}"
450 # Kludge: outside this function, we wouldn't know if we had just extracted
451 # a libc addon, or a plain package. Apply patches now.
452 CT_DoLog EXTRA "Patching '${file}'"
454 if [ "${libc_addon}" = "y" ]; then
455 # Some addon tarballs directly contain the correct addon directory,
456 # while others have the addon directory named after the tarball.
457 # Fix that by always using the short name (eg: linuxthreads, ports, etc...)
458 addon_short_name=$(echo "${file}" |sed -r -e 's/^[^-]+-//; s/-[^-]+$//;')
459 [ -d "${addon_short_name}" ] || ln -s "${file}" "${addon_short_name}"
460 # If libc addon, we're already in the correct place
467 [ "${CUSTOM_PATCH_ONLY}" = "y" ] || official_patch_dir="${CT_LIB_DIR}/patches/${base_file}/${ver_file}"
468 [ "${CT_CUSTOM_PATCH}" = "y" ] && custom_patch_dir="${CT_CUSTOM_PATCH_DIR}/${base_file}/${ver_file}"
469 for patch_dir in "${official_patch_dir}" "${custom_patch_dir}"; do
470 if [ -n "${patch_dir}" -a -d "${patch_dir}" ]; then
471 for p in "${patch_dir}"/*.patch; do
472 if [ -f "${p}" ]; then
473 CT_DoLog DEBUG "Applying patch '${p}'"
474 patch -g0 -F1 -p1 -f <"${p}" |CT_DoLog ALL
475 CT_TestAndAbort "Failed while applying patch file '${p}'" ${PIPESTATUS[0]} -ne 0
481 if [ "${CT_OVERIDE_CONFIG_GUESS_SUB}" = "y" ]; then
482 CT_DoLog ALL "Overiding config.guess and config.sub"
483 for cfg in config_guess config_sub; do
484 eval ${cfg}="${CT_LIB_DIR}/tools/${cfg/_/.}"
485 [ -e "${CT_TOP_DIR}/tools/${cfg/_/.}" ] && eval ${cfg}="${CT_TOP_DIR}/tools/${cfg/_/.}"
486 find . -type f -name "${cfg/_/.}" -exec cp -v "${!cfg}" {} \; |CT_DoLog ALL
493 # Two wrappers to call config.(guess|sub) either from CT_TOP_DIR or CT_LIB_DIR.
494 # Those from CT_TOP_DIR, if they exist, will be be more recent than those from CT_LIB_DIR.
496 if [ -x "${CT_TOP_DIR}/tools/config.guess" ]; then
497 "${CT_TOP_DIR}/tools/config.guess"
499 "${CT_LIB_DIR}/tools/config.guess"
504 if [ -x "${CT_TOP_DIR}/tools/config.sub" ]; then
505 "${CT_TOP_DIR}/tools/config.sub" "$@"
507 "${CT_LIB_DIR}/tools/config.sub" "$@"
511 # Compute the target tuple from what is provided by the user
512 # Usage: CT_DoBuildTargetTuple
513 # In fact this function takes the environment variables to build the target
514 # tuple. It is needed both by the normal build sequence, as well as the
515 # sample saving sequence.
516 CT_DoBuildTargetTuple() {
517 # Set the endianness suffix, and the default endianness gcc option
518 case "${CT_ARCH_BE},${CT_ARCH_LE}" in
519 y,) target_endian_eb=eb
521 CT_ARCH_ENDIAN_CFLAG="-mbig-endian"
522 CT_ARCH_ENDIAN_LDFLAG="-EB"
524 ,y) target_endian_eb=
526 CT_ARCH_ENDIAN_CFLAG="-mlittle-endian"
527 CT_ARCH_ENDIAN_LDFLAG="-EL"
531 # Set defaults for the system part of the tuple. Can be overriden
532 # by architecture-specific values.
534 glibc) CT_TARGET_SYS=gnu;;
535 uClibc) CT_TARGET_SYS=uclibc;;
538 # Transform the ARCH into a kernel-understandable ARCH
539 CT_KERNEL_ARCH="${CT_ARCH}"
541 # Set the default values for ARCH, ABI, CPU, TUNE, FPU and FLOAT
542 unset CT_ARCH_ARCH_CFLAG CT_ARCH_ABI_CFLAG CT_ARCH_CPU_CFLAG CT_ARCH_TUNE_CFLAG CT_ARCH_FPU_CFLAG CT_ARCH_FLOAT_CFLAG
543 unset CT_ARCH_WITH_ARCH CT_ARCH_WITH_ABI CT_ARCH_WITH_CPU CT_ARCH_WITH_TUNE CT_ARCH_WITH_FPU CT_ARCH_WITH_FLOAT
544 [ "${CT_ARCH_ARCH}" ] && { CT_ARCH_ARCH_CFLAG="-march=${CT_ARCH_ARCH}"; CT_ARCH_WITH_ARCH="--with-arch=${CT_ARCH_ARCH}"; }
545 [ "${CT_ARCH_ABI}" ] && { CT_ARCH_ABI_CFLAG="-mabi=${CT_ARCH_ABI}"; CT_ARCH_WITH_ABI="--with-abi=${CT_ARCH_ABI}"; }
546 [ "${CT_ARCH_CPU}" ] && { CT_ARCH_CPU_CFLAG="-mcpu=${CT_ARCH_CPU}"; CT_ARCH_WITH_CPU="--with-cpu=${CT_ARCH_CPU}"; }
547 [ "${CT_ARCH_TUNE}" ] && { CT_ARCH_TUNE_CFLAG="-mtune=${CT_ARCH_TUNE}"; CT_ARCH_WITH_TUNE="--with-tune=${CT_ARCH_TUNE}"; }
548 [ "${CT_ARCH_FPU}" ] && { CT_ARCH_FPU_CFLAG="-mfpu=${CT_ARCH_FPU}"; CT_ARCH_WITH_FPU="--with-fpu=${CT_ARCH_FPU}"; }
549 [ "${CT_ARCH_FLOAT_SW}" ] && { CT_ARCH_FLOAT_CFLAG="-msoft-float"; CT_ARCH_WITH_FLOAT="--with-float=soft"; }
551 # Call the architecture specific settings
554 # Finish the target tuple construction
555 case "${CT_KERNEL}" in
556 linux*) CT_TARGET_KERNEL=linux;;
558 CT_TARGET=$(CT_DoConfigSub "${CT_TARGET_ARCH}-${CT_TARGET_VENDOR:-unknown}-${CT_TARGET_KERNEL}-${CT_TARGET_SYS}")
560 # Prepare the target CFLAGS
561 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_ENDIAN_CFLAG}"
562 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ARCH_CFLAG}"
563 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ABI_CFLAG}"
564 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_CPU_CFLAG}"
565 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_TUNE_CFLAG}"
566 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_FPU_CFLAG}"
567 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_FLOAT_CFLAG}"
569 # Now on for the target LDFLAGS
570 CT_ARCH_TARGET_LDFLAGS="${CT_ARCH_ENDIAN_LDFLAG}"
573 # This function does pause the build until the user strikes "Return"
574 # Usage: CT_DoPause [optional_message]
577 local message="${1:-Pausing for your pleasure}"
578 CT_DoLog INFO "${message}"
579 read -p "Press 'Enter' to continue, or Ctrl-C to stop..." foo >&6
583 # This function saves the state of the toolchain to be able to restart
585 # Usage: CT_DoSaveState <next_step_name>
587 [ "${CT_DEBUG_CT_SAVE_STEPS}" = "y" ] || return 0
588 local state_name="$1"
589 local state_dir="${CT_STATE_DIR}/${state_name}"
591 CT_DoLog DEBUG "Saving state to restart at step '${state_name}'..."
592 rm -rf "${state_dir}"
593 mkdir -p "${state_dir}"
595 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
596 y) tar_opt=z; tar_ext=.gz;;
597 *) tar_opt=; tar_ext=;;
600 CT_DoLog DEBUG " Saving environment and aliases"
601 # We must omit shell functions
604 $0~/^[^ ]+ \(\)/ { _p = 0; }
606 $0 == "}" { _p = 1; }
607 ' >"${state_dir}/env.sh"
609 CT_DoLog DEBUG " Saving CT_CC_CORE_STATIC_PREFIX_DIR='${CT_CC_CORE_STATIC_PREFIX_DIR}'"
610 CT_Pushd "${CT_CC_CORE_STATIC_PREFIX_DIR}"
611 tar cv${tar_opt}f "${state_dir}/cc_core_static_prefix_dir.tar${tar_ext}" . |CT_DoLog DEBUG
614 CT_DoLog DEBUG " Saving CT_CC_CORE_SHARED_PREFIX_DIR='${CT_CC_CORE_SHARED_PREFIX_DIR}'"
615 CT_Pushd "${CT_CC_CORE_SHARED_PREFIX_DIR}"
616 tar cv${tar_opt}f "${state_dir}/cc_core_shared_prefix_dir.tar${tar_ext}" . |CT_DoLog DEBUG
619 CT_DoLog DEBUG " Saving CT_PREFIX_DIR='${CT_PREFIX_DIR}'"
620 CT_Pushd "${CT_PREFIX_DIR}"
621 tar cv${tar_opt}f "${state_dir}/prefix_dir.tar${tar_ext}" --exclude '*.log' . |CT_DoLog DEBUG
624 if [ "${CT_LOG_TO_FILE}" = "y" ]; then
625 CT_DoLog DEBUG " Saving log file"
627 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
628 y) gzip -3 -c "${CT_LOG_FILE}" >"${state_dir}/log.gz";;
629 *) cat "${CT_LOG_FILE}" >"${state_dir}/log";;
631 exec >>"${CT_LOG_FILE}"
635 # This function restores a previously saved state
636 # Usage: CT_DoLoadState <state_name>
638 local state_name="$1"
639 local state_dir="${CT_STATE_DIR}/${state_name}"
640 local old_RESTART="${CT_RESTART}"
641 local old_STOP="${CT_STOP}"
643 CT_TestOrAbort "The previous build did not reach the point where it could be restarted at '${CT_RESTART}'" -d "${state_dir}"
645 # We need to do something special with the log file!
646 if [ "${CT_LOG_TO_FILE}" = "y" ]; then
647 exec >"${state_dir}/tail.log"
649 CT_DoLog INFO "Restoring state at step '${state_name}', as requested."
651 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
652 y) tar_opt=z; tar_ext=.gz;;
653 *) tar_opt=; tar_ext=;;
656 CT_DoLog DEBUG " Removing previous build directories"
657 chmod -R u+rwX "${CT_PREFIX_DIR}" "${CT_CC_CORE_SHARED_PREFIX_DIR}" "${CT_CC_CORE_STATIC_PREFIX_DIR}"
658 rm -rf "${CT_PREFIX_DIR}" "${CT_CC_CORE_SHARED_PREFIX_DIR}" "${CT_CC_CORE_STATIC_PREFIX_DIR}"
659 mkdir -p "${CT_PREFIX_DIR}" "${CT_CC_CORE_SHARED_PREFIX_DIR}" "${CT_CC_CORE_STATIC_PREFIX_DIR}"
661 CT_DoLog DEBUG " Restoring CT_PREFIX_DIR='${CT_PREFIX_DIR}'"
662 CT_Pushd "${CT_PREFIX_DIR}"
663 tar xv${tar_opt}f "${state_dir}/prefix_dir.tar${tar_ext}" |CT_DoLog DEBUG
666 CT_DoLog DEBUG " Restoring CT_CC_CORE_SHARED_PREFIX_DIR='${CT_CC_CORE_SHARED_PREFIX_DIR}'"
667 CT_Pushd "${CT_CC_CORE_SHARED_PREFIX_DIR}"
668 tar xv${tar_opt}f "${state_dir}/cc_core_shared_prefix_dir.tar${tar_ext}" |CT_DoLog DEBUG
671 CT_DoLog DEBUG " Restoring CT_CC_CORE_STATIC_PREFIX_DIR='${CT_CC_CORE_STATIC_PREFIX_DIR}'"
672 CT_Pushd "${CT_CC_CORE_STATIC_PREFIX_DIR}"
673 tar xv${tar_opt}f "${state_dir}/cc_core_static_prefix_dir.tar${tar_ext}" |CT_DoLog DEBUG
676 # Restore the environment, discarding any error message
677 # (for example, read-only bash internals)
678 CT_DoLog DEBUG " Restoring environment"
679 . "${state_dir}/env.sh" >/dev/null 2>&1 || true
681 # Restore the new RESTART and STOP steps
682 CT_RESTART="${old_RESTART}"
683 CT_STOP="${old_STOP}"
684 unset old_stop old_restart
686 if [ "${CT_LOG_TO_FILE}" = "y" ]; then
687 CT_DoLog DEBUG " Restoring log file"
689 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
690 y) zcat "${state_dir}/log.gz" >"${CT_LOG_FILE}";;
691 *) cat "${state_dir}/log" >"${CT_LOG_FILE}";;
693 cat "${state_dir}/tail.log" >>"${CT_LOG_FILE}"
694 exec >>"${CT_LOG_FILE}"
695 rm -f "${state_dir}/tail.log"