scripts/getExtractPatch.sh
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue May 01 16:49:15 2007 +0000 (2007-05-01)
changeset 56 07a6a48962b7
parent 23 78d0b570baf7
permissions -rw-r--r--
Merge patches sent by Robert P. J. Day <rpjday@mindspring.com>.
Warning: the buildroot folks purposedly removed the skip-comment patch but didn't really said why. Keeping it for the sake of having it in svn just in case (removing it will be easier thant not having it at all).
     1 # This script will download tarballs, extract them and patch the source.
     2 # Copyright 2007 Yann E. MORIN
     3 # Licensed under the GPL v2. See COPYING in the root of this package
     4 
     5 # Download tarballs in sequence. Once we have everything, start extracting
     6 # and patching the tarballs.
     7 
     8 #-----------------------------------------------------------------------------
     9 
    10 _wget=`which wget || true`
    11 _curl=`which curl || true`
    12 #_svn=`which svn ||true`
    13 #_cvs=`which cvs || true`
    14 
    15 case "${_wget},${_curl}" in
    16     ,)  CT_Abort "Found neither curl nor wget. Please install one.";;
    17     ,*) CT_DoLog DEBUG "Using curl to retrieve tarballs"; CT_DoGetFile=CT_DoGetFileCurl;;
    18     *)  CT_DoLog DEBUG "Using wget to retrieve tarballs"; CT_DoGetFile=CT_DoGetFileWget;;
    19 esac
    20 
    21 CT_DoGetFileWget() {
    22     # Need to return true because it is legitimate to not find the tarball at
    23     # some of the provided URLs (think about snapshots, different layouts for
    24     # different gcc versions, etc...)
    25     # Some (very old!) FTP server might not support the passive mode, thus
    26     # retry without
    27     # With automated download as we are doing, it can be very dangerous to use
    28     # -c to continue the downloads. It's far better to simply overwrite the
    29     # destination file
    30     wget -nc --progress=dot:binary --tries=3 --passive-ftp "$1" || wget -nc --progress=dot:binary --tries=3 "$1" || true
    31 }
    32 
    33 CT_DoGetFileCurl() {
    34 	# Note: comments about wget method are also valid here
    35 	# Plus: no good progreess indicator is available with curl,
    36 	#       so output is consigned to oblivion
    37 	curl --ftp-pasv -O --retry 3 "$1" >/dev/null || curl -O --retry 3 "$1" >/dev/null || true
    38 }
    39 
    40 # For those wanting bleading edge, or to retrieve old uClibc snapshots
    41 # Usage: CT_GetFileSVN basename url
    42 #CT_DoGetFileSVN() {
    43 #    local basename="$1"
    44 #    local url="`echo \"$2\" |cut -d : -f 2-`"
    45 #    local tmp_dir
    46 #
    47 #    CT_TestOrAbort "You don't have subversion" -n "${_svn}"
    48 #    CT_MktempDir tmp_dir
    49 #    CT_Pushd "${tmp_dir}"
    50 #    svn export --force "${url}" "${basename}"
    51 #    tar cfj "${CT_TARBALLS_DIR}/${basename}.tar.bz2" "${basename}"
    52 #    CT_Popd
    53 #    rm -rf "${tmp_dir}"
    54 #}
    55 #
    56 #CT_DoGetFileCVS() {
    57 #    :
    58 #}
    59 
    60 # Download the file from one of the URLs passed as argument
    61 # Usage: CT_GetFile <filename> <url> [<url> ...]
    62 CT_GetFile() {
    63     local got_it
    64     local ext
    65     local url
    66     local file="$1"
    67     shift
    68 
    69     # Do we already have it?
    70     ext=`CT_GetFileExtension "${file}"`
    71     if [ -n "${ext}" ]; then
    72         if [ "${CT_FORCE_DOWNLOAD}" = "y" ]; then
    73             rm -f "${CT_TARBALLS_DIR}/${file}${ext}"
    74         else
    75             return 0
    76         fi
    77     fi
    78 
    79     CT_DoLog EXTRA "Retrieving \"${file}\""
    80     CT_Pushd "${CT_TARBALLS_DIR}"
    81     # File not yet downloaded, try to get it
    82     got_it=0
    83     if [ "${got_it}" != "y" ]; then
    84         # We'd rather have a bzip2'ed tarball, then gzipped, and finally plain tar.
    85         for ext in .tar.bz2 .tar.gz .tgz .tar; do
    86             # Try all urls in turn
    87             for url in "$@"; do
    88                 case "${url}" in
    89 #                    svn://*)    CT_DoGetFileSVN "${file}" ${url}";;
    90 #                    cvs://*)    CT_DoGetFileCVS "${file}" ${url}";;
    91                     *)  CT_DoLog EXTRA "Trying \"${url}/${file}${ext}\""
    92                         ${CT_DoGetFile} "${url}/${file}${ext}" 2>&1 |CT_DoLog DEBUG
    93                         ;;
    94                 esac
    95                 [ -f "${file}${ext}" ] && got_it=1 && break 2 || true
    96             done
    97         done
    98     fi
    99     CT_Popd
   100 
   101     CT_TestAndAbort "Could not download \"${file}\", and not present in \"${CT_TARBALLS_DIR}\"" ${got_it} -eq 0
   102 }
   103 
   104 #-----------------------------------------------------------------------------
   105 
   106 # Extract a tarball and patch.
   107 # Some tarballs need to be extracted in specific places. Eg.: glibc addons
   108 # must be extracted in the glibc directory; uCLibc locales must be extracted
   109 # in the extra/locale sub-directory of uClibc.
   110 CT_ExtractAndPatch() {
   111     local file="$1"
   112     local base_file=`echo "${file}" |cut -d - -f 1`
   113     local ver_file=`echo "${file}" |cut -d - -f 2-`
   114     local official_patch_dir
   115     local custom_patch_dir
   116     local libc_addon
   117     local ext=`CT_GetFileExtension "${file}"`
   118     CT_TestAndAbort "\"${file}\" not found in \"${CT_TARBALLS_DIR}\"" -z "${ext}"
   119     local full_file="${CT_TARBALLS_DIR}/${file}${ext}"
   120 
   121     CT_Pushd "${CT_SRC_DIR}"
   122 
   123     # Add-ons need a little love, really.
   124     case "${file}" in
   125         glibc-[a-z]*-*)
   126             CT_TestAndAbort "Trying to extract the C-library addon/locales \"${file}\" when C-library not yet extracted" ! -d "${CT_LIBC_FILE}"
   127             cd "${CT_LIBC_FILE}"
   128             libc_addon=y
   129             [ -f ".${file}.extracted" ] && return 0
   130             touch ".${file}.extracted"
   131             ;;
   132         uClibc-locale-*)
   133             CT_TestAndAbort "Trying to extract the C-library addon/locales \"${file}\" when C-library not yet extracted" ! -d "${CT_LIBC_FILE}"
   134             cd "${CT_LIBC_FILE}/extra/locale"
   135             libc_addon=y
   136             [ -f ".${file}.extracted" ] && return 0
   137             touch ".${file}.extracted"
   138             ;;
   139     esac
   140 
   141     # If the directory exists, then consider extraction and patching done
   142     [ -d "${file}" ] && return 0
   143 
   144     CT_DoLog EXTRA "Extracting \"${file}\""
   145     case "${ext}" in
   146         .tar.bz2)     tar xvjf "${full_file}" |CT_DoLog DEBUG;;
   147         .tar.gz|.tgz) tar xvzf "${full_file}" |CT_DoLog DEBUG;;
   148         .tar)         tar xvf  "${full_file}" |CT_DoLog DEBUG;;
   149         *)            CT_Abort "Don't know how to handle \"${file}\": unknown extension" ;;
   150     esac
   151 
   152     # Snapshots might not have the version number in the extracted directory
   153     # name. This is also the case for some (old) packages, such as libfloat.
   154     # Overcome this issue by symlink'ing the directory.
   155     if [ ! -d "${file}" -a "${libc_addon}" != "y" ]; then
   156         case "${ext}" in
   157             .tar.bz2)     base=`tar tjf "${full_file}" |head -n 1 |cut -d / -f 1 || true`;;
   158             .tar.gz|.tgz) base=`tar tzf "${full_file}" |head -n 1 |cut -d / -f 1 || true`;;
   159             .tar)         base=`tar tf  "${full_file}" |head -n 1 |cut -d / -f 1 || true`;;
   160         esac
   161         CT_TestOrAbort "There was a problem when extracting \"${file}\"" -d "${base}" -o "${base}" != "${file}"
   162         ln -s "${base}" "${file}"
   163     fi
   164 
   165     # Kludge: outside this function, we wouldn't know if we had just extracted
   166     # a libc addon, or a plain package. Apply patches now.
   167     CT_DoLog EXTRA "Patching \"${file}\""
   168 
   169     # If libc addon, we're already in the correct place.
   170     [ -z "${libc_addon}" ] && cd "${file}"
   171 
   172     [ "${CUSTOM_PATCH_ONLY}" = "y" ] || official_patch_dir="${CT_TOP_DIR}/patches/${base_file}/${ver_file}"
   173     [ "${CT_CUSTOM_PATCH}" = "y" ] && custom_patch_dir="${CT_CUSTOM_PATCH_DIR}/${base_file}/${ver_file}"
   174     for patch_dir in "${official_patch_dir}" "${custom_patch_dir}"; do
   175         if [ -n "${patch_dir}" -a -d "${patch_dir}" ]; then
   176             for p in "${patch_dir}"/*.patch; do
   177                 if [ -f "${p}" ]; then
   178                     CT_DoLog DEBUG "Applying patch \"${p}\""
   179                     patch -g0 -F1 -p1 -f <"${p}" |CT_DoLog DEBUG
   180                     CT_TestAndAbort "Failed while applying patch file \"${p}\"" ${PIPESTATUS[0]} -ne 0
   181                 fi
   182             done
   183         fi
   184     done
   185 
   186     CT_Popd
   187 }
   188 
   189 #-----------------------------------------------------------------------------
   190 
   191 # Get the file name extension of a component
   192 # Usage: CT_GetFileExtension <component-version>
   193 # If found, echoes the extension to stdout
   194 # If not found, echoes nothing on stdout.
   195 CT_GetFileExtension() {
   196     local ext
   197     local file="$1"
   198     local got_it=1
   199 
   200     CT_Pushd "${CT_TARBALLS_DIR}"
   201     for ext in .tar.gz .tar.bz2 .tgz .tar; do
   202         if [ -f "${file}${ext}" ]; then
   203             echo "${ext}"
   204             got_it=0
   205             break
   206         fi
   207     done
   208     CT_Popd
   209 
   210     return 0
   211 }
   212 
   213 #-----------------------------------------------------------------------------
   214 
   215 # Create needed directories, remove old ones
   216 mkdir -p "${CT_TARBALLS_DIR}"
   217 if [ "${CT_FORCE_EXTRACT}" = "y" -a -d "${CT_SRC_DIR}" ]; then
   218     mv "${CT_SRC_DIR}" "${CT_SRC_DIR}.$$"
   219     nohup rm -rf "${CT_SRC_DIR}.$$" >/dev/null 2>&1 &
   220 fi
   221 mkdir -p "${CT_SRC_DIR}"
   222 
   223 # Make all path absolute, it so much easier!
   224 # Now we have had the directories created, we even will get rid of embedded .. in paths:
   225 CT_SRC_DIR="`CT_MakeAbsolutePath \"${CT_SRC_DIR}\"`"
   226 CT_TARBALLS_DIR="`CT_MakeAbsolutePath \"${CT_TARBALLS_DIR}\"`"
   227 
   228 # Prepare the addons list to be parsable:
   229 addons_list="`echo \"${CT_LIBC_ADDONS_LIST}\" |sed -r -e 's/,/ /g; s/ $//g;'`"
   230 
   231 if [ "${CT_NO_DOWNLOAD}" != "y" ]; then
   232     CT_DoStep INFO "Retrieving needed toolchain components' tarballs"
   233 
   234     # Kernel: for now, I don't care about cygwin.
   235     if [ "${CT_KERNEL_LINUX_HEADERS_USE_CUSTOM_DIR}" != "y" ]; then
   236         CT_GetFile "${CT_KERNEL_FILE}"                                  \
   237                    ftp://ftp.kernel.org/pub/linux/kernel/v2.6           \
   238                    ftp://ftp.kernel.org/pub/linux/kernel/v2.4           \
   239                    ftp://ftp.kernel.org/pub/linux/kernel/v2.2           \
   240                    ftp://ftp.kernel.org/pub/linux/kernel/v2.6/testing   \
   241                    http://ep09.pld-linux.org/~mmazur/linux-libc-headers
   242     fi
   243 
   244     # binutils
   245     CT_GetFile "${CT_BINUTILS_FILE}"                            \
   246                ftp://ftp.gnu.org/gnu/binutils                   \
   247                ftp://ftp.kernel.org/pub/linux/devel/binutils
   248 
   249     # Core and final gcc
   250     # Ah! gcc folks are kind of 'different': they store the tarballs in
   251     # subdirectories of the same name! That's because gcc is such /crap/ that
   252     # it is such /big/ that it needs being splitted for distribution! Sad. :-(
   253     # Arrgghh! Some of those versions does not follow this convention:
   254     # gcc-3.3.3 lives in releases/gcc-3.3.3, while gcc-2.95.* isn't in a
   255     # subdirectory! You bastard!
   256     CT_GetFile "${CT_CC_CORE_FILE}"                                    \
   257                ftp://ftp.gnu.org/gnu/gcc/${CT_CC_CORE_FILE}            \
   258                ftp://ftp.gnu.org/gnu/gcc/releases/${CT_CC_CORE_FILE}   \
   259                ftp://ftp.gnu.org/gnu/gcc
   260     CT_GetFile "${CT_CC_FILE}"                                  \
   261                ftp://ftp.gnu.org/gnu/gcc/${CT_CC_FILE}          \
   262                ftp://ftp.gnu.org/gnu/gcc/releases/${CT_CC_FILE} \
   263                ftp://ftp.gnu.org/gnu/gcc
   264 
   265     # C library
   266     case "${CT_LIBC}" in
   267         glibc)
   268             # Ah! Not all GNU folks seem stupid. All glibc releases are in the same
   269             # directory. Good. Alas, there is no snapshot there. I'll deal with them
   270             # later on... :-/
   271             libc_src="ftp://ftp.gnu.org/gnu/glibc"
   272             ;;
   273         uClibc)
   274             # For uClibc, we have almost every thing: releases, and snapshots
   275             # for the last month or so. We'll have to deal with svn revisions
   276             # later...
   277             libc_src="http://www.uclibc.org/downloads
   278                       http://www.uclibc.org/downloads/snapshots
   279                       http://www.uclibc.org/downloads/old-releases"
   280             ;;
   281     esac
   282     CT_GetFile "${CT_LIBC_FILE}" ${libc_src}
   283 
   284     # C library addons
   285     addons_list=`echo "${CT_LIBC_ADDONS}" |sed -r -e 's/,/ /g; s/ $//g;'`
   286     for addon in ${addons_list}; do
   287         CT_GetFile "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}" ${libc_src}
   288     done
   289     [ "${CT_LIBC_GLIBC_USE_PORTS}" = "y" ] && CT_GetFile "${CT_LIBC}-ports-${CT_LIBC_VERSION}" ${libc_src}
   290     [ "${CT_LIBC_UCLIBC_LOCALES}" = "y" ] && CT_GetFile "uClibc-locale-030818" ${libc_src}
   291 
   292     # libfloat if asked for
   293     if [ "${CT_ARCH_FLOAT_SW_LIBFLOAT}" = "y" ]; then
   294         lib_float_url="ftp://ftp.de.debian.org/debian/pool/main/libf/libfloat/"
   295 
   296         # Please note: because the file we download, and the file we store on the
   297         # file system don't have the same name, CT_GetFile will always try to
   298         # download the file over and over.
   299         # To avoid this, we check that the file we want already exists in the
   300         # tarball directory first. This is an ugly hack that overrides the standard
   301         # CT_GetFile behavior... Sight...
   302         ext=`CT_GetFileExtension "${CT_LIBFLOAT_FILE}"`
   303         if [ -z "${ext}" ]; then
   304             CT_GetFile libfloat_990616.orig "${lib_float_url}"
   305             ext=`CT_GetFileExtension "libfloat_990616.orig"`
   306             # Hack: remove the .orig extension, and change _ to -
   307             mv -v "${CT_TARBALLS_DIR}/libfloat_990616.orig${ext}" \
   308                   "${CT_TARBALLS_DIR}/libfloat-990616${ext}"      2>&1 |CT_DoLog DEBUG
   309         fi
   310     fi
   311     
   312     CT_EndStep
   313 fi # CT_NO_DOWNLOAD
   314 
   315 if [ "${CT_ONLY_DOWNLOAD}" != "y" ]; then
   316     CT_DoStep INFO "Extracting and patching toolchain components"
   317 
   318     if [ "${CT_KERNEL_LINUX_HEADERS_USE_CUSTOM_DIR}" != "y" ]; then
   319         CT_ExtractAndPatch "${CT_KERNEL_FILE}"
   320     fi
   321     CT_ExtractAndPatch "${CT_BINUTILS_FILE}"
   322     CT_ExtractAndPatch "${CT_CC_CORE_FILE}"
   323     CT_ExtractAndPatch "${CT_CC_FILE}"
   324     CT_ExtractAndPatch "${CT_LIBC_FILE}"
   325     for addon in ${addons_list}; do
   326         CT_ExtractAndPatch "${CT_LIBC}-${addon}-${CT_LIBC_VERSION}"
   327     done
   328     [ "${CT_LIBC_GLIBC_USE_PORTS}" = "y" ] && CT_ExtractAndPatch "${CT_LIBC}-ports-${CT_LIBC_VERSION}"
   329     [ "${CT_LIBC_UCLIBC_LOCALES}" = "y" ] && CT_ExtractAndPatch "uClibc-locale-030818"
   330 
   331     [ "${CT_ARCH_FLOAT_SW_LIBFLOAT}" = "y" ] && CT_ExtractAndPatch "${CT_LIBFLOAT_FILE}"
   332 
   333     CT_EndStep
   334 fi