diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/build/binutils/binutils.sh | 2 | ||||
-rw-r--r-- | scripts/build/cc/gcc.sh | 18 | ||||
-rw-r--r-- | scripts/build/libc/glibc.sh | 17 | ||||
-rw-r--r-- | scripts/build/libc/mingw-w64.sh | 6 | ||||
-rw-r--r-- | scripts/crosstool-NG.sh.in | 59 | ||||
-rw-r--r-- | scripts/functions | 306 |
6 files changed, 239 insertions, 169 deletions
diff --git a/scripts/build/binutils/binutils.sh b/scripts/build/binutils/binutils.sh index 8fb51b8d..e0fe7f40 100644 --- a/scripts/build/binutils/binutils.sh +++ b/scripts/build/binutils/binutils.sh @@ -188,7 +188,7 @@ do_binutils_backend() { --disable-werror \ "${extra_config[@]}" \ ${CT_ARCH_WITH_FLOAT} \ - ${BINUTILS_SYSROOT_ARG} \ + ${CT_BINUTILS_SYSROOT_ARG} \ "${CT_BINUTILS_EXTRA_CONFIG_ARRAY[@]}" if [ "${static_build}" = "y" ]; then diff --git a/scripts/build/cc/gcc.sh b/scripts/build/cc/gcc.sh index 6019b35a..54dd514c 100644 --- a/scripts/build/cc/gcc.sh +++ b/scripts/build/cc/gcc.sh @@ -14,7 +14,7 @@ do_cc_get() { # GCC source tree, which will not be there unless we get it and # put it there ourselves if [ "${CT_CC_LANG_JAVA_USE_ECJ}" = "y" ]; then - if ! CT_GetFile ecj-latest .jar $(CT_Mirrors sourceware java); then + if ! CT_GetFile ecj ecj-latest .jar $(CT_Mirrors sourceware java); then # Should be a package, too - but with Java retirement in GCC, # it may not make sense. CT_Abort "Failed to download ecj-latest.jar" @@ -453,6 +453,18 @@ do_gcc_core_backend() { extra_config+=("--disable-libstdcxx-pch") fi + if [ "${CT_LIBC_GLIBC}" = "y" ]; then + # Report GLIBC's version to GCC, it affects the defaults on other options. + # Pass-2 should be able to get it from the headers, but for some options + # (such as --with-long-double-128) we need to get it right even in pass-1. + # GCC expects just two numbers separated by a dot. + local glibc_version + + CT_GetPkgVersion GLIBC glibc_version + glibc_version=`echo "${glibc_version}" | sed 's/\([1-9][0-9]*\.[1-9][0-9]*\).*/\1/'` + extra_config+=("--with-glibc-version=${glibc_version}") + fi + case "${CT_CC_GCC_LDBL_128}" in y) extra_config+=("--with-long-double-128");; m) ;; @@ -560,7 +572,7 @@ do_gcc_core_backend() { --target=${CT_TARGET} \ --prefix="${prefix}" \ --with-local-prefix="${CT_SYSROOT_DIR}" \ - ${CC_CORE_SYSROOT_ARG} \ + ${CT_CC_CORE_SYSROOT_ARG} \ "${extra_config[@]}" \ --enable-languages="${lang_list}" \ "${extra_user_config[@]}" @@ -1105,7 +1117,7 @@ do_gcc_backend() { --host=${host} \ --target=${CT_TARGET} \ --prefix="${prefix}" \ - ${CC_SYSROOT_ARG} \ + ${CT_CC_SYSROOT_ARG} \ "${extra_config[@]}" \ --with-local-prefix="${CT_SYSROOT_DIR}" \ --enable-long-long \ diff --git a/scripts/build/libc/glibc.sh b/scripts/build/libc/glibc.sh index eae64bc4..c09ff5cd 100644 --- a/scripts/build/libc/glibc.sh +++ b/scripts/build/libc/glibc.sh @@ -5,7 +5,6 @@ do_libc_get() { local date local version - local -a addons_list CT_Fetch GLIBC if [ "${CT_GLIBC_USE_PORTS_EXTERNAL}" = "y" ]; then @@ -15,13 +14,18 @@ do_libc_get() { } do_libc_extract() { - local addon - CT_ExtractPatch GLIBC if [ "${CT_GLIBC_USE_PORTS_EXTERNAL}" = "y" ]; then CT_ExtractPatch GLIBC_PORTS + + # This may create a bogus symlink if glibc-ports is using custom + # sources or has an overlay (and glibc is shared). However, + # we do not support concurrent use of the source directory + # and next run, if using different glibc-ports source, will override + # this symlink anyway. + CT_DoExecLog ALL ln -sf "${CT_GLIBC_PORTS_SRC_DIR}/${CT_GLIBC_PORTS_BASENAME}" \ + "${CT_GLIBC_SRC_DIR}/${CT_GLIBC_BASENAME}/ports" fi - # TBD make patches for addons (ports? anything else?) uniformly using short names # TBD make the configure timestamp fix in all patched packages (e.g. part of CT_ExtractPatch) } @@ -124,8 +128,9 @@ do_libc_backend_once() { # Also, if those two are missing, iconv build breaks extra_config+=( --disable-debug --disable-sanity-checks ) - # always include rpc, the user can still override it with TI-RPC - extra_config+=( --enable-obsolete-rpc ) + if [ "${CT_GLIBC_ENABLE_OBSOLETE_RPC}" = "y" ]; then + extra_config+=( --enable-obsolete-rpc ) + fi # Add some default glibc config options if not given by user. # We don't need to be conditional on whether the user did set different diff --git a/scripts/build/libc/mingw-w64.sh b/scripts/build/libc/mingw-w64.sh index 295b313b..21afb29d 100644 --- a/scripts/build/libc/mingw-w64.sh +++ b/scripts/build/libc/mingw-w64.sh @@ -63,10 +63,10 @@ do_libc_start_files() { do_check_mingw_vendor_tuple() { - if [ "${CT_MINGW_W64_VERSION%%.*}" -ge 4 ]; then + if [ "${CT_MINGW_W64_REQUIRES_W64_VENDOR}" = "y" ]; then CT_DoStep INFO "Checking configured vendor tuple" - if [ ${CT_TARGET_VENDOR} == w64 ]; then - CT_DoLog EXTRA "The tuple is set to '${CT_TARGET_VENDOR}', as recommended by mingw-64 developers." + if [ ${CT_TARGET_VENDOR} = "w64" ]; then + CT_DoLog DEBUG "The tuple is set to '${CT_TARGET_VENDOR}', as recommended by mingw-64 developers." else CT_DoLog WARN "The tuple vendor is '${CT_TARGET_VENDOR}', not equal to 'w64' and might break the toolchain!" fi diff --git a/scripts/crosstool-NG.sh.in b/scripts/crosstool-NG.sh.in index bd07c6b4..d5066e21 100644 --- a/scripts/crosstool-NG.sh.in +++ b/scripts/crosstool-NG.sh.in @@ -40,6 +40,8 @@ if [ "${CT_DEBUG_INTERACTIVE}" = "y" -a ! \( -t 0 -a -t 6 -a -t 2 \) ]; then exit 1 fi +CT_TrapEnvExport + # Override the locale early, in case we ever translate crosstool-NG messages if [ -z "${CT_NO_OVERRIDE_LC_MESSAGES}" ]; then export LC_ALL=C @@ -51,19 +53,19 @@ CT_SanitizePath # Some sanity checks in the environment and needed tools CT_DoLog INFO "Performing some trivial sanity checks" -CT_TestAndAbort "Don't set LD_LIBRARY_PATH. It screws up the build." -n "${LD_LIBRARY_PATH}" -CT_TestAndAbort "Don't set LIBRARY_PATH. It screws up the build." -n "${LIBRARY_PATH}" -CT_TestAndAbort "Don't set LPATH. It screws up the build." -n "${LPATH}" -CT_TestAndAbort "Don't set CPATH. It screws up the build." -n "${CPATH}" -CT_TestAndAbort "Don't set C_INCLUDE_PATH. It screws up the build." -n "${C_INCLUDE_PATH}" -CT_TestAndAbort "Don't set CPLUS_INCLUDE_PATH. It screws up the build." -n "${CPLUS_INCLUDE_PATH}" -CT_TestAndAbort "Don't set OBJC_INCLUDE_PATH. It screws up the build." -n "${OBJC_INCLUDE_PATH}" -CT_TestAndAbort "Don't set CFLAGS. It screws up the build." -n "${CFLAGS}" -CT_TestAndAbort "Don't set CXXFLAGS. It screws up the build." -n "${CXXFLAGS}" -CT_TestAndAbort "Don't set CC. It screws up the build." -n "${CC}" -CT_TestAndAbort "Don't set CXX. It screws up the build." -n "${CXX}" -CT_Test "GREP_OPTIONS screws up the build. Resetting." -n "${GREP_OPTIONS}" -export GREP_OPTIONS= +CT_TestAndAbort "Don't set LD_LIBRARY_PATH. It screws up the build." -n "${LD_LIBRARY_PATH+set}" +CT_TestAndAbort "Don't set LIBRARY_PATH. It screws up the build." -n "${LIBRARY_PATH+set}" +CT_TestAndAbort "Don't set LPATH. It screws up the build." -n "${LPATH+set}" +CT_TestAndAbort "Don't set CPATH. It screws up the build." -n "${CPATH+set}" +CT_TestAndAbort "Don't set C_INCLUDE_PATH. It screws up the build." -n "${C_INCLUDE_PATH+set}" +CT_TestAndAbort "Don't set CPLUS_INCLUDE_PATH. It screws up the build." -n "${CPLUS_INCLUDE_PATH+set}" +CT_TestAndAbort "Don't set OBJC_INCLUDE_PATH. It screws up the build." -n "${OBJC_INCLUDE_PATH+set}" +CT_TestAndAbort "Don't set CFLAGS. It screws up the build." -n "${CFLAGS+set}" +CT_TestAndAbort "Don't set CXXFLAGS. It screws up the build." -n "${CXXFLAGS+set}" +CT_TestAndAbort "Don't set CC. It screws up the build." -n "${CC+set}" +CT_TestAndAbort "Don't set CXX. It screws up the build." -n "${CXX+set}" +CT_Test "GREP_OPTIONS screws up the build. Unsetting." -n "${GREP_OPTIONS+set}" +unset GREP_OPTIONS # Workaround against openSUSE 12.1 that breaks ./configure for cross-compilation: export CONFIG_SITE= @@ -141,9 +143,13 @@ CT_DoStep DEBUG "Dumping user-supplied crosstool-NG configuration" CT_DoExecLog DEBUG ${grep} -E '^(# )?CT_' .config CT_EndStep -CT_DoLog DEBUG "Unsetting and unexporting MAKEFLAGS" +CT_DoLog DEBUG "Unsetting MAKEFLAGS" unset MAKEFLAGS -export MAKEFLAGS + +# Set the shell to be used by ./configure scripts and by Makefiles (those +# that support it!). +export CONFIG_SHELL="${CT_CONFIG_SHELL}" # for ./configure +export SHELL="${CT_CONFIG_SHELL}" # for Makefiles CT_DoLog INFO "Building environment variables" @@ -167,7 +173,7 @@ CT_PKGVERSION="crosstool-NG ${CT_VERSION}${CT_TOOLCHAIN_PKGVERSION:+ - ${CT_TOOL # Compute the working directories names CT_TARBALLS_DIR="${CT_WORK_DIR}/tarballs" CT_COMMON_SRC_DIR="${CT_WORK_DIR}/src" -CT_SRC_DIR="${CT_BUILD_DIR}/src" +CT_SRC_DIR="${CT_BUILD_TOP_DIR}/src" CT_BUILDTOOLS_PREFIX_DIR="${CT_BUILD_TOP_DIR}/buildtools" CT_STATE_DIR="${CT_WORK_DIR}/${CT_TARGET}/state" # Note about HOST_COMPLIBS_DIR: it's always gonna be in the buildtools dir, or a @@ -304,9 +310,9 @@ if [ -z "${CT_RESTART}" ]; then CT_DEBUGROOT_DIR="${CT_PREFIX_DIR}/${CT_TARGET}/${CT_SYSROOT_DIR_PREFIX}/debug-root" CT_HEADERS_DIR="${CT_SYSROOT_DIR}/usr/include" CT_SanitizeVarDir CT_SYSROOT_DIR CT_DEBUGROOT_DIR CT_HEADERS_DIR - BINUTILS_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}" - CC_CORE_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}" - CC_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}" + CT_BINUTILS_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}" + CT_CC_CORE_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}" + CT_CC_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}" # glibc's prefix must be exactly /usr, else --with-sysroot'd gcc will get # confused when $sysroot/usr/include is not present. # Note: --prefix=/usr is magic! @@ -320,11 +326,11 @@ if [ -z "${CT_RESTART}" ]; then # hack! Always use --with-sysroot for binutils. # binutils 2.14 and later obey it, older binutils ignore it. # Lets you build a working 32->64 bit cross gcc - BINUTILS_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}" + CT_BINUTILS_SYSROOT_ARG="--with-sysroot=${CT_SYSROOT_DIR}" # Use --with-headers, else final gcc will define disable_glibc while # building libgcc, and you'll have no profiling - CC_CORE_SYSROOT_ARG="--without-headers" - CC_SYSROOT_ARG="--with-headers=${CT_HEADERS_DIR}" + CT_CC_CORE_SYSROOT_ARG="--without-headers" + CT_CC_SYSROOT_ARG="--with-headers=${CT_HEADERS_DIR}" fi CT_DoExecLog ALL mkdir -p "${CT_SYSROOT_DIR}" CT_DoExecLog ALL mkdir -p "${CT_DEBUGROOT_DIR}" @@ -529,11 +535,6 @@ if [ -z "${CT_RESTART}" ]; then CT_DoLog DEBUG "CFLAGS for host compiler: '${CT_CFLAGS_FOR_HOST}'" CT_DoLog DEBUG "LDFLAGS for host compiler: '${CT_LDFLAGS_FOR_HOST}'" - # Set the shell to be used by ./configure scripts and by Makefiles (those - # that support it!). - export CONFIG_SHELL="${CT_CONFIG_SHELL}" # for ./configure - export SHELL="${CT_CONFIG_SHELL}" # for Makefiles - # And help make go faster JOBSFLAGS= # Override the configured jobs with what's been given on the command line @@ -601,9 +602,7 @@ if [ -z "${CT_RESTART}" ]; then CT_DoLog DEBUG "Other environment:" printenv |${grep} -v -E '^CT_.+=' |CT_DoLog DEBUG CT_EndStep -fi -if [ -z "${CT_RESTART}" ]; then CT_DoStep INFO "Retrieving needed toolchain components' tarballs" do_companion_tools_get do_kernel_get @@ -651,7 +650,7 @@ if [ "${CT_ONLY_DOWNLOAD}" != "y" -a "${CT_ONLY_EXTRACT}" != "y" ]; then else CT_DoSaveState ${step} if [ ${do_stop} -eq 1 ]; then - CT_DoLog ERROR "Stopping just after step '${prev_step}', as requested." + CT_DoLog INFO "Stopping just after step '${prev_step}', as requested." exit 0 fi fi diff --git a/scripts/functions b/scripts/functions index 5527fa21..f11ce23f 100644 --- a/scripts/functions +++ b/scripts/functions @@ -155,8 +155,28 @@ CT_OnError() { CT_DoLog ERROR ">> For more info on this error, look at the file: '${CT_BUILD_LOG#${CT_TOP_DIR}/}'" fi CT_DoLog ERROR ">> There is a list of known issues, some with workarounds, in:" - CT_DoLog ERROR ">> '${CT_DOC_DIR#${CT_TOP_DIR}/}/B - Known issues.txt'" + if [ -r "${CT_DOC_DIR}/manual/B_Known_issues.md" ]; then + CT_DoLog ERROR ">> '${CT_DOC_DIR#${CT_TOP_DIR}/}/manual/B_Known_issues.md'" + else + CT_DoLog ERROR ">> https://crosstool-ng.github.io/docs/known-issues/" + fi CT_DoLog ERROR ">>" + if [ -n "${CT_EXPERIMENTAL}" ]; then + CT_DoLog ERROR ">> NOTE: Your configuration includes features marked EXPERIMENTAL." + CT_DoLog ERROR ">> Before submitting a bug report, try to reproduce it without enabling" + CT_DoLog ERROR ">> any experimental features. Otherwise, you'll need to debug it" + CT_DoLog ERROR ">> and present an explanation why it is a bug in crosstool-NG - or" + CT_DoLog ERROR ">> preferably, a fix." + CT_DoLog ERROR ">>" + fi + if [ "${CT_PATCH_ORDER}" != "bundled" ]; then + CT_DoLog ERROR ">> NOTE: You configuration uses non-default patch sets. Please" + CT_DoLog ERROR ">> select 'bundled' as the set of patches applied and attempt" + CT_DoLog ERROR ">> to reproduce this issue. Issues reported with other patch" + CT_DoLog ERROR ">> set selections (none, local, bundled+local) are going to be" + CT_DoLog ERROR ">> closed without explanation." + CT_DoLog ERROR ">>" + fi CT_DoLog ERROR ">> If you feel this is a bug in crosstool-NG, report it at:" CT_DoLog ERROR ">> https://github.com/crosstool-ng/crosstool-ng/issues/" CT_DoLog ERROR ">>" @@ -178,7 +198,7 @@ trap CT_OnError ERR set -E # Make pipes fail on the _first_ failed command -# Not supported on bash < 3.x, but we need it, so drop the obsoleting bash-2.x +# Not supported on bash < 3.x, but we need it, so drop the obsolete bash-2.x set -o pipefail # Don't hash commands' locations, and search every time it is requested. @@ -624,6 +644,7 @@ CT_DoListTarballExt() { printf ".tar.xz\n" printf ".tar.lzma\n" + printf ".tar.lz\n" printf ".tar.bz2\n" printf ".tar.gz\n.tgz\n" printf ".tar\n" @@ -638,16 +659,13 @@ CT_GetFileExtension() { local ext local file="$1" - shift - local first_ext="$1" - for ext in ${first_ext} $(CT_DoListTarballExt); do + for ext in $(CT_DoListTarballExt); do if [ -e "${file}${ext}" -o -L "${file}${ext}" ]; then echo "${ext}" exit 0 fi done - exit 1 } @@ -658,8 +676,8 @@ CT_GetFileBasename() local ext for ext in $(CT_DoListTarballExt); do - if [ "${bn%.${ext}}" != "${bn}" ]; then - echo "${bn%.${ext}}" + if [ "${bn%${ext}}" != "${bn}" ]; then + echo "${bn%${ext}}" exit 0 fi done @@ -685,6 +703,7 @@ CT_DoGetFile() { T="${CT_CONNECT_TIMEOUT}" fi + CT_DoLog DEBUG "Trying '${url}'" if [ "${CT_DOWNLOAD_AGENT_WGET}" = "y" ]; then if CT_DoExecLog ALL wget ${CT_DOWNLOAD_WGET_OPTIONS} \ ${T:+-T ${T}} \ @@ -705,43 +724,15 @@ CT_DoGetFile() { # Success, we got it, good! mv "${tmp}" "${dest}" CT_DoLog DEBUG "Got it from: \"${url}\"" + return 0 else - # Woops... + # Whoops... rm -f "${tmp}" CT_DoLog DEBUG "Not at this location: \"${url}\"" + return 1 fi } -# This function tries to retrieve a tarball form a local directory -# Usage: CT_GetLocal <basename> [.extension] -CT_GetLocal() { - local basename="$1" - local first_ext="$2" - local ext - - # Do we already have it in *our* tarballs dir? - if ext="$( CT_GetFileExtension "${CT_TARBALLS_DIR}/${basename}" ${first_ext} )"; then - CT_DoLog DEBUG "Already have '${CT_TARBALLS_DIR}/${basename}${ext}'" - return 0 - fi - - if [ -n "${CT_LOCAL_TARBALLS_DIR}" ]; then - CT_DoLog DEBUG "Trying to retrieve an already downloaded copy of '${basename}'" - # We'd rather have a bzip2'ed tarball, then gzipped tarball, plain tarball, - # or, as a failover, a file without extension. - for ext in ${first_ext} $(CT_DoListTarballExt) ''; do - CT_DoLog DEBUG "Trying '${CT_LOCAL_TARBALLS_DIR}/${basename}${ext}'" - if [ -r "${CT_LOCAL_TARBALLS_DIR}/${basename}${ext}" -a \ - "${CT_FORCE_DOWNLOAD}" != "y" ]; then - CT_DoLog DEBUG "Got '${basename}' from local storage" - CT_DoExecLog ALL ln -s "${CT_LOCAL_TARBALLS_DIR}/${basename}${ext}" "${CT_TARBALLS_DIR}/${basename}${ext}" - return 0 - fi - done - fi - return 1 -} - # This function saves the specified to local storage if possible, # and if so, symlinks it for later usage # Usage: CT_SaveLocal </full/path/file.name> @@ -759,29 +750,34 @@ CT_SaveLocal() { } # Download the file from one of the URLs passed as argument -# Usage: CT_GetFile <basename> [.extension] <url> [url ...] +# Usage: CT_GetFile <packagename> <basename> <extensions> <url> [url ...] CT_GetFile() { local ext local -a URLS local url - local file="$1" - local first_ext - shift - # If next argument starts with a dot, then this is not an URL, - # and we can consider that it is a preferred extension. - case "$1" in - .*) first_ext="$1" - shift - ;; - esac + local package="$1" + local file="$2" + local extensions="$3" + shift 3 + + # Does any of the requested files exist localy? + for ext in ${extensions}; do + # Do we already have it in *our* tarballs dir? + if [ -r "${CT_TARBALLS_DIR}/${file}${ext}" ]; then + CT_DoLog DEBUG "Already have '${CT_TARBALLS_DIR}/${file}${ext}'" + return 0 + fi - # Does it exist localy? - if CT_GetLocal "${file}" ${first_ext}; then - return 0 - fi - # No, it does not... + if [ -n "${CT_LOCAL_TARBALLS_DIR}" -a "${CT_FORCE_DOWNLOAD}" != "y" -a \ + -r "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" ]; then + CT_DoLog DEBUG "Got '${file}' from local storage" + CT_DoExecLog ALL ln -s "${CT_LOCAL_TARBALLS_DIR}/${file}${ext}" \ + "${CT_TARBALLS_DIR}/${file}${ext}" + return 0 + fi + done - # If not allowed to download from the Internet, don't + # No, it does not... If not allowed to download from the Internet, don't. if [ "${CT_FORBID_DOWNLOAD}" = "y" ]; then CT_DoLog DEBUG "Not allowed to download from the Internet, aborting ${file} download" return 1 @@ -793,7 +789,9 @@ CT_GetFile() { # Add URLs on the LAN mirror if [ "${CT_USE_MIRROR}" = "y" ]; then CT_TestOrAbort "Please set the mirror base URL" -n "${CT_MIRROR_BASE_URL}" - URLS+=( "${CT_MIRROR_BASE_URL}/${file%-*}" ) + if [ -n "${package}" ]; then + URLS+=( "${CT_MIRROR_BASE_URL}/${package}" ) + fi URLS+=( "${CT_MIRROR_BASE_URL}" ) fi @@ -804,14 +802,11 @@ CT_GetFile() { # Scan all URLs in turn, and try to grab a tarball from there # Do *not* try git trees (ext=/.git), this is handled in a specific # wrapper, below - for ext in ${first_ext} $(CT_DoListTarballExt) ''; do + for ext in ${extensions}; do # Try all urls in turn for url in "${URLS[@]}"; do [ -n "${url}" ] || continue - CT_DoLog DEBUG "Trying '${url}/${file}${ext}'" - CT_DoGetFile "${url}/${file}${ext}" - if [ -f "${CT_TARBALLS_DIR}/${file}${ext}" ]; then - CT_DoLog DEBUG "Got '${file}' from the Internet" + if CT_DoGetFile "${url}/${file}${ext}"; then CT_SaveLocal "${CT_TARBALLS_DIR}/${file}${ext}" return 0 fi @@ -999,6 +994,30 @@ CT_DoPause() { return 0 } +# This function sets up trapping export/unset operations so that saving/restoring +# the state can restore status of environment exactly. +CT_TrapEnvExport() +{ + unset() + { + eval "builtin unset $*" + CT_ENVVAR_UNSET="${CT_ENVVAR_UNSET} $*" + } + + export() + { + local v + + for v in "$@"; do + eval "builtin export \"${v}\"" + case "${CT_ENVVAR_EXPORTED} " in + *" ${v%%=*} "*) continue;; + esac + CT_ENVVAR_EXPORTED="${CT_ENVVAR_EXPORTED} ${v%%=*}" + done + } +} + # This function creates a tarball of the specified directory, but # only if it exists # Usage: CT_DoTarballIfExists <dir> <tarball_basename> [extra_tar_options [...]] @@ -1058,26 +1077,35 @@ CT_DoSaveState() { [ "${CT_DEBUG_CT_SAVE_STEPS}" = "y" ] || return 0 local state_name="$1" local state_dir="${CT_STATE_DIR}/${state_name}" + local v CT_DoLog INFO "Saving state to restart at step '${state_name}'..." rm -rf "${state_dir}" mkdir -p "${state_dir}" + # Save only environment variables, not functions. + # Limit saving to our variables (CT_*) and exported variables. + # Also unset variables that have been removed from the environment. + # This generated script will be sourced from a function, so make + # all the definitions global by adding -g. Hope we don't have + # a multi-line variable that has a line starting with "declare" + # (or we'll need to run sed on each variable separately, only on + # the first line of it). CT_DoLog STATE " Saving environment and aliases" - # We must omit shell functions, and some specific bash variables - # that break when restoring the environment, later. We could do - # all the processing in the awk script, but a sed is easier... - set |${awk} ' - BEGIN { _p = 1; } - $0~/^[^ ]+ \(\)/ { _p = 0; } - _p == 1 - $0 == "}" { _p = 1; } - ' |${sed} -r -e '/^BASH_(ARGC|ARGV|LINENO|SOURCE|VERSINFO)=/d; - /^(UID|EUID)=/d; - /^(FUNCNAME|GROUPS|PPID|SHELLOPTS)=/d;' >"${state_dir}/env.sh" + { + for v in "${!CT_@}" ${CT_ENVVAR_EXPORTED}; do + # Check if it is still set + [ -n "${!v+set}" ] && declare -p "${v}" + done | ${sed} 's/^declare /declare -g /' + echo "builtin unset ${CT_ENVVAR_UNSET}" + } >"${state_dir}/env.sh" + + # Save .config to check it hasn't changed when resuming. + CT_DoExecLog STATE cp ".config" "${state_dir}/config" CT_DoTarballIfExists "${CT_BUILDTOOLS_PREFIX_DIR}" "${state_dir}/buildtools_dir" + CT_DoTarballIfExists "${CT_SRC_DIR}" "${state_dir}/src_dir" CT_DoTarballIfExists "${CT_PREFIX_DIR}" "${state_dir}/prefix_dir" --exclude '*.log' CT_DoLog STATE " Saving log file" @@ -1098,10 +1126,14 @@ CT_DoLoadState(){ local old_STOP="${CT_STOP}" CT_TestOrAbort "The previous build did not reach the point where it could be restarted at '${CT_RESTART}'" -d "${state_dir}" + if ! cmp ".config" "${state_dir}/config" >/dev/null 2>&1; then + CT_Abort "The configuration file has changed between two runs" + fi CT_DoLog INFO "Restoring state at step '${state_name}', as requested." CT_DoExtractTarballIfExists "${state_dir}/prefix_dir" "${CT_PREFIX_DIR}" + CT_DoExtractTarballIfExists "${state_dir}/src_dir" "${CT_SRC_DIR}" CT_DoExtractTarballIfExists "${state_dir}/buildtools_dir" "${CT_BUILDTOOLS_PREFIX_DIR}" # Restore the environment, discarding any error message @@ -1112,7 +1144,6 @@ CT_DoLoadState(){ # Restore the new RESTART and STOP steps CT_RESTART="${old_RESTART}" CT_STOP="${old_STOP}" - unset old_stop old_restart CT_DoLog STATE " Restoring log file" CT_LogDisable @@ -1667,6 +1698,7 @@ CT_PackageRun() { local sym="${1}" local run="${2}" + local src_dir="/unknown-src-dir" local v # Get rid of our arguments @@ -1682,7 +1714,7 @@ CT_PackageRun() # Variables that are per-fork for v in basename pkg_name version \ - src_release mirrors archive_filename archive_dirname \ + src_release mirrors archive_filename archive_dirname archive_formats \ src_devel devel_vcs devel_url devel_branch devel_revision devel_subdir devel_bootstrap \ src_custom custom_location; do eval "local ${v}=\${CT_${use}_${v^^}}" @@ -1701,7 +1733,8 @@ CT_PackageRun() # Save certain variables that may be modified by the callback. # Fetching the sources is run in the main process, so no need to # use CT_EnvModify. - for v in devel_branch devel_revision basename version; do + for v in devel_branch devel_revision basename version src_dir; do + eval "[ \"\${${v}}\" != \"\${CT_${use}_${v^^}}\" ] || continue" eval "CT_${use}_${v^^}=\${${v}}" eval "CT_DoLog DEBUG \"Override CT_${use}_${v^^}=\${CT_${use}_${v^^}}\"" done @@ -1719,7 +1752,7 @@ CT_DoFetch() else basename="${pkg_name}-${version}" fi - if ! CT_GetFile "${archive_filename}" ${mirrors}; then + if ! CT_GetFile "${pkg_name}" "${archive_filename}" "${archive_formats}" ${mirrors}; then CT_Abort "${pkg_name}: download failed" fi @@ -1748,8 +1781,9 @@ CT_DoFetch() # Try getting the tarball with empty list of URLs: it will only # attempt getting it from local storage or from the mirror if configured. + # Bzip2 offers a reasonable compromise between compression speed and size. if [ "${unique_id}" != "to.be.determined" ] && \ - CT_GetFile "${basename}" .tar.bz2; then + CT_GetFile "${pkg_name}" "${basename}" '.tar.bz2'; then return 0 fi @@ -1777,7 +1811,7 @@ CT_DoFetch() elif [ "${src_custom}" = "y" ]; then # Will be handled during extraction/patching version="local" - basename="${pkg_name}-${version}" + basename="${dir_name}" :; else CT_Abort "No known source for ${pkg_name}" @@ -1806,6 +1840,9 @@ CT_Extract() *.tar.lzma) xz -fdc "${file}" | CT_DoExecLog FILE tar x -v -f - -C "${dir}" ${components} ;; + *.tar.lz) + lzip -fdc "${file}" | CT_DoExecLog FILE tar x -v -f - -C "${dir}" ${components} + ;; *.tar.bz2) bzip2 -dc "${file}" | CT_DoExecLog FILE tar x -v -f - -C "${dir}" ${components} ;; @@ -1841,22 +1878,46 @@ CT_DoExtractPatch() local -a patch_dirs local bundled_patch_dir local local_patch_dir + local overlay + + # If using overlay, prepare it first - we need to determine where to unpack + # this component. + if [ "${CT_TARGET_USE_OVERLAY}" = "y" -a ! -d "${CT_BUILD_DIR}/overlay" ]; then + CT_DoExecLog ALL mkdir -p "${CT_BUILD_DIR}/overlay" + overlay="${CT_OVERLAY_LOCATION}/${CT_ARCH}_${CT_OVERLAY_NAME:-overlay}" + ext=`CT_GetFileExtension "${overlay}"` + if [ ! -r "${overlay}${ext}" ]; then + CT_Abort "Overlay ${overlay} not found" + fi + CT_Extract "${overlay}${ext}" "${CT_BUILD_DIR}/overlay" + fi + + # Can use common location only if using non-custom source, only bundled patches + # and no overlays. Otherwise, this source directory is custom-tailored for this + # particular configuration and cannot be reused by different configurations. + if [ "${src_custom}" != "y" -a \ + "${CT_PATCH_ORDER}" = "bundled" -a \ + ! -d "${CT_BUILD_DIR}/overlay/${dir_name}" ]; then + src_dir="${CT_COMMON_SRC_DIR}" + else + src_dir="${CT_SRC_DIR}" + fi if [ "${src_custom}" != "y" ]; then # Non-custom: extract to shared location # If the previous extraction/patching was aborted, clean up. - if [ -r "${CT_COMMON_SRC_DIR}/.${basename}.extracting" -o \ - -r "${CT_COMMON_SRC_DIR}/.${basename}.patching" ]; then + if [ -r "${src_dir}/.${basename}.extracting" -o \ + -r "${src_dir}/.${basename}.patching" ]; then CT_DoLog WARN "Sources for ${basename} were partially extracted/patched, cleaning up" - CT_DoExecLog ALL rm -rf "${CT_COMMON_SRC_DIR}/${basename}" - CT_DoExecLog ALL rm -f "${CT_COMMON_SRC_DIR}/.${basename}".* + CT_DoExecLog ALL rm -rf "${src_dir}/${basename}" + CT_DoExecLog ALL rm -f "${src_dir}/.${basename}".* fi - if [ -f "${CT_COMMON_SRC_DIR}/.${basename}.extracted" ]; then + if [ -f "${src_dir}/.${basename}.extracted" ]; then CT_DoLog DEBUG "Already extracted ${basename}" else CT_DoLog EXTRA "Extracting ${basename}" - CT_DoExecLog ALL touch "${CT_COMMON_SRC_DIR}/.${basename}.extracting" + CT_DoExecLog ALL touch "${src_dir}/.${basename}.extracting" if [ "${src_release}" = "y" ]; then archive="${archive_filename}" else @@ -1865,21 +1926,21 @@ CT_DoExtractPatch() # TBD save/discover the extension while fetching ext=`CT_GetFileExtension "${CT_TARBALLS_DIR}/${archive}"` if [ "${archive_dirname}" = "." ]; then - CT_mkdir_pushd "${CT_COMMON_SRC_DIR}/${basename}" - CT_Extract "${CT_TARBALLS_DIR}/${archive}${ext}" "${CT_COMMON_SRC_DIR}/${basename}" + CT_mkdir_pushd "${src_dir}/${basename}" + CT_Extract "${CT_TARBALLS_DIR}/${archive}${ext}" "${src_dir}/${basename}" CT_Popd else - CT_Extract "${CT_TARBALLS_DIR}/${archive}${ext}" "${CT_COMMON_SRC_DIR}" + CT_Extract "${CT_TARBALLS_DIR}/${archive}${ext}" "${src_dir}" fi - CT_DoExecLog ALL touch "${CT_COMMON_SRC_DIR}/.${basename}.extracted" - CT_DoExecLog ALL rm -f "${CT_COMMON_SRC_DIR}/.${basename}.extracting" + CT_DoExecLog ALL touch "${src_dir}/.${basename}.extracted" + CT_DoExecLog ALL rm -f "${src_dir}/.${basename}.extracting" fi - if [ -f "${CT_COMMON_SRC_DIR}/.${basename}.patched" ]; then + if [ -f "${src_dir}/.${basename}.patched" ]; then CT_DoLog DEBUG "Already patched ${basename}" else CT_DoLog EXTRA "Patching ${basename}" - CT_DoExecLog ALL touch "${CT_COMMON_SRC_DIR}/.${basename}.patching" + CT_DoExecLog ALL touch "${src_dir}/.${basename}.patching" bundled_patch_dir="${CT_LIB_DIR}/packages/${pkg_name}/${version}" local_patch_dir="${CT_LOCAL_PATCH_DIR}/${pkg_name}/${version}" @@ -1892,7 +1953,7 @@ CT_DoExtractPatch() none) patch_dirs=;; esac - CT_Pushd "${CT_COMMON_SRC_DIR}/${basename}" + CT_Pushd "${src_dir}/${basename}" for d in "${patch_dirs[@]}"; do CT_DoLog DEBUG "Looking for patches in '${d}'..." if [ -n "${d}" -a -d "${d}" ]; then @@ -1929,8 +1990,8 @@ CT_DoExtractPatch() CT_Popd - CT_DoExecLog ALL touch "${CT_COMMON_SRC_DIR}/.${basename}.patched" - CT_DoExecLog ALL rm -f "${CT_COMMON_SRC_DIR}/.${basename}.patching" + CT_DoExecLog ALL touch "${src_dir}/.${basename}.patched" + CT_DoExecLog ALL rm -f "${src_dir}/.${basename}.patching" fi else CT_DoLog WARN "${pkg_name}: using custom location, no patches applied" @@ -1938,50 +1999,33 @@ CT_DoExtractPatch() # Symlink/copy/overlay into per-target source directory if [ "${src_custom}" = "y" ]; then - # Custom sources: unpack or copy into per-target directory - if [ "${CT_TARGET_USE_OVERLAY}" ]; then - CT_DoLog WARN "${pkg_name}: using custom location, no overlays applied" - fi + # Custom sources: unpack or copy into per-target directory. Note that + # ${src_dir} is never ${CT_COMMON_SRC_DIR} in this case. if [ -d "${custom_location}" ]; then - CT_DoExecLog ALL cp -av "${custom_location}" "${CT_SRC_DIR}/${dir_name}" + CT_DoExecLog ALL cp -av "${custom_location}" "${src_dir}/${dir_name}" elif [ -f "${custom_location}" ]; then # Assume "foo.tar.gz" (or likes) contain the "foo" directory local bn - CT_Extract "${custom_location}" "${CT_SRC_DIR}" + CT_Extract "${custom_location}" "${src_dir}" bn=`CT_GetFileBasename "${custom_location##*/}"` CT_TestOrAbort "Unknown file extension: ${custom_location}" -n "${bn}" - CT_DoExecLog ALL mv -v "${CT_SRC_DIR}/${bn%${ext}}" "${CT_SRC_DIR}/${dir_name}" + CT_DoExecLog ALL mv -v "${src_dir}/${bn%${ext}}" "${src_dir}/${dir_name}" else CT_Abort "Neither file nor directory: ${custom_location}" fi - elif [ "${CT_TARGET_USE_OVERLAY}" = "y" ]; then - # Possibly has overlays; check and if it has, copy from common source and apply - # overlays. - local overlay - - if [ ! -d "${CT_BUILD_DIR}/overlay" ]; then - CT_DoLog ALL mkdir -p "${CT_BUILD_DIR}/overlay" - overlay="${CT_OVERLAY_LOCATION}/${CT_ARCH}_${CT_OVERLAY_NAME:-overlay}" - ext=`CT_GetFileExtension "${overlay}"` - if [ ! -r "${overlay}${ext}" ]; then - CT_Abort "Overlay ${overlay} not found" - fi - CT_Extract "${overlay}${ext}" "${CT_BUILD_DIR}/overlay" - fi - - if [ -d "${CT_BUILD_DIR}/overlay/${dir_name}" ]; then - CT_DoExecLog ALL cp -a "${CT_COMMON_SRC_DIR}/${basename}" "${CT_SRC_DIR}/${dir_name}" - tar cf - -C "${CT_BUILD_DIR}/overlay" "${dir_name}" | \ - CT_DoExecLog FILE tar xvf - -C "${CT_SRC_DIR}" - else - # No overlay for this component, just symlink - CT_DoExecLog ALL ln -s "${CT_COMMON_SRC_DIR}/${basename}" "${CT_SRC_DIR}/${dir_name}" - fi else # Common source, just symlink - CT_DoExecLog ALL ln -s "${CT_COMMON_SRC_DIR}/${basename}" "${CT_SRC_DIR}/${dir_name}" + CT_DoExecLog ALL ln -s "${src_dir}/${basename}" "${CT_SRC_DIR}/${dir_name}" + fi + + # Check if it has overlays and if it has, apply + if [ "${CT_TARGET_USE_OVERLAY}" = "y" -a \ + -d "${CT_BUILD_DIR}/overlay/${dir_name}" ]; then + tar cf - -C "${CT_BUILD_DIR}/overlay" "${dir_name}" | \ + CT_DoExecLog FILE tar xvf - -C "${src_dir}" fi + } # Extract/copy the sources to the shared source directory, then either symlink @@ -1994,3 +2038,13 @@ CT_ExtractPatch() shift CT_PackageRun "${pkg}" CT_DoExtractPatch "$@" } + +# Set the specified variable to the version of the package (main or fork) +# Usage: CT_GetPkgVersion PKG VAR +CT_GetPkgVersion() +{ + local rv + __do_GetPkgVersion() { rv="${version}"; } + CT_PackageRun "${1}" __do_GetPkgVersion + eval "${2}=\"${rv}\"" +} |