/[gentoo-x86]/eclass/eutils.eclass
Gentoo

Contents of /eclass/eutils.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.422 - (hide annotations) (download)
Fri Jun 21 23:52:50 2013 UTC (17 months, 1 week ago) by vapier
Branch: MAIN
Changes since 1.421: +13 -1 lines
isdigit: new func for testing if args are all numbers

1 mgorny 1.410 # Copyright 1999-2013 Gentoo Foundation
2 azarah 1.1 # Distributed under the terms of the GNU General Public License v2
3 vapier 1.422 # $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.421 2013/05/22 05:10:29 mgorny Exp $
4 vapier 1.283
5     # @ECLASS: eutils.eclass
6     # @MAINTAINER:
7     # base-system@gentoo.org
8     # @BLURB: many extra (but common) functions that are used in ebuilds
9     # @DESCRIPTION:
10     # The eutils eclass contains a suite of functions that complement
11     # the ones that ebuild.sh already contain. The idea is that the functions
12     # are not required in all ebuilds but enough utilize them to have a common
13     # home rather than having multiple ebuilds implementing the same thing.
14 swegener 1.286 #
15 vapier 1.283 # Due to the nature of this eclass, some functions may have maintainers
16     # different from the overall eclass!
17 azarah 1.1
18 vapier 1.371 if [[ ${___ECLASS_ONCE_EUTILS} != "recur -_+^+_- spank" ]] ; then
19     ___ECLASS_ONCE_EUTILS="recur -_+^+_- spank"
20    
21 mgorny 1.395 inherit multilib toolchain-funcs user
22 azarah 1.1
23 betelgeuse 1.329 if has "${EAPI:-0}" 0 1 2; then
24    
25 vapier 1.283 # @FUNCTION: epause
26     # @USAGE: [seconds]
27     # @DESCRIPTION:
28     # Sleep for the specified number of seconds (default of 5 seconds). Useful when
29     # printing a message the user should probably be reading and often used in
30     # conjunction with the ebeep function. If the EPAUSE_IGNORE env var is set,
31 betelgeuse 1.329 # don't wait at all. Defined in EAPIs 0 1 and 2.
32 ciaranm 1.98 epause() {
33 vapier 1.245 [[ -z ${EPAUSE_IGNORE} ]] && sleep ${1:-5}
34 ciaranm 1.98 }
35    
36 vapier 1.283 # @FUNCTION: ebeep
37     # @USAGE: [number of beeps]
38     # @DESCRIPTION:
39     # Issue the specified number of beeps (default of 5 beeps). Useful when
40     # printing a message the user should probably be reading and often used in
41     # conjunction with the epause function. If the EBEEP_IGNORE env var is set,
42 betelgeuse 1.329 # don't beep at all. Defined in EAPIs 0 1 and 2.
43 ciaranm 1.98 ebeep() {
44     local n
45 vapier 1.245 if [[ -z ${EBEEP_IGNORE} ]] ; then
46 ciaranm 1.98 for ((n=1 ; n <= ${1:-5} ; n++)) ; do
47     echo -ne "\a"
48     sleep 0.1 &>/dev/null ; sleep 0,1 &>/dev/null
49     echo -ne "\a"
50     sleep 1
51     done
52     fi
53     }
54    
55 reavertm 1.331 else
56    
57 reavertm 1.332 ebeep() {
58 reavertm 1.337 ewarn "QA Notice: ebeep is not defined in EAPI=${EAPI}, please file a bug at http://bugs.gentoo.org"
59 reavertm 1.332 }
60 reavertm 1.331
61 reavertm 1.332 epause() {
62 reavertm 1.337 ewarn "QA Notice: epause is not defined in EAPI=${EAPI}, please file a bug at http://bugs.gentoo.org"
63 reavertm 1.332 }
64 reavertm 1.331
65 betelgeuse 1.329 fi
66    
67 betelgeuse 1.348 # @FUNCTION: eqawarn
68     # @USAGE: [message]
69     # @DESCRIPTION:
70 mgorny 1.363 # Proxy to ewarn for package managers that don't provide eqawarn and use the PM
71     # implementation if available. Reuses PORTAGE_ELOG_CLASSES as set by the dev
72     # profile.
73 betelgeuse 1.348 if ! declare -F eqawarn >/dev/null ; then
74     eqawarn() {
75 mgorny 1.363 has qa ${PORTAGE_ELOG_CLASSES} && ewarn "$@"
76 ferringb 1.370 :
77 betelgeuse 1.348 }
78     fi
79    
80 hollow 1.298 # @FUNCTION: ecvs_clean
81 vapier 1.299 # @USAGE: [list of dirs]
82 hollow 1.298 # @DESCRIPTION:
83 vapier 1.299 # Remove CVS directories recursiveley. Useful when a source tarball contains
84     # internal CVS directories. Defaults to $PWD.
85 hollow 1.298 ecvs_clean() {
86 vapier 1.299 [[ -z $* ]] && set -- .
87 hollow 1.298 find "$@" -type d -name 'CVS' -prune -print0 | xargs -0 rm -rf
88     find "$@" -type f -name '.cvs*' -print0 | xargs -0 rm -rf
89     }
90    
91     # @FUNCTION: esvn_clean
92 vapier 1.299 # @USAGE: [list of dirs]
93 hollow 1.298 # @DESCRIPTION:
94 vapier 1.299 # Remove .svn directories recursiveley. Useful when a source tarball contains
95     # internal Subversion directories. Defaults to $PWD.
96 hollow 1.298 esvn_clean() {
97 vapier 1.299 [[ -z $* ]] && set -- .
98 hollow 1.298 find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf
99     }
100    
101 vapier 1.373 # @FUNCTION: estack_push
102     # @USAGE: <stack> [items to push]
103     # @DESCRIPTION:
104     # Push any number of items onto the specified stack. Pick a name that
105     # is a valid variable (i.e. stick to alphanumerics), and push as many
106     # items as you like onto the stack at once.
107     #
108     # The following code snippet will echo 5, then 4, then 3, then ...
109     # @CODE
110     # estack_push mystack 1 2 3 4 5
111     # while estack_pop mystack i ; do
112     # echo "${i}"
113     # done
114     # @CODE
115     estack_push() {
116     [[ $# -eq 0 ]] && die "estack_push: incorrect # of arguments"
117     local stack_name="__ESTACK_$1__" ; shift
118     eval ${stack_name}+=\( \"\$@\" \)
119     }
120    
121     # @FUNCTION: estack_pop
122     # @USAGE: <stack> [variable]
123     # @DESCRIPTION:
124     # Pop a single item off the specified stack. If a variable is specified,
125     # the popped item is stored there. If no more items are available, return
126     # 1, else return 0. See estack_push for more info.
127     estack_pop() {
128     [[ $# -eq 0 || $# -gt 2 ]] && die "estack_pop: incorrect # of arguments"
129    
130     # We use the fugly __estack_xxx var names to avoid collision with
131     # passing back the return value. If we used "local i" and the
132     # caller ran `estack_pop ... i`, we'd end up setting the local
133     # copy of "i" rather than the caller's copy. The __estack_xxx
134     # garbage is preferable to using $1/$2 everywhere as that is a
135     # bit harder to read.
136     local __estack_name="__ESTACK_$1__" ; shift
137     local __estack_retvar=$1 ; shift
138 vapier 1.376 eval local __estack_i=\${#${__estack_name}\[@\]}
139 vapier 1.373 # Don't warn -- let the caller interpret this as a failure
140     # or as normal behavior (akin to `shift`)
141     [[ $(( --__estack_i )) -eq -1 ]] && return 1
142    
143     if [[ -n ${__estack_retvar} ]] ; then
144 vapier 1.376 eval ${__estack_retvar}=\"\${${__estack_name}\[${__estack_i}\]}\"
145 vapier 1.373 fi
146 vapier 1.376 eval unset ${__estack_name}\[${__estack_i}\]
147 vapier 1.373 }
148    
149 vapier 1.322 # @FUNCTION: eshopts_push
150 vapier 1.330 # @USAGE: [options to `set` or `shopt`]
151 vapier 1.322 # @DESCRIPTION:
152     # Often times code will want to enable a shell option to change code behavior.
153     # Since changing shell options can easily break other pieces of code (which
154     # assume the default state), eshopts_push is used to (1) push the current shell
155     # options onto a stack and (2) pass the specified arguments to set.
156     #
157 vapier 1.330 # If the first argument is '-s' or '-u', we assume you want to call `shopt`
158     # rather than `set` as there are some options only available via that.
159     #
160 vapier 1.322 # A common example is to disable shell globbing so that special meaning/care
161     # may be used with variables/arguments to custom functions. That would be:
162     # @CODE
163 vapier 1.376 # eshopts_push -s noglob
164 vapier 1.322 # for x in ${foo} ; do
165     # if ...some check... ; then
166     # eshopts_pop
167     # return 0
168     # fi
169     # done
170     # eshopts_pop
171     # @CODE
172     eshopts_push() {
173 vapier 1.330 if [[ $1 == -[su] ]] ; then
174 vapier 1.376 estack_push eshopts "$(shopt -p)"
175 vapier 1.330 [[ $# -eq 0 ]] && return 0
176 vapier 1.375 shopt "$@" || die "${FUNCNAME}: bad options to shopt: $*"
177 vapier 1.330 else
178 vapier 1.376 estack_push eshopts $-
179 vapier 1.330 [[ $# -eq 0 ]] && return 0
180 vapier 1.375 set "$@" || die "${FUNCNAME}: bad options to set: $*"
181 vapier 1.330 fi
182 vapier 1.322 }
183    
184     # @FUNCTION: eshopts_pop
185     # @USAGE:
186     # @DESCRIPTION:
187     # Restore the shell options to the state saved with the corresponding
188     # eshopts_push call. See that function for more details.
189     eshopts_pop() {
190 vapier 1.376 local s
191     estack_pop eshopts s || die "${FUNCNAME}: unbalanced push"
192 vapier 1.330 if [[ ${s} == "shopt -"* ]] ; then
193 vapier 1.375 eval "${s}" || die "${FUNCNAME}: sanity: invalid shopt options: ${s}"
194 vapier 1.330 else
195 vapier 1.375 set +$- || die "${FUNCNAME}: sanity: invalid shell settings: $-"
196     set -${s} || die "${FUNCNAME}: sanity: unable to restore saved shell settings: ${s}"
197 vapier 1.330 fi
198 vapier 1.322 }
199    
200 vapier 1.373 # @FUNCTION: eumask_push
201     # @USAGE: <new umask>
202     # @DESCRIPTION:
203     # Set the umask to the new value specified while saving the previous
204     # value onto a stack. Useful for temporarily changing the umask.
205     eumask_push() {
206     estack_push eumask "$(umask)"
207     umask "$@" || die "${FUNCNAME}: bad options to umask: $*"
208     }
209    
210     # @FUNCTION: eumask_pop
211     # @USAGE:
212     # @DESCRIPTION:
213     # Restore the previous umask state.
214     eumask_pop() {
215 vapier 1.382 [[ $# -eq 0 ]] || die "${FUNCNAME}: we take no options"
216 vapier 1.373 local s
217     estack_pop eumask s || die "${FUNCNAME}: unbalanced push"
218     umask ${s} || die "${FUNCNAME}: sanity: could not restore umask: ${s}"
219     }
220    
221 vapier 1.422 # @FUNCTION: isdigit
222     # @USAGE: <number> [more numbers]
223     # @DESCRIPTION:
224     # Return true if all arguments are numbers.
225     isdigit() {
226     local d
227     for d ; do
228     [[ ${d:-bad} == *[!0-9]* ]] && return 1
229     done
230     return 0
231     }
232    
233 vapier 1.325 # @VARIABLE: EPATCH_SOURCE
234     # @DESCRIPTION:
235     # Default directory to search for patches.
236 azarah 1.2 EPATCH_SOURCE="${WORKDIR}/patch"
237 vapier 1.325 # @VARIABLE: EPATCH_SUFFIX
238     # @DESCRIPTION:
239     # Default extension for patches (do not prefix the period yourself).
240 azarah 1.2 EPATCH_SUFFIX="patch.bz2"
241 vapier 1.325 # @VARIABLE: EPATCH_OPTS
242     # @DESCRIPTION:
243 vapier 1.391 # Options to pass to patch. Meant for ebuild/package-specific tweaking
244     # such as forcing the patch level (-p#) or fuzz (-F#) factor. Note that
245     # for single patch tweaking, you can also pass flags directly to epatch.
246     EPATCH_OPTS=""
247     # @VARIABLE: EPATCH_COMMON_OPTS
248     # @DESCRIPTION:
249     # Common options to pass to `patch`. You probably should never need to
250     # change these. If you do, please discuss it with base-system first to
251     # be sure.
252 vapier 1.325 # @CODE
253     # -g0 - keep RCS, ClearCase, Perforce and SCCS happy #24571
254     # --no-backup-if-mismatch - do not leave .orig files behind
255     # -E - automatically remove empty files
256     # @CODE
257 vapier 1.391 EPATCH_COMMON_OPTS="-g0 -E --no-backup-if-mismatch"
258 vapier 1.325 # @VARIABLE: EPATCH_EXCLUDE
259     # @DESCRIPTION:
260 mr_bones_ 1.308 # List of patches not to apply. Note this is only file names,
261 vapier 1.325 # and not the full path. Globs accepted.
262 azarah 1.6 EPATCH_EXCLUDE=""
263 vapier 1.325 # @VARIABLE: EPATCH_SINGLE_MSG
264     # @DESCRIPTION:
265 azarah 1.9 # Change the printed message for a single patch.
266     EPATCH_SINGLE_MSG=""
267 vapier 1.325 # @VARIABLE: EPATCH_MULTI_MSG
268     # @DESCRIPTION:
269 vapier 1.173 # Change the printed message for multiple patches.
270     EPATCH_MULTI_MSG="Applying various patches (bugfixes/updates) ..."
271 vapier 1.325 # @VARIABLE: EPATCH_FORCE
272     # @DESCRIPTION:
273     # Only require patches to match EPATCH_SUFFIX rather than the extended
274     # arch naming style.
275 azarah 1.29 EPATCH_FORCE="no"
276 vapier 1.416 # @VARIABLE: EPATCH_USER_EXCLUDE
277     # @DEFAULT_UNSET
278     # @DESCRIPTION:
279     # List of patches not to apply. Note this is only file names,
280     # and not the full path. Globs accepted.
281 azarah 1.2
282 vapier 1.325 # @FUNCTION: epatch
283 vapier 1.391 # @USAGE: [options] [patches] [dirs of patches]
284 vapier 1.325 # @DESCRIPTION:
285     # epatch is designed to greatly simplify the application of patches. It can
286     # process patch files directly, or directories of patches. The patches may be
287     # compressed (bzip/gzip/etc...) or plain text. You generally need not specify
288     # the -p option as epatch will automatically attempt -p0 to -p5 until things
289     # apply successfully.
290 azarah 1.2 #
291 vapier 1.391 # If you do not specify any patches/dirs, then epatch will default to the
292     # directory specified by EPATCH_SOURCE.
293     #
294     # Any options specified that start with a dash will be passed down to patch
295     # for this specific invocation. As soon as an arg w/out a dash is found, then
296     # arg processing stops.
297 azarah 1.2 #
298 vapier 1.325 # When processing directories, epatch will apply all patches that match:
299     # @CODE
300 vapier 1.350 # if ${EPATCH_FORCE} != "yes"
301 vapier 1.325 # ??_${ARCH}_foo.${EPATCH_SUFFIX}
302     # else
303     # *.${EPATCH_SUFFIX}
304     # @CODE
305     # The leading ?? are typically numbers used to force consistent patch ordering.
306     # The arch field is used to apply patches only for the host architecture with
307     # the special value of "all" means apply for everyone. Note that using values
308     # other than "all" is highly discouraged -- you should apply patches all the
309     # time and let architecture details be detected at configure/compile time.
310 azarah 1.2 #
311 vapier 1.325 # If EPATCH_SUFFIX is empty, then no period before it is implied when searching
312     # for patches to apply.
313 azarah 1.2 #
314 vapier 1.325 # Refer to the other EPATCH_xxx variables for more customization of behavior.
315 azarah 1.2 epatch() {
316 swegener 1.231 _epatch_draw_line() {
317 vapier 1.325 # create a line of same length as input string
318 agriffis 1.229 [[ -z $1 ]] && set "$(printf "%65s" '')"
319     echo "${1//?/=}"
320 vapier 1.219 }
321 azarah 1.3
322 vapier 1.195 unset P4CONFIG P4PORT P4USER # keep perforce at bay #56402
323    
324 vapier 1.391 # First process options. We localize the EPATCH_OPTS setting
325     # from above so that we can pass it on in the loop below with
326     # any additional values the user has specified.
327     local EPATCH_OPTS=( ${EPATCH_OPTS[*]} )
328     while [[ $# -gt 0 ]] ; do
329     case $1 in
330     -*) EPATCH_OPTS+=( "$1" ) ;;
331     *) break ;;
332     esac
333     shift
334     done
335    
336 vapier 1.325 # Let the rest of the code process one user arg at a time --
337     # each arg may expand into multiple patches, and each arg may
338     # need to start off with the default global EPATCH_xxx values
339     if [[ $# -gt 1 ]] ; then
340     local m
341 vapier 1.94 for m in "$@" ; do
342     epatch "${m}"
343     done
344     return 0
345 azarah 1.3 fi
346    
347 vapier 1.325 local SINGLE_PATCH="no"
348     # no args means process ${EPATCH_SOURCE}
349     [[ $# -eq 0 ]] && set -- "${EPATCH_SOURCE}"
350    
351     if [[ -f $1 ]] ; then
352 azarah 1.3 SINGLE_PATCH="yes"
353 vapier 1.325 set -- "$1"
354     # Use the suffix from the single patch (localize it); the code
355     # below will find the suffix for us
356     local EPATCH_SUFFIX=$1
357    
358     elif [[ -d $1 ]] ; then
359     # Some people like to make dirs of patches w/out suffixes (vim)
360     set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"}
361 danarmak 1.32
362 vapier 1.359 elif [[ -f ${EPATCH_SOURCE}/$1 ]] ; then
363     # Re-use EPATCH_SOURCE as a search dir
364     epatch "${EPATCH_SOURCE}/$1"
365     return $?
366    
367 azarah 1.3 else
368 vapier 1.325 # sanity check ... if it isn't a dir or file, wtf man ?
369     [[ $# -ne 0 ]] && EPATCH_SOURCE=$1
370     echo
371     eerror "Cannot find \$EPATCH_SOURCE! Value for \$EPATCH_SOURCE is:"
372     eerror
373     eerror " ${EPATCH_SOURCE}"
374     eerror " ( ${EPATCH_SOURCE##*/} )"
375     echo
376     die "Cannot find \$EPATCH_SOURCE!"
377 azarah 1.3 fi
378 azarah 1.2
379 vapier 1.391 # Now that we know we're actually going to apply something, merge
380     # all of the patch options back in to a single variable for below.
381     EPATCH_OPTS="${EPATCH_COMMON_OPTS} ${EPATCH_OPTS[*]}"
382    
383 vapier 1.325 local PIPE_CMD
384 azarah 1.2 case ${EPATCH_SUFFIX##*\.} in
385 vapier 1.325 xz) PIPE_CMD="xz -dc" ;;
386     lzma) PIPE_CMD="lzma -dc" ;;
387     bz2) PIPE_CMD="bzip2 -dc" ;;
388     gz|Z|z) PIPE_CMD="gzip -dc" ;;
389     ZIP|zip) PIPE_CMD="unzip -p" ;;
390     *) ;;
391 azarah 1.2 esac
392    
393 vapier 1.325 [[ ${SINGLE_PATCH} == "no" ]] && einfo "${EPATCH_MULTI_MSG}"
394    
395     local x
396     for x in "$@" ; do
397     # If the patch dir given contains subdirs, or our EPATCH_SUFFIX
398     # didn't match anything, ignore continue on
399     [[ ! -f ${x} ]] && continue
400    
401     local patchname=${x##*/}
402    
403     # Apply single patches, or forced sets of patches, or
404     # patches with ARCH dependant names.
405 flameeyes 1.266 # ???_arch_foo.patch
406 vapier 1.325 # Else, skip this input altogether
407     local a=${patchname#*_} # strip the ???_
408     a=${a%%_*} # strip the _foo.patch
409     if ! [[ ${SINGLE_PATCH} == "yes" || \
410 ulm 1.354 ${EPATCH_FORCE} == "yes" || \
411     ${a} == all || \
412     ${a} == ${ARCH} ]]
413 azarah 1.2 then
414 vapier 1.325 continue
415     fi
416 azarah 1.6
417 vapier 1.325 # Let people filter things dynamically
418     if [[ -n ${EPATCH_EXCLUDE} ]] ; then
419     # let people use globs in the exclude
420     eshopts_push -o noglob
421    
422 scarabeus 1.328 local ex
423 vapier 1.325 for ex in ${EPATCH_EXCLUDE} ; do
424 scarabeus 1.328 if [[ ${patchname} == ${ex} ]] ; then
425 vapier 1.416 einfo " Skipping ${patchname} due to EPATCH_EXCLUDE ..."
426     eshopts_pop
427     continue 2
428     fi
429     done
430    
431     for ex in ${EPATCH_USER_EXCLUDE} ; do
432     if [[ ${patchname} == ${ex} ]] ; then
433     einfo " Skipping ${patchname} due to EPATCH_USER_EXCLUDE ..."
434 scarabeus 1.328 eshopts_pop
435     continue 2
436     fi
437 vapier 1.325 done
438 vapier 1.326
439 vapier 1.325 eshopts_pop
440     fi
441 danarmak 1.32
442 vapier 1.325 if [[ ${SINGLE_PATCH} == "yes" ]] ; then
443     if [[ -n ${EPATCH_SINGLE_MSG} ]] ; then
444     einfo "${EPATCH_SINGLE_MSG}"
445 azarah 1.3 else
446 vapier 1.325 einfo "Applying ${patchname} ..."
447 azarah 1.3 fi
448 vapier 1.325 else
449     einfo " ${patchname} ..."
450     fi
451 azarah 1.2
452 vapier 1.325 # most of the time, there will only be one run per unique name,
453     # but if there are more, make sure we get unique log filenames
454     local STDERR_TARGET="${T}/${patchname}.out"
455     if [[ -e ${STDERR_TARGET} ]] ; then
456     STDERR_TARGET="${T}/${patchname}-$$.out"
457     fi
458 azarah 1.2
459 vapier 1.369 printf "***** %s *****\nPWD: %s\n\n" "${patchname}" "${PWD}" > "${STDERR_TARGET}"
460 vapier 1.304
461 vapier 1.325 # Decompress the patch if need be
462     local count=0
463     local PATCH_TARGET
464     if [[ -n ${PIPE_CMD} ]] ; then
465     PATCH_TARGET="${T}/$$.patch"
466     echo "PIPE_COMMAND: ${PIPE_CMD} ${x} > ${PATCH_TARGET}" >> "${STDERR_TARGET}"
467 vapier 1.304
468 vapier 1.325 if ! (${PIPE_CMD} "${x}" > "${PATCH_TARGET}") >> "${STDERR_TARGET}" 2>&1 ; then
469     echo
470     eerror "Could not extract patch!"
471     #die "Could not extract patch!"
472     count=5
473     break
474 vapier 1.305 fi
475 vapier 1.325 else
476     PATCH_TARGET=${x}
477     fi
478 vapier 1.305
479 vapier 1.325 # Check for absolute paths in patches. If sandbox is disabled,
480     # people could (accidently) patch files in the root filesystem.
481     # Or trigger other unpleasantries #237667. So disallow -p0 on
482     # such patches.
483     local abs_paths=$(egrep -n '^[-+]{3} /' "${PATCH_TARGET}" | awk '$2 != "/dev/null" { print }')
484     if [[ -n ${abs_paths} ]] ; then
485     count=1
486     printf "NOTE: skipping -p0 due to absolute paths in patch:\n%s\n" "${abs_paths}" >> "${STDERR_TARGET}"
487     fi
488 vapier 1.353 # Similar reason, but with relative paths.
489     local rel_paths=$(egrep -n '^[-+]{3} [^ ]*[.][.]/' "${PATCH_TARGET}")
490     if [[ -n ${rel_paths} ]] ; then
491 vapier 1.419 echo
492     eerror "Rejected Patch: ${patchname} !"
493     eerror " ( ${PATCH_TARGET} )"
494     eerror
495     eerror "Your patch uses relative paths '../':"
496     eerror "${rel_paths}"
497     echo
498     die "you need to fix the relative paths in patch"
499 vapier 1.353 fi
500 vapier 1.325
501     # Dynamically detect the correct -p# ... i'm lazy, so shoot me :/
502 vapier 1.383 local patch_cmd
503 vapier 1.417 # Handle aliased patch command #404447 #461568
504     local patch="patch"
505     eval $(alias patch 2>/dev/null | sed 's:^alias ::')
506 vapier 1.325 while [[ ${count} -lt 5 ]] ; do
507 vapier 1.417 patch_cmd="${patch} -p${count} ${EPATCH_OPTS}"
508 vapier 1.383
509 vapier 1.325 # Generate some useful debug info ...
510     (
511     _epatch_draw_line "***** ${patchname} *****"
512     echo
513 vapier 1.383 echo "PATCH COMMAND: ${patch_cmd} < '${PATCH_TARGET}'"
514 vapier 1.325 echo
515     _epatch_draw_line "***** ${patchname} *****"
516 vapier 1.383 ${patch_cmd} --dry-run -f < "${PATCH_TARGET}" 2>&1
517 vapier 1.360 ret=$?
518     echo
519     echo "patch program exited with status ${ret}"
520     exit ${ret}
521 vapier 1.325 ) >> "${STDERR_TARGET}"
522 azarah 1.8
523 vapier 1.360 if [ $? -eq 0 ] ; then
524 vapier 1.325 (
525     _epatch_draw_line "***** ${patchname} *****"
526     echo
527     echo "ACTUALLY APPLYING ${patchname} ..."
528     echo
529     _epatch_draw_line "***** ${patchname} *****"
530 vapier 1.383 ${patch_cmd} < "${PATCH_TARGET}" 2>&1
531 vapier 1.360 ret=$?
532     echo
533     echo "patch program exited with status ${ret}"
534     exit ${ret}
535 vapier 1.325 ) >> "${STDERR_TARGET}"
536 danarmak 1.32
537 vapier 1.325 if [ $? -ne 0 ] ; then
538     echo
539     eerror "A dry-run of patch command succeeded, but actually"
540     eerror "applying the patch failed!"
541     #die "Real world sux compared to the dreamworld!"
542     count=5
543 azarah 1.2 fi
544 vapier 1.325 break
545 azarah 1.8 fi
546    
547 vapier 1.325 : $(( count++ ))
548     done
549 azarah 1.8
550 vapier 1.325 # if we had to decompress the patch, delete the temp one
551     if [[ -n ${PIPE_CMD} ]] ; then
552     rm -f "${PATCH_TARGET}"
553     fi
554 azarah 1.3
555 vapier 1.325 if [[ ${count} -ge 5 ]] ; then
556     echo
557     eerror "Failed Patch: ${patchname} !"
558     eerror " ( ${PATCH_TARGET} )"
559     eerror
560     eerror "Include in your bugreport the contents of:"
561     eerror
562     eerror " ${STDERR_TARGET}"
563     echo
564     die "Failed Patch: ${patchname}!"
565 azarah 1.2 fi
566 vapier 1.325
567 vapier 1.383 # if everything worked, delete the full debug patch log
568 vapier 1.325 rm -f "${STDERR_TARGET}"
569 vapier 1.383
570     # then log away the exact stuff for people to review later
571     cat <<-EOF >> "${T}/epatch.log"
572     PATCH: ${x}
573     CMD: ${patch_cmd}
574     PWD: ${PWD}
575    
576     EOF
577 vapier 1.325 eend 0
578 azarah 1.2 done
579 vapier 1.325
580     [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching"
581     : # everything worked
582 azarah 1.26 }
583 vapier 1.361
584     # @FUNCTION: epatch_user
585     # @USAGE:
586     # @DESCRIPTION:
587     # Applies user-provided patches to the source tree. The patches are
588 vapier 1.406 # taken from /etc/portage/patches/<CATEGORY>/<PF|P|PN>[:SLOT]/, where the first
589 vapier 1.361 # of these three directories to exist will be the one to use, ignoring
590 vapier 1.387 # any more general directories which might exist as well. They must end
591     # in ".patch" to be applied.
592 vapier 1.361 #
593     # User patches are intended for quick testing of patches without ebuild
594     # modifications, as well as for permanent customizations a user might
595     # desire. Obviously, there can be no official support for arbitrarily
596     # patched ebuilds. So whenever a build log in a bug report mentions that
597     # user patches were applied, the user should be asked to reproduce the
598     # problem without these.
599     #
600     # Not all ebuilds do call this function, so placing patches in the
601     # stated directory might or might not work, depending on the package and
602     # the eclasses it inherits and uses. It is safe to call the function
603     # repeatedly, so it is always possible to add a call at the ebuild
604     # level. The first call is the time when the patches will be
605     # applied.
606     #
607     # Ideally, this function should be called after gentoo-specific patches
608     # have been applied, so that their code can be modified as well, but
609     # before calls to e.g. eautoreconf, as the user patches might affect
610     # autotool input files as well.
611 vapier 1.318 epatch_user() {
612     [[ $# -ne 0 ]] && die "epatch_user takes no options"
613    
614 vapier 1.361 # Allow multiple calls to this function; ignore all but the first
615 vapier 1.383 local applied="${T}/epatch_user.log"
616 vapier 1.361 [[ -e ${applied} ]] && return 2
617    
618 vapier 1.318 # don't clobber any EPATCH vars that the parent might want
619 zmedico 1.323 local EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches
620 vapier 1.406 for check in ${CATEGORY}/{${P}-${PR},${P},${PN}}{,:${SLOT}}; do
621 vapier 1.318 EPATCH_SOURCE=${base}/${CTARGET}/${check}
622     [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check}
623     [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check}
624     if [[ -d ${EPATCH_SOURCE} ]] ; then
625     EPATCH_SOURCE=${EPATCH_SOURCE} \
626     EPATCH_SUFFIX="patch" \
627     EPATCH_FORCE="yes" \
628     EPATCH_MULTI_MSG="Applying user patches from ${EPATCH_SOURCE} ..." \
629     epatch
630 vapier 1.361 echo "${EPATCH_SOURCE}" > "${applied}"
631 vapier 1.349 return 0
632 vapier 1.318 fi
633     done
634 vapier 1.361 echo "none" > "${applied}"
635 vapier 1.349 return 1
636 vapier 1.318 }
637 azarah 1.26
638 vapier 1.283 # @FUNCTION: emktemp
639     # @USAGE: [temp dir]
640     # @DESCRIPTION:
641 vapier 1.52 # Cheap replacement for when debianutils (and thus mktemp)
642 vapier 1.283 # does not exist on the users system.
643 vapier 1.117 emktemp() {
644 vapier 1.119 local exe="touch"
645 vapier 1.194 [[ $1 == -d ]] && exe="mkdir" && shift
646     local topdir=$1
647 mr_bones_ 1.100
648 vapier 1.194 if [[ -z ${topdir} ]] ; then
649     [[ -z ${T} ]] \
650 vapier 1.117 && topdir="/tmp" \
651 vapier 1.194 || topdir=${T}
652 vapier 1.117 fi
653    
654 vapier 1.280 if ! type -P mktemp > /dev/null ; then
655     # system lacks `mktemp` so we have to fake it
656 vapier 1.117 local tmp=/
657 vapier 1.194 while [[ -e ${tmp} ]] ; do
658     tmp=${topdir}/tmp.${RANDOM}.${RANDOM}.${RANDOM}
659 vapier 1.117 done
660 vapier 1.194 ${exe} "${tmp}" || ${exe} -p "${tmp}"
661 vapier 1.117 echo "${tmp}"
662 vapier 1.52 else
663 vapier 1.280 # the args here will give slightly wierd names on BSD,
664     # but should produce a usable file on all userlands
665 flameeyes 1.223 if [[ ${exe} == "touch" ]] ; then
666 vapier 1.280 TMPDIR="${topdir}" mktemp -t tmp.XXXXXXXXXX
667 flameeyes 1.223 else
668 vapier 1.280 TMPDIR="${topdir}" mktemp -dt tmp.XXXXXXXXXX
669 flameeyes 1.223 fi
670 vapier 1.52 fi
671     }
672    
673 vapier 1.283 # @FUNCTION: edos2unix
674     # @USAGE: <file> [more files ...]
675     # @DESCRIPTION:
676     # A handy replacement for dos2unix, recode, fixdos, etc... This allows you
677     # to remove all of these text utilities from DEPEND variables because this
678     # is a script based solution. Just give it a list of files to convert and
679     # they will all be changed from the DOS CRLF format to the UNIX LF format.
680 vapier 1.24 edos2unix() {
681 vapier 1.366 [[ $# -eq 0 ]] && return 0
682     sed -i 's/\r$//' -- "$@" || die
683 vapier 1.39 }
684    
685 jlec 1.377 # @FUNCTION: make_desktop_entry
686     # @USAGE: make_desktop_entry(<command>, [name], [icon], [type], [fields])
687     # @DESCRIPTION:
688     # Make a .desktop file.
689     #
690     # @CODE
691     # binary: what command does the app run with ?
692     # name: the name that will show up in the menu
693 vapier 1.401 # icon: the icon to use in the menu entry
694 jlec 1.377 # this can be relative (to /usr/share/pixmaps) or
695     # a full path to an icon
696     # type: what kind of application is this?
697     # for categories:
698     # http://standards.freedesktop.org/menu-spec/latest/apa.html
699     # if unset, function tries to guess from package's category
700 vapier 1.341 # fields: extra fields to append to the desktop file; a printf string
701 jlec 1.377 # @CODE
702 vapier 1.39 make_desktop_entry() {
703 vapier 1.341 [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
704 vapier 1.39
705 vapier 1.158 local exec=${1}
706     local name=${2:-${PN}}
707 wolf31o2 1.293 local icon=${3:-${PN}}
708 vapier 1.158 local type=${4}
709 vapier 1.341 local fields=${5}
710 vapier 1.158
711     if [[ -z ${type} ]] ; then
712     local catmaj=${CATEGORY%%-*}
713     local catmin=${CATEGORY##*-}
714     case ${catmaj} in
715     app)
716     case ${catmin} in
717 pacho 1.384 accessibility) type="Utility;Accessibility";;
718 vapier 1.338 admin) type=System;;
719     antivirus) type=System;;
720 pacho 1.384 arch) type="Utility;Archiving";;
721     backup) type="Utility;Archiving";;
722     cdr) type="AudioVideo;DiscBurning";;
723     dicts) type="Office;Dictionary";;
724 vapier 1.338 doc) type=Documentation;;
725 pacho 1.384 editors) type="Utility;TextEditor";;
726     emacs) type="Development;TextEditor";;
727     emulation) type="System;Emulator";;
728     laptop) type="Settings;HardwareSettings";;
729 vapier 1.338 office) type=Office;;
730 pacho 1.384 pda) type="Office;PDA";;
731     vim) type="Development;TextEditor";;
732     xemacs) type="Development;TextEditor";;
733 vapier 1.158 esac
734 azarah 1.59 ;;
735 vapier 1.158
736     dev)
737 vapier 1.159 type="Development"
738 vapier 1.158 ;;
739    
740     games)
741     case ${catmin} in
742 wolf31o2 1.265 action|fps) type=ActionGame;;
743 vapier 1.338 arcade) type=ArcadeGame;;
744     board) type=BoardGame;;
745     emulation) type=Emulator;;
746     kids) type=KidsGame;;
747     puzzle) type=LogicGame;;
748     roguelike) type=RolePlaying;;
749     rpg) type=RolePlaying;;
750 vapier 1.158 simulation) type=Simulation;;
751 vapier 1.338 sports) type=SportsGame;;
752     strategy) type=StrategyGame;;
753 vapier 1.158 esac
754 vapier 1.159 type="Game;${type}"
755 vapier 1.158 ;;
756    
757 vapier 1.284 gnome)
758     type="Gnome;GTK"
759     ;;
760    
761     kde)
762     type="KDE;Qt"
763     ;;
764    
765 vapier 1.158 mail)
766 vapier 1.159 type="Network;Email"
767 vapier 1.158 ;;
768    
769     media)
770     case ${catmin} in
771 vapier 1.339 gfx)
772     type=Graphics
773     ;;
774     *)
775     case ${catmin} in
776     radio) type=Tuner;;
777     sound) type=Audio;;
778     tv) type=TV;;
779     video) type=Video;;
780     esac
781     type="AudioVideo;${type}"
782     ;;
783 vapier 1.158 esac
784 wolf31o2 1.65 ;;
785 vapier 1.158
786     net)
787     case ${catmin} in
788     dialup) type=Dialup;;
789 vapier 1.338 ftp) type=FileTransfer;;
790     im) type=InstantMessaging;;
791     irc) type=IRCClient;;
792     mail) type=Email;;
793     news) type=News;;
794     nntp) type=News;;
795     p2p) type=FileTransfer;;
796     voip) type=Telephony;;
797 vapier 1.158 esac
798 vapier 1.159 type="Network;${type}"
799 vapier 1.158 ;;
800    
801     sci)
802     case ${catmin} in
803 vapier 1.284 astro*) type=Astronomy;;
804 vapier 1.338 bio*) type=Biology;;
805     calc*) type=Calculator;;
806     chem*) type=Chemistry;;
807 vapier 1.284 elec*) type=Electronics;;
808 vapier 1.338 geo*) type=Geology;;
809     math*) type=Math;;
810 vapier 1.284 physics) type=Physics;;
811     visual*) type=DataVisualization;;
812 vapier 1.159 esac
813 abcd 1.336 type="Education;Science;${type}"
814 vapier 1.158 ;;
815    
816 vapier 1.284 sys)
817     type="System"
818     ;;
819    
820 vapier 1.158 www)
821     case ${catmin} in
822     client) type=WebBrowser;;
823     esac
824 abcd 1.336 type="Network;${type}"
825 azarah 1.59 ;;
826 vapier 1.158
827 azarah 1.59 *)
828     type=
829     ;;
830 vapier 1.39 esac
831     fi
832 carlo 1.177 if [ "${SLOT}" == "0" ] ; then
833     local desktop_name="${PN}"
834     else
835     local desktop_name="${PN}-${SLOT}"
836     fi
837 vapier 1.272 local desktop="${T}/$(echo ${exec} | sed 's:[[:space:]/:]:_:g')-${desktop_name}.desktop"
838 vapier 1.271 #local desktop=${T}/${exec%% *:-${desktop_name}}.desktop
839 vapier 1.39
840 abcd 1.336 # Don't append another ";" when a valid category value is provided.
841     type=${type%;}${type:+;}
842    
843     eshopts_push -s extglob
844     if [[ -n ${icon} && ${icon} != /* ]] && [[ ${icon} == *.xpm || ${icon} == *.png || ${icon} == *.svg ]]; then
845     ewarn "As described in the Icon Theme Specification, icon file extensions are not"
846     ewarn "allowed in .desktop files if the value is not an absolute path."
847     icon=${icon%.@(xpm|png|svg)}
848     fi
849     eshopts_pop
850    
851 vapier 1.271 cat <<-EOF > "${desktop}"
852     [Desktop Entry]
853     Name=${name}
854     Type=Application
855     Comment=${DESCRIPTION}
856     Exec=${exec}
857     TryExec=${exec%% *}
858     Icon=${icon}
859 abcd 1.336 Categories=${type}
860 vapier 1.271 EOF
861 vapier 1.39
862 vapier 1.341 if [[ ${fields:-=} != *=* ]] ; then
863     # 5th arg used to be value to Path=
864     ewarn "make_desktop_entry: update your 5th arg to read Path=${fields}"
865     fields="Path=${fields}"
866     fi
867 vapier 1.342 [[ -n ${fields} ]] && printf '%b\n' "${fields}" >> "${desktop}"
868 wolf31o2 1.293
869 vapier 1.204 (
870     # wrap the env here so that the 'insinto' call
871     # doesn't corrupt the env of the caller
872     insinto /usr/share/applications
873     doins "${desktop}"
874 vapier 1.340 ) || die "installing desktop file failed"
875 danarmak 1.32 }
876    
877 vapier 1.283 # @FUNCTION: validate_desktop_entries
878     # @USAGE: [directories]
879     # @MAINTAINER:
880     # Carsten Lohrke <carlo@gentoo.org>
881     # @DESCRIPTION:
882 carlo 1.278 # Validate desktop entries using desktop-file-utils
883 carlo 1.277 validate_desktop_entries() {
884     if [[ -x /usr/bin/desktop-file-validate ]] ; then
885     einfo "Checking desktop entry validity"
886     local directories=""
887 carlo 1.279 for d in /usr/share/applications $@ ; do
888     [[ -d ${D}${d} ]] && directories="${directories} ${D}${d}"
889 carlo 1.277 done
890 carlo 1.279 if [[ -n ${directories} ]] ; then
891     for FILE in $(find ${directories} -name "*\.desktop" \
892     -not -path '*.hidden*' | sort -u 2>/dev/null)
893     do
894     local temp=$(desktop-file-validate ${FILE} | grep -v "warning:" | \
895     sed -e "s|error: ||" -e "s|${FILE}:|--|g" )
896     [[ -n $temp ]] && elog ${temp/--/${FILE/${D}/}:}
897     done
898     fi
899 carlo 1.277 echo ""
900     else
901     einfo "Passing desktop entry validity check. Install dev-util/desktop-file-utils, if you want to help to improve Gentoo."
902     fi
903     }
904    
905 vapier 1.283 # @FUNCTION: make_session_desktop
906 vapier 1.314 # @USAGE: <title> <command> [command args...]
907 vapier 1.283 # @DESCRIPTION:
908     # Make a GDM/KDM Session file. The title is the file to execute to start the
909     # Window Manager. The command is the name of the Window Manager.
910 vapier 1.314 #
911     # You can set the name of the file via the ${wm} variable.
912 lanius 1.133 make_session_desktop() {
913 vapier 1.314 [[ -z $1 ]] && eerror "$0: You must specify the title" && return 1
914     [[ -z $2 ]] && eerror "$0: You must specify the command" && return 1
915 lanius 1.133
916 vapier 1.167 local title=$1
917     local command=$2
918 vapier 1.314 local desktop=${T}/${wm:-${PN}}.desktop
919     shift 2
920 lanius 1.133
921 vapier 1.271 cat <<-EOF > "${desktop}"
922     [Desktop Entry]
923     Name=${title}
924     Comment=This session logs you into ${title}
925 vapier 1.314 Exec=${command} $*
926 vapier 1.271 TryExec=${command}
927 vapier 1.314 Type=XSession
928 vapier 1.271 EOF
929 lanius 1.133
930 vapier 1.271 (
931     # wrap the env here so that the 'insinto' call
932     # doesn't corrupt the env of the caller
933 lanius 1.133 insinto /usr/share/xsessions
934     doins "${desktop}"
935 vapier 1.271 )
936 lanius 1.133 }
937    
938 vapier 1.283 # @FUNCTION: domenu
939     # @USAGE: <menus>
940     # @DESCRIPTION:
941     # Install the list of .desktop menu files into the appropriate directory
942     # (/usr/share/applications).
943 lanius 1.133 domenu() {
944 vapier 1.271 (
945     # wrap the env here so that the 'insinto' call
946     # doesn't corrupt the env of the caller
947     local i j ret=0
948 lanius 1.133 insinto /usr/share/applications
949 vapier 1.167 for i in "$@" ; do
950     if [[ -f ${i} ]] ; then
951     doins "${i}"
952 vapier 1.271 ((ret+=$?))
953 vapier 1.167 elif [[ -d ${i} ]] ; then
954     for j in "${i}"/*.desktop ; do
955     doins "${j}"
956 vapier 1.271 ((ret+=$?))
957 lanius 1.133 done
958 vapier 1.285 else
959     ((++ret))
960 swegener 1.190 fi
961 lanius 1.133 done
962 vapier 1.271 exit ${ret}
963     )
964 lanius 1.133 }
965 vapier 1.283
966     # @FUNCTION: newmenu
967     # @USAGE: <menu> <newname>
968     # @DESCRIPTION:
969     # Like all other new* functions, install the specified menu as newname.
970 vapier 1.167 newmenu() {
971 vapier 1.271 (
972     # wrap the env here so that the 'insinto' call
973     # doesn't corrupt the env of the caller
974 vapier 1.167 insinto /usr/share/applications
975 vapier 1.271 newins "$@"
976     )
977 vapier 1.167 }
978 lanius 1.133
979 hasufell 1.394 # @FUNCTION: _iconins
980     # @INTERNAL
981 vapier 1.283 # @DESCRIPTION:
982 hasufell 1.394 # function for use in doicon and newicon
983     _iconins() {
984 vapier 1.271 (
985     # wrap the env here so that the 'insinto' call
986     # doesn't corrupt the env of the caller
987 hasufell 1.394 local funcname=$1; shift
988     local size dir
989     local context=apps
990     local theme=hicolor
991    
992     while [[ $# -gt 0 ]] ; do
993     case $1 in
994     -s|--size)
995     if [[ ${2%%x*}x${2%%x*} == "$2" ]] ; then
996     size=${2%%x*}
997     else
998     size=${2}
999     fi
1000     case ${size} in
1001     16|22|24|32|36|48|64|72|96|128|192|256)
1002     size=${size}x${size};;
1003     scalable)
1004     ;;
1005     *)
1006     eerror "${size} is an unsupported icon size!"
1007     exit 1;;
1008     esac
1009     shift 2;;
1010     -t|--theme)
1011     theme=${2}
1012     shift 2;;
1013     -c|--context)
1014     context=${2}
1015     shift 2;;
1016     *)
1017     if [[ -z ${size} ]] ; then
1018     insinto /usr/share/pixmaps
1019     else
1020     insinto /usr/share/icons/${theme}/${size}/${context}
1021     fi
1022    
1023     if [[ ${funcname} == doicon ]] ; then
1024     if [[ -f $1 ]] ; then
1025     doins "${1}"
1026     elif [[ -d $1 ]] ; then
1027     shopt -s nullglob
1028     doins "${1}"/*.{png,svg}
1029     shopt -u nullglob
1030     else
1031     eerror "${1} is not a valid file/directory!"
1032     exit 1
1033     fi
1034     else
1035     break
1036     fi
1037     shift 1;;
1038     esac
1039 lanius 1.133 done
1040 hasufell 1.394 if [[ ${funcname} == newicon ]] ; then
1041     newins "$@"
1042     fi
1043     ) || die
1044     }
1045    
1046     # @FUNCTION: doicon
1047     # @USAGE: [options] <icons>
1048     # @DESCRIPTION:
1049     # Install icon into the icon directory /usr/share/icons or into
1050     # /usr/share/pixmaps if "--size" is not set.
1051     # This is useful in conjunction with creating desktop/menu files.
1052     #
1053     # @CODE
1054     # options:
1055     # -s, --size
1056     # !!! must specify to install into /usr/share/icons/... !!!
1057     # size of the icon, like 48 or 48x48
1058     # supported icon sizes are:
1059     # 16 22 24 32 36 48 64 72 96 128 192 256 scalable
1060     # -c, --context
1061     # defaults to "apps"
1062     # -t, --theme
1063     # defaults to "hicolor"
1064     #
1065     # icons: list of icons
1066     #
1067 hasufell 1.398 # example 1: doicon foobar.png fuqbar.svg suckbar.png
1068 hasufell 1.394 # results in: insinto /usr/share/pixmaps
1069 hasufell 1.398 # doins foobar.png fuqbar.svg suckbar.png
1070 hasufell 1.394 #
1071 ssuominen 1.399 # example 2: doicon -s 48 foobar.png fuqbar.png blobbar.png
1072 hasufell 1.394 # results in: insinto /usr/share/icons/hicolor/48x48/apps
1073 ssuominen 1.399 # doins foobar.png fuqbar.png blobbar.png
1074 hasufell 1.394 # @CODE
1075     doicon() {
1076     _iconins ${FUNCNAME} "$@"
1077 lanius 1.133 }
1078 vapier 1.283
1079     # @FUNCTION: newicon
1080 hasufell 1.394 # @USAGE: [options] <icon> <newname>
1081 vapier 1.283 # @DESCRIPTION:
1082 hasufell 1.394 # Like doicon, install the specified icon as newname.
1083     #
1084     # @CODE
1085     # example 1: newicon foobar.png NEWNAME.png
1086     # results in: insinto /usr/share/pixmaps
1087     # newins foobar.png NEWNAME.png
1088     #
1089     # example 2: newicon -s 48 foobar.png NEWNAME.png
1090     # results in: insinto /usr/share/icons/hicolor/48x48/apps
1091     # newins foobar.png NEWNAME.png
1092     # @CODE
1093 vapier 1.167 newicon() {
1094 hasufell 1.394 _iconins ${FUNCNAME} "$@"
1095 vapier 1.167 }
1096 lanius 1.133
1097 vapier 1.287 # @FUNCTION: strip-linguas
1098     # @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>]
1099     # @DESCRIPTION:
1100 mr_bones_ 1.100 # Make sure that LINGUAS only contains languages that
1101 vapier 1.287 # a package can support. The first form allows you to
1102     # specify a list of LINGUAS. The -i builds a list of po
1103     # files found in all the directories and uses the
1104     # intersection of the lists. The -u builds a list of po
1105     # files found in all the directories and uses the union
1106     # of the lists.
1107 vapier 1.92 strip-linguas() {
1108 vapier 1.242 local ls newls nols
1109 vapier 1.154 if [[ $1 == "-i" ]] || [[ $1 == "-u" ]] ; then
1110     local op=$1; shift
1111 vapier 1.315 ls=$(find "$1" -name '*.po' -exec basename {} .po ';'); shift
1112 vapier 1.92 local d f
1113     for d in "$@" ; do
1114 vapier 1.154 if [[ ${op} == "-u" ]] ; then
1115     newls=${ls}
1116 vapier 1.92 else
1117     newls=""
1118     fi
1119 vapier 1.315 for f in $(find "$d" -name '*.po' -exec basename {} .po ';') ; do
1120 vapier 1.154 if [[ ${op} == "-i" ]] ; then
1121 ssuominen 1.358 has ${f} ${ls} && newls="${newls} ${f}"
1122 vapier 1.92 else
1123 ssuominen 1.358 has ${f} ${ls} || newls="${newls} ${f}"
1124 vapier 1.92 fi
1125     done
1126 vapier 1.154 ls=${newls}
1127 vapier 1.92 done
1128     else
1129 vapier 1.236 ls="$@"
1130 vapier 1.92 fi
1131    
1132 vapier 1.242 nols=""
1133 vapier 1.92 newls=""
1134     for f in ${LINGUAS} ; do
1135 ssuominen 1.358 if has ${f} ${ls} ; then
1136 vapier 1.120 newls="${newls} ${f}"
1137 vapier 1.92 else
1138 vapier 1.242 nols="${nols} ${f}"
1139 vapier 1.92 fi
1140     done
1141 vapier 1.244 [[ -n ${nols} ]] \
1142 pacho 1.388 && einfo "Sorry, but ${PN} does not support the LINGUAS:" ${nols}
1143 vapier 1.237 export LINGUAS=${newls:1}
1144 vapier 1.92 }
1145 iggy 1.110
1146 vapier 1.283 # @FUNCTION: preserve_old_lib
1147     # @USAGE: <libs to preserve> [more libs]
1148     # @DESCRIPTION:
1149     # These functions are useful when a lib in your package changes ABI SONAME.
1150     # An example might be from libogg.so.0 to libogg.so.1. Removing libogg.so.0
1151 eradicator 1.111 # would break packages that link against it. Most people get around this
1152     # by using the portage SLOT mechanism, but that is not always a relevant
1153 vapier 1.283 # solution, so instead you can call this from pkg_preinst. See also the
1154     # preserve_old_lib_notify function.
1155 eradicator 1.111 preserve_old_lib() {
1156 vapier 1.268 if [[ ${EBUILD_PHASE} != "preinst" ]] ; then
1157 vapier 1.267 eerror "preserve_old_lib() must be called from pkg_preinst() only"
1158 vapier 1.276 die "Invalid preserve_old_lib() usage"
1159 vapier 1.267 fi
1160     [[ -z $1 ]] && die "Usage: preserve_old_lib <library to preserve> [more libraries to preserve]"
1161    
1162 vapier 1.297 # let portage worry about it
1163     has preserve-libs ${FEATURES} && return 0
1164    
1165 vapier 1.267 local lib dir
1166     for lib in "$@" ; do
1167     [[ -e ${ROOT}/${lib} ]] || continue
1168     dir=${lib%/*}
1169     dodir ${dir} || die "dodir ${dir} failed"
1170     cp "${ROOT}"/${lib} "${D}"/${lib} || die "cp ${lib} failed"
1171     touch "${D}"/${lib}
1172     done
1173 eradicator 1.111 }
1174    
1175 vapier 1.283 # @FUNCTION: preserve_old_lib_notify
1176     # @USAGE: <libs to notify> [more libs]
1177     # @DESCRIPTION:
1178     # Spit helpful messages about the libraries preserved by preserve_old_lib.
1179 eradicator 1.111 preserve_old_lib_notify() {
1180 vapier 1.268 if [[ ${EBUILD_PHASE} != "postinst" ]] ; then
1181 vapier 1.267 eerror "preserve_old_lib_notify() must be called from pkg_postinst() only"
1182 vapier 1.276 die "Invalid preserve_old_lib_notify() usage"
1183 vapier 1.267 fi
1184    
1185 vapier 1.297 # let portage worry about it
1186     has preserve-libs ${FEATURES} && return 0
1187    
1188 vapier 1.267 local lib notice=0
1189     for lib in "$@" ; do
1190     [[ -e ${ROOT}/${lib} ]] || continue
1191     if [[ ${notice} -eq 0 ]] ; then
1192     notice=1
1193     ewarn "Old versions of installed libraries were detected on your system."
1194     ewarn "In order to avoid breaking packages that depend on these old libs,"
1195     ewarn "the libraries are not being removed. You need to run revdep-rebuild"
1196     ewarn "in order to remove these old dependencies. If you do not have this"
1197     ewarn "helper program, simply emerge the 'gentoolkit' package."
1198     ewarn
1199     fi
1200 phajdan.jr 1.393 ewarn " # revdep-rebuild --library '${lib}' && rm '${lib}'"
1201 vapier 1.267 done
1202 eradicator 1.111 }
1203 vapier 1.125
1204 vapier 1.283 # @FUNCTION: built_with_use
1205     # @USAGE: [--hidden] [--missing <action>] [-a|-o] <DEPEND ATOM> <List of USE flags>
1206     # @DESCRIPTION:
1207 betelgeuse 1.329 #
1208     # Deprecated: Use EAPI 2 use deps in DEPEND|RDEPEND and with has_version calls.
1209     #
1210 vapier 1.283 # A temporary hack until portage properly supports DEPENDing on USE
1211     # flags being enabled in packages. This will check to see if the specified
1212     # DEPEND atom was built with the specified list of USE flags. The
1213     # --missing option controls the behavior if called on a package that does
1214     # not actually support the defined USE flags (aka listed in IUSE).
1215     # The default is to abort (call die). The -a and -o flags control
1216     # the requirements of the USE flags. They correspond to "and" and "or"
1217     # logic. So the -a flag means all listed USE flags must be enabled
1218 opfer 1.302 # while the -o flag means at least one of the listed IUSE flags must be
1219 vapier 1.283 # enabled. The --hidden option is really for internal use only as it
1220     # means the USE flag we're checking is hidden expanded, so it won't be found
1221     # in IUSE like normal USE flags.
1222 swegener 1.286 #
1223 vapier 1.283 # Remember that this function isn't terribly intelligent so order of optional
1224     # flags matter.
1225 vapier 1.125 built_with_use() {
1226 vapier 1.275 local hidden="no"
1227     if [[ $1 == "--hidden" ]] ; then
1228     hidden="yes"
1229     shift
1230     fi
1231    
1232 vapier 1.269 local missing_action="die"
1233     if [[ $1 == "--missing" ]] ; then
1234     missing_action=$2
1235     shift ; shift
1236     case ${missing_action} in
1237     true|false|die) ;;
1238     *) die "unknown action '${missing_action}'";;
1239     esac
1240     fi
1241    
1242 vapier 1.130 local opt=$1
1243     [[ ${opt:0:1} = "-" ]] && shift || opt="-a"
1244    
1245     local PKG=$(best_version $1)
1246 vapier 1.247 [[ -z ${PKG} ]] && die "Unable to resolve $1 to an installed package"
1247 vapier 1.130 shift
1248    
1249 vapier 1.213 local USEFILE=${ROOT}/var/db/pkg/${PKG}/USE
1250 vapier 1.249 local IUSEFILE=${ROOT}/var/db/pkg/${PKG}/IUSE
1251 vapier 1.213
1252 cardoe 1.273 # if the IUSE file doesn't exist, the read will error out, we need to handle
1253     # this gracefully
1254 vapier 1.275 if [[ ! -e ${USEFILE} ]] || [[ ! -e ${IUSEFILE} && ${hidden} == "no" ]] ; then
1255 cardoe 1.273 case ${missing_action} in
1256     true) return 0;;
1257     false) return 1;;
1258     die) die "Unable to determine what USE flags $PKG was built with";;
1259     esac
1260     fi
1261    
1262 vapier 1.275 if [[ ${hidden} == "no" ]] ; then
1263 zmedico 1.301 local IUSE_BUILT=( $(<"${IUSEFILE}") )
1264 vapier 1.275 # Don't check USE_EXPAND #147237
1265     local expand
1266     for expand in $(echo ${USE_EXPAND} | tr '[:upper:]' '[:lower:]') ; do
1267     if [[ $1 == ${expand}_* ]] ; then
1268     expand=""
1269     break
1270     fi
1271     done
1272     if [[ -n ${expand} ]] ; then
1273 zmedico 1.301 if ! has $1 ${IUSE_BUILT[@]#[-+]} ; then
1274 vapier 1.275 case ${missing_action} in
1275     true) return 0;;
1276     false) return 1;;
1277     die) die "$PKG does not actually support the $1 USE flag!";;
1278     esac
1279     fi
1280 vapier 1.269 fi
1281 vapier 1.250 fi
1282 vapier 1.249
1283 vapier 1.125 local USE_BUILT=$(<${USEFILE})
1284 vapier 1.130 while [[ $# -gt 0 ]] ; do
1285     if [[ ${opt} = "-o" ]] ; then
1286     has $1 ${USE_BUILT} && return 0
1287     else
1288     has $1 ${USE_BUILT} || return 1
1289     fi
1290 vapier 1.125 shift
1291     done
1292 vapier 1.130 [[ ${opt} = "-a" ]]
1293 vapier 1.125 }
1294 vapier 1.126
1295 vapier 1.289 # @FUNCTION: epunt_cxx
1296 vapier 1.283 # @USAGE: [dir to scan]
1297     # @DESCRIPTION:
1298     # Many configure scripts wrongly bail when a C++ compiler could not be
1299     # detected. If dir is not specified, then it defaults to ${S}.
1300     #
1301     # http://bugs.gentoo.org/73450
1302 vapier 1.126 epunt_cxx() {
1303 vapier 1.127 local dir=$1
1304     [[ -z ${dir} ]] && dir=${S}
1305     ebegin "Removing useless C++ checks"
1306 vapier 1.415 local f p any_found
1307 mgorny 1.412 while IFS= read -r -d '' f; do
1308 vapier 1.415 for p in "${PORTDIR}"/eclass/ELT-patches/nocxx/*.patch ; do
1309     if patch --no-backup-if-mismatch -p1 "${f}" "${p}" >/dev/null ; then
1310     any_found=1
1311     break
1312     fi
1313     done
1314 mgorny 1.412 done < <(find "${dir}" -name configure -print0)
1315 mgorny 1.410
1316 vapier 1.415 if [[ -z ${any_found} ]]; then
1317     eqawarn "epunt_cxx called unnecessarily (no C++ checks to punt)."
1318     fi
1319 vapier 1.127 eend 0
1320 vapier 1.126 }
1321 ka0ttic 1.143
1322 vapier 1.283 # @FUNCTION: make_wrapper
1323 wolf31o2 1.295 # @USAGE: <wrapper> <target> [chdir] [libpaths] [installpath]
1324 vapier 1.283 # @DESCRIPTION:
1325     # Create a shell wrapper script named wrapper in installpath
1326     # (defaults to the bindir) to execute target (default of wrapper) by
1327     # first optionally setting LD_LIBRARY_PATH to the colon-delimited
1328     # libpaths followed by optionally changing directory to chdir.
1329 wolf31o2 1.160 make_wrapper() {
1330 wolf31o2 1.164 local wrapper=$1 bin=$2 chdir=$3 libdir=$4 path=$5
1331 wolf31o2 1.160 local tmpwrapper=$(emktemp)
1332 vapier 1.414
1333     (
1334     echo '#!/bin/sh'
1335     [[ -n ${chdir} ]] && printf 'cd "%s"\n' "${chdir}"
1336     if [[ -n ${libdir} ]] ; then
1337     cat <<-EOF
1338     if [ "\${LD_LIBRARY_PATH+set}" = "set" ] ; then
1339     export LD_LIBRARY_PATH="\${LD_LIBRARY_PATH}:${libdir}"
1340     else
1341     export LD_LIBRARY_PATH="${libdir}"
1342     fi
1343     EOF
1344     fi
1345 vapier 1.202 # We don't want to quote ${bin} so that people can pass complex
1346 vapier 1.414 # things as ${bin} ... "./someprog --args"
1347     printf 'exec %s "$@"\n' "${bin}"
1348     ) > "${tmpwrapper}"
1349 wolf31o2 1.160 chmod go+rx "${tmpwrapper}"
1350 vapier 1.414
1351 vapier 1.201 if [[ -n ${path} ]] ; then
1352 vapier 1.283 (
1353 vapier 1.201 exeinto "${path}"
1354 wolf31o2 1.164 newexe "${tmpwrapper}" "${wrapper}"
1355 vapier 1.283 ) || die
1356 wolf31o2 1.164 else
1357 vapier 1.283 newbin "${tmpwrapper}" "${wrapper}" || die
1358 wolf31o2 1.164 fi
1359 wolf31o2 1.160 }
1360 mr_bones_ 1.311
1361 vapier 1.351 # @FUNCTION: path_exists
1362     # @USAGE: [-a|-o] <paths>
1363     # @DESCRIPTION:
1364     # Check if the specified paths exist. Works for all types of paths
1365     # (files/dirs/etc...). The -a and -o flags control the requirements
1366     # of the paths. They correspond to "and" and "or" logic. So the -a
1367     # flag means all the paths must exist while the -o flag means at least
1368     # one of the paths must exist. The default behavior is "and". If no
1369     # paths are specified, then the return value is "false".
1370     path_exists() {
1371     local opt=$1
1372     [[ ${opt} == -[ao] ]] && shift || opt="-a"
1373    
1374     # no paths -> return false
1375     # same behavior as: [[ -e "" ]]
1376     [[ $# -eq 0 ]] && return 1
1377    
1378     local p r=0
1379     for p in "$@" ; do
1380     [[ -e ${p} ]]
1381     : $(( r += $? ))
1382     done
1383    
1384     case ${opt} in
1385     -a) return $(( r != 0 )) ;;
1386     -o) return $(( r == $# )) ;;
1387     esac
1388     }
1389 mgorny 1.364
1390     # @FUNCTION: in_iuse
1391     # @USAGE: <flag>
1392     # @DESCRIPTION:
1393     # Determines whether the given flag is in IUSE. Strips IUSE default prefixes
1394     # as necessary.
1395     #
1396     # Note that this function should not be used in the global scope.
1397     in_iuse() {
1398     debug-print-function ${FUNCNAME} "${@}"
1399     [[ ${#} -eq 1 ]] || die "Invalid args to ${FUNCNAME}()"
1400    
1401     local flag=${1}
1402     local liuse=( ${IUSE} )
1403    
1404     has "${flag}" "${liuse[@]#[+-]}"
1405     }
1406 vapier 1.365
1407 vapier 1.367 # @FUNCTION: use_if_iuse
1408     # @USAGE: <flag>
1409     # @DESCRIPTION:
1410     # Return true if the given flag is in USE and IUSE.
1411     #
1412     # Note that this function should not be used in the global scope.
1413     use_if_iuse() {
1414     in_iuse $1 || return 1
1415     use $1
1416     }
1417    
1418 vapier 1.365 # @FUNCTION: usex
1419     # @USAGE: <USE flag> [true output] [false output] [true suffix] [false suffix]
1420     # @DESCRIPTION:
1421 axs 1.404 # Proxy to declare usex for package managers or EAPIs that do not provide it
1422     # and use the package manager implementation when available (i.e. EAPI >= 5).
1423 vapier 1.365 # If USE flag is set, echo [true output][true suffix] (defaults to "yes"),
1424     # otherwise echo [false output][false suffix] (defaults to "no").
1425 ulm 1.405 if has "${EAPI:-0}" 0 1 2 3 4; then
1426 axs 1.404 usex() { use "$1" && echo "${2-yes}$4" || echo "${3-no}$5" ; } #382963
1427     fi
1428 vapier 1.371
1429 mgorny 1.395 # @FUNCTION: prune_libtool_files
1430 mgorny 1.408 # @USAGE: [--all|--modules]
1431 mgorny 1.395 # @DESCRIPTION:
1432     # Locate unnecessary libtool files (.la) and libtool static archives
1433     # (.a) and remove them from installation image.
1434     #
1435     # By default, .la files are removed whenever the static linkage can
1436     # either be performed using pkg-config or doesn't introduce additional
1437     # flags.
1438     #
1439 mgorny 1.408 # If '--modules' argument is passed, .la files for modules (plugins) are
1440     # removed as well. This is usually useful when the package installs
1441     # plugins and the plugin loader does not use .la files.
1442     #
1443     # If '--all' argument is passed, all .la files are removed without
1444     # performing any heuristic on them. You shouldn't ever use that,
1445     # and instead report a bug in the algorithm instead.
1446 mgorny 1.395 #
1447     # The .a files are only removed whenever corresponding .la files state
1448     # that they should not be linked to, i.e. whenever these files
1449     # correspond to plugins.
1450     #
1451 mgorny 1.411 # Note: if your package installs both static libraries and .pc files
1452     # which use variable substitution for -l flags, you need to add
1453     # pkg-config to your DEPEND.
1454 mgorny 1.395 prune_libtool_files() {
1455     debug-print-function ${FUNCNAME} "$@"
1456    
1457 mgorny 1.408 local removing_all removing_modules opt
1458 mgorny 1.395 for opt; do
1459     case "${opt}" in
1460     --all)
1461     removing_all=1
1462 mgorny 1.408 removing_modules=1
1463     ;;
1464     --modules)
1465     removing_modules=1
1466 mgorny 1.395 ;;
1467     *)
1468     die "Invalid argument to ${FUNCNAME}(): ${opt}"
1469     esac
1470     done
1471    
1472     local f
1473 mgorny 1.407 local queue=()
1474 mgorny 1.395 while IFS= read -r -d '' f; do # for all .la files
1475     local archivefile=${f/%.la/.a}
1476    
1477 mgorny 1.420 # The following check is done by libtool itself.
1478     # It helps us avoid removing random files which match '*.la',
1479     # see bug #468380.
1480 mgorny 1.421 if ! sed -n -e '/^# Generated by .*libtool/q0;4q1' "${f}"; then
1481 mgorny 1.420 continue
1482     fi
1483    
1484 mgorny 1.395 [[ ${f} != ${archivefile} ]] || die 'regex sanity check failed'
1485 mgorny 1.418 local reason pkgconfig_scanned
1486     local snotlink=$(sed -n -e 's:^shouldnotlink=::p' "${f}")
1487 mgorny 1.395
1488 mgorny 1.418 if [[ ${snotlink} == yes ]]; then
1489 mgorny 1.408
1490 mgorny 1.418 # Remove static libs we're not supposed to link against.
1491 mgorny 1.400 if [[ -f ${archivefile} ]]; then
1492     einfo "Removing unnecessary ${archivefile#${D%/}} (static plugin)"
1493 mgorny 1.407 queue+=( "${archivefile}" )
1494 mgorny 1.400 fi
1495 mgorny 1.395
1496     # The .la file may be used by a module loader, so avoid removing it
1497     # unless explicitly requested.
1498 mgorny 1.408 if [[ ${removing_modules} ]]; then
1499     reason='module'
1500     fi
1501 mgorny 1.395
1502 mgorny 1.420 else
1503 mgorny 1.418
1504     # Remove .la files when:
1505     # - user explicitly wants us to remove all .la files,
1506     # - respective static archive doesn't exist,
1507     # - they are covered by a .pc file already,
1508     # - they don't provide any new information (no libs & no flags).
1509    
1510     if [[ ${removing_all} ]]; then
1511     reason='requested'
1512     elif [[ ! -f ${archivefile} ]]; then
1513     reason='no static archive'
1514     elif [[ ! $(sed -nre \
1515     "s/^(dependency_libs|inherited_linker_flags)='(.*)'$/\2/p" \
1516     "${f}") ]]; then
1517     reason='no libs & flags'
1518     else
1519     if [[ ! ${pkgconfig_scanned} ]]; then
1520     # Create a list of all .pc-covered libs.
1521     local pc_libs=()
1522     if [[ ! ${removing_all} ]]; then
1523     local pc
1524     local tf=${T}/prune-lt-files.pc
1525     local pkgconf=$(tc-getPKG_CONFIG)
1526    
1527     while IFS= read -r -d '' pc; do # for all .pc files
1528     local arg libs
1529    
1530     # Use pkg-config if available (and works),
1531     # fallback to sed.
1532     if ${pkgconf} --exists "${pc}" &>/dev/null; then
1533     sed -e '/^Requires:/d' "${pc}" > "${tf}"
1534     libs=$(${pkgconf} --libs "${tf}")
1535     else
1536     libs=$(sed -ne 's/^Libs://p' "${pc}")
1537     fi
1538    
1539     for arg in ${libs}; do
1540     if [[ ${arg} == -l* ]]; then
1541     if [[ ${arg} == '*$*' ]]; then
1542     eqawarn "${FUNCNAME}: variable substitution likely failed in ${pc}"
1543     eqawarn "(arg: ${arg})"
1544     eqawarn "Most likely, you need to add virtual/pkgconfig to DEPEND."
1545     fi
1546    
1547     pc_libs+=( lib${arg#-l}.la )
1548 mgorny 1.411 fi
1549 mgorny 1.418 done
1550     done < <(find "${D}" -type f -name '*.pc' -print0)
1551 mgorny 1.411
1552 mgorny 1.418 rm -f "${tf}"
1553     fi
1554 mgorny 1.402
1555 mgorny 1.418 pkgconfig_scanned=1
1556     fi # pkgconfig_scanned
1557 mgorny 1.402
1558 mgorny 1.418 has "${f##*/}" "${pc_libs[@]}" && reason='covered by .pc'
1559     fi # removal due to .pc
1560 mgorny 1.402
1561 mgorny 1.418 fi # shouldnotlink==no
1562 mgorny 1.395
1563     if [[ ${reason} ]]; then
1564     einfo "Removing unnecessary ${f#${D%/}} (${reason})"
1565 mgorny 1.407 queue+=( "${f}" )
1566 mgorny 1.395 fi
1567 mgorny 1.407 done < <(find "${D}" -xtype f -name '*.la' -print0)
1568    
1569     if [[ ${queue[@]} ]]; then
1570     rm -f "${queue[@]}"
1571     fi
1572 mgorny 1.395 }
1573    
1574 vapier 1.372 check_license() { die "you no longer need this as portage supports ACCEPT_LICENSE itself"; }
1575    
1576 vapier 1.371 fi

  ViewVC Help
Powered by ViewVC 1.1.20