Introduce target-specific LDFLAGS, the same way we have CFLAGS for the target.
It seems to be helping gcc somewhat into telling the correct endianness to ld that sticks with little endian even when the target is big (eg armeb-unknown-linux-uclibcgnueabi).
There's still work to do, especially finish the gcc part that is not in this commit.
/trunk/scripts/functions | 9 7 2 0 +++++++--
1 file changed, 7 insertions(+), 2 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 # Tail message to be logged whatever happens
109 # Usage: CT_DoEnd <level>
113 CT_STOP_DATE=$(CT_DoDate +%s%N)
114 CT_STOP_DATE_HUMAN=$(CT_DoDate +%Y%m%d.%H%M%S)
115 CT_DoLog "${level:-INFO}" "Build completed at ${CT_STOP_DATE_HUMAN}"
116 elapsed=$((CT_STOP_DATE-CT_STAR_DATE))
117 elapsed_min=$((elapsed/(60*1000*1000*1000)))
118 elapsed_sec=$(printf "%02d" $(((elapsed%(60*1000*1000*1000))/(1000*1000*1000))))
119 elapsed_csec=$(printf "%02d" $(((elapsed%(1000*1000*1000))/(10*1000*1000))))
120 CT_DoLog ${level:-INFO} "(elapsed: ${elapsed_min}:${elapsed_sec}.${elapsed_csec})"
123 # Abort the execution with an error message
124 # Usage: CT_Abort <message>
130 # Test a condition, and print a message if satisfied
131 # Usage: CT_Test <message> <tests>
136 test "$@" && CT_DoLog WARN "$m"
140 # Test a condition, and abort with an error message if satisfied
141 # Usage: CT_TestAndAbort <message> <tests>
145 test "$@" && CT_Abort "$m"
149 # Test a condition, and abort with an error message if not satisfied
150 # Usage: CT_TestAndAbort <message> <tests>
154 test "$@" || CT_Abort "$m"
158 # Test the presence of a tool, or abort if not found
159 # Usage: CT_HasOrAbort <tool>
161 CT_TestAndAbort "'${1}' not found and needed for successful toolchain build." -z ""$(CT_Which "${1}")
165 # Search a program: wrap "which" for those system where
166 # "which" verbosely says there is no match (Mdk are such
168 # Usage: CT_Which <filename>
170 which "$1" 2>/dev/null || true
173 # Get current date with nanosecond precision
174 # On those system not supporting nanosecond precision, faked with rounding down
175 # to the highest entire second
176 # Usage: CT_DoDate <fmt>
178 date "$1" |sed -r -e 's/%N$/000000000/;'
182 CT_STEP_MESSAGE[${CT_STEP_COUNT}]="<none>"
183 # Memorise a step being done so that any error is caught
184 # Usage: CT_DoStep <loglevel> <message>
186 local start=$(CT_DoDate +%s%N)
187 CT_DoLog "$1" "================================================================="
189 CT_STEP_COUNT=$((CT_STEP_COUNT+1))
190 CT_STEP_LEVEL[${CT_STEP_COUNT}]="$1"; shift
191 CT_STEP_START[${CT_STEP_COUNT}]="${start}"
192 CT_STEP_MESSAGE[${CT_STEP_COUNT}]="$1"
196 # End the step just being done
199 local stop=$(CT_DoDate +%s%N)
200 local duration=$(printf "%032d" $((stop-${CT_STEP_START[${CT_STEP_COUNT}]})) |sed -r -e 's/([[:digit:]]{2})[[:digit:]]{7}$/\.\1/; s/^0+//; s/^\./0\./;')
201 local level="${CT_STEP_LEVEL[${CT_STEP_COUNT}]}"
202 local message="${CT_STEP_MESSAGE[${CT_STEP_COUNT}]}"
203 CT_STEP_COUNT=$((CT_STEP_COUNT-1))
204 CT_DoLog "${level}" "${message}: done in ${duration}s"
208 # Pushes into a directory, and pops back
210 pushd "$1" >/dev/null 2>&1
216 # Makes a path absolute
217 # Usage: CT_MakeAbsolutePath path
218 CT_MakeAbsolutePath() {
219 # Try to cd in that directory
225 # No such directory, fail back to guessing
228 *) echo "$(pwd)/$1";;
235 # Creates a temporary directory
236 # $1: variable to assign to
237 # Usage: CT_MktempDir foo
239 # Some mktemp do not allow more than 6 Xs
240 eval "$1"=$(mktemp -q -d "${CT_BUILD_DIR}/.XXXXXX")
241 CT_TestOrAbort "Could not make temporary directory" -n "${!1}" -a -d "${!1}"
244 # Echoes the specified string on stdout until the pipe breaks.
247 # Usage: CT_DoYes "" |make oldconfig
252 # Get the file name extension of a component
253 # Usage: CT_GetFileExtension <component_name-component_version>
254 # If found, echoes the extension to stdout
255 # If not found, echoes nothing on stdout.
256 CT_GetFileExtension() {
260 CT_Pushd "${CT_TARBALLS_DIR}"
261 # we need to also check for an empty extension for those very
262 # peculiar components that don't have one (such as sstrip from
264 for ext in .tar.gz .tar.bz2 .tgz .tar ''; do
265 if [ -f "${file}${ext}" ]; then
275 # Download an URL using wget
276 # Usage: CT_DoGetFileWget <URL>
278 # Need to return true because it is legitimate to not find the tarball at
279 # some of the provided URLs (think about snapshots, different layouts for
280 # different gcc versions, etc...)
281 # Some (very old!) FTP server might not support the passive mode, thus
283 # With automated download as we are doing, it can be very dangerous to use
284 # -c to continue the downloads. It's far better to simply overwrite the
286 # Some company networks have firewalls to connect to the internet, but it's
287 # not easy to detect them, and wget does not timeout by default while
288 # connecting, so force a global ${CT_CONNECT_TIMEOUT}-second timeout.
289 wget -T ${CT_CONNECT_TIMEOUT} -nc --progress=dot:binary --tries=3 --passive-ftp "$1" \
290 || wget -T ${CT_CONNECT_TIMEOUT} -nc --progress=dot:binary --tries=3 "$1" \
294 # Download an URL using curl
295 # Usage: CT_DoGetFileCurl <URL>
297 # Note: comments about wget method (above) are also valid here
298 # Plus: no good progress indicator is available with curl,
299 # so output is consigned to oblivion
300 curl --ftp-pasv -O --retry 3 "$1" --connect-timeout ${CT_CONNECT_TIMEOUT} >/dev/null \
301 || curl -O --retry 3 "$1" --connect-timeout ${CT_CONNECT_TIMEOUT} >/dev/null \
305 _wget=$(CT_Which wget)
306 _curl=$(CT_Which curl)
307 # Wrapper function to call one of curl or wget
308 # Usage: CT_DoGetFile <URL>
310 case "${_wget},${_curl}" in
311 ,) CT_DoError "Could find neither wget nor curl";;
312 ,*) CT_DoGetFileCurl "$1" 2>&1 |CT_DoLog ALL;;
313 *) CT_DoGetFileWget "$1" 2>&1 |CT_DoLog ALL;;
317 # Download the file from one of the URLs passed as argument
318 # Usage: CT_GetFile <filename> [extension] <url> [url ...]
326 .tar.bz2|.tar.gz|.tgz|.tar)
332 # Do we already have it?
333 ext=$(CT_GetFileExtension "${file}")
334 if [ -n "${ext}" ]; then
335 CT_DoLog DEBUG "Already have '${file}'"
339 CT_Pushd "${CT_TARBALLS_DIR}"
340 # We'd rather have a bzip2'ed tarball, then gzipped tarball, plain tarball,
341 # or, as a failover, a file without extension.
342 # Try local copy first, if it exists
343 for ext in ${first_ext} .tar.bz2 .tar.gz .tgz .tar ''; do
344 CT_DoLog DEBUG "Trying '${CT_LOCAL_TARBALLS_DIR}/${file}${ext}'"
345 if [ -r "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" -a \
346 "${CT_FORCE_DOWNLOAD}" != "y" ]; then
347 CT_DoLog EXTRA "Using '${file}' from local storage"
348 ln -sv "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" "${file}${ext}" |CT_DoLog ALL
353 CT_DoLog EXTRA "Retrieving '${file}' from network"
354 for ext in ${first_ext} .tar.bz2 .tar.gz .tgz .tar ''; do
355 # Try all urls in turn
357 CT_DoLog DEBUG "Trying '${url}/${file}${ext}'"
358 CT_DoGetFile "${url}/${file}${ext}"
359 if [ -f "${file}${ext}" ]; then
360 # No need to test if the file already exists because
361 # it does NOT. If it did exist, we'd have been stopped
362 # above, when looking for local copies.
363 if [ "${CT_SAVE_TARBALLS}" = "y" ]; then
364 CT_DoLog EXTRA "Saving '${file}' to local storage"
365 mv "${file}${ext}" "${CT_LOCAL_TARBALLS_DIR}" |CT_DoLog ALL
366 ln -sv "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" "${file}${ext}" |CT_DoLog ALL
374 CT_Abort "Could not download '${file}', and not present in '${CT_LOCAL_TARBALLS_DIR}'"
377 # Extract a tarball and patch the resulting sources if necessary.
378 # Some tarballs need to be extracted in specific places. Eg.: glibc addons
379 # must be extracted in the glibc directory; uCLibc locales must be extracted
380 # in the extra/locale sub-directory of uClibc.
381 CT_ExtractAndPatch() {
383 local base_file=$(echo "${file}" |cut -d - -f 1)
384 local ver_file=$(echo "${file}" |cut -d - -f 2-)
385 local official_patch_dir
386 local custom_patch_dir
388 local ext=$(CT_GetFileExtension "${file}")
389 CT_TestAndAbort "'${file}' not found in '${CT_TARBALLS_DIR}'" -z "${ext}"
390 local full_file="${CT_TARBALLS_DIR}/${file}${ext}"
392 CT_Pushd "${CT_SRC_DIR}"
394 # Add-ons need a little love, really.
397 CT_TestAndAbort "Trying to extract the C-library addon/locales '${file}' when C-library not yet extracted" ! -d "${CT_LIBC_FILE}"
400 [ -f ".${file}.extracted" ] && return 0
401 touch ".${file}.extracted"
404 CT_TestAndAbort "Trying to extract the C-library addon/locales '${file}' when C-library not yet extracted" ! -d "${CT_LIBC_FILE}"
405 cd "${CT_LIBC_FILE}/extra/locale"
407 [ -f ".${file}.extracted" ] && return 0
408 touch ".${file}.extracted"
412 # If the directory exists, then consider extraction and patching done
413 if [ -d "${file}" ]; then
414 CT_DoLog DEBUG "Already extracted '${file}'"
418 CT_DoLog EXTRA "Extracting '${file}'"
420 .tar.bz2) tar xvjf "${full_file}" |CT_DoLog ALL;;
421 .tar.gz|.tgz) tar xvzf "${full_file}" |CT_DoLog ALL;;
422 .tar) tar xvf "${full_file}" |CT_DoLog ALL;;
423 *) CT_Abort "Don't know how to handle '${file}': unknown extension" ;;
426 # Snapshots might not have the version number in the extracted directory
427 # name. This is also the case for some (odd) packages, such as D.U.M.A.
428 # Overcome this issue by symlink'ing the directory.
429 if [ ! -d "${file}" -a "${libc_addon}" != "y" ]; then
431 .tar.bz2) base=$(tar tjf "${full_file}" |head -n 1 |cut -d / -f 1 || true);;
432 .tar.gz|.tgz) base=$(tar tzf "${full_file}" |head -n 1 |cut -d / -f 1 || true);;
433 .tar) base=$(tar tf "${full_file}" |head -n 1 |cut -d / -f 1 || true);;
435 CT_TestOrAbort "There was a problem when extracting '${file}'" -d "${base}" -o "${base}" != "${file}"
436 ln -s "${base}" "${file}"
439 # Kludge: outside this function, we wouldn't know if we had just extracted
440 # a libc addon, or a plain package. Apply patches now.
441 CT_DoLog EXTRA "Patching '${file}'"
443 if [ "${libc_addon}" = "y" ]; then
444 # Some addon tarballs directly contain the correct addon directory,
445 # while others have the addon directory named after the tarball.
446 # Fix that by always using the short name (eg: linuxthreads, ports, etc...)
447 addon_short_name=$(echo "${file}" |sed -r -e 's/^[^-]+-//; s/-[^-]+$//;')
448 [ -d "${addon_short_name}" ] || ln -s "${file}" "${addon_short_name}"
449 # If libc addon, we're already in the correct place
456 [ "${CUSTOM_PATCH_ONLY}" = "y" ] || official_patch_dir="${CT_LIB_DIR}/patches/${base_file}/${ver_file}"
457 [ "${CT_CUSTOM_PATCH}" = "y" ] && custom_patch_dir="${CT_CUSTOM_PATCH_DIR}/${base_file}/${ver_file}"
458 for patch_dir in "${official_patch_dir}" "${custom_patch_dir}"; do
459 if [ -n "${patch_dir}" -a -d "${patch_dir}" ]; then
460 for p in "${patch_dir}"/*.patch; do
461 if [ -f "${p}" ]; then
462 CT_DoLog DEBUG "Applying patch '${p}'"
463 patch -g0 -F1 -p1 -f <"${p}" |CT_DoLog ALL
464 CT_TestAndAbort "Failed while applying patch file '${p}'" ${PIPESTATUS[0]} -ne 0
470 if [ "${CT_OVERIDE_CONFIG_GUESS_SUB}" = "y" ]; then
471 CT_DoLog ALL "Overiding config.guess and config.sub"
472 for cfg in config_guess config_sub; do
473 eval ${cfg}="${CT_LIB_DIR}/tools/${cfg/_/.}"
474 [ -e "${CT_TOP_DIR}/tools/${cfg/_/.}" ] && eval ${cfg}="${CT_TOP_DIR}/tools/${cfg/_/.}"
475 find . -type f -name "${cfg/_/.}" -exec cp -v "${!cfg}" {} \; |CT_DoLog ALL
482 # Two wrappers to call config.(guess|sub) either from CT_TOP_DIR or CT_LIB_DIR.
483 # Those from CT_TOP_DIR, if they exist, will be be more recent than those from CT_LIB_DIR.
485 if [ -x "${CT_TOP_DIR}/tools/config.guess" ]; then
486 "${CT_TOP_DIR}/tools/config.guess"
488 "${CT_LIB_DIR}/tools/config.guess"
493 if [ -x "${CT_TOP_DIR}/tools/config.sub" ]; then
494 "${CT_TOP_DIR}/tools/config.sub" "$@"
496 "${CT_LIB_DIR}/tools/config.sub" "$@"
500 # Compute the target tuple from what is provided by the user
501 # Usage: CT_DoBuildTargetTuple
502 # In fact this function takes the environment variables to build the target
503 # tuple. It is needed both by the normal build sequence, as well as the
504 # sample saving sequence.
505 CT_DoBuildTargetTuple() {
506 # Set the endianness suffix, and the default endianness gcc option
507 case "${CT_ARCH_BE},${CT_ARCH_LE}" in
508 y,) target_endian_eb=eb
510 CT_ARCH_ENDIAN_CFLAG="-mbig-endian"
511 CT_ARCH_ENDIAN_LDFLAG="-EB"
513 ,y) target_endian_eb=
515 CT_ARCH_ENDIAN_CFLAG="-mlittle-endian"
516 CT_ARCH_ENDIAN_LDFLAG="-EL"
520 # Set defaults for the system part of the tuple. Can be overriden
521 # by architecture-specific values.
523 glibc) CT_TARGET_SYS=gnu;;
524 uClibc) CT_TARGET_SYS=uclibc;;
527 # Transform the ARCH into a kernel-understandable ARCH
528 CT_KERNEL_ARCH="${CT_ARCH}"
530 # Set the default values for ARCH, ABI, CPU, TUNE, FPU and FLOAT
531 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
532 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
533 [ "${CT_ARCH_ARCH}" ] && { CT_ARCH_ARCH_CFLAG="-march=${CT_ARCH_ARCH}"; CT_ARCH_WITH_ARCH="--with-arch=${CT_ARCH_ARCH}"; }
534 [ "${CT_ARCH_ABI}" ] && { CT_ARCH_ABI_CFLAG="-mabi=${CT_ARCH_ABI}"; CT_ARCH_WITH_ABI="--with-abi=${CT_ARCH_ABI}"; }
535 [ "${CT_ARCH_CPU}" ] && { CT_ARCH_CPU_CFLAG="-mcpu=${CT_ARCH_CPU}"; CT_ARCH_WITH_CPU="--with-cpu=${CT_ARCH_CPU}"; }
536 [ "${CT_ARCH_TUNE}" ] && { CT_ARCH_TUNE_CFLAG="-mtune=${CT_ARCH_TUNE}"; CT_ARCH_WITH_TUNE="--with-tune=${CT_ARCH_TUNE}"; }
537 [ "${CT_ARCH_FPU}" ] && { CT_ARCH_FPU_CFLAG="-mfpu=${CT_ARCH_FPU}"; CT_ARCH_WITH_FPU="--with-fpu=${CT_ARCH_FPU}"; }
538 [ "${CT_ARCH_FLOAT_SW}" ] && { CT_ARCH_FLOAT_CFLAG="-msoft-float"; CT_ARCH_WITH_FLOAT="--with-float=soft"; }
540 # Call the architecture specific settings
543 # Finish the target tuple construction
544 case "${CT_KERNEL}" in
545 linux*) CT_TARGET_KERNEL=linux;;
547 CT_TARGET=$(CT_DoConfigSub "${CT_TARGET_ARCH}-${CT_TARGET_VENDOR:-unknown}-${CT_TARGET_KERNEL}-${CT_TARGET_SYS}")
549 # Prepare the target CFLAGS
550 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_ENDIAN_CFLAG}"
551 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ARCH_CFLAG}"
552 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ABI_CFLAG}"
553 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_CPU_CFLAG}"
554 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_TUNE_CFLAG}"
555 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_FPU_CFLAG}"
556 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_FLOAT_CFLAG}"
558 # Now on for the target LDFLAGS
559 CT_ARCH_TARGET_LDFLAGS="${CT_ARCH_ENDIAN_LDFLAG}"
562 # This function does pause the build until the user strikes "Return"
563 # Usage: CT_DoPause [optional_message]
566 local message="${1:-Pausing for your pleasure}"
567 CT_DoLog INFO "${message}"
568 read -p "Press 'Enter' to continue, or Ctrl-C to stop..." foo >&6
572 # This function saves the state of the toolchain to be able to restart
574 # Usage: CT_DoSaveState <next_step_name>
576 [ "${CT_DEBUG_CT_SAVE_STEPS}" = "y" ] || return 0
577 local state_name="$1"
578 local state_dir="${CT_STATE_DIR}/${state_name}"
580 CT_DoLog DEBUG "Saving state to restart at step '${state_name}'..."
581 rm -rf "${state_dir}"
582 mkdir -p "${state_dir}"
584 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
585 y) tar_opt=z; tar_ext=.gz;;
586 *) tar_opt=; tar_ext=;;
589 CT_DoLog DEBUG " Saving environment and aliases"
590 # We must omit shell functions
593 $0~/^[^ ]+ \(\)/ { _p = 0; }
595 $0 == "}" { _p = 1; }
596 ' >"${state_dir}/env.sh"
598 CT_DoLog DEBUG " Saving CT_CC_CORE_STATIC_PREFIX_DIR='${CT_CC_CORE_STATIC_PREFIX_DIR}'"
599 CT_Pushd "${CT_CC_CORE_STATIC_PREFIX_DIR}"
600 tar cv${tar_opt}f "${state_dir}/cc_core_static_prefix_dir.tar${tar_ext}" . |CT_DoLog DEBUG
603 CT_DoLog DEBUG " Saving CT_CC_CORE_SHARED_PREFIX_DIR='${CT_CC_CORE_SHARED_PREFIX_DIR}'"
604 CT_Pushd "${CT_CC_CORE_SHARED_PREFIX_DIR}"
605 tar cv${tar_opt}f "${state_dir}/cc_core_shared_prefix_dir.tar${tar_ext}" . |CT_DoLog DEBUG
608 CT_DoLog DEBUG " Saving CT_PREFIX_DIR='${CT_PREFIX_DIR}'"
609 CT_Pushd "${CT_PREFIX_DIR}"
610 tar cv${tar_opt}f "${state_dir}/prefix_dir.tar${tar_ext}" --exclude '*.log' . |CT_DoLog DEBUG
613 if [ "${CT_LOG_TO_FILE}" = "y" ]; then
614 CT_DoLog DEBUG " Saving log file"
616 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
617 y) gzip -3 -c "${CT_LOG_FILE}" >"${state_dir}/log.gz";;
618 *) cat "${CT_LOG_FILE}" >"${state_dir}/log";;
620 exec >>"${CT_LOG_FILE}"
624 # This function restores a previously saved state
625 # Usage: CT_DoLoadState <state_name>
627 local state_name="$1"
628 local state_dir="${CT_STATE_DIR}/${state_name}"
629 local old_RESTART="${CT_RESTART}"
630 local old_STOP="${CT_STOP}"
632 CT_TestOrAbort "The previous build did not reach the point where it could be restarted at '${CT_RESTART}'" -d "${state_dir}"
634 # We need to do something special with the log file!
635 if [ "${CT_LOG_TO_FILE}" = "y" ]; then
636 exec >"${state_dir}/tail.log"
638 CT_DoLog INFO "Restoring state at step '${state_name}', as requested."
640 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
641 y) tar_opt=z; tar_ext=.gz;;
642 *) tar_opt=; tar_ext=;;
645 CT_DoLog DEBUG " Removing previous build directories"
646 chmod -R u+rwX "${CT_PREFIX_DIR}" "${CT_CC_CORE_SHARED_PREFIX_DIR}" "${CT_CC_CORE_STATIC_PREFIX_DIR}"
647 rm -rf "${CT_PREFIX_DIR}" "${CT_CC_CORE_SHARED_PREFIX_DIR}" "${CT_CC_CORE_STATIC_PREFIX_DIR}"
648 mkdir -p "${CT_PREFIX_DIR}" "${CT_CC_CORE_SHARED_PREFIX_DIR}" "${CT_CC_CORE_STATIC_PREFIX_DIR}"
650 CT_DoLog DEBUG " Restoring CT_PREFIX_DIR='${CT_PREFIX_DIR}'"
651 CT_Pushd "${CT_PREFIX_DIR}"
652 tar xv${tar_opt}f "${state_dir}/prefix_dir.tar${tar_ext}" |CT_DoLog DEBUG
655 CT_DoLog DEBUG " Restoring CT_CC_CORE_SHARED_PREFIX_DIR='${CT_CC_CORE_SHARED_PREFIX_DIR}'"
656 CT_Pushd "${CT_CC_CORE_SHARED_PREFIX_DIR}"
657 tar xv${tar_opt}f "${state_dir}/cc_core_shared_prefix_dir.tar${tar_ext}" |CT_DoLog DEBUG
660 CT_DoLog DEBUG " Restoring CT_CC_CORE_STATIC_PREFIX_DIR='${CT_CC_CORE_STATIC_PREFIX_DIR}'"
661 CT_Pushd "${CT_CC_CORE_STATIC_PREFIX_DIR}"
662 tar xv${tar_opt}f "${state_dir}/cc_core_static_prefix_dir.tar${tar_ext}" |CT_DoLog DEBUG
665 # Restore the environment, discarding any error message
666 # (for example, read-only bash internals)
667 CT_DoLog DEBUG " Restoring environment"
668 . "${state_dir}/env.sh" >/dev/null 2>&1 || true
670 # Restore the new RESTART and STOP steps
671 CT_RESTART="${old_RESTART}"
672 CT_STOP="${old_STOP}"
673 unset old_stop old_restart
675 if [ "${CT_LOG_TO_FILE}" = "y" ]; then
676 CT_DoLog DEBUG " Restoring log file"
678 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
679 y) zcat "${state_dir}/log.gz" >"${CT_LOG_FILE}";;
680 *) cat "${state_dir}/log" >"${CT_LOG_FILE}";;
682 cat "${state_dir}/tail.log" >>"${CT_LOG_FILE}"
683 exec >>"${CT_LOG_FILE}"
684 rm -f "${state_dir}/tail.log"