qi: download sources from gitweb
[qi-bootmenu-system/guyou.git] / sources / functions-fwl.sh
blob141c8b7af22170225856f26bd6607f8680ddb2dd
1 #!/bin/echo "This file is sourced, not run"
3 # Lots of reusable functions. This file is sourced, not run.
5 function blank_tempdir()
7 # sanity test: never rm -rf something we don't own.
8 [ -z "$1" ] && dienow
9 touch -c "$1" || dienow
11 # Delete old directory, create new one.
12 rm -rf "$1"
13 mkdir -p "$1" || dienow
16 # Figure out if we're using the stable or unstable versions of a package.
18 function unstable()
20 [ ! -z "$(echo ,"$USE_UNSTABLE", | grep ,"$1",)" ]
23 # Find all files in $STAGE_DIR newer than $CURSRC.
25 function recent_binary_files()
27 PREVIOUS=
28 (cd "$STAGE_DIR" || dienow
29 # Note $WORK/$PACKAGE != $CURSRC here for renamed packages like gcc-core.
30 find . -depth -newer "$WORK/$PACKAGE/FWL-TIMESTAMP" \
31 | sed -e 's/^.//' -e 's/^.//' -e '/^$/d'
32 ) | while read i
34 TEMP="${PREVIOUS##"$i"/}"
36 if [ $[${#PREVIOUS}-${#TEMP}] -ne $[${#i}+1] ]
37 then
38 # Because the expanded $i might have \ chars in it, that's why.
39 echo -n "$i"
40 echo -ne '\0'
42 PREVIOUS="$i"
43 done
46 # Strip the version number off a tarball
48 function cleanup()
50 # If package build exited with an error, do not continue.
52 #[ $? -ne 0 ] && dienow
54 if [ ! -z "$BINARY_PACKAGE_TARBALLS" ]
55 then
56 TARNAME="$PACKAGE-$STAGE_NAME-${ARCH_NAME}".tar.bz2
57 echo -n Creating "$TARNAME"
58 { recent_binary_files | xargs -0 tar -cjvf \
59 "$BUILD/${TARNAME}".tar.bz2 -C "$STAGE_DIR" || dienow
60 } | dotprogress
63 if [ ! -z "$NO_CLEANUP" ]
64 then
65 echo "skip cleanup $PACKAGE $@"
66 return
69 # Loop deleting directories
71 cd "$WORK" || dienow
72 for i in "$PACKAGE" "$@"
74 [ -z "$i" ] && continue
75 echo "cleanup $i"
76 rm -rf "$i" || dienow
77 done
80 # Give filename.tar.ext minus the version number.
82 function noversion()
84 echo "$1" | sed -e 's/-*\(\([0-9\.]\)*\([_-]rc\)*\(-pre\)*\([0-9][a-zA-Z]\)*\)*\(\.tar\..z2*\)$/'"$2"'\6/'
87 # Given a filename.tar.ext, return the versino number.
89 function getversion()
91 echo "$1" | sed -e 's/.*-\(\([0-9\.]\)*\([_-]rc\)*\(-pre\)*\([0-9][a-zA-Z]\)*\)*\(\.tar\..z2*\)$/'"$2"'\1/'
94 # Give package name, minus file's version number and archive extension.
96 function basename()
98 noversion $1 | sed 's/\.tar\..z2*$//'
101 # output the sha1sum of a file
102 function sha1file()
104 sha1sum "$@" | awk '{print $1}'
107 # Extract tarball named in $1 and apply all relevant patches into
108 # "$BUILD/packages/$1". Record sha1sum of tarball and patch files in
109 # sha1-for-source.txt. Re-extract if tarball or patches change.
111 function extract()
113 FILENAME="$1"
114 SRCTREE="${BUILD}/packages"
115 SHA1FILE="$(echo "${SRCTREE}/${PACKAGE}/sha1-for-source.txt")"
117 # Sanity check: don't ever "rm -rf /". Just don't.
119 if [ -z "$PACKAGE" ] || [ -z "$SRCTREE" ]
120 then
121 dienow
124 # If the source tarball doesn't exist, but the extracted directory is there,
125 # assume everything's ok.
127 [ ! -e "$FILENAME" ] && [ -e "$SHA1FILE" ] && return 0
129 SHA1TAR="$(sha1file "${SRCDIR}/${FILENAME}")"
131 # If it's already extracted and up to date (including patches), do nothing.
132 SHALIST=$(cat "$SHA1FILE" 2> /dev/null)
133 if [ ! -z "$SHALIST" ]
134 then
135 for i in "$SHA1TAR" $(sha1file "${SOURCES}/patches/${PACKAGE}"-* 2>/dev/null)
137 # Is this sha1 in the file?
138 if [ -z "$(echo "$SHALIST" | sed -n "s/$i/$i/p" )" ]
139 then
140 SHALIST=missing
141 break
143 # Remove it
144 SHALIST="$(echo "$SHALIST" | sed "s/$i//" )"
145 done
146 # If we matched all the sha1sums, nothing more to do.
147 [ -z "$SHALIST" ] && return 0
150 echo -n "Extracting '${PACKAGE}'"
151 # Delete the old tree (if any). Create new empty working directories.
152 rm -rf "${BUILD}/temp" "${SRCTREE}/${PACKAGE}" 2>/dev/null
153 mkdir -p "${BUILD}"/{temp,packages} || dienow
155 # Is it a bzip2 or gzip tarball?
156 DECOMPRESS=""
157 [ "$FILENAME" != "${FILENAME/%\.tar\.bz2/}" ] && DECOMPRESS="j"
158 [ "$FILENAME" != "${FILENAME/%\.tar\.gz/}" ] && DECOMPRESS="z"
160 { tar -xv${DECOMPRESS} -f "${SRCDIR}/${FILENAME}" -C "${BUILD}/temp" || dienow
161 } | dotprogress
163 mv "${BUILD}/temp/"* "${SRCTREE}/${PACKAGE}" &&
164 rmdir "${BUILD}/temp" &&
165 echo "$SHA1TAR" > "$SHA1FILE"
167 [ $? -ne 0 ] && dienow
169 # Apply any patches to this package
171 ls "${SOURCES}/patches/${PACKAGE}"-* 2> /dev/null | sort | while read i
173 if [ -f "$i" ]
174 then
175 echo "Applying $i"
176 (cd "${SRCTREE}/${PACKAGE}" && patch -p1 -i "$i") || dienow
177 sha1file "$i" >> "$SHA1FILE"
179 done
182 function try_checksum()
184 SUM="$(sha1file "$SRCDIR/$FILENAME" 2>/dev/null)"
185 if [ x"$SUM" == x"$SHA1" ] || [ -z "$SHA1" ] && [ -f "$SRCDIR/$FILENAME" ]
186 then
187 if [ -z "$SHA1" ]
188 then
189 echo "No SHA1 for $FILENAME ($SUM)"
190 else
191 echo "Confirmed $FILENAME"
194 # Preemptively extract source packages?
196 [ -z "$EXTRACT_ALL" ] && return 0
197 EXTRACT_ONLY=1 setupfor "$(basename "$FILENAME")"
198 return $?
201 return 1
205 function try_download()
207 # Return success if we have a valid copy of the file
209 try_checksum && return 0
211 # If there's a corrupted file, delete it. In theory it would be nice
212 # to resume downloads, but wget creates "*.1" files instead.
214 rm "$SRCDIR/$FILENAME" 2> /dev/null
216 # If we have another source, try to download file.
218 if [ -n "$1" ]
219 then
220 wget -t 2 -T 60 -O "$SRCDIR/$FILENAME" "$1" ||
221 (rm "$SRCDIR/$FILENAME"; return 2)
222 touch -c "$SRCDIR/$FILENAME"
225 try_checksum
228 # Confirm a file matches sha1sum, else try to download it from mirror list.
230 function download()
232 FILENAME=`echo "$URL" | sed 's .*/ '`
233 [ -z "$RENAME" ] || FILENAME="$(echo "$FILENAME" | sed -r "$RENAME")"
234 ALTFILENAME=alt-"$(noversion "$FILENAME" -0)"
236 echo -ne "checking $FILENAME\r"
238 # Update timestamps on both stable and unstable tarballs (if any)
239 # so cleanup_oldfiles doesn't delete them
240 touch -c "$SRCDIR"/{"$FILENAME","$ALTFILENAME"} 2>/dev/null
242 # Is the unstable version selected?
243 if unstable "$(basename "$FILENAME")"
244 then
245 # Download new one as alt-packagename.tar.ext
246 FILENAME="$ALTFILENAME" SHA1= try_download "$UNSTABLE" ||
247 ([ ! -z "$PREFERRED_MIRROR" ] && SHA1= FILENAME="$ALTFILENAME" try_download "$PREFERRED_MIRROR/$ALTFILENAME")
248 return $?
251 # If environment variable specifies a preferred mirror, try that first.
253 if [ ! -z "$PREFERRED_MIRROR" ]
254 then
255 try_download "$PREFERRED_MIRROR/$FILENAME" && return 0
258 # Try standard locations
259 # Note: the URLs in mirror list cannot contain whitespace.
261 try_download "$URL" && return 0
262 for i in $MIRROR_LIST
264 try_download "$i/$FILENAME" && return 0
265 done
267 # Return failure.
269 echo "Could not download $FILENAME"
270 echo -en "\e[0m"
271 return 1
274 # Clean obsolete files out of the source directory
276 START_TIME=`date +%s`
278 function cleanup_oldfiles()
280 for i in "${SRCDIR}"/*
282 if [ -f "$i" ] && [ "$(date +%s -r "$i")" -lt "${START_TIME}" ]
283 then
284 echo Removing old file "$i"
285 rm -rf "$i"
287 done
290 # An exit function that works properly even from a subshell.
292 function actually_dienow()
294 echo -e "\n\e[31mExiting due to errors ($PACKAGE)\e[0m"
295 exit 1
298 trap actually_dienow SIGUSR1
299 TOPSHELL=$$
301 function dienow()
303 kill -USR1 $TOPSHELL
304 exit 1
307 # Turn a bunch of output lines into a much quieter series of periods.
309 function dotprogress()
312 while read i
314 x=$[$x + 1]
315 if [[ "$x" -eq 25 ]]
316 then
318 echo -n .
320 done
321 echo
324 function set_titlebar()
326 [ -z "$NO_TITLE_BAR" ] &&
327 echo -en "\033]2;$1\007"
330 # Extract package $1, use out-of-tree build directory $2 (or $1 if no $2)
331 # Use link directory $3 (or $1 if no $3)
333 function setupfor()
335 export WRAPPY_LOGPATH="$WRAPPY_LOGDIR/cmdlines.${STAGE_NAME}.setupfor"
337 # Figure out whether we're using an unstable package.
339 PACKAGE="$1"
340 unstable "$PACKAGE" && PACKAGE=alt-"$PACKAGE"
342 # Make sure the source is already extracted and up-to-date.
343 cd "${SRCDIR}" &&
344 extract "${PACKAGE}-"*.tar* || exit 1
346 # If all we want to do is extract source, bail out now.
347 [ ! -z "$EXTRACT_ONLY" ] && return 0
349 # Set CURSRC
350 CURSRC="$PACKAGE"
351 if [ ! -z "$3" ]
352 then
353 CURSRC="$3"
354 unstable "$CURSRC" && CURSRC=alt-"$CURSRC"
356 export CURSRC="${WORK}/${CURSRC}"
358 [ -z "$SNAPSHOT_SYMLINK" ] && LINKTYPE="l" || LINKTYPE="s"
360 # Announce package, with easy-to-grep-for "===" marker.
362 echo "=== Building $PACKAGE ($ARCH_NAME $STAGE_NAME)"
363 echo "Snapshot '$PACKAGE'..."
364 cd "${WORK}" || dienow
365 if [ $# -lt 3 ]
366 then
367 rm -rf "${CURSRC}" || dienow
369 mkdir -p "${CURSRC}" &&
370 cp -${LINKTYPE}fR "${SRCTREE}/$PACKAGE/"* "${CURSRC}"
372 [ $? -ne 0 ] && dienow
374 # Do we have a separate working directory?
376 if [ -z "$2" ]
377 then
378 cd "$PACKAGE"* || dienow
379 else
380 mkdir -p "$2" && cd "$2" || dienow
382 export WRAPPY_LOGPATH="$WRAPPY_LOGDIR/cmdlines.${STAGE_NAME}.$1"
384 # Change window title bar to package now
385 set_titlebar "$ARCH_NAME $STAGE_NAME $PACKAGE"
387 # Ugly bug workaround: timestamp granularity in a lot of filesystems is only
388 # 1 second, so find -newer misses things installed in the same second, so we
389 # make sure it's a new second before we start actually doing anything.
391 if [ ! -z "$BINARY_PACKAGE_TARBALLS" ]
392 then
393 touch "${CURSRC}/FWL-TIMESTAMP" || dienow
394 TIME=$(date +%s)
395 while true
397 [ $TIME != "$(date +%s)" ] && break
398 sleep .1
399 done
403 # Figure out what version of a package we last built
405 function get_download_version()
407 getversion $(sed -n 's@URL=.*/\(.[^ ]*\).*@\1@p' "$TOP/download.sh" | grep ${1}-)
410 # Filter out unnecessary noise
412 maybe_quiet()
414 [ -z "$QUIET" ] && cat || grep "^==="
417 # Run a command either in foreground or background, depending on $FORK
419 maybe_fork()
421 if [ -z "$FORK" ]
422 then
423 eval "$*"
424 else
425 eval "$*" &
429 # Kill a process and all its decendants
431 function killtree()
433 local KIDS=""
435 while [ $# -ne 0 ]
437 KIDS="$KIDS $(pgrep -P$1)"
438 shift
439 done
441 KIDS="$(echo -n $KIDS)"
442 if [ ! -z "$KIDS" ]
443 then
444 # Depth first kill avoids reparent_to_init hiding stuff.
445 killtree $KIDS
446 kill $KIDS 2>/dev/null