scripts/addToolsVersion: properly handle .in vs. .in.2
While most components have their version in the .in file, some
have it in the .in.2 (eg. elf2flt).
Currently, to handle this case, we indiscriminately munge both files,
but this is wrong: in the elf2flt case, if we add a binutils version,
we do not want it to be added to elf2flt, and conversely.
So, for each tool, we need to explicitly know what file to munge.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
1 # This file contains some usefull common functions -*- sh -*-
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
14 # To avoid printing the backtace for each sub-shell
15 # up to the top-level, just remember we've dumped it
16 if [ ! -f "${CT_WORK_DIR}/backtrace" ]; then
17 touch "${CT_WORK_DIR}/backtrace"
19 # Print steps backtrace
20 step_depth=${CT_STEP_COUNT}
21 CT_STEP_COUNT=1 # To have a zero-indentation
25 for((step=step_depth; step>0; step--)); do
26 CT_DoLog ERROR ">> ${intro} in step '${CT_STEP_MESSAGE[${step}]}'"
30 # Print functions backtrace
31 intro="Error happened in"
33 for((depth=1; ${BASH_LINENO[$((${depth}-1))]}>0; depth++)); do
34 file="${BASH_SOURCE[${depth}]#${CT_LIB_DIR}/}"
35 func="${FUNCNAME[${depth}]}"
36 line="@${BASH_LINENO[${depth}-1]:-?}"
37 CT_DoLog ERROR ">> ${intro}: ${func}[${file}${line}]"
41 # If the user asked for interactive debugging, dump him/her to a shell
42 if [ "${CT_DEBUG_INTERACTIVE}" = "y" ]; then
43 # We do not want this sub-shell exit status to be caught, because
44 # it is absolutely legit that it exits with non-zero.
45 # Save the trap handler to restore it after our debug-shell
46 old_trap="$(trap -p ERR)"
50 printf "\r \n\nCurrent command"
51 if [ -n "${cur_cmd}" ]; then
52 printf ":\n %s\n" "${cur_cmd}"
56 printf "exited with error code: %d\n" ${ret}
57 printf "Please fix it up and finish by exiting the shell with one of these values:\n"
58 printf " 1 fixed, continue with next build command\n"
59 if [ -n "${cur_cmd}" ]; then
60 printf " 2 repeat this build command\n"
62 printf " 3 abort build\n\n"
64 ${bash} --rcfile <(printf "PS1='ct-ng:\w> '\nPROMPT_COMMAND=''\n") -i
67 1) printf "\nContinuing past the failed command.\n\n"
70 2) if [ -n "${cur_cmd}" ]; then
71 printf "\nRe-trying last command.\n\n"
77 printf "\nPlease exit with one of these values:\n"
78 printf " 1 fixed, continue with next build command\n"
79 if [ -n "${cur_cmd}" ]; then
80 printf " 2 repeat this build command\n"
82 printf " 3 abort build\n"
87 # Restore the trap handler
90 1) rm -f "${CT_WORK_DIR}/backtrace"; touch "${CT_BUILD_DIR}/skip"; return;;
91 2) rm -f "${CT_WORK_DIR}/backtrace"; touch "${CT_BUILD_DIR}/repeat"; return;;
92 # 3 is an abort, continue...
97 # And finally, in top-level shell, print some hints
98 if [ ${BASH_SUBSHELL} -eq 0 ]; then
99 # Help diagnose the error
100 CT_STEP_COUNT=1 # To have a zero-indentation
102 if [ "${CT_LOG_TO_FILE}" = "y" ]; then
103 CT_DoLog ERROR ">> For more info on this error, look at the file: '${tmp_log_file#${CT_TOP_DIR}/}'"
105 CT_DoLog ERROR ">> There is a list of known issues, some with workarounds, in:"
106 CT_DoLog ERROR ">> '${CT_DOC_DIR#${CT_TOP_DIR}/}/B - Known issues.txt'"
110 rm -f "${CT_WORK_DIR}/backtrace"
115 # Install the fault handler
118 # Inherit the fault handler in subshells and functions
121 # Make pipes fail on the _first_ failed command
122 # Not supported on bash < 3.x, but we need it, so drop the obsoleting bash-2.x
125 # Don't hash commands' locations, and search every time it is requested.
126 # This is slow, but needed because of the static/shared core gcc which shall
127 # always match to shared if it exists, and only fallback to static if the
128 # shared is not found
132 # - first of all, save stdout so we can see the live logs: fd #6
133 # (also save stdin and stderr for use by CT_DEBUG_INTERACTIVE)
135 # - then point stdout to the log file
136 tmp_log_file="${CT_TOP_DIR}/build.log"
137 rm -f "${tmp_log_file}"
138 exec >>"${tmp_log_file}"
140 # The different log levels:
151 # Make it easy to use \n and !
155 # A function to log what is happening
156 # Different log level are available:
157 # - ERROR: A serious, fatal error occurred
158 # - WARN: A non fatal, non serious error occurred, take your responsbility with the generated build
159 # - INFO: Informational messages
160 # - EXTRA: Extra informational messages
161 # - CFG: Output of various "./configure"-type scripts
162 # - FILE: File / archive unpacking.
163 # - STATE: State save & restore
164 # - ALL: Component's build messages
165 # - DEBUG: Internal debug messages
166 # Usage: CT_DoLog <level> [message]
167 # If message is empty, then stdin will be logged.
169 local max_level LEVEL level cur_l cur_L
171 eval max_level="\${CT_LOG_LEVEL_${CT_LOG_LEVEL_MAX}}"
172 # Set the maximum log level to DEBUG if we have none
173 [ -z "${max_level}" ] && max_level=${CT_LOG_LEVEL_DEBUG}
176 eval level="\${CT_LOG_LEVEL_${LEVEL}}"
178 if [ $# -eq 0 ]; then
182 fi |( IFS="${CR}" # We want the full lines, even leading spaces
188 indent=$((2*CT_STEP_COUNT))
190 case "${CT_LOG_SEE_TOOLS_WARN},${line}" in
191 y,*"warning:"*) cur_L=WARN; cur_l=${CT_LOG_LEVEL_WARN};;
192 y,*"WARNING:"*) cur_L=WARN; cur_l=${CT_LOG_LEVEL_WARN};;
193 *"error:"*) cur_L=ERROR; cur_l=${CT_LOG_LEVEL_ERROR};;
194 *"make["*"]: *** ["*) cur_L=ERROR; cur_l=${CT_LOG_LEVEL_ERROR};;
195 *) cur_L="${LEVEL}"; cur_l="${level}";;
197 # There will always be a log file (stdout, fd #1), be it /dev/null
198 printf "[%-5s]%*s%s%s\n" "${cur_L}" "${indent}" " " "${line}"
199 if [ ${cur_l} -le ${max_level} ]; then
200 # Only print to console (fd #6) if log level is high enough.
201 printf "${CT_LOG_PROGRESS_BAR:+\r}[%-5s]%*s%s%s\n" "${cur_L}" "${indent}" " " "${line}" >&6
203 if [ "${CT_LOG_PROGRESS_BAR}" = "y" ]; then
204 printf "\r[%02d:%02d] %s " $((SECONDS/60)) $((SECONDS%60)) "${_prog_bar[$((_prog_bar_cpt/10))]}" >&6
205 _prog_bar_cpt=$(((_prog_bar_cpt+1)%40))
213 # Execute an action, and log its messages
214 # It is possible to even log local variable assignments (a-la: var=val ./cmd opts)
215 # Usage: CT_DoExecLog <level> [VAR=val...] <command> [parameters...]
227 *=*) eval export "'${1}'"; shift;;
231 # This while-loop goes hand-in-hand with the ERR trap handler:
232 # - if the command terminates successfully, then we hit the break
233 # statement, and we exit the loop
234 # - if the command terminates in error, then the ERR handler kicks
236 # - if the user did *not* ask for interactive debugging, the ERR
237 # handler exits, and we hit the end of the sub-shell
238 # - if the user did ask for interactive debugging, the ERR handler
239 # spawns a shell. Upon termination of this shell, the ERR handler
240 # examines the exit status of the shell:
241 # - if 1, the ERR handler returns; then we hit the else statement,
242 # then the break, and we exit the 'while' loop, to continue the
244 # - if 2, the ERR handler touches the repeat file, and returns;
245 # then we hit the if statement, and we loop for one more
247 # - if 3, the ERR handler exits with the command's exit status,
249 # - for any other exit status of the shell, the ERR handler
250 # prints an informational message, and respawns the shell
252 # This allows a user to get an interactive shell that has the same
253 # environment (PATH and so on) that the failed command was ran with.
255 rm -f "${CT_BUILD_DIR}/repeat"
256 CT_DoLog DEBUG "==> Executing: ${cur_cmd}"
257 "${@}" 2>&1 |CT_DoLog "${level}"
259 if [ -f "${CT_BUILD_DIR}/repeat" ]; then
260 rm -f "${CT_BUILD_DIR}/repeat"
262 elif [ -f "${CT_BUILD_DIR}/skip" ]; then
263 rm -f "${CT_BUILD_DIR}/skip"
272 # Catch failure of the sub-shell
276 # Tail message to be logged whatever happens
277 # Usage: CT_DoEnd <level>
281 CT_STOP_DATE=$(CT_DoDate +%s%N)
282 CT_STOP_DATE_HUMAN=$(CT_DoDate +%Y%m%d.%H%M%S)
283 if [ "${level}" != "ERROR" ]; then
284 CT_DoLog "${level:-INFO}" "Build completed at ${CT_STOP_DATE_HUMAN}"
286 elapsed=$((CT_STOP_DATE-CT_STAR_DATE))
287 elapsed_min=$((elapsed/(60*1000*1000*1000)))
288 elapsed_sec=$(printf "%02d" $(((elapsed%(60*1000*1000*1000))/(1000*1000*1000))))
289 elapsed_csec=$(printf "%02d" $(((elapsed%(1000*1000*1000))/(10*1000*1000))))
290 CT_DoLog ${level:-INFO} "(elapsed: ${elapsed_min}:${elapsed_sec}.${elapsed_csec})"
293 # Remove entries referring to . and other relative paths
294 # Usage: CT_SanitizePath
300 # Only accept absolute paths;
301 # Note: as a special case the empty string in PATH is equivalent to .
302 if [ -n "${p}" -a -z "${p%%/*}" ]; then
303 new="${new}${new:+:}${p}"
309 # Sanitise the directory name contained in the variable passed as argument:
310 # - remove duplicate /
311 # Usage: CT_SanitiseVarDir CT_PREFIX_DIR
312 CT_SanitiseVarDir() {
318 eval "old_dir=\"\${${var}}\""
319 new_dir="$( printf "${old_dir}" \
320 |sed -r -e 's:/+:/:g;' \
322 eval "${var}=\"${new_dir}\""
323 CT_DoLog DEBUG "Sanitised '${var}': '${old_dir}' -> '${new_dir}'"
327 # Abort the execution with an error message
328 # Usage: CT_Abort <message>
334 # Test a condition, and print a message if satisfied
335 # Usage: CT_Test <message> <tests>
340 CT_DoLog DEBUG "Testing '! ( $* )'"
341 test "$@" && CT_DoLog WARN "$m"
345 # Test a condition, and abort with an error message if satisfied
346 # Usage: CT_TestAndAbort <message> <tests>
350 CT_DoLog DEBUG "Testing '! ( $* )'"
351 test "$@" && CT_Abort "$m"
355 # Test a condition, and abort with an error message if not satisfied
356 # Usage: CT_TestAndAbort <message> <tests>
360 CT_DoLog DEBUG "Testing '$*'"
361 test "$@" || CT_Abort "$m"
365 # Test the presence of a tool, or abort if not found
366 # Usage: CT_HasOrAbort <tool>
368 CT_TestAndAbort "'${1}' not found and needed for successful toolchain build." -z "$(CT_Which "${1}")"
372 # Search a program: wrap "which" for those system where "which"
373 # verbosely says there is no match (such as on Mandriva).
374 # Usage: CT_Which <filename>
376 which "$1" 2>/dev/null || true
379 # Get current date with nanosecond precision
380 # On those system not supporting nanosecond precision, faked with rounding down
381 # to the highest entire second
382 # Usage: CT_DoDate <fmt>
384 date "$1" |sed -r -e 's/%?N$/000000000/;'
388 CT_STEP_MESSAGE[${CT_STEP_COUNT}]="(top-level)"
389 # Memorise a step being done so that any error is caught
390 # Usage: CT_DoStep <loglevel> <message>
392 local start=$(CT_DoDate +%s%N)
393 CT_DoLog "$1" "================================================================="
395 CT_STEP_COUNT=$((CT_STEP_COUNT+1))
396 CT_STEP_LEVEL[${CT_STEP_COUNT}]="$1"; shift
397 CT_STEP_START[${CT_STEP_COUNT}]="${start}"
398 CT_STEP_MESSAGE[${CT_STEP_COUNT}]="$1"
402 # End the step just being done
405 local stop=$(CT_DoDate +%s%N)
406 local duration=$(printf "%032d" $((stop-${CT_STEP_START[${CT_STEP_COUNT}]})) |sed -r -e 's/([[:digit:]]{2})[[:digit:]]{7}$/\.\1/; s/^0+//; s/^\./0\./;')
407 local elapsed=$(printf "%02d:%02d" $((SECONDS/60)) $((SECONDS%60)))
408 local level="${CT_STEP_LEVEL[${CT_STEP_COUNT}]}"
409 local message="${CT_STEP_MESSAGE[${CT_STEP_COUNT}]}"
410 CT_STEP_COUNT=$((CT_STEP_COUNT-1))
411 CT_DoLog "${level}" "${message}: done in ${duration}s (at ${elapsed})"
415 # Pushes into a directory, and pops back
417 pushd "$1" >/dev/null 2>&1
423 # Create a dir and cd or pushd into it
424 # Usage: CT_mkdir_cd <dir/to/create>
425 # CT_mkdir_pushd <dir/to/create>
439 # Creates a temporary directory
440 # $1: variable to assign to
441 # Usage: CT_MktempDir foo
443 # Some mktemp do not allow more than 6 Xs
444 eval "$1"=$(mktemp -q -d "${CT_BUILD_DIR}/tmp.XXXXXX")
445 CT_TestOrAbort "Could not make temporary directory" -n "${!1}" -a -d "${!1}"
446 CT_DoLog DEBUG "Made temporary directory '${!1}'"
450 # Removes one or more directories, even if it is read-only, or its parent is
451 # Usage: CT_DoForceRmdir dir [...]
455 for dir in "${@}"; do
456 [ -d "${dir}" ] || continue
459 mode="$(stat -c '%a' "$(dirname "${dir}")")"
462 mode="$(stat -f '%Lp' "$(dirname "${dir}")")"
465 CT_Abort "Unhandled host OS $CT_SYS_OS"
468 CT_DoExecLog ALL chmod u+w "$(dirname "${dir}")"
469 CT_DoExecLog ALL chmod -R u+w "${dir}"
470 CT_DoExecLog ALL rm -rf "${dir}"
471 CT_DoExecLog ALL chmod ${mode} "$(dirname "${dir}")"
475 # Echoes the specified string on stdout until the pipe breaks.
478 # Usage: CT_DoYes "" |make oldconfig
483 # Add the specified directory to LD_LIBRARY_PATH, and export it
484 # If the specified patch is already present, just export
486 # $2: add as 'first' or 'last' path, 'first' is assumed if $2 is empty
487 # Usage CT_SetLibPath /some/where/lib [first|last]
492 case ":${LD_LIBRARY_PATH}:" in
496 CT_DoLog DEBUG "Adding '${path}' at end of LD_LIBRARY_PATH"
497 LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}${path}"
500 CT_DoLog DEBUG "Adding '${path}' at start of LD_LIBRARY_PATH"
501 LD_LIBRARY_PATH="${path}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
504 CT_Abort "Incorrect position '${pos}' to add '${path}' to LD_LIBRARY_PATH"
509 CT_DoLog DEBUG "==> LD_LIBRARY_PATH='${LD_LIBRARY_PATH}'"
510 export LD_LIBRARY_PATH
513 # Build up the list of allowed tarball extensions
514 # Add them in the prefered order; most preferred comes first
515 CT_DoListTarballExt() {
516 if [ "${CT_CONFIGURE_has_xz}" = "y" ]; then
519 if [ "${CT_CONFIGURE_has_lzma}" = "y" \
520 -o "${CT_CONFIGURE_has_xz}" = "y" ]; then
524 printf ".tar.gz\n.tgz\n"
528 # Get the file name extension of a component
529 # Usage: CT_GetFileExtension <component_name-component_version> [extension]
530 # If found, echoes the extension to stdout, and return 0
531 # If not found, echoes nothing on stdout, and return !0.
532 CT_GetFileExtension() {
538 # we need to also check for an empty extension for those very
539 # peculiar components that don't have one (such as sstrip from
541 for ext in ${first_ext} $(CT_DoListTarballExt) /.git ''; do
542 if [ -e "${CT_TARBALLS_DIR}/${file}${ext}" ]; then
551 # Try to retrieve the specified URL (HTTP or FTP)
552 # Usage: CT_DoGetFile <URL>
553 # This functions always returns true (0), as it can be legitimate not
554 # to find the requested URL (think about snapshots, different layouts
555 # for different gcc versions, etc...).
558 local dest="${CT_TARBALLS_DIR}/${url##*/}"
559 local tmp="${dest}.tmp-dl"
561 # Remove potential left-over from a previous run
564 # We also retry a few times, in case there is a transient error (eg. behind
565 # a dynamic IP that changes during the transfer...)
566 # With automated download as we are doing, it can be very dangerous to
567 # continue the downloads. It's far better to simply overwrite the
569 # Some company networks have firewalls to connect to the internet, but it's
570 # not easy to detect them, so force a global ${CT_CONNECT_TIMEOUT}-second
572 # For curl, no good progress indicator is available. So, be silent.
573 if CT_DoExecLog ALL wget --passive-ftp --tries=3 -nc \
574 --progress=dot:binary \
575 -T ${CT_CONNECT_TIMEOUT} \
579 # Success, we got it, good!
580 mv "${tmp}" "${dest}"
581 CT_DoLog DEBUG "Got it from: \"${url}\""
585 CT_DoLog DEBUG "Not at this location: \"${url}\""
589 # This function tries to retrieve a tarball form a local directory
590 # Usage: CT_GetLocal <basename> [.extension]
596 # Do we already have it in *our* tarballs dir?
597 if ext="$( CT_GetFileExtension "${basename}" ${first_ext} )"; then
598 CT_DoLog DEBUG "Already have '${basename}'"
602 if [ -n "${CT_LOCAL_TARBALLS_DIR}" ]; then
603 CT_DoLog DEBUG "Trying to retrieve an already downloaded copy of '${basename}'"
604 # We'd rather have a bzip2'ed tarball, then gzipped tarball, plain tarball,
605 # or, as a failover, a file without extension.
606 for ext in ${first_ext} $(CT_DoListTarballExt) ''; do
607 CT_DoLog DEBUG "Trying '${CT_LOCAL_TARBALLS_DIR}/${basename}${ext}'"
608 if [ -r "${CT_LOCAL_TARBALLS_DIR}/${basename}${ext}" -a \
609 "${CT_FORCE_DOWNLOAD}" != "y" ]; then
610 CT_DoLog DEBUG "Got '${basename}' from local storage"
611 CT_DoExecLog ALL ln -s "${CT_LOCAL_TARBALLS_DIR}/${basename}${ext}" "${CT_TARBALLS_DIR}/${basename}${ext}"
619 # This function gets the custom source from either a tarball or directory
620 # Usage: CT_GetCustom <component> <custom_version> <custom_location>
622 local custom_component="$1"
623 local custom_version="$2"
624 local custom_location="$3"
625 local custom_name="${custom_component}-${custom_version}"
627 CT_TestAndAbort "${custom_name}: CT_CUSTOM_LOCATION_ROOT_DIR or ${custom_component}'s CUSTOM_LOCATION must be set." \
628 -z "${CT_CUSTOM_LOCATION_ROOT_DIR}" -a -z "${custom_location}"
630 if [ -n "${CT_CUSTOM_LOCATION_ROOT_DIR}" \
631 -a -z "${custom_location}" ]; then
632 custom_location="${CT_CUSTOM_LOCATION_ROOT_DIR}/${custom_component}"
635 CT_DoLog EXTRA "Using '${custom_name}' from custom location"
636 if [ ! -d "${custom_location}" ]; then
637 # We need to know the custom tarball extension,
638 # so we can create a properly-named symlink, which
639 # we use later on in 'extract'
640 case "${custom_location}" in
641 *.tar.bz2) custom_name="${custom_name}.tar.bz2";;
642 *.tar.gz|*.tgz) custom_name="${custom_name}.tar.gz";;
643 *.tar) custom_name="${custom_name}.tar";;
644 *) CT_Abort "Unknown extension for custom tarball '${custom_location}'";;
646 CT_DoExecLog DEBUG ln -sf "${custom_location}" \
647 "${CT_TARBALLS_DIR}/${custom_name}"
649 CT_DoExecLog DEBUG ln -snf "${custom_location}" \
650 "${CT_SRC_DIR}/${custom_name}"
654 # This function saves the specified to local storage if possible,
655 # and if so, symlinks it for later usage
656 # Usage: CT_SaveLocal </full/path/file.name>
659 local basename="${file##*/}"
661 if [ "${CT_SAVE_TARBALLS}" = "y" ]; then
662 CT_DoLog EXTRA "Saving '${basename}' to local storage"
663 # The file may already exist if downloads are forced: remove it first
664 CT_DoExecLog ALL rm -f "${CT_LOCAL_TARBALLS_DIR}/${basename}"
665 CT_DoExecLog ALL mv -f "${file}" "${CT_LOCAL_TARBALLS_DIR}"
666 CT_DoExecLog ALL ln -s "${CT_LOCAL_TARBALLS_DIR}/${basename}" "${file}"
670 # Download the file from one of the URLs passed as argument
671 # Usage: CT_GetFile <basename> [.extension] <url> [url ...]
679 # If next argument starts with a dot, then this is not an URL,
680 # and we can consider that it is a preferred extension.
687 # Does it exist localy?
688 if CT_GetLocal "${file}" ${first_ext}; then
693 # If not allowed to download from the Internet, don't
694 if [ "${CT_FORBID_DOWNLOAD}" = "y" ]; then
695 CT_DoLog DEBUG "Not allowed to download from the Internet, aborting ${file} download"
699 # Try to retrieve the file
700 CT_DoLog EXTRA "Retrieving '${file}'"
702 # Add URLs on the LAN mirror
703 if [ "${CT_USE_MIRROR}" = "y" ]; then
704 CT_TestOrAbort "Please set the mirror base URL" -n "${CT_MIRROR_BASE_URL}"
705 URLS+=( "${CT_MIRROR_BASE_URL}/${file%-*}" )
706 URLS+=( "${CT_MIRROR_BASE_URL}" )
709 if [ "${CT_FORCE_MIRROR}" != "y" ]; then
713 # Scan all URLs in turn, and try to grab a tarball from there
714 # Do *not* try git trees (ext=/.git), this is handled in a specific
716 for ext in ${first_ext} $(CT_DoListTarballExt) ''; do
717 # Try all urls in turn
718 for url in "${URLS[@]}"; do
719 [ -n "${url}" ] || continue
720 CT_DoLog DEBUG "Trying '${url}/${file}${ext}'"
721 CT_DoGetFile "${url}/${file}${ext}"
722 if [ -f "${CT_TARBALLS_DIR}/${file}${ext}" ]; then
723 CT_DoLog DEBUG "Got '${file}' from the Internet"
724 CT_SaveLocal "${CT_TARBALLS_DIR}/${file}${ext}"
730 # Just return error, someone may want to catch and handle the error
731 # (eg. glibc/eglibc add-ons can be missing).
735 # Checkout from CVS, and build the associated tarball
736 # The tarball will be called ${basename}.tar.bz2
737 # Prerequisite: either the server does not require password,
738 # or the user must already be logged in.
739 # 'tag' is the tag to retrieve. Must be specified, but can be empty.
740 # If dirname is specified, then module will be renamed to dirname
741 # prior to building the tarball.
742 # Usage: CT_GetCVS <basename> <url> <module> <tag> [dirname[=subdir]]
743 # Note: if '=subdir' is given, then it is used instead of 'module'.
748 local tag="${4:+-r ${4}}"
752 # First try locally, then the mirror
753 if CT_GetFile "${basename}"; then
754 # Got it! Return early! :-)
758 if [ "${CT_FORBID_DOWNLOAD}" = "y" ]; then
759 CT_DoLog WARN "Downloads forbidden, not trying cvs retrieval"
764 CT_Pushd "${tmp_dir}"
766 CT_DoExecLog ALL cvs -z 9 -d "${uri}" co -P ${tag} "${module}"
767 if [ -n "${dirname}" ]; then
770 CT_DoExecLog DEBUG mv "${dirname#*=}" "${dirname%%=*}"
771 CT_DoExecLog ALL tar cjf "${CT_TARBALLS_DIR}/${basename}.tar.bz2" "${dirname%%=*}"
774 CT_DoExecLog ALL mv "${module}" "${dirname}"
775 CT_DoExecLog ALL tar cjf "${CT_TARBALLS_DIR}/${basename}.tar.bz2" "${dirname:-${module}}"
779 CT_SaveLocal "${CT_TARBALLS_DIR}/${basename}.tar.bz2"
782 CT_DoExecLog ALL rm -rf "${tmp_dir}"
785 # Check out from SVN, and build the associated tarball
786 # The tarball will be called ${basename}.tar.bz2
787 # Prerequisite: either the server does not require password,
788 # or the user must already be logged in.
789 # 'rev' is the revision to retrieve
790 # Usage: CT_GetSVN <basename> <url> [rev]
796 # First try locally, then the mirror
797 if CT_GetFile "${basename}"; then
798 # Got it! Return early! :-)
802 if [ "${CT_FORBID_DOWNLOAD}" = "y" ]; then
803 CT_DoLog WARN "Downloads forbidden, not trying svn retrieval"
808 CT_Pushd "${tmp_dir}"
810 if ! CT_DoExecLog ALL svn export ${rev:+-r ${rev}} "${uri}" "${basename}"; then
811 CT_DoLog WARN "Could not retrieve '${basename}'"
814 CT_DoExecLog ALL tar cjf "${CT_TARBALLS_DIR}/${basename}.tar.bz2" "${basename}"
815 CT_SaveLocal "${CT_TARBALLS_DIR}/${basename}.tar.bz2"
818 CT_DoExecLog ALL rm -rf "${tmp_dir}"
822 # Tries the given URLs in turn until one can get cloned. No tarball will be created.
823 # Prerequisites: either the server does not require password,
824 # or the user has already taken any action to authenticate to the server.
825 # The cloned tree will *not* be stored in the local tarballs dir!
826 # Usage: CT_GetGit <basename> <url [url ...]>
828 local basename="$1"; shift
832 if [ "${CT_FORBID_DOWNLOAD}" = "y" ]; then
833 CT_DoLog WARN "Downloads forbidden, not trying git retrieval"
837 # Do we have it in our tarballs dir?
838 if [ -d "${CT_TARBALLS_DIR}/${basename}/.git" ]; then
839 CT_DoLog EXTRA "Updating git tree '${basename}'"
840 CT_Pushd "${CT_TARBALLS_DIR}/${basename}"
841 CT_DoExecLog ALL git pull
844 CT_DoLog EXTRA "Retrieving git tree '${basename}'"
845 for url in "${@}"; do
846 CT_DoLog ALL "Trying to clone from '${url}'"
847 CT_DoForceRmdir "${CT_TARBALLS_DIR}/${basename}"
848 if git clone "${url}" "${CT_TARBALLS_DIR}/${basename}" 2>&1 |CT_DoLog ALL; then
853 CT_TestOrAbort "Could not clone '${basename}'" ${cloned} -ne 0
858 # Some tarballs need to be extracted in specific places. Eg.: glibc addons
859 # must be extracted in the glibc directory; uCLibc locales must be extracted
860 # in the extra/locale sub-directory of uClibc. This is taken into account
861 # by the caller, that did a 'cd' into the correct path before calling us
862 # and sets nochdir to 'nochdir'.
863 # Note also that this function handles the git trees!
864 # Usage: CT_Extract <basename> [nochdir] [options]
865 # where 'options' are dependent on the source (eg. git branch/tag...)
873 if [ "${nochdir}" = "nochdir" ]; then
877 nochdir="${CT_SRC_DIR}"
883 if ! ext="$(CT_GetFileExtension "${basename}")"; then
884 CT_DoLog WARN "'${basename}' not found in '${CT_TARBALLS_DIR}'"
887 local full_file="${CT_TARBALLS_DIR}/${basename}${ext}"
889 # Check if already extracted
890 if [ -e "${CT_SRC_DIR}/.${basename}.extracted" ]; then
891 CT_DoLog DEBUG "Already extracted '${basename}'"
895 # Check if previously partially extracted
896 if [ -e "${CT_SRC_DIR}/.${basename}.extracting" ]; then
897 CT_DoLog ERROR "The '${basename}' sources were partially extracted."
898 CT_DoLog ERROR "Please remove first:"
899 CT_DoLog ERROR " - the source dir for '${basename}', in '${CT_SRC_DIR}'"
900 CT_DoLog ERROR " - the file '${CT_SRC_DIR}/.${basename}.extracting'"
901 CT_Abort "I'll stop now to avoid any carnage..."
903 CT_DoExecLog DEBUG touch "${CT_SRC_DIR}/.${basename}.extracting"
905 CT_Pushd "${nochdir}"
907 CT_DoLog EXTRA "Extracting '${basename}'"
908 CT_DoExecLog FILE mkdir -p "${basename}"
909 tar_opts=( "--strip-components=1" )
910 tar_opts+=( "-C" "${basename}" )
914 # - lzma can be handled either with 'xz' or 'lzma'
915 # - we get lzma tarball only if either or both are available
916 # - so, if we get an lzma tarball, and either 'xz' or 'lzma' is
917 # missing, we can assume the other is available
918 if [ "${CT_CONFIGURE_has_lzma}" = "y" ]; then
919 lzma_prog="lzma -fdc"
924 .tar.xz) xz -fdc "${full_file}" | CT_DoExecLog FILE tar "${tar_opts[@]}" -f -;;
925 .tar.lzma) ${lzma_prog} "${full_file}" | CT_DoExecLog FILE tar "${tar_opts[@]}" -f -;;
926 .tar.bz2) bzip2 -dc "${full_file}" | CT_DoExecLog FILE tar "${tar_opts[@]}" -f -;;
927 .tar.gz|.tgz) gzip -dc "${full_file}" | CT_DoExecLog FILE tar "${tar_opts[@]}" -f -;;
928 .tar) CT_DoExecLog FILE tar "${tar_opts[@]}" -f "${full_file}";;
929 /.git) CT_ExtractGit "${basename}" "${@}";;
930 *) CT_DoLog WARN "Don't know how to handle '${basename}${ext}': unknown extension"
935 # Don't mark as being extracted for git
938 *) CT_DoExecLog DEBUG touch "${CT_SRC_DIR}/.${basename}.extracted";;
940 CT_DoExecLog DEBUG rm -f "${CT_SRC_DIR}/.${basename}.extracting"
945 # Create a working git clone of a local git repository
946 # Usage: CT_ExtractGit <basename> [ref]
947 # where 'ref' is the reference to use:
948 # the full name of a branch, like "remotes/origin/branch_name"
949 # a date as understandable by git, like "YYYY-MM-DD[ hh[:mm[:ss]]]"
951 # If 'ref' is not given, the current repository HEAD will be used
953 local basename="${1}"
958 # pushd now to be able to get git revlist in case ref is a date
959 repo="${CT_TARBALLS_DIR}/${basename}"
962 # What kind of reference is ${ref} ?
963 if [ -z "${ref}" ]; then
965 ref=$(git rev-list -n1 HEAD)
966 elif git tag |grep -E "^${ref}$" >/dev/null 2>&1; then
968 elif git branch -a --no-color |grep -E "^. ${ref}$" >/dev/null 2>&1; then
970 elif date -d "${ref}" >/dev/null 2>&1; then
972 ref=$(git rev-list -n1 --before="${ref}")
974 CT_Abort "Reference '${ref}' is an incorrect git reference: neither tag, branch nor date"
979 CT_DoExecLog FILE rmdir "${basename}"
980 case "${ref_type}" in
981 branch) CT_DoExecLog FILE git clone -b "${ref}" "${repo}" "${basename}" ;;
982 *) CT_DoExecLog FILE git clone "${repo}" "${basename}"
983 CT_Pushd "${basename}"
984 CT_DoExecLog FILE git checkout "${ref}"
990 # Patches the specified component
991 # See CT_Extract, above, for explanations on 'nochdir'
992 # Usage: CT_Patch [nochdir] <packagename> <packageversion>
993 # If the package directory is *not* packagename-packageversion, then
994 # the caller must cd into the proper directory first, and call us
1005 local bundled_patch_dir
1006 local local_patch_dir
1008 if [ "${nochdir}" = "nochdir" ]; then
1012 pkgdir="${pkgname}-${version}"
1017 pkgdir="${pkgname}-${version}"
1018 nochdir="${CT_SRC_DIR}/${pkgdir}"
1021 # Check if already patched
1022 if [ -e "${CT_SRC_DIR}/.${pkgdir}.patched" ]; then
1023 CT_DoLog DEBUG "Already patched '${pkgdir}'"
1027 # Check if already partially patched
1028 if [ -e "${CT_SRC_DIR}/.${pkgdir}.patching" ]; then
1029 CT_DoLog ERROR "The '${pkgdir}' sources were partially patched."
1030 CT_DoLog ERROR "Please remove first:"
1031 CT_DoLog ERROR " - the source dir for '${pkgdir}', in '${CT_SRC_DIR}'"
1032 CT_DoLog ERROR " - the file '${CT_SRC_DIR}/.${pkgdir}.extracted'"
1033 CT_DoLog ERROR " - the file '${CT_SRC_DIR}/.${pkgdir}.patching'"
1034 CT_Abort "I'll stop now to avoid any carnage..."
1036 touch "${CT_SRC_DIR}/.${pkgdir}.patching"
1038 CT_Pushd "${nochdir}"
1040 CT_DoLog EXTRA "Patching '${pkgdir}'"
1042 bundled_patch_dir="${CT_LIB_DIR}/patches/${pkgname}/${version}"
1043 local_patch_dir="${CT_LOCAL_PATCH_DIR}/${pkgname}/${version}"
1045 case "${CT_PATCH_ORDER}" in
1046 bundled) patch_dirs=("${bundled_patch_dir}");;
1047 local) patch_dirs=("${local_patch_dir}");;
1048 bundled,local) patch_dirs=("${bundled_patch_dir}" "${local_patch_dir}");;
1049 local,bundled) patch_dirs=("${local_patch_dir}" "${bundled_patch_dir}");;
1053 for d in "${patch_dirs[@]}"; do
1054 CT_DoLog DEBUG "Looking for patches in '${d}'..."
1055 if [ -n "${d}" -a -d "${d}" ]; then
1056 for p in "${d}"/*.patch; do
1057 if [ -f "${p}" ]; then
1058 CT_DoExecLog ALL patch --no-backup-if-mismatch -g0 -F1 -p1 -f -i "${p}"
1061 if [ "${CT_PATCH_SINGLE}" = "y" ]; then
1067 if [ "${CT_OVERIDE_CONFIG_GUESS_SUB}" = "y" ]; then
1068 CT_DoLog ALL "Overiding config.guess and config.sub"
1069 for cfg in config_guess config_sub; do
1070 eval ${cfg}="${CT_LIB_DIR}/scripts/${cfg/_/.}"
1071 [ -e "${CT_TOP_DIR}/scripts/${cfg/_/.}" ] && eval ${cfg}="${CT_TOP_DIR}/scripts/${cfg/_/.}"
1072 # Can't use CT_DoExecLog because of the '{} \;' to be passed un-mangled to find
1073 find . -type f -name "${cfg/_/.}" -exec cp -v "${!cfg}" {} \; |CT_DoLog ALL
1077 CT_DoExecLog DEBUG touch "${CT_SRC_DIR}/.${pkgdir}.patched"
1078 CT_DoExecLog DEBUG rm -f "${CT_SRC_DIR}/.${pkgdir}.patching"
1083 # Two wrappers to call config.(guess|sub) either from CT_TOP_DIR or CT_LIB_DIR.
1084 # Those from CT_TOP_DIR, if they exist, will be be more recent than those from CT_LIB_DIR.
1085 CT_DoConfigGuess() {
1086 if [ -x "${CT_TOP_DIR}/scripts/config.guess" ]; then
1087 "${CT_TOP_DIR}/scripts/config.guess"
1089 "${CT_LIB_DIR}/scripts/config.guess"
1094 if [ -x "${CT_TOP_DIR}/scripts/config.sub" ]; then
1095 "${CT_TOP_DIR}/scripts/config.sub" "$@"
1097 "${CT_LIB_DIR}/scripts/config.sub" "$@"
1101 # Compute the target tuple from what is provided by the user
1102 # Usage: CT_DoBuildTargetTuple
1103 # In fact this function takes the environment variables to build the target
1104 # tuple. It is needed both by the normal build sequence, as well as the
1105 # sample saving sequence.
1106 CT_DoBuildTargetTuple() {
1107 # Set the endianness suffix, and the default endianness gcc option
1108 case "${CT_ARCH_ENDIAN}" in
1112 CT_ARCH_ENDIAN_CFLAG="-mbig-endian"
1113 CT_ARCH_ENDIAN_LDFLAG="-Wl,-EB"
1118 CT_ARCH_ENDIAN_CFLAG="-mlittle-endian"
1119 CT_ARCH_ENDIAN_LDFLAG="-Wl,-EL"
1123 # Build the default architecture tuple part
1124 CT_TARGET_ARCH="${CT_ARCH}"
1126 # Set defaults for the system part of the tuple. Can be overriden
1127 # by architecture-specific values.
1128 case "${CT_LIBC}" in
1129 *glibc) CT_TARGET_SYS=gnu;;
1130 uClibc) CT_TARGET_SYS=uclibc;;
1131 *) CT_TARGET_SYS=elf;;
1134 # Set the default values for ARCH, ABI, CPU, TUNE, FPU and FLOAT
1135 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
1136 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
1137 [ "${CT_ARCH_ARCH}" ] && { CT_ARCH_ARCH_CFLAG="-march=${CT_ARCH_ARCH}"; CT_ARCH_WITH_ARCH="--with-arch=${CT_ARCH_ARCH}"; }
1138 [ "${CT_ARCH_ABI}" ] && { CT_ARCH_ABI_CFLAG="-mabi=${CT_ARCH_ABI}"; CT_ARCH_WITH_ABI="--with-abi=${CT_ARCH_ABI}"; }
1139 [ "${CT_ARCH_CPU}" ] && { CT_ARCH_CPU_CFLAG="-mcpu=${CT_ARCH_CPU}"; CT_ARCH_WITH_CPU="--with-cpu=${CT_ARCH_CPU}"; }
1140 [ "${CT_ARCH_TUNE}" ] && { CT_ARCH_TUNE_CFLAG="-mtune=${CT_ARCH_TUNE}"; CT_ARCH_WITH_TUNE="--with-tune=${CT_ARCH_TUNE}"; }
1141 [ "${CT_ARCH_FPU}" ] && { CT_ARCH_FPU_CFLAG="-mfpu=${CT_ARCH_FPU}"; CT_ARCH_WITH_FPU="--with-fpu=${CT_ARCH_FPU}"; }
1143 case "${CT_ARCH_FLOAT}" in
1145 CT_ARCH_FLOAT_CFLAG="-mhard-float"
1146 CT_ARCH_WITH_FLOAT="--with-float=hard"
1149 CT_ARCH_FLOAT_CFLAG="-msoft-float"
1150 CT_ARCH_WITH_FLOAT="--with-float=soft"
1153 CT_ARCH_FLOAT_CFLAG="-mfloat-abi=softfp"
1154 CT_ARCH_WITH_FLOAT="--with-float=softfp"
1158 # Build the default kernel tuple part
1159 CT_TARGET_KERNEL="${CT_KERNEL}"
1161 # Overide the default values with the components specific settings
1162 CT_DoArchTupleValues
1163 CT_DoKernelTupleValues
1165 # Finish the target tuple construction
1166 CT_TARGET="${CT_TARGET_ARCH}"
1167 CT_TARGET="${CT_TARGET}${CT_TARGET_VENDOR:+-${CT_TARGET_VENDOR}}"
1168 CT_TARGET="${CT_TARGET}${CT_TARGET_KERNEL:+-${CT_TARGET_KERNEL}}"
1169 CT_TARGET="${CT_TARGET}${CT_TARGET_SYS:+-${CT_TARGET_SYS}}"
1173 if [ -n "${CT_TARGET_ALIAS_SED_EXPR}" ]; then
1174 __sed_alias=$(echo "${CT_TARGET}" |sed -r -e "${CT_TARGET_ALIAS_SED_EXPR}")
1176 case ":${CT_TARGET_VENDOR}:${CT_TARGET_ALIAS}:${__sed_alias}:" in
1177 :*" "*:*:*:) CT_Abort "Don't use spaces in the vendor string, it breaks things.";;
1178 :*"-"*:*:*:) CT_Abort "Don't use dashes in the vendor string, it breaks things.";;
1179 :*:*" "*:*:) CT_Abort "Don't use spaces in the target alias, it breaks things.";;
1180 :*:*:*" "*:) CT_Abort "Don't use spaces in the target sed transform, it breaks things.";;
1184 CT_TARGET=$(CT_DoConfigSub "${CT_TARGET}")
1185 # Prepare the target CFLAGS
1186 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ENDIAN_CFLAG}"
1187 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ARCH_CFLAG}"
1188 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ABI_CFLAG}"
1189 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_CPU_CFLAG}"
1190 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_TUNE_CFLAG}"
1191 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_FPU_CFLAG}"
1192 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_FLOAT_CFLAG}"
1194 # Now on for the target LDFLAGS
1195 CT_ARCH_TARGET_LDFLAGS="${CT_ARCH_TARGET_LDFLAGS} ${CT_ARCH_ENDIAN_LDFLAG}"
1198 # This function does pause the build until the user strikes "Return"
1199 # Usage: CT_DoPause [optional_message]
1202 local message="${1:-Pausing for your pleasure}"
1203 CT_DoLog INFO "${message}"
1204 read -p "Press 'Enter' to continue, or Ctrl-C to stop..." foo >&6
1208 # This function creates a tarball of the specified directory, but
1210 # Usage: CT_DoTarballIfExists <dir> <tarball_basename> [extra_tar_options [...]]
1211 CT_DoTarballIfExists() {
1215 local -a extra_tar_opts=( "$@" )
1218 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
1219 y) compress=( gzip -c -3 - ); tar_ext=.gz;;
1220 *) compress=( cat - ); tar_ext=;;
1223 if [ -d "${dir}" ]; then
1224 CT_DoLog DEBUG " Saving '${dir}'"
1225 { tar c -C "${dir}" -v -f - "${extra_tar_opts[@]}" . \
1226 |"${compress[@]}" >"${tarball}.tar${tar_ext}" ;
1227 } 2>&1 |sed -r -e 's/^/ /;' |CT_DoLog STATE
1229 CT_DoLog STATE " Not saving '${dir}': does not exist"
1233 # This function extracts a tarball to the specified directory, but
1234 # only if the tarball exists
1235 # Usage: CT_DoExtractTarballIfExists <tarball_basename> <dir> [extra_tar_options [...]]
1236 CT_DoExtractTarballIfExists() {
1240 local -a extra_tar_opts=( "$@" )
1243 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
1244 y) uncompress=( gzip -c -d ); tar_ext=.gz;;
1245 *) uncompress=( cat ); tar_ext=;;
1248 if [ -f "${tarball}.tar${tar_ext}" ]; then
1249 CT_DoLog DEBUG " Restoring '${dir}'"
1250 CT_DoForceRmdir "${dir}"
1251 CT_DoExecLog DEBUG mkdir -p "${dir}"
1252 { "${uncompress[@]}" "${tarball}.tar${tar_ext}" \
1253 |tar x -C "${dir}" -v -f - "${extra_tar_opts[@]}" ;
1254 } 2>&1 |sed -r -e 's/^/ /;' |CT_DoLog STATE
1256 CT_DoLog STATE " Not restoring '${dir}': does not exist"
1260 # This function saves the state of the toolchain to be able to restart
1262 # Usage: CT_DoSaveState <next_step_name>
1264 [ "${CT_DEBUG_CT_SAVE_STEPS}" = "y" ] || return 0
1265 local state_name="$1"
1266 local state_dir="${CT_STATE_DIR}/${state_name}"
1268 # Log this to the log level required by the user
1269 CT_DoLog ${CT_LOG_LEVEL_MAX} "Saving state to restart at step '${state_name}'..."
1271 rm -rf "${state_dir}"
1272 mkdir -p "${state_dir}"
1274 CT_DoLog STATE " Saving environment and aliases"
1275 # We must omit shell functions, and some specific bash variables
1276 # that break when restoring the environment, later. We could do
1277 # all the processing in the awk script, but a sed is easier...
1280 $0~/^[^ ]+ \(\)/ { _p = 0; }
1282 $0 == "}" { _p = 1; }
1283 ' |sed -r -e '/^BASH_(ARGC|ARGV|LINENO|SOURCE|VERSINFO)=/d;
1285 /^(FUNCNAME|GROUPS|PPID|SHELLOPTS)=/d;' >"${state_dir}/env.sh"
1287 CT_DoTarballIfExists "${CT_BUILDTOOLS_PREFIX_DIR}" "${state_dir}/buildtools_dir"
1288 CT_DoTarballIfExists "${CT_CONFIG_DIR}" "${state_dir}/config_dir"
1289 CT_DoTarballIfExists "${CT_PREFIX_DIR}" "${state_dir}/prefix_dir" --exclude '*.log'
1291 CT_DoLog STATE " Saving log file"
1293 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
1294 y) gzip -3 -c "${tmp_log_file}" >"${state_dir}/log.gz";;
1295 *) cat "${tmp_log_file}" >"${state_dir}/log";;
1297 exec >>"${tmp_log_file}"
1300 # This function restores a previously saved state
1301 # Usage: CT_DoLoadState <state_name>
1303 local state_name="$1"
1304 local state_dir="${CT_STATE_DIR}/${state_name}"
1305 local old_RESTART="${CT_RESTART}"
1306 local old_STOP="${CT_STOP}"
1308 CT_TestOrAbort "The previous build did not reach the point where it could be restarted at '${CT_RESTART}'" -d "${state_dir}"
1310 # We need to do something special with the log file!
1311 if [ "${CT_LOG_TO_FILE}" = "y" ]; then
1312 exec >"${state_dir}/tail.log"
1315 # Log this to the log level required by the user
1316 CT_DoLog ${CT_LOG_LEVEL_MAX} "Restoring state at step '${state_name}', as requested."
1318 CT_DoExtractTarballIfExists "${state_dir}/prefix_dir" "${CT_PREFIX_DIR}"
1319 CT_DoExtractTarballIfExists "${state_dir}/config_dir" "${CT_CONFIG_DIR}"
1320 CT_DoExtractTarballIfExists "${state_dir}/buildtools_dir" "${CT_BUILDTOOLS_PREFIX_DIR}"
1322 # Restore the environment, discarding any error message
1323 # (for example, read-only bash internals)
1324 CT_DoLog STATE " Restoring environment"
1325 . "${state_dir}/env.sh" >/dev/null 2>&1 || true
1327 # Restore the new RESTART and STOP steps
1328 CT_RESTART="${old_RESTART}"
1329 CT_STOP="${old_STOP}"
1330 unset old_stop old_restart
1332 CT_DoLog STATE " Restoring log file"
1334 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
1335 y) zcat "${state_dir}/log.gz" >"${tmp_log_file}";;
1336 *) cat "${state_dir}/log" >"${tmp_log_file}";;
1338 cat "${state_dir}/tail.log" >>"${tmp_log_file}"
1339 exec >>"${tmp_log_file}"
1340 rm -f "${state_dir}/tail.log"