Bart De VOS pointed out that removing absolute paths from the libc linker scripts is plainly wrong.
It dates from dawn ages of the original crosstool code, and is not well explained. At that time, binutils might not understand the sysroot stuff, and it was necessary to remove absolute paths in that case.
/trunk/scripts/build/libc/glibc.sh | 14 2 12 0 ++------------
1 file changed, 2 insertions(+), 12 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 # Bail out early in subshell, the upper level shell will act accordingly.
9 [ ${BASH_SUBSHELL} -eq 0 ] || exit $ret
10 CT_DoLog ERROR "Build failed in step '${CT_STEP_MESSAGE[${CT_STEP_COUNT}]}'"
11 for((step=(CT_STEP_COUNT-1); step>1; step--)); do
12 CT_DoLog ERROR " called in step '${CT_STEP_MESSAGE[${step}]}'"
14 CT_DoLog ERROR "Error happened in '${BASH_SOURCE[1]}' in function '${FUNCNAME[1]}' (line unknown, sorry)"
15 for((depth=2; ${BASH_LINENO[$((${depth}-1))]}>0; depth++)); do
16 CT_DoLog ERROR " called from '${BASH_SOURCE[${depth}]}' at line # ${BASH_LINENO[${depth}-1]} in function '${FUNCNAME[${depth}]}'"
18 [ "${CT_LOG_TO_FILE}" = "y" ] && CT_DoLog ERROR "Look at '${CT_LOG_FILE}' for more info on this error."
24 # Install the fault handler
27 # Inherit the fault handler in subshells and functions
30 # Make pipes fail on the _first_ failed command
31 # Not supported on bash < 3.x, but we need it, so drop the obsoleting bash-2.x
34 # Don't hash commands' locations, and search every time it is requested.
35 # This is slow, but needed because of the static/shared core gcc which shall
36 # always match to shared if it exists, and only fallback to static if the
41 # - first of all, save stdout so we can see the live logs: fd #6
43 # - then point stdout to the log file (temporary for now)
44 tmp_log_file="${CT_TOP_DIR}/log.$$"
45 exec >>"${tmp_log_file}"
47 # The different log levels:
55 # A function to log what is happening
56 # Different log level are available:
57 # - ERROR: A serious, fatal error occurred
58 # - WARN: A non fatal, non serious error occurred, take your responsbility with the generated build
59 # - INFO: Informational messages
60 # - EXTRA: Extra informational messages
61 # - DEBUG: Debug messages
62 # - ALL: Component's build messages
63 # Usage: CT_DoLog <level> [message]
64 # If message is empty, then stdin will be logged.
66 local max_level LEVEL level cur_l cur_L
68 eval max_level="\${CT_LOG_LEVEL_${CT_LOG_LEVEL_MAX}}"
69 # Set the maximum log level to DEBUG if we have none
70 [ -z "${max_level}" ] && max_level=${CT_LOG_LEVEL_DEBUG}
73 eval level="\${CT_LOG_LEVEL_${LEVEL}}"
79 fi |( IFS="\n" # We want the full lines, even leading spaces
85 indent=$((2*CT_STEP_COUNT))
87 case "${CT_LOG_SEE_TOOLS_WARN},${line}" in
88 y,*"warning:"*) cur_L=WARN; cur_l=${CT_LOG_LEVEL_WARN};;
89 y,*"WARNING:"*) cur_L=WARN; cur_l=${CT_LOG_LEVEL_WARN};;
90 *"error:"*) cur_L=ERROR; cur_l=${CT_LOG_LEVEL_ERROR};;
91 *"make["?*"]:"*"Stop.") cur_L=ERROR; cur_l=${CT_LOG_LEVEL_ERROR};;
92 *) cur_L="${LEVEL}"; cur_l="${level}";;
94 # There will always be a log file (stdout, fd #1), be it /dev/null
95 printf "[%-5s]%*s%s%s\n" "${cur_L}" "${indent}" " " "${line}"
96 if [ ${cur_l} -le ${max_level} ]; then
97 # Only print to console (fd #6) if log level is high enough.
98 printf "\r[%-5s]%*s%s%s\n" "${cur_L}" "${indent}" " " "${line}" >&6
100 if [ "${CT_LOG_PROGRESS_BAR}" = "y" ]; then
101 printf "\r[%02d:%02d] %s " $((SECONDS/60)) $((SECONDS%60)) "${_prog_bar[$((_prog_bar_cpt/10))]}" >&6
102 _prog_bar_cpt=$(((_prog_bar_cpt+1)%40))
110 # Execute an action, and log its messages
111 # Usage: CT_DoExecLog <level> <[VAR=val...] command [parameters...]>
115 CT_DoLog DEBUG "==> Executing: '${@}'"
116 "${@}" 2>&1 |CT_DoLog "${level}"
119 # Tail message to be logged whatever happens
120 # Usage: CT_DoEnd <level>
124 CT_STOP_DATE=$(CT_DoDate +%s%N)
125 CT_STOP_DATE_HUMAN=$(CT_DoDate +%Y%m%d.%H%M%S)
126 if [ "${level}" != "ERROR" ]; then
127 CT_DoLog "${level:-INFO}" "Build completed at ${CT_STOP_DATE_HUMAN}"
129 elapsed=$((CT_STOP_DATE-CT_STAR_DATE))
130 elapsed_min=$((elapsed/(60*1000*1000*1000)))
131 elapsed_sec=$(printf "%02d" $(((elapsed%(60*1000*1000*1000))/(1000*1000*1000))))
132 elapsed_csec=$(printf "%02d" $(((elapsed%(1000*1000*1000))/(10*1000*1000))))
133 CT_DoLog ${level:-INFO} "(elapsed: ${elapsed_min}:${elapsed_sec}.${elapsed_csec})"
136 # Abort the execution with an error message
137 # Usage: CT_Abort <message>
143 # Test a condition, and print a message if satisfied
144 # Usage: CT_Test <message> <tests>
149 test "$@" && CT_DoLog WARN "$m"
153 # Test a condition, and abort with an error message if satisfied
154 # Usage: CT_TestAndAbort <message> <tests>
158 test "$@" && CT_Abort "$m"
162 # Test a condition, and abort with an error message if not satisfied
163 # Usage: CT_TestAndAbort <message> <tests>
167 test "$@" || CT_Abort "$m"
171 # Test the presence of a tool, or abort if not found
172 # Usage: CT_HasOrAbort <tool>
174 CT_TestAndAbort "'${1}' not found and needed for successful toolchain build." -z "$(CT_Which "${1}")"
178 # Search a program: wrap "which" for those system where
179 # "which" verbosely says there is no match (Mdk are such
181 # Usage: CT_Which <filename>
183 which "$1" 2>/dev/null || true
186 # Get current date with nanosecond precision
187 # On those system not supporting nanosecond precision, faked with rounding down
188 # to the highest entire second
189 # Usage: CT_DoDate <fmt>
191 date "$1" |sed -r -e 's/%N$/000000000/;'
195 CT_STEP_MESSAGE[${CT_STEP_COUNT}]="<none>"
196 # Memorise a step being done so that any error is caught
197 # Usage: CT_DoStep <loglevel> <message>
199 local start=$(CT_DoDate +%s%N)
200 CT_DoLog "$1" "================================================================="
202 CT_STEP_COUNT=$((CT_STEP_COUNT+1))
203 CT_STEP_LEVEL[${CT_STEP_COUNT}]="$1"; shift
204 CT_STEP_START[${CT_STEP_COUNT}]="${start}"
205 CT_STEP_MESSAGE[${CT_STEP_COUNT}]="$1"
209 # End the step just being done
212 local stop=$(CT_DoDate +%s%N)
213 local duration=$(printf "%032d" $((stop-${CT_STEP_START[${CT_STEP_COUNT}]})) |sed -r -e 's/([[:digit:]]{2})[[:digit:]]{7}$/\.\1/; s/^0+//; s/^\./0\./;')
214 local elapsed=$(printf "%02d:%02d" $((SECONDS/60)) $((SECONDS%60)))
215 local level="${CT_STEP_LEVEL[${CT_STEP_COUNT}]}"
216 local message="${CT_STEP_MESSAGE[${CT_STEP_COUNT}]}"
217 CT_STEP_COUNT=$((CT_STEP_COUNT-1))
218 CT_DoLog "${level}" "${message}: done in ${duration}s (at ${elapsed})"
222 # Pushes into a directory, and pops back
224 pushd "$1" >/dev/null 2>&1
230 # Makes a path absolute
231 # Usage: CT_MakeAbsolutePath path
232 CT_MakeAbsolutePath() {
233 # Try to cd in that directory
239 # No such directory, fail back to guessing
242 *) echo "$(pwd)/$1";;
249 # Creates a temporary directory
250 # $1: variable to assign to
251 # Usage: CT_MktempDir foo
253 # Some mktemp do not allow more than 6 Xs
254 eval "$1"=$(mktemp -q -d "${CT_BUILD_DIR}/.XXXXXX")
255 CT_TestOrAbort "Could not make temporary directory" -n "${!1}" -a -d "${!1}"
256 CT_DoLog DEBUG "Made temporary directory '${!1}'"
260 # Echoes the specified string on stdout until the pipe breaks.
263 # Usage: CT_DoYes "" |make oldconfig
268 # Get the file name extension of a component
269 # Usage: CT_GetFileExtension <component_name-component_version> [extension]
270 # If found, echoes the extension to stdout
271 # If not found, echoes nothing on stdout.
272 CT_GetFileExtension() {
278 CT_Pushd "${CT_TARBALLS_DIR}"
279 # we need to also check for an empty extension for those very
280 # peculiar components that don't have one (such as sstrip from
282 for ext in ${first_ext} .tar.gz .tar.bz2 .tgz .tar ''; do
283 if [ -f "${file}${ext}" ]; then
293 # Set environment for proxy access
294 # Usage: CT_DoSetProxy <proxy_type>
295 # where proxy_type is one of 'http', 'sockssys', 'socks4' or 'socks5',
296 # or empty (to not change proxy settings).
301 case "${CT_PROXY_USER}:${CT_PROXY_PASS}" in
303 :*) http_proxy="${http_proxy}:${CT_PROXY_PASS}@";;
304 *:) http_proxy="${http_proxy}${CT_PROXY_USER}@";;
305 *:*) http_proxy="${http_proxy}${CT_PROXY_USER}:${CT_PROXY_PASS}@";;
307 export http_proxy="${http_proxy}${CT_PROXY_HOST}:${CT_PROXY_PORT}/"
308 export https_proxy="${http_proxy}"
309 export ftp_proxy="${http_proxy}"
310 CT_DoLog DEBUG "http_proxy='${http_proxy}'"
317 # Remove any lingering config file from any previous run
318 rm -f "${CT_BUILD_DIR}/tsocks.conf"
319 # Find all interfaces and build locally accessible networks
320 server_ip=$(ping -c 1 -W 2 "${CT_PROXY_HOST}" |head -n 1 |sed -r -e 's/^[^\(]+\(([^\)]+)\).*$/\1/;' || true)
321 CT_TestOrAbort "SOCKS proxy '${CT_PROXY_HOST}' has no IP." -n "${server_ip}"
322 /sbin/ifconfig |awk -v server_ip="${server_ip}" '
324 split( server_ip, tmp, "\\." );
325 server_ip_num = tmp[1] * 2^24 + tmp[2] * 2^16 + tmp[3] * 2^8 + tmp[4] * 2^0;
329 $0 ~ /^[[:space:]]*inet addr:/ {
330 split( $2, tmp, ":|\\." );
331 if( ( tmp[2] == 127 ) && ( tmp[3] == 0 ) && ( tmp[4] == 0 ) && ( tmp[5] == 1 ) ) {
332 /* Skip 127.0.0.1, it'\''s taken care of by tsocks itself */
335 ip_num = tmp[2] * 2^24 + tmp[3] * 2^16 + tmp[4] * 2 ^8 + tmp[5] * 2^0;
340 } while( (i!=0) && ( and( server_ip_num, mask ) == and( ip_num, mask ) ) );
341 mask = and( 0xFFFFFFFF, lshift( mask, 1 ) );
342 if( (i!=0) && (mask!=0) ) {
343 masked_ip = and( ip_num, mask );
344 for( i=0; i<pairs; i++ ) {
345 if( ( masked_ip == ips[i] ) && ( mask == masks[i] ) ) {
349 ips[pairs] = masked_ip;
352 printf( "local = %d.%d.%d.%d/%d.%d.%d.%d\n",
353 and( 0xFF, masked_ip / 2^24 ),
354 and( 0xFF, masked_ip / 2^16 ),
355 and( 0xFF, masked_ip / 2^8 ),
356 and( 0xFF, masked_ip / 2^0 ),
357 and( 0xFF, mask / 2^24 ),
358 and( 0xFF, mask / 2^16 ),
359 and( 0xFF, mask / 2^8 ),
360 and( 0xFF, mask / 2^0 ) );
363 ' >"${CT_BUILD_DIR}/tsocks.conf"
364 ( echo "server = ${server_ip}";
365 echo "server_port = ${CT_PROXY_PORT}";
366 [ -n "${CT_PROXY_USER}" ] && echo "default_user=${CT_PROXY_USER}";
367 [ -n "${CT_PROXY_PASS}" ] && echo "default_pass=${CT_PROXY_PASS}";
368 ) >>"${CT_BUILD_DIR}/tsocks.conf"
369 case "${CT_PROXY_TYPE/socks}" in
370 4|5) proxy_type="${CT_PROXY_TYPE/socks}";;
372 reply=$(inspectsocks "${server_ip}" "${CT_PROXY_PORT}" 2>&1 || true)
374 *"server is a version 4 socks server") proxy_type=4;;
375 *"server is a version 5 socks server") proxy_type=5;;
376 *) CT_Abort "Unable to determine SOCKS proxy type for '${CT_PROXY_HOST}:${CT_PROXY_PORT}'"
380 echo "server_type = ${proxy_type}" >> "${CT_BUILD_DIR}/tsocks.conf"
382 # If tsocks was found, then validateconf is present (distributed with tsocks).
383 CT_DoExecLog DEBUG validateconf -f "${CT_BUILD_DIR}/tsocks.conf"
384 export TSOCKS_CONF_FILE="${CT_BUILD_DIR}/tsocks.conf"
390 # Download an URL using wget
391 # Usage: CT_DoGetFileWget <URL>
393 # Need to return true because it is legitimate to not find the tarball at
394 # some of the provided URLs (think about snapshots, different layouts for
395 # different gcc versions, etc...)
396 # Some (very old!) FTP server might not support the passive mode, thus
398 # With automated download as we are doing, it can be very dangerous to use
399 # -c to continue the downloads. It's far better to simply overwrite the
401 # Some company networks have firewalls to connect to the internet, but it's
402 # not easy to detect them, and wget does not timeout by default while
403 # connecting, so force a global ${CT_CONNECT_TIMEOUT}-second timeout.
404 wget -T ${CT_CONNECT_TIMEOUT} -nc --progress=dot:binary --tries=3 --passive-ftp "$1" \
405 || wget -T ${CT_CONNECT_TIMEOUT} -nc --progress=dot:binary --tries=3 "$1" \
409 # Download an URL using curl
410 # Usage: CT_DoGetFileCurl <URL>
412 # Note: comments about wget method (above) are also valid here
413 # Plus: no good progress indicator is available with curl,
414 # so output is consigned to oblivion
415 curl --ftp-pasv -O --retry 3 "$1" --connect-timeout ${CT_CONNECT_TIMEOUT} >/dev/null \
416 || curl -O --retry 3 "$1" --connect-timeout ${CT_CONNECT_TIMEOUT} >/dev/null \
420 _wget=$(CT_Which wget)
421 _curl=$(CT_Which curl)
422 # Wrapper function to call one of curl or wget
423 # Usage: CT_DoGetFile <URL>
425 case "${_wget},${_curl}" in
426 ,) CT_DoError "Could find neither wget nor curl";;
427 ,*) CT_DoExecLog ALL CT_DoGetFileCurl "$1" 2>&1;;
428 *) CT_DoExecLog ALL CT_DoGetFileWget "$1" 2>&1;;
432 # Download the file from one of the URLs passed as argument
433 # Usage: CT_GetFile <filename> [extension] <url> [url ...]
440 # If next argument starts with a dot, then this is not an URL,
441 # and we can consider that it is a preferred extension.
448 # Do we already have it?
449 ext=$(CT_GetFileExtension "${file}" ${first_ext})
450 if [ -n "${ext}" ]; then
451 CT_DoLog DEBUG "Already have '${file}'"
455 # Try to retrieve the file
456 CT_DoLog EXTRA "Retrieving '${file}'"
457 CT_Pushd "${CT_TARBALLS_DIR}"
459 if [ -n "${CT_LOCAL_TARBALLS_DIR}" ]; then
460 CT_DoLog DEBUG "Trying to retrieve an already downloaded copy of '${file}'"
461 # We'd rather have a bzip2'ed tarball, then gzipped tarball, plain tarball,
462 # or, as a failover, a file without extension.
463 # Try local copy first, if it exists
464 for ext in ${first_ext} .tar.bz2 .tar.gz .tgz .tar ''; do
465 CT_DoLog DEBUG "Trying '${CT_LOCAL_TARBALLS_DIR}/${file}${ext}'"
466 if [ -r "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" -a \
467 "${CT_FORCE_DOWNLOAD}" != "y" ]; then
468 CT_DoLog DEBUG "Got '${file}' from local storage"
469 CT_DoExecLog ALL ln -s "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" "${file}${ext}"
475 # Not found locally, try from the network
477 # Start with LAN mirror
478 if [ "${CT_USE_LAN_MIRROR}" = "y" ]; then
479 CT_DoSetProxy ${CT_LAN_MIRROR_USE_PROXY:+${CT_PROXY_TYPE}}
480 CT_DoLog DEBUG "Trying to retrieve a copy of '${file}' from LAN mirror '${CT_LAN_MIRROR_HOSTNAME}'"
481 CT_TestOrAbort "Please set the LAN mirror hostname" -n "${CT_LAN_MIRROR_HOSTNAME}"
482 CT_TestOrAbort "Please tell me where to find tarballs on the LAN mirror '${CT_LAN_MIRROR_HOSTNAME}'" -n "${CT_LAN_MIRROR_BASE}"
483 for ext in ${first_ext} .tar.bz2 .tar.gz .tgz .tar ''; do
484 # Please note: we just have the file's basename in a single piece.
485 # So we have to just try and split it back into name and version... :-(
486 for url in "${CT_LAN_MIRROR_SCHEME}://${CT_LAN_MIRROR_HOSTNAME}/${CT_LAN_MIRROR_BASE}/${file%-*}" \
487 "${CT_LAN_MIRROR_SCHEME}://${CT_LAN_MIRROR_HOSTNAME}/${CT_LAN_MIRROR_BASE}"; \
489 CT_DoLog DEBUG "Trying '${url}/${file}${ext}'"
490 CT_DoGetFile "${url}/${file}${ext}"
491 if [ -f "${file}${ext}" ]; then
492 CT_DoLog DEBUG "Got '${file}' from the LAN mirror"
493 if [ "${CT_SAVE_TARBALLS}" = "y" ]; then
494 # The file may already exist if downloads are forced: remove it first
495 CT_DoLog EXTRA "Saving '${file}' to local storage"
496 CT_DoExecLog ALL rm -f "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}"
497 CT_DoExecLog ALL mv -f "${file}${ext}" "${CT_LOCAL_TARBALLS_DIR}"
498 CT_DoExecLog ALL ln -s "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" "${file}${ext}"
506 # OK, available neither localy, nor from the LAN mirror (if any).
507 CT_DoSetProxy ${CT_PROXY_TYPE}
508 for ext in ${first_ext} .tar.bz2 .tar.gz .tgz .tar ''; do
509 # Try all urls in turn
511 CT_DoLog DEBUG "Trying '${url}/${file}${ext}'"
512 CT_DoGetFile "${url}/${file}${ext}"
513 if [ -f "${file}${ext}" ]; then
514 CT_DoLog DEBUG "Got '${file}' from the Internet"
515 if [ "${CT_SAVE_TARBALLS}" = "y" ]; then
516 # The file may already exist if downloads are forced: remove it first
517 CT_DoLog EXTRA "Saving '${file}' to local storage"
518 CT_DoExecLog ALL rm -f "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}"
519 CT_DoExecLog ALL mv -f "${file}${ext}" "${CT_LOCAL_TARBALLS_DIR}"
520 CT_DoExecLog ALL ln -s "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" "${file}${ext}"
528 CT_Abort "Could not retrieve '${file}'."
531 # Extract a tarball and patch the resulting sources if necessary.
532 # Some tarballs need to be extracted in specific places. Eg.: glibc addons
533 # must be extracted in the glibc directory; uCLibc locales must be extracted
534 # in the extra/locale sub-directory of uClibc.
535 CT_ExtractAndPatch() {
537 local base_file=$(echo "${file}" |cut -d - -f 1)
538 local ver_file=$(echo "${file}" |cut -d - -f 2-)
539 local official_patch_dir
540 local custom_patch_dir
542 local ext=$(CT_GetFileExtension "${file}")
543 CT_TestAndAbort "'${file}' not found in '${CT_TARBALLS_DIR}'" -z "${ext}"
544 local full_file="${CT_TARBALLS_DIR}/${file}${ext}"
546 CT_Pushd "${CT_SRC_DIR}"
548 # Add-ons need a little love, really.
550 glibc-[a-z]*-*|eglibc-[a-z]*-*)
551 CT_TestAndAbort "Trying to extract the C-library addon/locales '${file}' when C-library not yet extracted" ! -d "${CT_LIBC_FILE}"
554 [ -f ".${file}.extracted" ] && return 0
555 touch ".${file}.extracted"
558 CT_TestAndAbort "Trying to extract the C-library addon/locales '${file}' when C-library not yet extracted" ! -d "${CT_LIBC_FILE}"
559 cd "${CT_LIBC_FILE}/extra/locale"
561 [ -f ".${file}.extracted" ] && return 0
562 touch ".${file}.extracted"
566 # If the directory exists, then consider extraction and patching done
567 if [ -d "${file}" ]; then
568 CT_DoLog DEBUG "Already extracted '${file}'"
572 CT_DoLog EXTRA "Extracting and patching '${file}'"
574 .tar.bz2) CT_DoExecLog ALL tar xvjf "${full_file}";;
575 .tar.gz|.tgz) CT_DoExecLog ALL tar xvzf "${full_file}";;
576 .tar) CT_DoExecLog ALL tar xvf "${full_file}";;
577 *) CT_Abort "Don't know how to handle '${file}': unknown extension" ;;
580 # Snapshots might not have the version number in the extracted directory
581 # name. This is also the case for some (odd) packages, such as D.U.M.A.
582 # Overcome this issue by symlink'ing the directory.
583 if [ ! -d "${file}" -a "${libc_addon}" != "y" ]; then
585 .tar.bz2) base=$(tar tjf "${full_file}" |head -n 1 |cut -d / -f 1 || true);;
586 .tar.gz|.tgz) base=$(tar tzf "${full_file}" |head -n 1 |cut -d / -f 1 || true);;
587 .tar) base=$(tar tf "${full_file}" |head -n 1 |cut -d / -f 1 || true);;
589 CT_TestOrAbort "There was a problem when extracting '${file}'" -d "${base}" -o "${base}" != "${file}"
590 ln -s "${base}" "${file}"
593 # Kludge: outside this function, we wouldn't know if we had just extracted
594 # a libc addon, or a plain package. Apply patches now.
595 if [ "${libc_addon}" = "y" ]; then
596 # Some addon tarballs directly contain the correct addon directory,
597 # while others have the addon directory named after the tarball.
598 # Fix that by always using the short name (eg: linuxthreads, ports, etc...)
599 addon_short_name=$(echo "${file}" |sed -r -e 's/^[^-]+-//; s/-[^-]+$//;')
600 [ -d "${addon_short_name}" ] || ln -s "${file}" "${addon_short_name}"
601 # If libc addon, we're already in the correct place
608 [ "${CUSTOM_PATCH_ONLY}" = "y" ] || official_patch_dir="${CT_LIB_DIR}/patches/${base_file}/${ver_file}"
609 [ "${CT_CUSTOM_PATCH}" = "y" ] && custom_patch_dir="${CT_CUSTOM_PATCH_DIR}/${base_file}/${ver_file}"
610 for patch_dir in "${official_patch_dir}" "${custom_patch_dir}"; do
611 if [ -n "${patch_dir}" -a -d "${patch_dir}" ]; then
612 for p in "${patch_dir}"/*.patch; do
613 if [ -f "${p}" ]; then
614 CT_DoLog DEBUG "Applying patch '${p}'"
615 CT_DoExecLog ALL patch -g0 -F1 -p1 -f <"${p}"
616 CT_TestAndAbort "Failed while applying patch file '${p}'" ${PIPESTATUS[0]} -ne 0
622 if [ "${CT_OVERIDE_CONFIG_GUESS_SUB}" = "y" ]; then
623 CT_DoLog ALL "Overiding config.guess and config.sub"
624 for cfg in config_guess config_sub; do
625 eval ${cfg}="${CT_LIB_DIR}/tools/${cfg/_/.}"
626 [ -e "${CT_TOP_DIR}/tools/${cfg/_/.}" ] && eval ${cfg}="${CT_TOP_DIR}/tools/${cfg/_/.}"
627 # Can't use CT_DoExecLog because of the '{} \;' to be passed un-mangled to find
628 find . -type f -name "${cfg/_/.}" -exec cp -v "${!cfg}" {} \; |CT_DoLog ALL
635 # Two wrappers to call config.(guess|sub) either from CT_TOP_DIR or CT_LIB_DIR.
636 # Those from CT_TOP_DIR, if they exist, will be be more recent than those from CT_LIB_DIR.
638 if [ -x "${CT_TOP_DIR}/tools/config.guess" ]; then
639 "${CT_TOP_DIR}/tools/config.guess"
641 "${CT_LIB_DIR}/tools/config.guess"
646 if [ -x "${CT_TOP_DIR}/tools/config.sub" ]; then
647 "${CT_TOP_DIR}/tools/config.sub" "$@"
649 "${CT_LIB_DIR}/tools/config.sub" "$@"
653 # Compute the target tuple from what is provided by the user
654 # Usage: CT_DoBuildTargetTuple
655 # In fact this function takes the environment variables to build the target
656 # tuple. It is needed both by the normal build sequence, as well as the
657 # sample saving sequence.
658 CT_DoBuildTargetTuple() {
659 # Set the endianness suffix, and the default endianness gcc option
660 case "${CT_ARCH_BE},${CT_ARCH_LE}" in
661 y,) target_endian_eb=eb
663 CT_ARCH_ENDIAN_CFLAG="-mbig-endian"
664 CT_ARCH_ENDIAN_LDFLAG="-EB"
666 ,y) target_endian_eb=
668 CT_ARCH_ENDIAN_CFLAG="-mlittle-endian"
669 CT_ARCH_ENDIAN_LDFLAG="-EL"
673 # Set defaults for the system part of the tuple. Can be overriden
674 # by architecture-specific values.
676 none) CT_TARGET_SYS=elf;;
677 *glibc) CT_TARGET_SYS=gnu;;
678 uClibc) CT_TARGET_SYS=uclibc;;
681 # Transform the ARCH into a kernel-understandable ARCH
682 CT_KERNEL_ARCH="${CT_ARCH}"
684 # Set the default values for ARCH, ABI, CPU, TUNE, FPU and FLOAT
685 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
686 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
687 [ "${CT_ARCH_ARCH}" ] && { CT_ARCH_ARCH_CFLAG="-march=${CT_ARCH_ARCH}"; CT_ARCH_WITH_ARCH="--with-arch=${CT_ARCH_ARCH}"; }
688 [ "${CT_ARCH_ABI}" ] && { CT_ARCH_ABI_CFLAG="-mabi=${CT_ARCH_ABI}"; CT_ARCH_WITH_ABI="--with-abi=${CT_ARCH_ABI}"; }
689 [ "${CT_ARCH_CPU}" ] && { CT_ARCH_CPU_CFLAG="-mcpu=${CT_ARCH_CPU}"; CT_ARCH_WITH_CPU="--with-cpu=${CT_ARCH_CPU}"; }
690 [ "${CT_ARCH_TUNE}" ] && { CT_ARCH_TUNE_CFLAG="-mtune=${CT_ARCH_TUNE}"; CT_ARCH_WITH_TUNE="--with-tune=${CT_ARCH_TUNE}"; }
691 [ "${CT_ARCH_FPU}" ] && { CT_ARCH_FPU_CFLAG="-mfpu=${CT_ARCH_FPU}"; CT_ARCH_WITH_FPU="--with-fpu=${CT_ARCH_FPU}"; }
692 [ "${CT_ARCH_FLOAT_SW}" ] && { CT_ARCH_FLOAT_CFLAG="-msoft-float"; CT_ARCH_WITH_FLOAT="--with-float=soft"; }
694 # Call the architecture specific settings
697 # Finish the target tuple construction
698 case "${CT_KERNEL}" in
699 none) CT_TARGET_KERNEL=;;
700 linux) CT_TARGET_KERNEL=linux-;;
702 CT_TARGET=$(CT_DoConfigSub "${CT_TARGET_ARCH}-${CT_TARGET_VENDOR:-unknown}-${CT_TARGET_KERNEL}${CT_TARGET_SYS}")
704 # Prepare the target CFLAGS
705 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ENDIAN_CFLAG}"
706 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ARCH_CFLAG}"
707 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_ABI_CFLAG}"
708 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_CPU_CFLAG}"
709 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_TUNE_CFLAG}"
710 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_FPU_CFLAG}"
711 CT_ARCH_TARGET_CFLAGS="${CT_ARCH_TARGET_CFLAGS} ${CT_ARCH_FLOAT_CFLAG}"
713 # Now on for the target LDFLAGS
714 CT_ARCH_TARGET_LDFLAGS="${CT_ARCH_TARGET_LDFLAGS} ${CT_ARCH_ENDIAN_LDFLAG}"
717 # This function does pause the build until the user strikes "Return"
718 # Usage: CT_DoPause [optional_message]
721 local message="${1:-Pausing for your pleasure}"
722 CT_DoLog INFO "${message}"
723 read -p "Press 'Enter' to continue, or Ctrl-C to stop..." foo >&6
727 # This function saves the state of the toolchain to be able to restart
729 # Usage: CT_DoSaveState <next_step_name>
731 [ "${CT_DEBUG_CT_SAVE_STEPS}" = "y" ] || return 0
732 local state_name="$1"
733 local state_dir="${CT_STATE_DIR}/${state_name}"
735 CT_DoLog DEBUG "Saving state to restart at step '${state_name}'..."
736 rm -rf "${state_dir}"
737 mkdir -p "${state_dir}"
739 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
740 y) tar_opt=z; tar_ext=.gz;;
741 *) tar_opt=; tar_ext=;;
744 CT_DoLog DEBUG " Saving environment and aliases"
745 # We must omit shell functions, and some specific bash variables
746 # that break when restoring the environment, later. We could do
747 # all the processing in the awk script, but a sed is easier...
750 $0~/^[^ ]+ \(\)/ { _p = 0; }
752 $0 == "}" { _p = 1; }
753 ' |sed -r -e '/^BASH_(ARGC|ARGV|LINENO|SOURCE|VERSINFO)=/d;
755 /^(FUNCNAME|GROUPS|PPID|SHELLOPTS)=/d;' >"${state_dir}/env.sh"
757 CT_DoLog DEBUG " Saving CT_CC_CORE_STATIC_PREFIX_DIR='${CT_CC_CORE_STATIC_PREFIX_DIR}'"
758 CT_Pushd "${CT_CC_CORE_STATIC_PREFIX_DIR}"
759 CT_DoExecLog DEBUG tar cv${tar_opt}f "${state_dir}/cc_core_static_prefix_dir.tar${tar_ext}" .
762 CT_DoLog DEBUG " Saving CT_CC_CORE_SHARED_PREFIX_DIR='${CT_CC_CORE_SHARED_PREFIX_DIR}'"
763 CT_Pushd "${CT_CC_CORE_SHARED_PREFIX_DIR}"
764 CT_DoExecLog DEBUG tar cv${tar_opt}f "${state_dir}/cc_core_shared_prefix_dir.tar${tar_ext}" .
767 CT_DoLog DEBUG " Saving CT_PREFIX_DIR='${CT_PREFIX_DIR}'"
768 CT_Pushd "${CT_PREFIX_DIR}"
769 CT_DoExecLog DEBUG tar cv${tar_opt}f "${state_dir}/prefix_dir.tar${tar_ext}" --exclude '*.log' .
772 if [ "${CT_LOG_TO_FILE}" = "y" ]; then
773 CT_DoLog DEBUG " Saving log file"
775 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
776 y) gzip -3 -c "${CT_LOG_FILE}" >"${state_dir}/log.gz";;
777 *) cat "${CT_LOG_FILE}" >"${state_dir}/log";;
779 exec >>"${CT_LOG_FILE}"
783 # This function restores a previously saved state
784 # Usage: CT_DoLoadState <state_name>
786 local state_name="$1"
787 local state_dir="${CT_STATE_DIR}/${state_name}"
788 local old_RESTART="${CT_RESTART}"
789 local old_STOP="${CT_STOP}"
791 CT_TestOrAbort "The previous build did not reach the point where it could be restarted at '${CT_RESTART}'" -d "${state_dir}"
793 # We need to do something special with the log file!
794 if [ "${CT_LOG_TO_FILE}" = "y" ]; then
795 exec >"${state_dir}/tail.log"
797 CT_DoLog INFO "Restoring state at step '${state_name}', as requested."
799 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
800 y) tar_opt=z; tar_ext=.gz;;
801 *) tar_opt=; tar_ext=;;
804 CT_DoLog DEBUG " Removing previous build directories"
805 chmod -R u+rwX "${CT_PREFIX_DIR}" "${CT_CC_CORE_SHARED_PREFIX_DIR}" "${CT_CC_CORE_STATIC_PREFIX_DIR}"
806 rm -rf "${CT_PREFIX_DIR}" "${CT_CC_CORE_SHARED_PREFIX_DIR}" "${CT_CC_CORE_STATIC_PREFIX_DIR}"
807 mkdir -p "${CT_PREFIX_DIR}" "${CT_CC_CORE_SHARED_PREFIX_DIR}" "${CT_CC_CORE_STATIC_PREFIX_DIR}"
809 CT_DoLog DEBUG " Restoring CT_PREFIX_DIR='${CT_PREFIX_DIR}'"
810 CT_Pushd "${CT_PREFIX_DIR}"
811 CT_DoExecLog DEBUG tar xv${tar_opt}f "${state_dir}/prefix_dir.tar${tar_ext}"
814 CT_DoLog DEBUG " Restoring CT_CC_CORE_SHARED_PREFIX_DIR='${CT_CC_CORE_SHARED_PREFIX_DIR}'"
815 CT_Pushd "${CT_CC_CORE_SHARED_PREFIX_DIR}"
816 CT_DoExecLog DEBUG tar xv${tar_opt}f "${state_dir}/cc_core_shared_prefix_dir.tar${tar_ext}"
819 CT_DoLog DEBUG " Restoring CT_CC_CORE_STATIC_PREFIX_DIR='${CT_CC_CORE_STATIC_PREFIX_DIR}'"
820 CT_Pushd "${CT_CC_CORE_STATIC_PREFIX_DIR}"
821 CT_DoExecLog DEBUG tar xv${tar_opt}f "${state_dir}/cc_core_static_prefix_dir.tar${tar_ext}"
824 # Restore the environment, discarding any error message
825 # (for example, read-only bash internals)
826 CT_DoLog DEBUG " Restoring environment"
827 . "${state_dir}/env.sh" >/dev/null 2>&1 || true
829 # Restore the new RESTART and STOP steps
830 CT_RESTART="${old_RESTART}"
831 CT_STOP="${old_STOP}"
832 unset old_stop old_restart
834 if [ "${CT_LOG_TO_FILE}" = "y" ]; then
835 CT_DoLog DEBUG " Restoring log file"
837 case "${CT_DEBUG_CT_SAVE_STEPS_GZIP}" in
838 y) zcat "${state_dir}/log.gz" >"${CT_LOG_FILE}";;
839 *) cat "${state_dir}/log" >"${CT_LOG_FILE}";;
841 cat "${state_dir}/tail.log" >>"${CT_LOG_FILE}"
842 exec >>"${CT_LOG_FILE}"
843 rm -f "${state_dir}/tail.log"