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

Diff of /eclass/eutils.eclass

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.361 Revision 1.413
1# Copyright 1999-2011 Gentoo Foundation 1# Copyright 1999-2013 Gentoo Foundation
2# Distributed under the terms of the GNU General Public License v2 2# Distributed under the terms of the GNU General Public License v2
3# $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.361 2011/08/08 02:01:40 vapier Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/eutils.eclass,v 1.413 2013/03/09 18:18:09 mgorny Exp $
4 4
5# @ECLASS: eutils.eclass 5# @ECLASS: eutils.eclass
6# @MAINTAINER: 6# @MAINTAINER:
7# base-system@gentoo.org 7# base-system@gentoo.org
8# @BLURB: many extra (but common) functions that are used in ebuilds 8# @BLURB: many extra (but common) functions that are used in ebuilds
13# home rather than having multiple ebuilds implementing the same thing. 13# home rather than having multiple ebuilds implementing the same thing.
14# 14#
15# Due to the nature of this eclass, some functions may have maintainers 15# Due to the nature of this eclass, some functions may have maintainers
16# different from the overall eclass! 16# different from the overall eclass!
17 17
18inherit multilib portability 18if [[ ${___ECLASS_ONCE_EUTILS} != "recur -_+^+_- spank" ]] ; then
19___ECLASS_ONCE_EUTILS="recur -_+^+_- spank"
19 20
20DESCRIPTION="Based on the ${ECLASS} eclass" 21inherit multilib toolchain-funcs user
21 22
22if has "${EAPI:-0}" 0 1 2; then 23if has "${EAPI:-0}" 0 1 2; then
23 24
24# @FUNCTION: epause 25# @FUNCTION: epause
25# @USAGE: [seconds] 26# @USAGE: [seconds]
64fi 65fi
65 66
66# @FUNCTION: eqawarn 67# @FUNCTION: eqawarn
67# @USAGE: [message] 68# @USAGE: [message]
68# @DESCRIPTION: 69# @DESCRIPTION:
69# Proxy to einfo for package managers that don't provide eqawarn and use the PM 70# Proxy to ewarn for package managers that don't provide eqawarn and use the PM
70# implementation if available. 71# implementation if available. Reuses PORTAGE_ELOG_CLASSES as set by the dev
72# profile.
71if ! declare -F eqawarn >/dev/null ; then 73if ! declare -F eqawarn >/dev/null ; then
72 eqawarn() { 74 eqawarn() {
73 einfo "$@" 75 has qa ${PORTAGE_ELOG_CLASSES} && ewarn "$@"
76 :
74 } 77 }
75fi 78fi
76 79
77# @FUNCTION: ecvs_clean 80# @FUNCTION: ecvs_clean
78# @USAGE: [list of dirs] 81# @USAGE: [list of dirs]
93esvn_clean() { 96esvn_clean() {
94 [[ -z $* ]] && set -- . 97 [[ -z $* ]] && set -- .
95 find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf 98 find "$@" -type d -name '.svn' -prune -print0 | xargs -0 rm -rf
96} 99}
97 100
101# @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
115estack_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.
127estack_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 eval local __estack_i=\${#${__estack_name}\[@\]}
139 # 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 eval ${__estack_retvar}=\"\${${__estack_name}\[${__estack_i}\]}\"
145 fi
146 eval unset ${__estack_name}\[${__estack_i}\]
147}
148
98# @FUNCTION: eshopts_push 149# @FUNCTION: eshopts_push
99# @USAGE: [options to `set` or `shopt`] 150# @USAGE: [options to `set` or `shopt`]
100# @DESCRIPTION: 151# @DESCRIPTION:
101# Often times code will want to enable a shell option to change code behavior. 152# Often times code will want to enable a shell option to change code behavior.
102# Since changing shell options can easily break other pieces of code (which 153# Since changing shell options can easily break other pieces of code (which
107# rather than `set` as there are some options only available via that. 158# rather than `set` as there are some options only available via that.
108# 159#
109# A common example is to disable shell globbing so that special meaning/care 160# A common example is to disable shell globbing so that special meaning/care
110# may be used with variables/arguments to custom functions. That would be: 161# may be used with variables/arguments to custom functions. That would be:
111# @CODE 162# @CODE
112# eshopts_push -o noglob 163# eshopts_push -s noglob
113# for x in ${foo} ; do 164# for x in ${foo} ; do
114# if ...some check... ; then 165# if ...some check... ; then
115# eshopts_pop 166# eshopts_pop
116# return 0 167# return 0
117# fi 168# fi
118# done 169# done
119# eshopts_pop 170# eshopts_pop
120# @CODE 171# @CODE
121eshopts_push() { 172eshopts_push() {
122 # have to assume __ESHOPTS_SAVE__ isn't screwed with
123 # as a `declare -a` here will reset its value
124 local i=${#__ESHOPTS_SAVE__[@]}
125 if [[ $1 == -[su] ]] ; then 173 if [[ $1 == -[su] ]] ; then
126 __ESHOPTS_SAVE__[$i]=$(shopt -p) 174 estack_push eshopts "$(shopt -p)"
127 [[ $# -eq 0 ]] && return 0 175 [[ $# -eq 0 ]] && return 0
128 shopt "$@" || die "eshopts_push: bad options to shopt: $*" 176 shopt "$@" || die "${FUNCNAME}: bad options to shopt: $*"
129 else 177 else
130 __ESHOPTS_SAVE__[$i]=$- 178 estack_push eshopts $-
131 [[ $# -eq 0 ]] && return 0 179 [[ $# -eq 0 ]] && return 0
132 set "$@" || die "eshopts_push: bad options to set: $*" 180 set "$@" || die "${FUNCNAME}: bad options to set: $*"
133 fi 181 fi
134} 182}
135 183
136# @FUNCTION: eshopts_pop 184# @FUNCTION: eshopts_pop
137# @USAGE: 185# @USAGE:
138# @DESCRIPTION: 186# @DESCRIPTION:
139# Restore the shell options to the state saved with the corresponding 187# Restore the shell options to the state saved with the corresponding
140# eshopts_push call. See that function for more details. 188# eshopts_push call. See that function for more details.
141eshopts_pop() { 189eshopts_pop() {
142 [[ $# -ne 0 ]] && die "eshopts_pop takes no arguments" 190 local s
143 local i=$(( ${#__ESHOPTS_SAVE__[@]} - 1 )) 191 estack_pop eshopts s || die "${FUNCNAME}: unbalanced push"
144 [[ ${i} -eq -1 ]] && die "eshopts_{push,pop}: unbalanced pair"
145 local s=${__ESHOPTS_SAVE__[$i]}
146 unset __ESHOPTS_SAVE__[$i]
147 if [[ ${s} == "shopt -"* ]] ; then 192 if [[ ${s} == "shopt -"* ]] ; then
148 eval "${s}" || die "eshopts_pop: sanity: invalid shopt options: ${s}" 193 eval "${s}" || die "${FUNCNAME}: sanity: invalid shopt options: ${s}"
149 else 194 else
150 set +$- || die "eshopts_pop: sanity: invalid shell settings: $-" 195 set +$- || die "${FUNCNAME}: sanity: invalid shell settings: $-"
151 set -${s} || die "eshopts_pop: sanity: unable to restore saved shell settings: ${s}" 196 set -${s} || die "${FUNCNAME}: sanity: unable to restore saved shell settings: ${s}"
152 fi 197 fi
198}
199
200# @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.
205eumask_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.
214eumask_pop() {
215 [[ $# -eq 0 ]] || die "${FUNCNAME}: we take no options"
216 local s
217 estack_pop eumask s || die "${FUNCNAME}: unbalanced push"
218 umask ${s} || die "${FUNCNAME}: sanity: could not restore umask: ${s}"
153} 219}
154 220
155# @VARIABLE: EPATCH_SOURCE 221# @VARIABLE: EPATCH_SOURCE
156# @DESCRIPTION: 222# @DESCRIPTION:
157# Default directory to search for patches. 223# Default directory to search for patches.
160# @DESCRIPTION: 226# @DESCRIPTION:
161# Default extension for patches (do not prefix the period yourself). 227# Default extension for patches (do not prefix the period yourself).
162EPATCH_SUFFIX="patch.bz2" 228EPATCH_SUFFIX="patch.bz2"
163# @VARIABLE: EPATCH_OPTS 229# @VARIABLE: EPATCH_OPTS
164# @DESCRIPTION: 230# @DESCRIPTION:
165# Default options for patch: 231# Options to pass to patch. Meant for ebuild/package-specific tweaking
232# such as forcing the patch level (-p#) or fuzz (-F#) factor. Note that
233# for single patch tweaking, you can also pass flags directly to epatch.
234EPATCH_OPTS=""
235# @VARIABLE: EPATCH_COMMON_OPTS
236# @DESCRIPTION:
237# Common options to pass to `patch`. You probably should never need to
238# change these. If you do, please discuss it with base-system first to
239# be sure.
166# @CODE 240# @CODE
167# -g0 - keep RCS, ClearCase, Perforce and SCCS happy #24571 241# -g0 - keep RCS, ClearCase, Perforce and SCCS happy #24571
168# --no-backup-if-mismatch - do not leave .orig files behind 242# --no-backup-if-mismatch - do not leave .orig files behind
169# -E - automatically remove empty files 243# -E - automatically remove empty files
170# @CODE 244# @CODE
171EPATCH_OPTS="-g0 -E --no-backup-if-mismatch" 245EPATCH_COMMON_OPTS="-g0 -E --no-backup-if-mismatch"
172# @VARIABLE: EPATCH_EXCLUDE 246# @VARIABLE: EPATCH_EXCLUDE
173# @DESCRIPTION: 247# @DESCRIPTION:
174# List of patches not to apply. Note this is only file names, 248# List of patches not to apply. Note this is only file names,
175# and not the full path. Globs accepted. 249# and not the full path. Globs accepted.
176EPATCH_EXCLUDE="" 250EPATCH_EXCLUDE=""
187# Only require patches to match EPATCH_SUFFIX rather than the extended 261# Only require patches to match EPATCH_SUFFIX rather than the extended
188# arch naming style. 262# arch naming style.
189EPATCH_FORCE="no" 263EPATCH_FORCE="no"
190 264
191# @FUNCTION: epatch 265# @FUNCTION: epatch
192# @USAGE: [patches] [dirs of patches] 266# @USAGE: [options] [patches] [dirs of patches]
193# @DESCRIPTION: 267# @DESCRIPTION:
194# epatch is designed to greatly simplify the application of patches. It can 268# epatch is designed to greatly simplify the application of patches. It can
195# process patch files directly, or directories of patches. The patches may be 269# process patch files directly, or directories of patches. The patches may be
196# compressed (bzip/gzip/etc...) or plain text. You generally need not specify 270# compressed (bzip/gzip/etc...) or plain text. You generally need not specify
197# the -p option as epatch will automatically attempt -p0 to -p5 until things 271# the -p option as epatch will automatically attempt -p0 to -p5 until things
198# apply successfully. 272# apply successfully.
199# 273#
200# If you do not specify any options, then epatch will default to the directory 274# If you do not specify any patches/dirs, then epatch will default to the
201# specified by EPATCH_SOURCE. 275# directory specified by EPATCH_SOURCE.
276#
277# Any options specified that start with a dash will be passed down to patch
278# for this specific invocation. As soon as an arg w/out a dash is found, then
279# arg processing stops.
202# 280#
203# When processing directories, epatch will apply all patches that match: 281# When processing directories, epatch will apply all patches that match:
204# @CODE 282# @CODE
205# if ${EPATCH_FORCE} != "yes" 283# if ${EPATCH_FORCE} != "yes"
206# ??_${ARCH}_foo.${EPATCH_SUFFIX} 284# ??_${ARCH}_foo.${EPATCH_SUFFIX}
224 echo "${1//?/=}" 302 echo "${1//?/=}"
225 } 303 }
226 304
227 unset P4CONFIG P4PORT P4USER # keep perforce at bay #56402 305 unset P4CONFIG P4PORT P4USER # keep perforce at bay #56402
228 306
307 # First process options. We localize the EPATCH_OPTS setting
308 # from above so that we can pass it on in the loop below with
309 # any additional values the user has specified.
310 local EPATCH_OPTS=( ${EPATCH_OPTS[*]} )
311 while [[ $# -gt 0 ]] ; do
312 case $1 in
313 -*) EPATCH_OPTS+=( "$1" ) ;;
314 *) break ;;
315 esac
316 shift
317 done
318
229 # Let the rest of the code process one user arg at a time -- 319 # Let the rest of the code process one user arg at a time --
230 # each arg may expand into multiple patches, and each arg may 320 # each arg may expand into multiple patches, and each arg may
231 # need to start off with the default global EPATCH_xxx values 321 # need to start off with the default global EPATCH_xxx values
232 if [[ $# -gt 1 ]] ; then 322 if [[ $# -gt 1 ]] ; then
233 local m 323 local m
266 eerror " ${EPATCH_SOURCE}" 356 eerror " ${EPATCH_SOURCE}"
267 eerror " ( ${EPATCH_SOURCE##*/} )" 357 eerror " ( ${EPATCH_SOURCE##*/} )"
268 echo 358 echo
269 die "Cannot find \$EPATCH_SOURCE!" 359 die "Cannot find \$EPATCH_SOURCE!"
270 fi 360 fi
361
362 # Now that we know we're actually going to apply something, merge
363 # all of the patch options back in to a single variable for below.
364 EPATCH_OPTS="${EPATCH_COMMON_OPTS} ${EPATCH_OPTS[*]}"
271 365
272 local PIPE_CMD 366 local PIPE_CMD
273 case ${EPATCH_SUFFIX##*\.} in 367 case ${EPATCH_SUFFIX##*\.} in
274 xz) PIPE_CMD="xz -dc" ;; 368 xz) PIPE_CMD="xz -dc" ;;
275 lzma) PIPE_CMD="lzma -dc" ;; 369 lzma) PIPE_CMD="lzma -dc" ;;
334 local STDERR_TARGET="${T}/${patchname}.out" 428 local STDERR_TARGET="${T}/${patchname}.out"
335 if [[ -e ${STDERR_TARGET} ]] ; then 429 if [[ -e ${STDERR_TARGET} ]] ; then
336 STDERR_TARGET="${T}/${patchname}-$$.out" 430 STDERR_TARGET="${T}/${patchname}-$$.out"
337 fi 431 fi
338 432
339 printf "***** %s *****\n\n" "${patchname}" > "${STDERR_TARGET}" 433 printf "***** %s *****\nPWD: %s\n\n" "${patchname}" "${PWD}" > "${STDERR_TARGET}"
340 434
341 # Decompress the patch if need be 435 # Decompress the patch if need be
342 local count=0 436 local count=0
343 local PATCH_TARGET 437 local PATCH_TARGET
344 if [[ -n ${PIPE_CMD} ]] ; then 438 if [[ -n ${PIPE_CMD} ]] ; then
372 eqawarn " In the future this will cause a failure." 466 eqawarn " In the future this will cause a failure."
373 eqawarn "${rel_paths}" 467 eqawarn "${rel_paths}"
374 fi 468 fi
375 469
376 # Dynamically detect the correct -p# ... i'm lazy, so shoot me :/ 470 # Dynamically detect the correct -p# ... i'm lazy, so shoot me :/
471 local patch_cmd
377 while [[ ${count} -lt 5 ]] ; do 472 while [[ ${count} -lt 5 ]] ; do
473 patch_cmd="${BASH_ALIASES[patch]:-patch} -p${count} ${EPATCH_OPTS}"
474
378 # Generate some useful debug info ... 475 # Generate some useful debug info ...
379 ( 476 (
380 _epatch_draw_line "***** ${patchname} *****" 477 _epatch_draw_line "***** ${patchname} *****"
381 echo 478 echo
382 echo "PATCH COMMAND: patch -p${count} ${EPATCH_OPTS} < '${PATCH_TARGET}'" 479 echo "PATCH COMMAND: ${patch_cmd} < '${PATCH_TARGET}'"
383 echo 480 echo
384 _epatch_draw_line "***** ${patchname} *****" 481 _epatch_draw_line "***** ${patchname} *****"
385 patch -p${count} ${EPATCH_OPTS} --dry-run -f < "${PATCH_TARGET}" 2>&1 482 ${patch_cmd} --dry-run -f < "${PATCH_TARGET}" 2>&1
386 ret=$? 483 ret=$?
387 echo 484 echo
388 echo "patch program exited with status ${ret}" 485 echo "patch program exited with status ${ret}"
389 exit ${ret} 486 exit ${ret}
390 ) >> "${STDERR_TARGET}" 487 ) >> "${STDERR_TARGET}"
394 _epatch_draw_line "***** ${patchname} *****" 491 _epatch_draw_line "***** ${patchname} *****"
395 echo 492 echo
396 echo "ACTUALLY APPLYING ${patchname} ..." 493 echo "ACTUALLY APPLYING ${patchname} ..."
397 echo 494 echo
398 _epatch_draw_line "***** ${patchname} *****" 495 _epatch_draw_line "***** ${patchname} *****"
399 patch -p${count} ${EPATCH_OPTS} < "${PATCH_TARGET}" 2>&1 496 ${patch_cmd} < "${PATCH_TARGET}" 2>&1
400 ret=$? 497 ret=$?
401 echo 498 echo
402 echo "patch program exited with status ${ret}" 499 echo "patch program exited with status ${ret}"
403 exit ${ret} 500 exit ${ret}
404 ) >> "${STDERR_TARGET}" 501 ) >> "${STDERR_TARGET}"
431 eerror " ${STDERR_TARGET}" 528 eerror " ${STDERR_TARGET}"
432 echo 529 echo
433 die "Failed Patch: ${patchname}!" 530 die "Failed Patch: ${patchname}!"
434 fi 531 fi
435 532
436 # if everything worked, delete the patch log 533 # if everything worked, delete the full debug patch log
437 rm -f "${STDERR_TARGET}" 534 rm -f "${STDERR_TARGET}"
535
536 # then log away the exact stuff for people to review later
537 cat <<-EOF >> "${T}/epatch.log"
538 PATCH: ${x}
539 CMD: ${patch_cmd}
540 PWD: ${PWD}
541
542 EOF
438 eend 0 543 eend 0
439 done 544 done
440 545
441 [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching" 546 [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching"
442 : # everything worked 547 : # everything worked
444 549
445# @FUNCTION: epatch_user 550# @FUNCTION: epatch_user
446# @USAGE: 551# @USAGE:
447# @DESCRIPTION: 552# @DESCRIPTION:
448# Applies user-provided patches to the source tree. The patches are 553# Applies user-provided patches to the source tree. The patches are
449# taken from /etc/portage/patches/<CATEGORY>/<PF|P|PN>/, where the first 554# taken from /etc/portage/patches/<CATEGORY>/<PF|P|PN>[:SLOT]/, where the first
450# of these three directories to exist will be the one to use, ignoring 555# of these three directories to exist will be the one to use, ignoring
451# any more general directories which might exist as well. 556# any more general directories which might exist as well. They must end
557# in ".patch" to be applied.
452# 558#
453# User patches are intended for quick testing of patches without ebuild 559# User patches are intended for quick testing of patches without ebuild
454# modifications, as well as for permanent customizations a user might 560# modifications, as well as for permanent customizations a user might
455# desire. Obviously, there can be no official support for arbitrarily 561# desire. Obviously, there can be no official support for arbitrarily
456# patched ebuilds. So whenever a build log in a bug report mentions that 562# patched ebuilds. So whenever a build log in a bug report mentions that
470# autotool input files as well. 576# autotool input files as well.
471epatch_user() { 577epatch_user() {
472 [[ $# -ne 0 ]] && die "epatch_user takes no options" 578 [[ $# -ne 0 ]] && die "epatch_user takes no options"
473 579
474 # Allow multiple calls to this function; ignore all but the first 580 # Allow multiple calls to this function; ignore all but the first
475 local applied="${T}/epach_user.applied" 581 local applied="${T}/epatch_user.log"
476 [[ -e ${applied} ]] && return 2 582 [[ -e ${applied} ]] && return 2
477 583
478 # don't clobber any EPATCH vars that the parent might want 584 # don't clobber any EPATCH vars that the parent might want
479 local EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches 585 local EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches
480 for check in {${CATEGORY}/${PF},${CATEGORY}/${P},${CATEGORY}/${PN}}; do 586 for check in ${CATEGORY}/{${P}-${PR},${P},${PN}}{,:${SLOT}}; do
481 EPATCH_SOURCE=${base}/${CTARGET}/${check} 587 EPATCH_SOURCE=${base}/${CTARGET}/${check}
482 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check} 588 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check}
483 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check} 589 [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check}
484 if [[ -d ${EPATCH_SOURCE} ]] ; then 590 if [[ -d ${EPATCH_SOURCE} ]] ; then
485 EPATCH_SOURCE=${EPATCH_SOURCE} \ 591 EPATCH_SOURCE=${EPATCH_SOURCE} \
528 TMPDIR="${topdir}" mktemp -dt tmp.XXXXXXXXXX 634 TMPDIR="${topdir}" mktemp -dt tmp.XXXXXXXXXX
529 fi 635 fi
530 fi 636 fi
531} 637}
532 638
533# @FUNCTION: egetent
534# @USAGE: <database> <key>
535# @MAINTAINER:
536# base-system@gentoo.org (Linux)
537# Joe Jezak <josejx@gmail.com> (OS X)
538# usata@gentoo.org (OS X)
539# Aaron Walker <ka0ttic@gentoo.org> (FreeBSD)
540# @DESCRIPTION:
541# Small wrapper for getent (Linux),
542# nidump (< Mac OS X 10.5), dscl (Mac OS X 10.5),
543# and pw (FreeBSD) used in enewuser()/enewgroup()
544egetent() {
545 case ${CHOST} in
546 *-darwin[678])
547 case "$2" in
548 *[!0-9]*) # Non numeric
549 nidump $1 . | awk -F":" "{ if (\$1 ~ /^$2\$/) {print \$0;exit;} }"
550 ;;
551 *) # Numeric
552 nidump $1 . | awk -F":" "{ if (\$3 == $2) {print \$0;exit;} }"
553 ;;
554 esac
555 ;;
556 *-darwin*)
557 local mytype=$1
558 [[ "passwd" == $mytype ]] && mytype="Users"
559 [[ "group" == $mytype ]] && mytype="Groups"
560 case "$2" in
561 *[!0-9]*) # Non numeric
562 dscl . -read /$mytype/$2 2>/dev/null |grep RecordName
563 ;;
564 *) # Numeric
565 local mykey="UniqueID"
566 [[ $mytype == "Groups" ]] && mykey="PrimaryGroupID"
567 dscl . -search /$mytype $mykey $2 2>/dev/null
568 ;;
569 esac
570 ;;
571 *-freebsd*|*-dragonfly*)
572 local opts action="user"
573 [[ $1 == "passwd" ]] || action="group"
574
575 # lookup by uid/gid
576 if [[ $2 == [[:digit:]]* ]] ; then
577 [[ ${action} == "user" ]] && opts="-u" || opts="-g"
578 fi
579
580 pw show ${action} ${opts} "$2" -q
581 ;;
582 *-netbsd*|*-openbsd*)
583 grep "$2:\*:" /etc/$1
584 ;;
585 *)
586 type -p nscd >& /dev/null && nscd -i "$1"
587 getent "$1" "$2"
588 ;;
589 esac
590}
591
592# @FUNCTION: enewuser
593# @USAGE: <user> [uid] [shell] [homedir] [groups] [params]
594# @DESCRIPTION:
595# Same as enewgroup, you are not required to understand how to properly add
596# a user to the system. The only required parameter is the username.
597# Default uid is (pass -1 for this) next available, default shell is
598# /bin/false, default homedir is /dev/null, there are no default groups,
599# and default params sets the comment as 'added by portage for ${PN}'.
600enewuser() {
601 case ${EBUILD_PHASE} in
602 unpack|compile|test|install)
603 eerror "'enewuser()' called from '${EBUILD_PHASE}()' which is not a pkg_* function."
604 eerror "Package fails at QA and at life. Please file a bug."
605 die "Bad package! enewuser is only for use in pkg_* functions!"
606 esac
607
608 # get the username
609 local euser=$1; shift
610 if [[ -z ${euser} ]] ; then
611 eerror "No username specified !"
612 die "Cannot call enewuser without a username"
613 fi
614
615 # lets see if the username already exists
616 if [[ -n $(egetent passwd "${euser}") ]] ; then
617 return 0
618 fi
619 einfo "Adding user '${euser}' to your system ..."
620
621 # options to pass to useradd
622 local opts=
623
624 # handle uid
625 local euid=$1; shift
626 if [[ -n ${euid} && ${euid} != -1 ]] ; then
627 if [[ ${euid} -gt 0 ]] ; then
628 if [[ -n $(egetent passwd ${euid}) ]] ; then
629 euid="next"
630 fi
631 else
632 eerror "Userid given but is not greater than 0 !"
633 die "${euid} is not a valid UID"
634 fi
635 else
636 euid="next"
637 fi
638 if [[ ${euid} == "next" ]] ; then
639 for ((euid = 101; euid <= 999; euid++)); do
640 [[ -z $(egetent passwd ${euid}) ]] && break
641 done
642 fi
643 opts="${opts} -u ${euid}"
644 einfo " - Userid: ${euid}"
645
646 # handle shell
647 local eshell=$1; shift
648 if [[ ! -z ${eshell} ]] && [[ ${eshell} != "-1" ]] ; then
649 if [[ ! -e ${ROOT}${eshell} ]] ; then
650 eerror "A shell was specified but it does not exist !"
651 die "${eshell} does not exist in ${ROOT}"
652 fi
653 if [[ ${eshell} == */false || ${eshell} == */nologin ]] ; then
654 eerror "Do not specify ${eshell} yourself, use -1"
655 die "Pass '-1' as the shell parameter"
656 fi
657 else
658 for shell in /sbin/nologin /usr/sbin/nologin /bin/false /usr/bin/false /dev/null ; do
659 [[ -x ${ROOT}${shell} ]] && break
660 done
661
662 if [[ ${shell} == "/dev/null" ]] ; then
663 eerror "Unable to identify the shell to use, proceeding with userland default."
664 case ${USERLAND} in
665 GNU) shell="/bin/false" ;;
666 BSD) shell="/sbin/nologin" ;;
667 Darwin) shell="/usr/sbin/nologin" ;;
668 *) die "Unable to identify the default shell for userland ${USERLAND}"
669 esac
670 fi
671
672 eshell=${shell}
673 fi
674 einfo " - Shell: ${eshell}"
675 opts="${opts} -s ${eshell}"
676
677 # handle homedir
678 local ehome=$1; shift
679 if [[ -z ${ehome} ]] || [[ ${ehome} == "-1" ]] ; then
680 ehome="/dev/null"
681 fi
682 einfo " - Home: ${ehome}"
683 opts="${opts} -d ${ehome}"
684
685 # handle groups
686 local egroups=$1; shift
687 if [[ ! -z ${egroups} ]] ; then
688 local oldifs=${IFS}
689 local defgroup="" exgroups=""
690
691 export IFS=","
692 for g in ${egroups} ; do
693 export IFS=${oldifs}
694 if [[ -z $(egetent group "${g}") ]] ; then
695 eerror "You must add group ${g} to the system first"
696 die "${g} is not a valid GID"
697 fi
698 if [[ -z ${defgroup} ]] ; then
699 defgroup=${g}
700 else
701 exgroups="${exgroups},${g}"
702 fi
703 export IFS=","
704 done
705 export IFS=${oldifs}
706
707 opts="${opts} -g ${defgroup}"
708 if [[ ! -z ${exgroups} ]] ; then
709 opts="${opts} -G ${exgroups:1}"
710 fi
711 else
712 egroups="(none)"
713 fi
714 einfo " - Groups: ${egroups}"
715
716 # handle extra and add the user
717 local oldsandbox=${SANDBOX_ON}
718 export SANDBOX_ON="0"
719 case ${CHOST} in
720 *-darwin*)
721 ### Make the user
722 if [[ -z $@ ]] ; then
723 dscl . create /users/${euser} uid ${euid}
724 dscl . create /users/${euser} shell ${eshell}
725 dscl . create /users/${euser} home ${ehome}
726 dscl . create /users/${euser} realname "added by portage for ${PN}"
727 ### Add the user to the groups specified
728 local oldifs=${IFS}
729 export IFS=","
730 for g in ${egroups} ; do
731 dscl . merge /groups/${g} users ${euser}
732 done
733 export IFS=${oldifs}
734 else
735 einfo "Extra options are not supported on Darwin yet"
736 einfo "Please report the ebuild along with the info below"
737 einfo "eextra: $@"
738 die "Required function missing"
739 fi
740 ;;
741 *-freebsd*|*-dragonfly*)
742 if [[ -z $@ ]] ; then
743 pw useradd ${euser} ${opts} \
744 -c "added by portage for ${PN}" \
745 die "enewuser failed"
746 else
747 einfo " - Extra: $@"
748 pw useradd ${euser} ${opts} \
749 "$@" || die "enewuser failed"
750 fi
751 ;;
752
753 *-netbsd*)
754 if [[ -z $@ ]] ; then
755 useradd ${opts} ${euser} || die "enewuser failed"
756 else
757 einfo " - Extra: $@"
758 useradd ${opts} ${euser} "$@" || die "enewuser failed"
759 fi
760 ;;
761
762 *-openbsd*)
763 if [[ -z $@ ]] ; then
764 useradd -u ${euid} -s ${eshell} \
765 -d ${ehome} -c "Added by portage for ${PN}" \
766 -g ${egroups} ${euser} || die "enewuser failed"
767 else
768 einfo " - Extra: $@"
769 useradd -u ${euid} -s ${eshell} \
770 -d ${ehome} -c "Added by portage for ${PN}" \
771 -g ${egroups} ${euser} "$@" || die "enewuser failed"
772 fi
773 ;;
774
775 *)
776 if [[ -z $@ ]] ; then
777 useradd -r ${opts} \
778 -c "added by portage for ${PN}" \
779 ${euser} \
780 || die "enewuser failed"
781 else
782 einfo " - Extra: $@"
783 useradd -r ${opts} "$@" \
784 ${euser} \
785 || die "enewuser failed"
786 fi
787 ;;
788 esac
789
790 if [[ ! -e ${ROOT}/${ehome} ]] ; then
791 einfo " - Creating ${ehome} in ${ROOT}"
792 mkdir -p "${ROOT}/${ehome}"
793 chown ${euser} "${ROOT}/${ehome}"
794 chmod 755 "${ROOT}/${ehome}"
795 fi
796
797 export SANDBOX_ON=${oldsandbox}
798}
799
800# @FUNCTION: enewgroup
801# @USAGE: <group> [gid]
802# @DESCRIPTION:
803# This function does not require you to understand how to properly add a
804# group to the system. Just give it a group name to add and enewgroup will
805# do the rest. You may specify the gid for the group or allow the group to
806# allocate the next available one.
807enewgroup() {
808 case ${EBUILD_PHASE} in
809 unpack|compile|test|install)
810 eerror "'enewgroup()' called from '${EBUILD_PHASE}()' which is not a pkg_* function."
811 eerror "Package fails at QA and at life. Please file a bug."
812 die "Bad package! enewgroup is only for use in pkg_* functions!"
813 esac
814
815 # get the group
816 local egroup="$1"; shift
817 if [ -z "${egroup}" ]
818 then
819 eerror "No group specified !"
820 die "Cannot call enewgroup without a group"
821 fi
822
823 # see if group already exists
824 if [[ -n $(egetent group "${egroup}") ]]; then
825 return 0
826 fi
827 einfo "Adding group '${egroup}' to your system ..."
828
829 # options to pass to useradd
830 local opts=
831
832 # handle gid
833 local egid="$1"; shift
834 if [ ! -z "${egid}" ]
835 then
836 if [ "${egid}" -gt 0 ]
837 then
838 if [ -z "`egetent group ${egid}`" ]
839 then
840 if [[ "${CHOST}" == *-darwin* ]]; then
841 opts="${opts} ${egid}"
842 else
843 opts="${opts} -g ${egid}"
844 fi
845 else
846 egid="next available; requested gid taken"
847 fi
848 else
849 eerror "Groupid given but is not greater than 0 !"
850 die "${egid} is not a valid GID"
851 fi
852 else
853 egid="next available"
854 fi
855 einfo " - Groupid: ${egid}"
856
857 # handle extra
858 local eextra="$@"
859 opts="${opts} ${eextra}"
860
861 # add the group
862 local oldsandbox="${SANDBOX_ON}"
863 export SANDBOX_ON="0"
864 case ${CHOST} in
865 *-darwin*)
866 if [ ! -z "${eextra}" ];
867 then
868 einfo "Extra options are not supported on Darwin/OS X yet"
869 einfo "Please report the ebuild along with the info below"
870 einfo "eextra: ${eextra}"
871 die "Required function missing"
872 fi
873
874 # If we need the next available
875 case ${egid} in
876 *[!0-9]*) # Non numeric
877 for ((egid = 101; egid <= 999; egid++)); do
878 [[ -z $(egetent group ${egid}) ]] && break
879 done
880 esac
881 dscl . create /groups/${egroup} gid ${egid}
882 dscl . create /groups/${egroup} passwd '*'
883 ;;
884
885 *-freebsd*|*-dragonfly*)
886 case ${egid} in
887 *[!0-9]*) # Non numeric
888 for ((egid = 101; egid <= 999; egid++)); do
889 [[ -z $(egetent group ${egid}) ]] && break
890 done
891 esac
892 pw groupadd ${egroup} -g ${egid} || die "enewgroup failed"
893 ;;
894
895 *-netbsd*)
896 case ${egid} in
897 *[!0-9]*) # Non numeric
898 for ((egid = 101; egid <= 999; egid++)); do
899 [[ -z $(egetent group ${egid}) ]] && break
900 done
901 esac
902 groupadd -g ${egid} ${egroup} || die "enewgroup failed"
903 ;;
904
905 *)
906 # We specify -r so that we get a GID in the system range from login.defs
907 groupadd -r ${opts} ${egroup} || die "enewgroup failed"
908 ;;
909 esac
910 export SANDBOX_ON="${oldsandbox}"
911}
912
913# @FUNCTION: edos2unix 639# @FUNCTION: edos2unix
914# @USAGE: <file> [more files ...] 640# @USAGE: <file> [more files ...]
915# @DESCRIPTION: 641# @DESCRIPTION:
916# A handy replacement for dos2unix, recode, fixdos, etc... This allows you 642# A handy replacement for dos2unix, recode, fixdos, etc... This allows you
917# to remove all of these text utilities from DEPEND variables because this 643# to remove all of these text utilities from DEPEND variables because this
918# is a script based solution. Just give it a list of files to convert and 644# is a script based solution. Just give it a list of files to convert and
919# they will all be changed from the DOS CRLF format to the UNIX LF format. 645# they will all be changed from the DOS CRLF format to the UNIX LF format.
920edos2unix() { 646edos2unix() {
921 echo "$@" | xargs sed -i 's/\r$//' 647 [[ $# -eq 0 ]] && return 0
648 sed -i 's/\r$//' -- "$@" || die
922} 649}
923 650
924# Make a desktop file ! 651# @FUNCTION: make_desktop_entry
925# Great for making those icons in kde/gnome startmenu !
926# Amaze your friends ! Get the women ! Join today !
927#
928# make_desktop_entry(<command>, [name], [icon], [type], [fields]) 652# @USAGE: make_desktop_entry(<command>, [name], [icon], [type], [fields])
653# @DESCRIPTION:
654# Make a .desktop file.
929# 655#
656# @CODE
930# binary: what command does the app run with ? 657# binary: what command does the app run with ?
931# name: the name that will show up in the menu 658# name: the name that will show up in the menu
932# icon: give your little like a pretty little icon ... 659# icon: the icon to use in the menu entry
933# this can be relative (to /usr/share/pixmaps) or 660# this can be relative (to /usr/share/pixmaps) or
934# a full path to an icon 661# a full path to an icon
935# type: what kind of application is this ? for categories: 662# type: what kind of application is this?
663# for categories:
936# http://standards.freedesktop.org/menu-spec/latest/apa.html 664# http://standards.freedesktop.org/menu-spec/latest/apa.html
665# if unset, function tries to guess from package's category
937# fields: extra fields to append to the desktop file; a printf string 666# fields: extra fields to append to the desktop file; a printf string
667# @CODE
938make_desktop_entry() { 668make_desktop_entry() {
939 [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable" 669 [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
940 670
941 local exec=${1} 671 local exec=${1}
942 local name=${2:-${PN}} 672 local name=${2:-${PN}}
948 local catmaj=${CATEGORY%%-*} 678 local catmaj=${CATEGORY%%-*}
949 local catmin=${CATEGORY##*-} 679 local catmin=${CATEGORY##*-}
950 case ${catmaj} in 680 case ${catmaj} in
951 app) 681 app)
952 case ${catmin} in 682 case ${catmin} in
953 accessibility) type=Accessibility;; 683 accessibility) type="Utility;Accessibility";;
954 admin) type=System;; 684 admin) type=System;;
955 antivirus) type=System;; 685 antivirus) type=System;;
956 arch) type=Archiving;; 686 arch) type="Utility;Archiving";;
957 backup) type=Archiving;; 687 backup) type="Utility;Archiving";;
958 cdr) type=DiscBurning;; 688 cdr) type="AudioVideo;DiscBurning";;
959 dicts) type=Dictionary;; 689 dicts) type="Office;Dictionary";;
960 doc) type=Documentation;; 690 doc) type=Documentation;;
961 editors) type=TextEditor;; 691 editors) type="Utility;TextEditor";;
962 emacs) type=TextEditor;; 692 emacs) type="Development;TextEditor";;
963 emulation) type=Emulator;; 693 emulation) type="System;Emulator";;
964 laptop) type=HardwareSettings;; 694 laptop) type="Settings;HardwareSettings";;
965 office) type=Office;; 695 office) type=Office;;
966 pda) type=PDA;; 696 pda) type="Office;PDA";;
967 vim) type=TextEditor;; 697 vim) type="Development;TextEditor";;
968 xemacs) type=TextEditor;; 698 xemacs) type="Development;TextEditor";;
969 esac 699 esac
970 ;; 700 ;;
971 701
972 dev) 702 dev)
973 type="Development" 703 type="Development"
1210 insinto /usr/share/applications 940 insinto /usr/share/applications
1211 newins "$@" 941 newins "$@"
1212 ) 942 )
1213} 943}
1214 944
1215# @FUNCTION: doicon 945# @FUNCTION: _iconins
1216# @USAGE: <list of icons> 946# @INTERNAL
1217# @DESCRIPTION: 947# @DESCRIPTION:
1218# Install the list of icons into the icon directory (/usr/share/pixmaps). 948# function for use in doicon and newicon
1219# This is useful in conjunction with creating desktop/menu files. 949_iconins() {
1220doicon() {
1221 ( 950 (
1222 # wrap the env here so that the 'insinto' call 951 # wrap the env here so that the 'insinto' call
1223 # doesn't corrupt the env of the caller 952 # doesn't corrupt the env of the caller
1224 local i j ret 953 local funcname=$1; shift
1225 insinto /usr/share/pixmaps 954 local size dir
1226 for i in "$@" ; do 955 local context=apps
1227 if [[ -f ${i} ]] ; then 956 local theme=hicolor
1228 doins "${i}" 957
1229 ((ret+=$?)) 958 while [[ $# -gt 0 ]] ; do
1230 elif [[ -d ${i} ]] ; then 959 case $1 in
1231 for j in "${i}"/*.png ; do 960 -s|--size)
1232 doins "${j}" 961 if [[ ${2%%x*}x${2%%x*} == "$2" ]] ; then
1233 ((ret+=$?)) 962 size=${2%%x*}
1234 done
1235 else 963 else
1236 ((++ret)) 964 size=${2}
1237 fi 965 fi
1238 done
1239 exit ${ret}
1240 )
1241}
1242
1243# @FUNCTION: newicon
1244# @USAGE: <icon> <newname>
1245# @DESCRIPTION:
1246# Like all other new* functions, install the specified icon as newname.
1247newicon() {
1248 (
1249 # wrap the env here so that the 'insinto' call
1250 # doesn't corrupt the env of the caller
1251 insinto /usr/share/pixmaps
1252 newins "$@"
1253 )
1254}
1255
1256# for internal use only (unpack_pdv and unpack_makeself)
1257find_unpackable_file() {
1258 local src=$1
1259 if [[ -z ${src} ]] ; then
1260 src=${DISTDIR}/${A}
1261 else
1262 if [[ -e ${DISTDIR}/${src} ]] ; then
1263 src=${DISTDIR}/${src}
1264 elif [[ -e ${PWD}/${src} ]] ; then
1265 src=${PWD}/${src}
1266 elif [[ -e ${src} ]] ; then
1267 src=${src}
1268 fi
1269 fi
1270 [[ ! -e ${src} ]] && return 1
1271 echo "${src}"
1272}
1273
1274# @FUNCTION: unpack_pdv
1275# @USAGE: <file to unpack> <size of off_t>
1276# @DESCRIPTION:
1277# Unpack those pesky pdv generated files ...
1278# They're self-unpacking programs with the binary package stuffed in
1279# the middle of the archive. Valve seems to use it a lot ... too bad
1280# it seems to like to segfault a lot :(. So lets take it apart ourselves.
1281#
1282# You have to specify the off_t size ... I have no idea how to extract that
1283# information out of the binary executable myself. Basically you pass in
1284# the size of the off_t type (in bytes) on the machine that built the pdv
1285# archive.
1286#
1287# One way to determine this is by running the following commands:
1288#
1289# @CODE
1290# strings <pdv archive> | grep lseek
1291# strace -elseek <pdv archive>
1292# @CODE
1293#
1294# Basically look for the first lseek command (we do the strings/grep because
1295# sometimes the function call is _llseek or something) and steal the 2nd
1296# parameter. Here is an example:
1297#
1298# @CODE
1299# vapier@vapier 0 pdv_unpack # strings hldsupdatetool.bin | grep lseek
1300# lseek
1301# vapier@vapier 0 pdv_unpack # strace -elseek ./hldsupdatetool.bin
1302# lseek(3, -4, SEEK_END) = 2981250
1303# @CODE
1304#
1305# Thus we would pass in the value of '4' as the second parameter.
1306unpack_pdv() {
1307 local src=$(find_unpackable_file "$1")
1308 local sizeoff_t=$2
1309
1310 [[ -z ${src} ]] && die "Could not locate source for '$1'"
1311 [[ -z ${sizeoff_t} ]] && die "No idea what off_t size was used for this pdv :("
1312
1313 local shrtsrc=$(basename "${src}")
1314 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1315 local metaskip=$(tail -c ${sizeoff_t} "${src}" | hexdump -e \"%i\")
1316 local tailskip=$(tail -c $((${sizeoff_t}*2)) "${src}" | head -c ${sizeoff_t} | hexdump -e \"%i\")
1317
1318 # grab metadata for debug reasons
1319 local metafile=$(emktemp)
1320 tail -c +$((${metaskip}+1)) "${src}" > "${metafile}"
1321
1322 # rip out the final file name from the metadata
1323 local datafile=$(tail -c +$((${metaskip}+1)) "${src}" | strings | head -n 1)
1324 datafile=$(basename "${datafile}")
1325
1326 # now lets uncompress/untar the file if need be
1327 local tmpfile=$(emktemp)
1328 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null | head -c 512 > ${tmpfile}
1329
1330 local iscompressed=$(file -b "${tmpfile}")
1331 if [[ ${iscompressed:0:8} == "compress" ]] ; then
1332 iscompressed=1
1333 mv ${tmpfile}{,.Z}
1334 gunzip ${tmpfile}
1335 else
1336 iscompressed=0
1337 fi
1338 local istar=$(file -b "${tmpfile}")
1339 if [[ ${istar:0:9} == "POSIX tar" ]] ; then
1340 istar=1
1341 else
1342 istar=0
1343 fi
1344
1345 #for some reason gzip dies with this ... dd cant provide buffer fast enough ?
1346 #dd if=${src} ibs=${metaskip} count=1 \
1347 # | dd ibs=${tailskip} skip=1 \
1348 # | gzip -dc \
1349 # > ${datafile}
1350 if [ ${iscompressed} -eq 1 ] ; then
1351 if [ ${istar} -eq 1 ] ; then
1352 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1353 | head -c $((${metaskip}-${tailskip})) \
1354 | tar -xzf -
1355 else
1356 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1357 | head -c $((${metaskip}-${tailskip})) \
1358 | gzip -dc \
1359 > ${datafile}
1360 fi
1361 else
1362 if [ ${istar} -eq 1 ] ; then
1363 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1364 | head -c $((${metaskip}-${tailskip})) \
1365 | tar --no-same-owner -xf -
1366 else
1367 tail -c +$((${tailskip}+1)) ${src} 2>/dev/null \
1368 | head -c $((${metaskip}-${tailskip})) \
1369 > ${datafile}
1370 fi
1371 fi
1372 true
1373 #[ -s "${datafile}" ] || die "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1374 #assert "failure unpacking pdv ('${metaskip}' '${tailskip}' '${datafile}')"
1375}
1376
1377# @FUNCTION: unpack_makeself
1378# @USAGE: [file to unpack] [offset] [tail|dd]
1379# @DESCRIPTION:
1380# Unpack those pesky makeself generated files ...
1381# They're shell scripts with the binary package tagged onto
1382# the end of the archive. Loki utilized the format as does
1383# many other game companies.
1384#
1385# If the file is not specified, then ${A} is used. If the
1386# offset is not specified then we will attempt to extract
1387# the proper offset from the script itself.
1388unpack_makeself() {
1389 local src_input=${1:-${A}}
1390 local src=$(find_unpackable_file "${src_input}")
1391 local skip=$2
1392 local exe=$3
1393
1394 [[ -z ${src} ]] && die "Could not locate source for '${src_input}'"
1395
1396 local shrtsrc=$(basename "${src}")
1397 echo ">>> Unpacking ${shrtsrc} to ${PWD}"
1398 if [[ -z ${skip} ]] ; then
1399 local ver=$(grep -m1 -a '#.*Makeself' "${src}" | awk '{print $NF}')
1400 local skip=0
1401 exe=tail
1402 case ${ver} in 966 case ${size} in
1403 1.5.*|1.6.0-nv) # tested 1.5.{3,4,5} ... guessing 1.5.x series is same 967 16|22|24|32|36|48|64|72|96|128|192|256)
1404 skip=$(grep -a ^skip= "${src}" | cut -d= -f2) 968 size=${size}x${size};;
1405 ;; 969 scalable)
1406 2.0|2.0.1)
1407 skip=$(grep -a ^$'\t'tail "${src}" | awk '{print $2}' | cut -b2-)
1408 ;;
1409 2.1.1)
1410 skip=$(grep -a ^offset= "${src}" | awk '{print $2}' | cut -b2-)
1411 (( skip++ ))
1412 ;;
1413 2.1.2)
1414 skip=$(grep -a ^offset= "${src}" | awk '{print $3}' | head -n 1)
1415 (( skip++ ))
1416 ;;
1417 2.1.3)
1418 skip=`grep -a ^offset= "${src}" | awk '{print $3}'`
1419 (( skip++ ))
1420 ;;
1421 2.1.4|2.1.5)
1422 skip=$(grep -a offset=.*head.*wc "${src}" | awk '{print $3}' | head -n 1)
1423 skip=$(head -n ${skip} "${src}" | wc -c)
1424 exe="dd"
1425 ;; 970 ;;
1426 *) 971 *)
1427 eerror "I'm sorry, but I was unable to support the Makeself file." 972 eerror "${size} is an unsupported icon size!"
1428 eerror "The version I detected was '${ver}'." 973 exit 1;;
1429 eerror "Please file a bug about the file ${shrtsrc} at"
1430 eerror "http://bugs.gentoo.org/ so that support can be added."
1431 die "makeself version '${ver}' not supported"
1432 ;;
1433 esac 974 esac
1434 debug-print "Detected Makeself version ${ver} ... using ${skip} as offset" 975 shift 2;;
1435 fi 976 -t|--theme)
1436 case ${exe} in 977 theme=${2}
1437 tail) exe="tail -n +${skip} '${src}'";; 978 shift 2;;
1438 dd) exe="dd ibs=${skip} skip=1 if='${src}'";; 979 -c|--context)
1439 *) die "makeself cant handle exe '${exe}'" 980 context=${2}
1440 esac 981 shift 2;;
1441
1442 # lets grab the first few bytes of the file to figure out what kind of archive it is
1443 local filetype tmpfile=$(emktemp)
1444 eval ${exe} 2>/dev/null | head -c 512 > "${tmpfile}"
1445 filetype=$(file -b "${tmpfile}") || die
1446 case ${filetype} in
1447 *tar\ archive*)
1448 eval ${exe} | tar --no-same-owner -xf -
1449 ;;
1450 bzip2*)
1451 eval ${exe} | bzip2 -dc | tar --no-same-owner -xf -
1452 ;;
1453 gzip*)
1454 eval ${exe} | tar --no-same-owner -xzf -
1455 ;;
1456 compress*)
1457 eval ${exe} | gunzip | tar --no-same-owner -xf -
1458 ;;
1459 *) 982 *)
1460 eerror "Unknown filetype \"${filetype}\" ?"
1461 false
1462 ;;
1463 esac
1464 assert "failure unpacking (${filetype}) makeself ${shrtsrc} ('${ver}' +${skip})"
1465}
1466
1467# @FUNCTION: check_license
1468# @USAGE: [license]
1469# @DESCRIPTION:
1470# Display a license for user to accept. If no license is
1471# specified, then ${LICENSE} is used.
1472check_license() {
1473 local lic=$1
1474 if [ -z "${lic}" ] ; then
1475 lic="${PORTDIR}/licenses/${LICENSE}"
1476 else
1477 if [ -e "${PORTDIR}/licenses/${lic}" ] ; then
1478 lic="${PORTDIR}/licenses/${lic}"
1479 elif [ -e "${PWD}/${lic}" ] ; then
1480 lic="${PWD}/${lic}"
1481 elif [ -e "${lic}" ] ; then
1482 lic="${lic}"
1483 fi
1484 fi
1485 local l="`basename ${lic}`"
1486
1487 # here is where we check for the licenses the user already
1488 # accepted ... if we don't find a match, we make the user accept
1489 local alic
1490 eshopts_push -o noglob # so that bash doesn't expand "*"
1491 for alic in ${ACCEPT_LICENSE} ; do
1492 if [[ ${alic} == ${l} ]]; then
1493 eshopts_pop
1494 return 0
1495 fi
1496 done
1497 eshopts_pop
1498 [ ! -f "${lic}" ] && die "Could not find requested license ${lic}"
1499
1500 local licmsg=$(emktemp)
1501 cat <<-EOF > ${licmsg}
1502 **********************************************************
1503 The following license outlines the terms of use of this
1504 package. You MUST accept this license for installation to
1505 continue. When you are done viewing, hit 'q'. If you
1506 CTRL+C out of this, the install will not run!
1507 **********************************************************
1508
1509 EOF
1510 cat ${lic} >> ${licmsg}
1511 ${PAGER:-less} ${licmsg} || die "Could not execute pager (${PAGER}) to accept ${lic}"
1512 einfon "Do you accept the terms of this license (${l})? [yes/no] "
1513 read alic
1514 case ${alic} in
1515 yes|Yes|y|Y)
1516 return 0
1517 ;;
1518 *)
1519 echo;echo;echo
1520 eerror "You MUST accept the license to continue! Exiting!"
1521 die "Failed to accept license"
1522 ;;
1523 esac
1524}
1525
1526# @FUNCTION: cdrom_get_cds
1527# @USAGE: <file on cd1> [file on cd2] [file on cd3] [...]
1528# @DESCRIPTION:
1529# Aquire cd(s) for those lovely cd-based emerges. Yes, this violates
1530# the whole 'non-interactive' policy, but damnit I want CD support !
1531#
1532# With these cdrom functions we handle all the user interaction and
1533# standardize everything. All you have to do is call cdrom_get_cds()
1534# and when the function returns, you can assume that the cd has been
1535# found at CDROM_ROOT.
1536#
1537# The function will attempt to locate a cd based upon a file that is on
1538# the cd. The more files you give this function, the more cds
1539# the cdrom functions will handle.
1540#
1541# Normally the cdrom functions will refer to the cds as 'cd #1', 'cd #2',
1542# etc... If you want to give the cds better names, then just export
1543# the appropriate CDROM_NAME variable before calling cdrom_get_cds().
1544# Use CDROM_NAME for one cd, or CDROM_NAME_# for multiple cds. You can
1545# also use the CDROM_NAME_SET bash array.
1546#
1547# For those multi cd ebuilds, see the cdrom_load_next_cd() function.
1548cdrom_get_cds() {
1549 # first we figure out how many cds we're dealing with by
1550 # the # of files they gave us
1551 local cdcnt=0
1552 local f=
1553 for f in "$@" ; do
1554 ((++cdcnt))
1555 export CDROM_CHECK_${cdcnt}="$f"
1556 done
1557 export CDROM_TOTAL_CDS=${cdcnt}
1558 export CDROM_CURRENT_CD=1
1559
1560 # now we see if the user gave use CD_ROOT ...
1561 # if they did, let's just believe them that it's correct
1562 if [[ -n ${CD_ROOT}${CD_ROOT_1} ]] ; then
1563 local var=
1564 cdcnt=0
1565 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1566 ((++cdcnt))
1567 var="CD_ROOT_${cdcnt}"
1568 [[ -z ${!var} ]] && var="CD_ROOT"
1569 if [[ -z ${!var} ]] ; then 983 if [[ -z ${size} ]] ; then
1570 eerror "You must either use just the CD_ROOT" 984 insinto /usr/share/pixmaps
1571 eerror "or specify ALL the CD_ROOT_X variables." 985 else
1572 eerror "In this case, you will need ${CDROM_TOTAL_CDS} CD_ROOT_X variables." 986 insinto /usr/share/icons/${theme}/${size}/${context}
1573 die "could not locate CD_ROOT_${cdcnt}"
1574 fi 987 fi
1575 done
1576 export CDROM_ROOT=${CD_ROOT_1:-${CD_ROOT}}
1577 einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1578 export CDROM_SET=-1
1579 for f in ${CDROM_CHECK_1//:/ } ; do
1580 ((++CDROM_SET))
1581 [[ -e ${CDROM_ROOT}/${f} ]] && break
1582 done
1583 export CDROM_MATCH=${f}
1584 return
1585 fi
1586 988
1587 # User didn't help us out so lets make sure they know they can 989 if [[ ${funcname} == doicon ]] ; then
1588 # simplify the whole process ...
1589 if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1590 einfo "This ebuild will need the ${CDROM_NAME:-cdrom for ${PN}}"
1591 echo
1592 einfo "If you do not have the CD, but have the data files"
1593 einfo "mounted somewhere on your filesystem, just export"
1594 einfo "the variable CD_ROOT so that it points to the"
1595 einfo "directory containing the files."
1596 echo
1597 einfo "For example:"
1598 einfo "export CD_ROOT=/mnt/cdrom"
1599 echo
1600 else
1601 if [[ -n ${CDROM_NAME_SET} ]] ; then
1602 # Translate the CDROM_NAME_SET array into CDROM_NAME_#
1603 cdcnt=0
1604 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1605 ((++cdcnt))
1606 export CDROM_NAME_${cdcnt}="${CDROM_NAME_SET[$((${cdcnt}-1))]}"
1607 done
1608 fi
1609
1610 einfo "This package will need access to ${CDROM_TOTAL_CDS} cds."
1611 cdcnt=0
1612 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1613 ((++cdcnt))
1614 var="CDROM_NAME_${cdcnt}"
1615 [[ ! -z ${!var} ]] && einfo " CD ${cdcnt}: ${!var}"
1616 done
1617 echo
1618 einfo "If you do not have the CDs, but have the data files"
1619 einfo "mounted somewhere on your filesystem, just export"
1620 einfo "the following variables so they point to the right place:"
1621 einfon ""
1622 cdcnt=0
1623 while [[ ${cdcnt} -lt ${CDROM_TOTAL_CDS} ]] ; do
1624 ((++cdcnt))
1625 echo -n " CD_ROOT_${cdcnt}"
1626 done
1627 echo
1628 einfo "Or, if you have all the files in the same place, or"
1629 einfo "you only have one cdrom, you can export CD_ROOT"
1630 einfo "and that place will be used as the same data source"
1631 einfo "for all the CDs."
1632 echo
1633 einfo "For example:"
1634 einfo "export CD_ROOT_1=/mnt/cdrom"
1635 echo
1636 fi
1637
1638 export CDROM_SET=""
1639 export CDROM_CURRENT_CD=0
1640 cdrom_load_next_cd
1641}
1642
1643# @FUNCTION: cdrom_load_next_cd
1644# @DESCRIPTION:
1645# Some packages are so big they come on multiple CDs. When you're done reading
1646# files off a CD and want access to the next one, just call this function.
1647# Again, all the messy details of user interaction are taken care of for you.
1648# Once this returns, just read the variable CDROM_ROOT for the location of the
1649# mounted CD. Note that you can only go forward in the CD list, so make sure
1650# you only call this function when you're done using the current CD.
1651cdrom_load_next_cd() {
1652 local var
1653 ((++CDROM_CURRENT_CD))
1654
1655 unset CDROM_ROOT
1656 var=CD_ROOT_${CDROM_CURRENT_CD}
1657 [[ -z ${!var} ]] && var="CD_ROOT"
1658 if [[ -z ${!var} ]] ; then 990 if [[ -f $1 ]] ; then
1659 var="CDROM_CHECK_${CDROM_CURRENT_CD}" 991 doins "${1}"
1660 _cdrom_locate_file_on_cd ${!var} 992 elif [[ -d $1 ]] ; then
1661 else 993 shopt -s nullglob
1662 export CDROM_ROOT=${!var} 994 doins "${1}"/*.{png,svg}
1663 fi 995 shopt -u nullglob
1664
1665 einfo "Found CD #${CDROM_CURRENT_CD} root at ${CDROM_ROOT}"
1666}
1667
1668# this is used internally by the cdrom_get_cds() and cdrom_load_next_cd()
1669# functions. this should *never* be called from an ebuild.
1670# all it does is try to locate a give file on a cd ... if the cd isn't
1671# found, then a message asking for the user to insert the cdrom will be
1672# displayed and we'll hang out here until:
1673# (1) the file is found on a mounted cdrom
1674# (2) the user hits CTRL+C
1675_cdrom_locate_file_on_cd() {
1676 local mline=""
1677 local showedmsg=0 showjolietmsg=0
1678
1679 while [[ -z ${CDROM_ROOT} ]] ; do
1680 local i=0
1681 local -a cdset=(${*//:/ })
1682 if [[ -n ${CDROM_SET} ]] ; then
1683 cdset=(${cdset[${CDROM_SET}]})
1684 fi
1685
1686 while [[ -n ${cdset[${i}]} ]] ; do
1687 local dir=$(dirname ${cdset[${i}]})
1688 local file=$(basename ${cdset[${i}]})
1689
1690 local point= node= fs= foo=
1691 while read point node fs foo ; do
1692 [[ " cd9660 iso9660 udf " != *" ${fs} "* ]] && \
1693 ! [[ ${fs} == "subfs" && ",${opts}," == *",fs=cdfss,"* ]] \
1694 && continue
1695 point=${point//\040/ }
1696 [[ ! -d ${point}/${dir} ]] && continue
1697 [[ -z $(find "${point}/${dir}" -maxdepth 1 -iname "${file}") ]] && continue
1698 export CDROM_ROOT=${point}
1699 export CDROM_SET=${i}
1700 export CDROM_MATCH=${cdset[${i}]}
1701 return
1702 done <<< "$(get_mounts)"
1703
1704 ((++i))
1705 done
1706
1707 echo
1708 if [[ ${showedmsg} -eq 0 ]] ; then
1709 if [[ ${CDROM_TOTAL_CDS} -eq 1 ]] ; then
1710 if [[ -z ${CDROM_NAME} ]] ; then
1711 einfo "Please insert+mount the cdrom for ${PN} now !"
1712 else 996 else
1713 einfo "Please insert+mount the ${CDROM_NAME} cdrom now !" 997 eerror "${1} is not a valid file/directory!"
998 exit 1
1714 fi 999 fi
1715 else 1000 else
1716 if [[ -z ${CDROM_NAME_1} ]] ; then 1001 break
1717 einfo "Please insert+mount cd #${CDROM_CURRENT_CD} for ${PN} now !"
1718 else
1719 local var="CDROM_NAME_${CDROM_CURRENT_CD}"
1720 einfo "Please insert+mount the ${!var} cdrom now !"
1721 fi
1722 fi 1002 fi
1723 showedmsg=1 1003 shift 1;;
1724 fi 1004 esac
1725 einfo "Press return to scan for the cd again"
1726 einfo "or hit CTRL+C to abort the emerge."
1727 echo
1728 if [[ ${showjolietmsg} -eq 0 ]] ; then
1729 showjolietmsg=1
1730 else
1731 ewarn "If you are having trouble with the detection"
1732 ewarn "of your CD, it is possible that you do not have"
1733 ewarn "Joliet support enabled in your kernel. Please"
1734 ewarn "check that CONFIG_JOLIET is enabled in your kernel."
1735 ebeep 5
1736 fi
1737 read || die "something is screwed with your system"
1738 done 1005 done
1006 if [[ ${funcname} == newicon ]] ; then
1007 newins "$@"
1008 fi
1009 ) || die
1010}
1011
1012# @FUNCTION: doicon
1013# @USAGE: [options] <icons>
1014# @DESCRIPTION:
1015# Install icon into the icon directory /usr/share/icons or into
1016# /usr/share/pixmaps if "--size" is not set.
1017# This is useful in conjunction with creating desktop/menu files.
1018#
1019# @CODE
1020# options:
1021# -s, --size
1022# !!! must specify to install into /usr/share/icons/... !!!
1023# size of the icon, like 48 or 48x48
1024# supported icon sizes are:
1025# 16 22 24 32 36 48 64 72 96 128 192 256 scalable
1026# -c, --context
1027# defaults to "apps"
1028# -t, --theme
1029# defaults to "hicolor"
1030#
1031# icons: list of icons
1032#
1033# example 1: doicon foobar.png fuqbar.svg suckbar.png
1034# results in: insinto /usr/share/pixmaps
1035# doins foobar.png fuqbar.svg suckbar.png
1036#
1037# example 2: doicon -s 48 foobar.png fuqbar.png blobbar.png
1038# results in: insinto /usr/share/icons/hicolor/48x48/apps
1039# doins foobar.png fuqbar.png blobbar.png
1040# @CODE
1041doicon() {
1042 _iconins ${FUNCNAME} "$@"
1043}
1044
1045# @FUNCTION: newicon
1046# @USAGE: [options] <icon> <newname>
1047# @DESCRIPTION:
1048# Like doicon, install the specified icon as newname.
1049#
1050# @CODE
1051# example 1: newicon foobar.png NEWNAME.png
1052# results in: insinto /usr/share/pixmaps
1053# newins foobar.png NEWNAME.png
1054#
1055# example 2: newicon -s 48 foobar.png NEWNAME.png
1056# results in: insinto /usr/share/icons/hicolor/48x48/apps
1057# newins foobar.png NEWNAME.png
1058# @CODE
1059newicon() {
1060 _iconins ${FUNCNAME} "$@"
1739} 1061}
1740 1062
1741# @FUNCTION: strip-linguas 1063# @FUNCTION: strip-linguas
1742# @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>] 1064# @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>]
1743# @DESCRIPTION: 1065# @DESCRIPTION:
1781 else 1103 else
1782 nols="${nols} ${f}" 1104 nols="${nols} ${f}"
1783 fi 1105 fi
1784 done 1106 done
1785 [[ -n ${nols} ]] \ 1107 [[ -n ${nols} ]] \
1786 && ewarn "Sorry, but ${PN} does not support the LINGUAS:" ${nols} 1108 && einfo "Sorry, but ${PN} does not support the LINGUAS:" ${nols}
1787 export LINGUAS=${newls:1} 1109 export LINGUAS=${newls:1}
1788} 1110}
1789 1111
1790# @FUNCTION: preserve_old_lib 1112# @FUNCTION: preserve_old_lib
1791# @USAGE: <libs to preserve> [more libs] 1113# @USAGE: <libs to preserve> [more libs]
1839 ewarn "the libraries are not being removed. You need to run revdep-rebuild" 1161 ewarn "the libraries are not being removed. You need to run revdep-rebuild"
1840 ewarn "in order to remove these old dependencies. If you do not have this" 1162 ewarn "in order to remove these old dependencies. If you do not have this"
1841 ewarn "helper program, simply emerge the 'gentoolkit' package." 1163 ewarn "helper program, simply emerge the 'gentoolkit' package."
1842 ewarn 1164 ewarn
1843 fi 1165 fi
1844 # temp hack for #348634 #357225
1845 [[ ${PN} == "mpfr" ]] && lib=${lib##*/}
1846 ewarn " # revdep-rebuild --library '${lib}'" 1166 ewarn " # revdep-rebuild --library '${lib}' && rm '${lib}'"
1847 done 1167 done
1848 if [[ ${notice} -eq 1 ]] ; then
1849 ewarn
1850 ewarn "Once you've finished running revdep-rebuild, it should be safe to"
1851 ewarn "delete the old libraries. Here is a copy & paste for the lazy:"
1852 for lib in "$@" ; do
1853 ewarn " # rm '${lib}'"
1854 done
1855 fi
1856} 1168}
1857 1169
1858# @FUNCTION: built_with_use 1170# @FUNCTION: built_with_use
1859# @USAGE: [--hidden] [--missing <action>] [-a|-o] <DEPEND ATOM> <List of USE flags> 1171# @USAGE: [--hidden] [--missing <action>] [-a|-o] <DEPEND ATOM> <List of USE flags>
1860# @DESCRIPTION: 1172# @DESCRIPTION:
1955# http://bugs.gentoo.org/73450 1267# http://bugs.gentoo.org/73450
1956epunt_cxx() { 1268epunt_cxx() {
1957 local dir=$1 1269 local dir=$1
1958 [[ -z ${dir} ]] && dir=${S} 1270 [[ -z ${dir} ]] && dir=${S}
1959 ebegin "Removing useless C++ checks" 1271 ebegin "Removing useless C++ checks"
1960 local f 1272 local f any_found
1961 find "${dir}" -name configure | while read f ; do 1273 while IFS= read -r -d '' f; do
1962 patch --no-backup-if-mismatch -p0 "${f}" "${PORTDIR}/eclass/ELT-patches/nocxx/nocxx.patch" > /dev/null 1274 patch --no-backup-if-mismatch -p0 "${f}" \
1963 done 1275 "${PORTDIR}/eclass/ELT-patches/nocxx/nocxx.patch" > /dev/null \
1276 && any_found=1
1277 done < <(find "${dir}" -name configure -print0)
1278
1279# if [[ -z ${any_found} ]]; then
1280# eqawarn "epunt_cxx called unnecessarily (no C++ checks to punt)."
1281# fi
1964 eend 0 1282 eend 0
1965} 1283}
1966 1284
1967# @FUNCTION: make_wrapper 1285# @FUNCTION: make_wrapper
1968# @USAGE: <wrapper> <target> [chdir] [libpaths] [installpath] 1286# @USAGE: <wrapper> <target> [chdir] [libpaths] [installpath]
2025 case ${opt} in 1343 case ${opt} in
2026 -a) return $(( r != 0 )) ;; 1344 -a) return $(( r != 0 )) ;;
2027 -o) return $(( r == $# )) ;; 1345 -o) return $(( r == $# )) ;;
2028 esac 1346 esac
2029} 1347}
1348
1349# @FUNCTION: in_iuse
1350# @USAGE: <flag>
1351# @DESCRIPTION:
1352# Determines whether the given flag is in IUSE. Strips IUSE default prefixes
1353# as necessary.
1354#
1355# Note that this function should not be used in the global scope.
1356in_iuse() {
1357 debug-print-function ${FUNCNAME} "${@}"
1358 [[ ${#} -eq 1 ]] || die "Invalid args to ${FUNCNAME}()"
1359
1360 local flag=${1}
1361 local liuse=( ${IUSE} )
1362
1363 has "${flag}" "${liuse[@]#[+-]}"
1364}
1365
1366# @FUNCTION: use_if_iuse
1367# @USAGE: <flag>
1368# @DESCRIPTION:
1369# Return true if the given flag is in USE and IUSE.
1370#
1371# Note that this function should not be used in the global scope.
1372use_if_iuse() {
1373 in_iuse $1 || return 1
1374 use $1
1375}
1376
1377# @FUNCTION: usex
1378# @USAGE: <USE flag> [true output] [false output] [true suffix] [false suffix]
1379# @DESCRIPTION:
1380# Proxy to declare usex for package managers or EAPIs that do not provide it
1381# and use the package manager implementation when available (i.e. EAPI >= 5).
1382# If USE flag is set, echo [true output][true suffix] (defaults to "yes"),
1383# otherwise echo [false output][false suffix] (defaults to "no").
1384if has "${EAPI:-0}" 0 1 2 3 4; then
1385 usex() { use "$1" && echo "${2-yes}$4" || echo "${3-no}$5" ; } #382963
1386fi
1387
1388# @FUNCTION: prune_libtool_files
1389# @USAGE: [--all|--modules]
1390# @DESCRIPTION:
1391# Locate unnecessary libtool files (.la) and libtool static archives
1392# (.a) and remove them from installation image.
1393#
1394# By default, .la files are removed whenever the static linkage can
1395# either be performed using pkg-config or doesn't introduce additional
1396# flags.
1397#
1398# If '--modules' argument is passed, .la files for modules (plugins) are
1399# removed as well. This is usually useful when the package installs
1400# plugins and the plugin loader does not use .la files.
1401#
1402# If '--all' argument is passed, all .la files are removed without
1403# performing any heuristic on them. You shouldn't ever use that,
1404# and instead report a bug in the algorithm instead.
1405#
1406# The .a files are only removed whenever corresponding .la files state
1407# that they should not be linked to, i.e. whenever these files
1408# correspond to plugins.
1409#
1410# Note: if your package installs both static libraries and .pc files
1411# which use variable substitution for -l flags, you need to add
1412# pkg-config to your DEPEND.
1413prune_libtool_files() {
1414 debug-print-function ${FUNCNAME} "$@"
1415
1416 local removing_all removing_modules opt
1417 for opt; do
1418 case "${opt}" in
1419 --all)
1420 removing_all=1
1421 removing_modules=1
1422 ;;
1423 --modules)
1424 removing_modules=1
1425 ;;
1426 *)
1427 die "Invalid argument to ${FUNCNAME}(): ${opt}"
1428 esac
1429 done
1430
1431 local f
1432 local queue=()
1433 while IFS= read -r -d '' f; do # for all .la files
1434 local archivefile=${f/%.la/.a}
1435
1436 [[ ${f} != ${archivefile} ]] || die 'regex sanity check failed'
1437
1438 local reason pkgconfig_scanned
1439
1440 # Remove static libs we're not supposed to link against.
1441 if grep -q '^shouldnotlink=yes$' "${f}"; then
1442 if [[ -f ${archivefile} ]]; then
1443 einfo "Removing unnecessary ${archivefile#${D%/}} (static plugin)"
1444 queue+=( "${archivefile}" )
1445 fi
1446
1447 # The .la file may be used by a module loader, so avoid removing it
1448 # unless explicitly requested.
1449 if [[ ${removing_modules} ]]; then
1450 reason='module'
1451 fi
1452
1453 # Remove .la files when:
1454 # - user explicitly wants us to remove all .la files,
1455 # - respective static archive doesn't exist,
1456 # - they are covered by a .pc file already,
1457 # - they don't provide any new information (no libs & no flags).
1458
1459 elif [[ ${removing_all} ]]; then
1460 reason='requested'
1461 elif [[ ! -f ${archivefile} ]]; then
1462 reason='no static archive'
1463 elif [[ ! $(sed -nre \
1464 "s/^(dependency_libs|inherited_linker_flags)='(.*)'$/\2/p" \
1465 "${f}") ]]; then
1466 reason='no libs & flags'
1467 else
1468 if [[ ! ${pkgconfig_scanned} ]]; then
1469 # Create a list of all .pc-covered libs.
1470 local pc_libs=()
1471 if [[ ! ${removing_all} ]]; then
1472 local pc
1473 local tf=${T}/prune-lt-files.pc
1474 local pkgconf=$(tc-getPKG_CONFIG)
1475
1476 while IFS= read -r -d '' pc; do # for all .pc files
1477 local arg libs
1478
1479 # Use pkg-config if available (and works),
1480 # fallback to sed.
1481 if ${pkgconf} --exists "${pc}" &>/dev/null; then
1482 sed -e '/^Requires:/d' "${pc}" > "${tf}"
1483 libs=$(${pkgconf} --libs "${tf}")
1484 else
1485 libs=$(sed -ne 's/^Libs://p' "${pc}")
1486 fi
1487
1488 for arg in ${libs}; do
1489 if [[ ${arg} == -l* ]]; then
1490 if [[ ${arg} == '*$*' ]]; then
1491 eqawarn "${FUNCNAME}: variable substitution likely failed in ${pc}"
1492 eqawarn "(arg: ${arg})"
1493 eqawarn "Most likely, you need to add virtual/pkgconfig to DEPEND."
1494 fi
1495
1496 pc_libs+=( lib${arg#-l}.la )
1497 fi
1498 done
1499 done < <(find "${D}" -type f -name '*.pc' -print0)
1500
1501 rm -f "${tf}"
1502 fi
1503
1504 pkgconfig_scanned=1
1505 fi
1506
1507 has "${f##*/}" "${pc_libs[@]}" && reason='covered by .pc'
1508 fi
1509
1510 if [[ ${reason} ]]; then
1511 einfo "Removing unnecessary ${f#${D%/}} (${reason})"
1512 queue+=( "${f}" )
1513 fi
1514 done < <(find "${D}" -xtype f -name '*.la' -print0)
1515
1516 if [[ ${queue[@]} ]]; then
1517 rm -f "${queue[@]}"
1518 fi
1519}
1520
1521check_license() { die "you no longer need this as portage supports ACCEPT_LICENSE itself"; }
1522
1523fi

Legend:
Removed from v.1.361  
changed lines
  Added in v.1.413

  ViewVC Help
Powered by ViewVC 1.1.20