2 # Copyright 1999-2011 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
5 # Miscellaneous shell functions that make use of the ebuild env but don't need
6 # to be included directly in ebuild.sh.
8 # We're sourcing ebuild.sh here so that we inherit all of it's goodness,
9 # including bashrc trickery. This approach allows us to do our miscellaneous
10 # shell work withing the same env that ebuild.sh has, but without polluting
11 # ebuild.sh itself with unneeded logic and shell code.
13 # XXX hack: clear the args so ebuild.sh doesn't see them
14 MISC_FUNCTIONS_ARGS="$@"
17 source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}/ebuild.sh"
19 install_symlink_html_docs() {
20 [[ " ${FEATURES} " == *" force-prefix "* ]] || \
21 case "$EAPI" in 0|1|2) local ED=${D} ;; esac
22 cd "${ED}" || die "cd failed"
23 #symlink the html documentation (if DOC_SYMLINKS_DIR is set in make.conf)
24 if [ -n "${DOC_SYMLINKS_DIR}" ] ; then
26 for docdir in "${HTMLDOC_DIR:-does/not/exist}" "${PF}/html" "${PF}/HTML" "${P}/html" "${P}/HTML" ; do
27 if [ -d "usr/share/doc/${docdir}" ] ; then
28 mydocdir="/usr/share/doc/${docdir}"
31 if [ -n "${mydocdir}" ] ; then
33 if [ -z "${SLOT}" -o "${SLOT}" = "0" ] ; then
34 mysympath="${DOC_SYMLINKS_DIR}/${CATEGORY}/${PN}"
36 mysympath="${DOC_SYMLINKS_DIR}/${CATEGORY}/${PN}-${SLOT}"
38 einfo "Symlinking ${mysympath} to the HTML documentation"
39 dodir "${DOC_SYMLINKS_DIR}/${CATEGORY}"
40 dosym "${mydocdir}" "${mysympath}"
45 # replacement for "readlink -f" or "realpath"
47 local f=$1 b n=10 wd=$(pwd)
48 while (( n-- > 0 )); do
49 while [[ ${f: -1} = / && ${#f} -gt 1 ]]; do
53 cd "${f%"${b}"}" 2>/dev/null || break
54 if [[ ! -L ${b} ]]; then
67 local -a include exclude incl_d incl_f
68 local f g i real_f real_d
69 [[ " ${FEATURES} " == *" force-prefix "* ]] || \
70 case "$EAPI" in 0|1|2) local ED=${D} ;; esac
72 # Canonicalize path names and check for their existence.
73 real_d=$(canonicalize "${ED}")
74 for (( i = 0; i < ${#PORTAGE_DOCOMPRESS[@]}; i++ )); do
75 real_f=$(canonicalize "${ED}${PORTAGE_DOCOMPRESS[i]}")
76 f=${real_f#"${real_d}"}
77 if [[ ${real_f} != "${f}" ]] && [[ -d ${real_f} || -f ${real_f} ]]
79 include[${#include[@]}]=${f:-/}
80 elif [[ ${i} -ge 3 ]]; then
81 ewarn "prepcompress:" \
82 "ignoring nonexistent path '${PORTAGE_DOCOMPRESS[i]}'"
85 for (( i = 0; i < ${#PORTAGE_DOCOMPRESS_SKIP[@]}; i++ )); do
86 real_f=$(canonicalize "${ED}${PORTAGE_DOCOMPRESS_SKIP[i]}")
87 f=${real_f#"${real_d}"}
88 if [[ ${real_f} != "${f}" ]] && [[ -d ${real_f} || -f ${real_f} ]]
90 exclude[${#exclude[@]}]=${f:-/}
91 elif [[ ${i} -ge 1 ]]; then
92 ewarn "prepcompress:" \
93 "ignoring nonexistent path '${PORTAGE_DOCOMPRESS_SKIP[i]}'"
97 # Remove redundant entries from lists.
98 # For the include list, remove any entries that are:
99 # a) contained in a directory in the include or exclude lists, or
100 # b) identical with an entry in the exclude list.
101 for (( i = ${#include[@]} - 1; i >= 0; i-- )); do
103 for g in "${include[@]}"; do
104 if [[ ${f} == "${g%/}"/* ]]; then
109 for g in "${exclude[@]}"; do
110 if [[ ${f} = "${g}" || ${f} == "${g%/}"/* ]]; then
116 # For the exclude list, remove any entries that are:
117 # a) contained in a directory in the exclude list, or
118 # b) _not_ contained in a directory in the include list.
119 for (( i = ${#exclude[@]} - 1; i >= 0; i-- )); do
121 for g in "${exclude[@]}"; do
122 if [[ ${f} == "${g%/}"/* ]]; then
127 for g in "${include[@]}"; do
128 [[ ${f} == "${g%/}"/* ]] && continue 2
133 # Split the include list into directories and files
134 for f in "${include[@]}"; do
135 if [[ -d ${ED}${f} ]]; then
136 incl_d[${#incl_d[@]}]=${f}
138 incl_f[${#incl_f[@]}]=${f}
142 # Queue up for compression.
143 # ecompress{,dir} doesn't like to be called with empty argument lists.
144 [[ ${#incl_d[@]} -gt 0 ]] && ecompressdir --queue "${incl_d[@]}"
145 [[ ${#incl_f[@]} -gt 0 ]] && ecompress --queue "${incl_f[@]/#/${ED}}"
146 [[ ${#exclude[@]} -gt 0 ]] && ecompressdir --ignore "${exclude[@]}"
152 [[ " ${FEATURES} " == *" force-prefix "* ]] || \
153 case "$EAPI" in 0|1|2) local ED=${D} ;; esac
155 cd "${ED}" || die "cd failed"
159 has "${EAPI}" 0 1 2 3 || prepcompress
160 ecompressdir --dequeue
163 # Prefix specific checks
164 [[ ${ED} != ${D} ]] && install_qa_check_prefix
167 for x in etc/app-defaults usr/man usr/info usr/X11R6 usr/doc usr/locale ; do
168 [[ -d ${ED}/$x ]] && f+=" $x\n"
171 if [[ -n $f ]] ; then
172 eqawarn "QA Notice: This ebuild installs into the following deprecated directories:"
177 # Now we look for all world writable files.
178 local unsafe_files=$(find "${ED}" -type f -perm -2 | sed -e "s:^${ED}:- :")
179 if [[ -n ${unsafe_files} ]] ; then
180 vecho "QA Security Notice: world writable file(s):"
181 vecho "${unsafe_files}"
182 vecho "- This may or may not be a security problem, most of the time it is one."
183 vecho "- Please double check that $PF really needs a world writeable bit and file bugs accordingly."
187 if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT}; then
188 local qa_var insecure_rpath=0 tmp_quiet=${PORTAGE_QUIET}
191 # display warnings when using stricter because we die afterwards
192 if has stricter ${FEATURES} ; then
196 # Make sure we disallow insecure RUNPATH/RPATHs.
197 # 1) References to PORTAGE_BUILDDIR are banned because it's a
198 # security risk. We don't want to load files from a
199 # temporary directory.
200 # 2) If ROOT != "/", references to ROOT are banned because
201 # that directory won't exist on the target system.
202 # 3) Null paths are banned because the loader will search $PWD when
203 # it finds null paths.
204 local forbidden_dirs="${PORTAGE_BUILDDIR}"
205 if [[ -n "${ROOT}" && "${ROOT}" != "/" ]]; then
206 forbidden_dirs+=" ${ROOT}"
208 local dir l rpath_files=$(scanelf -F '%F:%r' -qBR "${ED}")
210 for dir in ${forbidden_dirs}; do
211 for l in $(echo "${rpath_files}" | grep -E ":${dir}|::|: "); do
213 if ! has stricter ${FEATURES}; then
214 vecho "Auto fixing rpaths for ${l%%:*}"
215 TMPDIR="${dir}" scanelf -BXr "${l%%:*}" -o /dev/null
220 # Reject set*id binaries with $ORIGIN in RPATH #260331
222 find "${ED}" -type f \( -perm -u+s -o -perm -g+s \) -print0 | \
223 xargs -0 scanelf -qyRF '%r %p' | grep '$ORIGIN'
227 if [[ -n ${f}${x} ]] ; then
229 eqawarn "QA Notice: The following files contain insecure RUNPATHs"
230 eqawarn " Please file a bug about this at http://bugs.gentoo.org/"
231 eqawarn " with the maintaining herd of the package."
232 eqawarn "${f}${f:+${x:+\n}}${x}"
234 if [[ -n ${x} ]] || has stricter ${FEATURES} ; then
239 # TEXTRELs are baaaaaaaad
240 # Allow devs to mark things as ignorable ... e.g. things that are
241 # binary-only and upstream isn't cooperating (nvidia-glx) ... we
242 # allow ebuild authors to set QA_TEXTRELS_arch and QA_TEXTRELS ...
243 # the former overrides the latter ... regexes allowed ! :)
244 qa_var="QA_TEXTRELS_${ARCH/-/_}"
245 [[ -n ${!qa_var} ]] && QA_TEXTRELS=${!qa_var}
246 [[ -n ${QA_STRICT_TEXTRELS} ]] && QA_TEXTRELS=""
247 export QA_TEXTRELS="${QA_TEXTRELS} lib*/modules/*.ko"
248 f=$(scanelf -qyRF '%t %p' "${ED}" | grep -v 'usr/lib/debug/')
249 if [[ -n ${f} ]] ; then
250 scanelf -qyRAF '%T %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-textrel.log
252 eqawarn "QA Notice: The following files contain runtime text relocations"
253 eqawarn " Text relocations force the dynamic linker to perform extra"
254 eqawarn " work at startup, waste system resources, and may pose a security"
255 eqawarn " risk. On some architectures, the code may not even function"
256 eqawarn " properly, if at all."
257 eqawarn " For more information, see http://hardened.gentoo.org/pic-fix-guide.xml"
258 eqawarn " Please include the following list of files in your report:"
261 die_msg="${die_msg} textrels,"
265 # Also, executable stacks only matter on linux (and just glibc atm ...)
267 case ${CTARGET:-${CHOST}} in
269 # Check for files with executable stacks, but only on arches which
270 # are supported at the moment. Keep this list in sync with
271 # http://hardened.gentoo.org/gnu-stack.xml (Arch Status)
272 case ${CTARGET:-${CHOST}} in
273 arm*|i?86*|ia64*|m68k*|s390*|sh*|x86_64*)
274 # Allow devs to mark things as ignorable ... e.g. things
275 # that are binary-only and upstream isn't cooperating ...
276 # we allow ebuild authors to set QA_EXECSTACK_arch and
277 # QA_EXECSTACK ... the former overrides the latter ...
278 # regexes allowed ! :)
280 qa_var="QA_EXECSTACK_${ARCH/-/_}"
281 [[ -n ${!qa_var} ]] && QA_EXECSTACK=${!qa_var}
282 [[ -n ${QA_STRICT_EXECSTACK} ]] && QA_EXECSTACK=""
283 qa_var="QA_WX_LOAD_${ARCH/-/_}"
284 [[ -n ${!qa_var} ]] && QA_WX_LOAD=${!qa_var}
285 [[ -n ${QA_STRICT_WX_LOAD} ]] && QA_WX_LOAD=""
286 export QA_EXECSTACK="${QA_EXECSTACK} lib*/modules/*.ko"
287 export QA_WX_LOAD="${QA_WX_LOAD} lib*/modules/*.ko"
288 f=$(scanelf -qyRAF '%e %p' "${ED}" | grep -v 'usr/lib/debug/')
293 if [[ -n ${f} ]] ; then
294 # One more pass to help devs track down the source
295 scanelf -qyRAF '%e %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-execstack.log
297 eqawarn "QA Notice: The following files contain writable and executable sections"
298 eqawarn " Files with such sections will not work properly (or at all!) on some"
299 eqawarn " architectures/operating systems. A bug should be filed at"
300 eqawarn " http://bugs.gentoo.org/ to make sure the issue is fixed."
301 eqawarn " For more information, see http://hardened.gentoo.org/gnu-stack.xml"
302 eqawarn " Please include the following list of files in your report:"
303 eqawarn " Note: Bugs should be filed for the respective maintainers"
304 eqawarn " of the package in question and not hardened@g.o."
307 die_msg="${die_msg} execstacks"
311 # Check for files built without respecting CFLAGS
312 if [[ "${CFLAGS}" == *-frecord-gcc-switches* ]] && \
313 ! has binchecks ${RESTRICT} ; then
314 qa_var="QA_DT_SWITCHES_${ARCH/-/_}"
315 eval "[[ -n \${!qa_var} ]] && QA_DT_SWITCHES=(\"\${${qa_var}[@]}\")"
316 f=$(scanelf -qyRF '%k %p' -k \!.GCC.command.line "${ED}" | sed -e "s:\!.GCC.command.line ::")
317 if [[ -n ${f} ]] ; then
318 echo "${f}" > "${T}"/scanelf-ignored-CFLAGS.log
319 if [ "${QA_STRICT_DT_SWITCHES-unset}" == unset ] ; then
320 if [[ ${#QA_DT_SWITCHES[@]} -gt 1 ]] ; then
321 for x in "${QA_DT_SWITCHES[@]}" ; do
322 sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-CFLAGS.log
327 for x in ${QA_DT_SWITCHES} ; do
328 sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-CFLAGS.log
334 # Filter anything under /usr/lib/debug/ in order to avoid
335 # duplicate warnings for splitdebug files.
336 sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \
337 -i "${T}"/scanelf-ignored-CFLAGS.log
338 f=$(<"${T}"/scanelf-ignored-CFLAGS.log)
339 if [[ -n ${f} ]] ; then
341 eqawarn "${BAD}QA Notice: Files built without respecting CFLAGS have been detected${NORMAL}"
342 eqawarn " Please include the following list of files in your report:"
347 rm -f "${T}"/scanelf-ignored-CFLAGS.log
352 # Check for files built without respecting LDFLAGS
353 if [[ "${LDFLAGS}" == *,--hash-style=gnu* ]] && \
354 ! has binchecks ${RESTRICT} ; then
355 qa_var="QA_DT_HASH_${ARCH/-/_}"
356 eval "[[ -n \${!qa_var} ]] && QA_DT_HASH=(\"\${${qa_var}[@]}\")"
357 f=$(scanelf -qyRF '%k %p' -k .hash "${ED}" | sed -e "s:\.hash ::")
358 if [[ -n ${f} ]] ; then
359 echo "${f}" > "${T}"/scanelf-ignored-LDFLAGS.log
360 if [ "${QA_STRICT_DT_HASH-unset}" == unset ] ; then
361 if [[ ${#QA_DT_HASH[@]} -gt 1 ]] ; then
362 for x in "${QA_DT_HASH[@]}" ; do
363 sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-LDFLAGS.log
368 for x in ${QA_DT_HASH} ; do
369 sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-LDFLAGS.log
375 # Filter anything under /usr/lib/debug/ in order to avoid
376 # duplicate warnings for splitdebug files.
377 sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \
378 -i "${T}"/scanelf-ignored-LDFLAGS.log
379 f=$(<"${T}"/scanelf-ignored-LDFLAGS.log)
380 if [[ -n ${f} ]] ; then
382 eqawarn "${BAD}QA Notice: Files built without respecting LDFLAGS have been detected${NORMAL}"
383 eqawarn " Please include the following list of files in your report:"
388 rm -f "${T}"/scanelf-ignored-LDFLAGS.log
393 # Save NEEDED information after removing self-contained providers
394 rm -f "$PORTAGE_BUILDDIR"/build-info/NEEDED{,.ELF.2}
395 scanelf -qyRF '%a;%p;%S;%r;%n' "${D}" | { while IFS= read -r l; do
396 arch=${l%%;*}; l=${l#*;}
397 obj="/${l%%;*}"; l=${l#*;}
398 soname=${l%%;*}; l=${l#*;}
399 rpath=${l%%;*}; l=${l#*;}; [ "${rpath}" = " - " ] && rpath=""
400 needed=${l%%;*}; l=${l#*;}
401 if [ -z "${rpath}" -o -n "${rpath//*ORIGIN*}" ]; then
402 # object doesn't contain $ORIGIN in its runpath attribute
403 echo "${obj} ${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED
404 echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
407 # replace $ORIGIN with the dirname of the current object for the lookup
408 opath=$(echo :${rpath}: | sed -e "s#.*:\(.*\)\$ORIGIN\(.*\):.*#\1${dir}\2#")
409 sneeded=$(echo ${needed} | tr , ' ')
411 for lib in ${sneeded}; do
413 for path in ${opath//:/ }; do
414 [ -e "${D}/${path}/${lib}" ] && found=1 && break
416 [ "${found}" -eq 0 ] && rneeded="${rneeded},${lib}"
419 if [ -n "${rneeded}" ]; then
420 echo "${obj} ${rneeded}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED
421 echo "${arch:3};${obj};${soname};${rpath};${rneeded}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
426 [ -n "${QA_SONAME_NO_SYMLINK}" ] && \
427 echo "${QA_SONAME_NO_SYMLINK}" > \
428 "${PORTAGE_BUILDDIR}"/build-info/QA_SONAME_NO_SYMLINK
430 if [[ ${insecure_rpath} -eq 1 ]] ; then
431 die "Aborting due to serious QA concerns with RUNPATH/RPATH"
432 elif [[ -n ${die_msg} ]] && has stricter ${FEATURES} ; then
433 die "Aborting due to QA concerns: ${die_msg}"
436 # Check for shared libraries lacking SONAMEs
437 qa_var="QA_SONAME_${ARCH/-/_}"
438 eval "[[ -n \${!qa_var} ]] && QA_SONAME=(\"\${${qa_var}[@]}\")"
439 f=$(scanelf -ByF '%S %p' "${ED}"{,usr/}lib*/lib*.so* | gawk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:")
440 if [[ -n ${f} ]] ; then
441 echo "${f}" > "${T}"/scanelf-missing-SONAME.log
442 if [[ "${QA_STRICT_SONAME-unset}" == unset ]] ; then
443 if [[ ${#QA_SONAME[@]} -gt 1 ]] ; then
444 for x in "${QA_SONAME[@]}" ; do
445 sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log
450 for x in ${QA_SONAME} ; do
451 sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log
457 sed -e "/^\$/d" -i "${T}"/scanelf-missing-SONAME.log
458 f=$(<"${T}"/scanelf-missing-SONAME.log)
459 if [[ -n ${f} ]] ; then
461 eqawarn "QA Notice: The following shared libraries lack a SONAME"
466 rm -f "${T}"/scanelf-missing-SONAME.log
470 # Check for shared libraries lacking NEEDED entries
471 qa_var="QA_DT_NEEDED_${ARCH/-/_}"
472 eval "[[ -n \${!qa_var} ]] && QA_DT_NEEDED=(\"\${${qa_var}[@]}\")"
473 f=$(scanelf -ByF '%n %p' "${ED}"{,usr/}lib*/lib*.so* | gawk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:")
474 if [[ -n ${f} ]] ; then
475 echo "${f}" > "${T}"/scanelf-missing-NEEDED.log
476 if [[ "${QA_STRICT_DT_NEEDED-unset}" == unset ]] ; then
477 if [[ ${#QA_DT_NEEDED[@]} -gt 1 ]] ; then
478 for x in "${QA_DT_NEEDED[@]}" ; do
479 sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log
484 for x in ${QA_DT_NEEDED} ; do
485 sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log
491 sed -e "/^\$/d" -i "${T}"/scanelf-missing-NEEDED.log
492 f=$(<"${T}"/scanelf-missing-NEEDED.log)
493 if [[ -n ${f} ]] ; then
495 eqawarn "QA Notice: The following shared libraries lack NEEDED entries"
500 rm -f "${T}"/scanelf-missing-NEEDED.log
504 PORTAGE_QUIET=${tmp_quiet}
507 local unsafe_files=$(find "${ED}" -type f '(' -perm -2002 -o -perm -4002 ')' | sed -e "s:^${ED}:/:")
508 if [[ -n ${unsafe_files} ]] ; then
509 eqawarn "QA Notice: Unsafe files detected (set*id and world writable)"
510 eqawarn "${unsafe_files}"
511 die "Unsafe files found in \${D}. Portage will not install them."
514 if [[ -d ${D}/${D} ]] ; then
515 declare -i INSTALLTOD=0
516 for i in $(find "${D}/${D}/"); do
517 eqawarn "QA Notice: /${i##${D}/${D}} installed in \${D}/\${D}"
520 die "Aborting due to QA concerns: ${INSTALLTOD} files installed in ${D}/${D}"
524 # Sanity check syntax errors in init.d scripts
526 for d in /etc/conf.d /etc/init.d ; do
527 [[ -d ${ED}/${d} ]] || continue
528 for i in "${ED}"/${d}/* ; do
529 [[ -L ${i} ]] && continue
530 # if empty conf.d/init.d dir exists (baselayout), then i will be "/etc/conf.d/*" and not exist
531 [[ ! -e ${i} ]] && continue
532 bash -n "${i}" || die "The init.d file has syntax errors: ${i}"
536 # this should help to ensure that all (most?) shared libraries are executable
537 # and that all libtool scripts / static libraries are not executable
539 for i in "${ED}"opt/*/lib{,32,64} \
541 "${ED}"usr/lib{,32,64} \
542 "${ED}"usr/X11R6/lib{,32,64} ; do
543 [[ ! -d ${i} ]] && continue
545 for j in "${i}"/*.so.* "${i}"/*.so ; do
546 [[ ! -e ${j} ]] && continue
547 [[ -L ${j} ]] && continue
548 [[ -x ${j} ]] && continue
549 vecho "making executable: ${j#${ED}}"
553 for j in "${i}"/*.a "${i}"/*.la ; do
554 [[ ! -e ${j} ]] && continue
555 [[ -L ${j} ]] && continue
556 [[ ! -x ${j} ]] && continue
557 vecho "removing executable bit: ${j#${ED}}"
561 for j in "${i}"/*.{a,dll,dylib,sl,so}.* "${i}"/*.{a,dll,dylib,sl,so} ; do
562 [[ ! -e ${j} ]] && continue
563 [[ ! -L ${j} ]] && continue
564 linkdest=$(readlink "${j}")
565 if [[ ${linkdest} == /* ]] ; then
567 eqawarn "QA Notice: Found an absolute symlink in a library directory:"
568 eqawarn " ${j#${D}} -> ${linkdest}"
569 eqawarn " It should be a relative symlink if in the same directory"
570 eqawarn " or a linker script if it crosses the /usr boundary."
575 # When installing static libraries into /usr/lib and shared libraries into
576 # /lib, we have to make sure we have a linker script in /usr/lib along side
577 # the static library, or gcc will utilize the static lib when linking :(.
578 # http://bugs.gentoo.org/4411
581 for a in "${ED}"usr/lib*/*.a ; do
583 if [[ ! -e ${s} ]] ; then
584 s=${s%usr/*}${s##*/usr/}
585 if [[ -e ${s} ]] ; then
587 eqawarn "QA Notice: Missing gen_usr_ldscript for ${s##*/}"
592 [[ ${abort} == "yes" ]] && die "add those ldscripts"
594 # Make sure people don't store libtool files or static libs in /lib
595 f=$(ls "${ED}"lib*/*.{a,la} 2>/dev/null)
596 if [[ -n ${f} ]] ; then
598 eqawarn "QA Notice: Excessive files found in the / partition"
601 die "static archives (*.a) and libtool library files (*.la) do not belong in /"
604 # Verify that the libtool files don't contain bogus $D entries.
605 local abort=no gentoo_bug=no always_overflow=no
606 for a in "${ED}"usr/lib*/*.la ; do
608 if grep -qs "${ED}" "${a}" ; then
610 eqawarn "QA Notice: ${s} appears to contain PORTAGE_TMPDIR paths"
614 [[ ${abort} == "yes" ]] && die "soiled libtool library files found"
616 # Evaluate misc gcc warnings
617 if [[ -n ${PORTAGE_LOG_FILE} && -r ${PORTAGE_LOG_FILE} ]] ; then
618 # In debug mode, this variable definition and corresponding grep calls
619 # will produce false positives if they're shown in the trace.
621 if [[ ${-/x/} != $- ]] ; then
626 ": warning: dereferencing type-punned pointer will break strict-aliasing rules"
627 ": warning: dereferencing pointer .* does break strict-aliasing rules"
628 ": warning: implicit declaration of function"
629 ": warning: incompatible implicit declaration of built-in function"
630 ": warning: is used uninitialized in this function" # we'll ignore "may" and "might"
631 ": warning: comparisons like X<=Y<=Z do not have their mathematical meaning"
632 ": warning: null argument where non-null required"
633 ": warning: array subscript is below array bounds"
634 ": warning: array subscript is above array bounds"
635 ": warning: attempt to free a non-heap object"
636 ": warning: .* called with .*bigger.* than .* destination buffer"
637 ": warning: call to .* will always overflow destination buffer"
638 ": warning: assuming pointer wraparound does not occur when comparing"
639 ": warning: hex escape sequence out of range"
640 ": warning: [^ ]*-hand operand of comma .*has no effect"
641 ": warning: converting to non-pointer type .* from NULL"
642 ": warning: NULL used in arithmetic"
643 ": warning: passing NULL to non-pointer argument"
644 ": warning: the address of [^ ]* will always evaluate as"
645 ": warning: the address of [^ ]* will never be NULL"
646 ": warning: too few arguments for format"
647 ": warning: reference to local variable .* returned"
648 ": warning: returning reference to temporary"
649 ": warning: function returns address of local variable"
650 # this may be valid code :/
651 #": warning: multi-character character constant"
652 # need to check these two ...
653 #": warning: assuming signed overflow does not occur when"
654 #": warning: comparison with string literal results in unspecified behav"
655 # yacc/lex likes to trigger this one
656 #": warning: extra tokens at end of .* directive"
657 # only gcc itself triggers this ?
658 #": warning: .*noreturn.* function does return"
659 # these throw false positives when 0 is used instead of NULL
660 #": warning: missing sentinel in function call"
661 #": warning: not enough variable arguments to fit a sentinel"
666 [[ $PORTAGE_LOG_FILE = *.gz ]] && grep_cmd=zgrep
667 while [[ -n ${msgs[${i}]} ]] ; do
669 # force C locale to work around slow unicode locales #160234
670 f=$(LC_ALL=C $grep_cmd "${m}" "${PORTAGE_LOG_FILE}")
671 if [[ -n ${f} ]] ; then
673 # for now, don't make this fatal (see bug #337031)
675 # ": warning: call to .* will always overflow destination buffer") always_overflow=yes ;;
677 if [[ $always_overflow = yes ]] ; then
679 eerror "QA Notice: Package triggers severe warnings which indicate that it"
680 eerror " may exhibit random runtime failures."
684 eerror " Please file a bug about this at http://bugs.gentoo.org/"
685 eerror " with the maintaining herd of the package."
689 eqawarn "QA Notice: Package triggers severe warnings which indicate that it"
690 eqawarn " may exhibit random runtime failures."
697 [[ $PORTAGE_LOG_FILE = *.gz ]] && cat_cmd=zcat
698 [[ $reset_debug = 1 ]] && set -x
699 f=$($cat_cmd "${PORTAGE_LOG_FILE}" | \
700 "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/check-implicit-pointer-usage.py || die "check-implicit-pointer-usage.py failed")
701 if [[ -n ${f} ]] ; then
703 # In the future this will be a forced "die". In preparation,
704 # increase the log level from "qa" to "eerror" so that people
705 # are aware this is a problem that must be fixed asap.
707 # just warn on 32bit hosts but bail on 64bit hosts
709 alpha*|hppa64*|ia64*|powerpc64*|mips64*|sparc64*|sparcv9*|x86_64*) gentoo_bug=yes ;;
714 if [[ $gentoo_bug = yes ]] ; then
716 eerror "QA Notice: Package triggers severe warnings which indicate that it"
717 eerror " will almost certainly crash on 64bit architectures."
721 eerror " Please file a bug about this at http://bugs.gentoo.org/"
722 eerror " with the maintaining herd of the package."
726 eqawarn "QA Notice: Package triggers severe warnings which indicate that it"
727 eqawarn " will almost certainly crash on 64bit architectures."
733 if [[ ${abort} == "yes" ]] ; then
734 if [[ $gentoo_bug = yes || $always_overflow = yes ]] ; then
735 die "install aborted due to" \
736 "severe warnings shown above"
738 echo "Please do not file a Gentoo bug and instead" \
739 "report the above QA issues directly to the upstream" \
740 "developers of this software." | fmt -w 70 | \
741 while read -r line ; do eqawarn "${line}" ; done
742 eqawarn "Homepage: ${HOMEPAGE}"
743 has stricter ${FEATURES} && die "install aborted due to" \
744 "severe warnings shown above"
749 # Portage regenerates this on the installed system.
750 rm -f "${ED}"/usr/share/info/dir{,.gz,.bz2}
752 if has multilib-strict ${FEATURES} && \
753 [[ -x /usr/bin/file && -x /usr/bin/find ]] && \
754 [[ -n ${MULTILIB_STRICT_DIRS} && -n ${MULTILIB_STRICT_DENY} ]]
756 local abort=no dir file firstrun=yes
757 MULTILIB_STRICT_EXEMPT=$(echo ${MULTILIB_STRICT_EXEMPT} | sed -e 's:\([(|)]\):\\\1:g')
758 for dir in ${MULTILIB_STRICT_DIRS} ; do
759 [[ -d ${ED}/${dir} ]] || continue
760 for file in $(find ${ED}/${dir} -type f | grep -v "^${ED}/${dir}/${MULTILIB_STRICT_EXEMPT}"); do
761 if file ${file} | egrep -q "${MULTILIB_STRICT_DENY}" ; then
762 if [[ ${firstrun} == yes ]] ; then
763 echo "Files matching a file type that is not allowed:"
767 echo " ${file#${ED}//}"
771 [[ ${abort} == yes ]] && die "multilib-strict check failed!"
774 # ensure packages don't install systemd units automagically
775 if ! has systemd ${INHERITED} && \
776 [[ -d "${ED}"/lib/systemd/system ]]
778 eqawarn "QA Notice: package installs systemd unit files (/lib/systemd/system)"
779 eqawarn " but does not inherit systemd.eclass."
780 has stricter ${FEATURES} \
781 && die "install aborted due to missing inherit of systemd.eclass"
785 install_qa_check_prefix() {
786 if [[ -d ${ED}/${D} ]] ; then
787 find "${ED}/${D}" | \
789 eqawarn "QA Notice: /${i##${ED}/${D}} installed in \${ED}/\${D}"
791 die "Aborting due to QA concerns: files installed in ${ED}/${D}"
794 if [[ -d ${ED}/${EPREFIX} ]] ; then
795 find "${ED}/${EPREFIX}/" | \
797 eqawarn "QA Notice: ${i#${D}} double prefix"
799 die "Aborting due to QA concerns: double prefix files installed"
802 if [[ -d ${D} ]] ; then
803 INSTALLTOD=$(find ${D%/} | egrep -v "^${ED}" | sed -e "s|^${D%/}||" | awk '{if (length($0) <= length("'"${EPREFIX}"'")) { if (substr("'"${EPREFIX}"'", 1, length($0)) != $0) {print $0;} } else if (substr($0, 1, length("'"${EPREFIX}"'")) != "'"${EPREFIX}"'") {print $0;} }')
804 if [[ -n ${INSTALLTOD} ]] ; then
805 eqawarn "QA Notice: the following files are outside of the prefix:"
806 eqawarn "${INSTALLTOD}"
807 die "Aborting due to QA concerns: there are files installed outside the prefix"
811 # all further checks rely on ${ED} existing
812 [[ -d ${ED} ]] || return
814 # this does not really belong here, but it's closely tied to
815 # the code below; many runscripts generate positives here, and we
816 # know they don't work (bug #196294) so as long as that one
817 # remains an issue, simply remove them as they won't work
818 # anyway, avoid etc/init.d/functions.sh from being thrown away
819 if [[ ( -d "${ED}"/etc/conf.d || -d "${ED}"/etc/init.d ) && ! -f "${ED}"/etc/init.d/functions.sh ]] ; then
820 ewarn "removed /etc/init.d and /etc/conf.d directories until bug #196294 has been resolved"
821 rm -Rf "${ED}"/etc/{conf,init}.d
824 # check shebangs, bug #282539
825 rm -f "${T}"/non-prefix-shebangs-errs
826 local WHITELIST=" /usr/bin/env "
827 # this is hell expensive, but how else?
828 find "${ED}" -executable \! -type d -print0 \
829 | xargs -0 grep -H -n -m1 "^#!" \
833 local pos=${f#*:} ; pos=${pos%:*}
835 # shebang always appears on the first line ;)
836 [[ ${pos} != 1 ]] && continue
838 IFS=$'\r'$'\n'$'\t'" "
839 line=( ${line#"#!"} )
841 [[ ${WHITELIST} == *" ${line[0]} "* ]] && continue
842 local fp=${fn#${D}} ; fp=/${fp%/*}
843 # line[0] can be an absolutised path, bug #342929
844 local eprefix=$(canonicalize ${EPREFIX})
846 # in case we deal with a symlink, make sure we don't replace it
847 # with a real file (sed -i does that)
848 if [[ -L ${fn} ]] ; then
850 [[ ${rf} != /* ]] && rf=${fn%/*}/${rf}
851 # ignore symlinks pointing to outside prefix
852 # as seen in sys-devel/native-cctools
853 [[ $(canonicalize "/${rf#${D}}") != ${eprefix}/* ]] && continue
855 # does the shebang start with ${EPREFIX}, and does it exist?
856 if [[ ${line[0]} == ${EPREFIX}/* || ${line[0]} == ${eprefix}/* ]] ; then
857 if [[ ! -e ${ROOT%/}${line[0]} && ! -e ${D%/}${line[0]} ]] ; then
858 # hmm, refers explicitly to $EPREFIX, but doesn't exist,
859 # if it's in PATH that's wrong in any case
860 if [[ ":${PATH}:" == *":${fp}:"* ]] ; then
861 echo "${fn#${D}}:${line[0]} (explicit EPREFIX but target not found)" \
862 >> "${T}"/non-prefix-shebangs-errs
864 eqawarn "${fn#${D}} has explicit EPREFIX in shebang but target not found (${line[0]})"
869 # unprefixed shebang, is the script directly in $PATH?
870 if [[ ":${PATH}:" == *":${fp}:"* ]] ; then
871 if [[ -e ${EROOT}${line[0]} || -e ${ED}${line[0]} ]] ; then
872 # is it unprefixed, but we can just fix it because a
873 # prefixed variant exists
874 eqawarn "prefixing shebang of ${fn#${D}}"
875 # statement is made idempotent on purpose, because
876 # symlinks may point to the same target, and hence the
877 # same real file may be sedded multiple times since we
878 # read the shebangs in one go upfront for performance
880 sed -i -e '1s:^#! \?'"${line[0]}"':#!'"${EPREFIX}"${line[0]}':' "${rf}"
883 # this is definitely wrong: script in $PATH and invalid shebang
884 echo "${fn#${D}}:${line[0]} (script ${fn##*/} installed in PATH but interpreter ${line[0]} not found)" \
885 >> "${T}"/non-prefix-shebangs-errs
888 # unprefixed/invalid shebang, but outside $PATH, this may be
889 # intended (e.g. config.guess) so remain silent by default
890 has stricter ${FEATURES} && \
891 eqawarn "invalid shebang in ${fn#${D}}: ${line[0]}"
894 if [[ -e "${T}"/non-prefix-shebangs-errs ]] ; then
895 eqawarn "QA Notice: the following files use invalid (possible non-prefixed) shebangs:"
898 done < "${T}"/non-prefix-shebangs-errs
899 rm -f "${T}"/non-prefix-shebangs-errs
900 die "Aborting due to QA concerns: invalid shebangs found"
907 local install_mask="$*"
909 # we don't want globbing for initial expansion, but afterwards, we do
913 for no_inst in ${install_mask}; do
915 quiet_mode || einfo "Removing ${no_inst}"
917 rm -Rf "${root}"/${no_inst} >&/dev/null
919 # we also need to handle globs (*.a, *.h, etc)
920 find "${root}" \( -path "${no_inst}" -or -name "${no_inst}" \) \
921 -exec rm -fR {} \; >/dev/null 2>&1
923 # set everything back the way we found it
929 if [ -z "${D}" ]; then
930 eerror "${FUNCNAME}: D is unset"
934 [[ " ${FEATURES} " == *" force-prefix "* ]] || \
935 case "$EAPI" in 0|1|2) local ED=${D} ;; esac
937 # Make sure $PWD is not ${D} so that we don't leave gmon.out files
938 # in there in case any tools were built with -pg in CFLAGS.
941 # remove man pages, info pages, docs if requested
943 for f in man info doc; do
944 if has no${f} $FEATURES; then
945 INSTALL_MASK="${INSTALL_MASK} /usr/share/${f}"
949 install_mask "${ED}" "${INSTALL_MASK}"
951 # remove share dir if unnessesary
952 if has nodoc $FEATURES || has noman $FEATURES || has noinfo $FEATURES; then
953 rmdir "${ED}usr/share" &> /dev/null
958 if [ -z "${D}" ]; then
959 eerror "${FUNCNAME}: D is unset"
963 [[ " ${FEATURES} " == *" force-prefix "* ]] || \
964 case "$EAPI" in 0|1|2) local ED=${D} ;; esac
966 # Smart FileSystem Permissions
967 if has sfperms $FEATURES; then
969 find "${ED}" -type f -perm -4000 -print0 | \
970 while read -r -d $'\0' i ; do
971 if [ -n "$(find "$i" -perm -2000)" ] ; then
972 ebegin ">>> SetUID and SetGID: [chmod o-r] /${i#${ED}}"
976 ebegin ">>> SetUID: [chmod go-r] /${i#${ED}}"
981 find "${ED}" -type f -perm -2000 -print0 | \
982 while read -r -d $'\0' i ; do
983 if [ -n "$(find "$i" -perm -4000)" ] ; then
984 # This case is already handled
985 # by the SetUID check above.
988 ebegin ">>> SetGID: [chmod o-r] /${i#${ED}}"
996 preinst_suid_scan() {
997 if [ -z "${D}" ]; then
998 eerror "${FUNCNAME}: D is unset"
1002 [[ " ${FEATURES} " == *" force-prefix "* ]] || \
1003 case "$EAPI" in 0|1|2) local ED=${D} ;; esac
1005 # total suid control.
1006 if has suidctl $FEATURES; then
1008 sfconf=${PORTAGE_CONFIGROOT}etc/portage/suidctl.conf
1009 # sandbox prevents us from writing directly
1010 # to files outside of the sandbox, but this
1011 # can easly be bypassed using the addwrite() function
1012 addwrite "${sfconf}"
1013 vecho ">>> Performing suid scan in ${ED}"
1014 for i in $(find "${ED}" -type f \( -perm -4000 -o -perm -2000 \) ); do
1015 if [ -s "${sfconf}" ]; then
1016 install_path=/${i#${ED}}
1017 if grep -q "^${install_path}\$" "${sfconf}" ; then
1018 vecho "- ${install_path} is an approved suid file"
1020 vecho ">>> Removing sbit on non registered ${install_path}"
1021 for x in 5 4 3 2 1 0; do sleep 0.25 ; done
1022 ls_ret=$(ls -ldh "${i}")
1024 grep "^#${install_path}$" "${sfconf}" > /dev/null || {
1025 vecho ">>> Appending commented out entry to ${sfconf} for ${PF}"
1026 echo "## ${ls_ret%${ED}*}${install_path}" >> "${sfconf}"
1027 echo "#${install_path}" >> "${sfconf}"
1033 vecho "suidctl feature set but you are lacking a ${sfconf}"
1039 preinst_selinux_labels() {
1040 if [ -z "${D}" ]; then
1041 eerror "${FUNCNAME}: D is unset"
1044 if has selinux ${FEATURES}; then
1045 # SELinux file labeling (needs to always be last in dyn_preinst)
1046 # only attempt to label if setfiles is executable
1047 # and 'context' is available on selinuxfs.
1048 if [ -f /selinux/context -a -x /usr/sbin/setfiles -a -x /usr/sbin/selinuxconfig ]; then
1049 vecho ">>> Setting SELinux security labels"
1051 eval "$(/usr/sbin/selinuxconfig)" || \
1052 die "Failed to determine SELinux policy paths.";
1054 addwrite /selinux/context;
1056 /usr/sbin/setfiles "${file_contexts_path}" -r "${D}" "${D}"
1057 ) || die "Failed to set SELinux security labels."
1059 # nonfatal, since merging can happen outside a SE kernel
1060 # like during a recovery situation
1061 vecho "!!! Unable to set SELinux security labels"
1068 [[ " ${FEATURES} " == *" force-prefix "* ]] || \
1069 case "$EAPI" in 0|1|2) local ED=${D} ;; esac
1071 # Make sure $PWD is not ${D} so that we don't leave gmon.out files
1072 # in there in case any tools were built with -pg in CFLAGS.
1074 install_mask "${ED}" "${PKG_INSTALL_MASK}"
1075 local tar_options=""
1076 [[ $PORTAGE_VERBOSE = 1 ]] && tar_options+=" -v"
1077 # Sandbox is disabled in case the user wants to use a symlink
1078 # for $PKGDIR and/or $PKGDIR/All.
1079 export SANDBOX_ON="0"
1080 [ -z "${PORTAGE_BINPKG_TMPFILE}" ] && \
1081 die "PORTAGE_BINPKG_TMPFILE is unset"
1082 mkdir -p "${PORTAGE_BINPKG_TMPFILE%/*}" || die "mkdir failed"
1083 tar $tar_options -cf - $PORTAGE_BINPKG_TAR_OPTS -C "${D}" . | \
1084 $PORTAGE_BZIP2_COMMAND -c > "$PORTAGE_BINPKG_TMPFILE"
1085 assert "failed to pack binary package: '$PORTAGE_BINPKG_TMPFILE'"
1086 PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \
1087 "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/xpak-helper.py recompose \
1088 "$PORTAGE_BINPKG_TMPFILE" "$PORTAGE_BUILDDIR/build-info"
1089 if [ $? -ne 0 ]; then
1090 rm -f "${PORTAGE_BINPKG_TMPFILE}"
1091 die "Failed to append metadata to the tbz2 file"
1094 if type md5sum &>/dev/null ; then
1095 md5_hash=$(md5sum "${PORTAGE_BINPKG_TMPFILE}")
1096 md5_hash=${md5_hash%% *}
1097 elif type md5 &>/dev/null ; then
1098 md5_hash=$(md5 "${PORTAGE_BINPKG_TMPFILE}")
1099 md5_hash=${md5_hash##* }
1101 [ -n "${md5_hash}" ] && \
1102 echo ${md5_hash} > "${PORTAGE_BUILDDIR}"/build-info/BINPKGMD5
1104 cd "${PORTAGE_BUILDDIR}"
1105 >> "$PORTAGE_BUILDDIR/.packaged" || \
1106 die "Failed to create $PORTAGE_BUILDDIR/.packaged"
1110 local sources_dir=/usr/src/rpm/SOURCES
1111 mkdir -p "${sources_dir}"
1112 declare -a tar_args=("${EBUILD}")
1113 [[ -d ${FILESDIR} ]] && tar_args=("${EBUILD}" "${FILESDIR}")
1114 tar czf "${sources_dir}/${PF}.tar.gz" \
1115 "${tar_args[@]}" || \
1116 die "Failed to create base rpm tarball."
1118 cat <<__END1__ > ${PF}.spec
1119 Summary: ${DESCRIPTION}
1124 Group: portage/${CATEGORY}
1125 Source: ${PF}.tar.gz
1149 [[ " ${FEATURES} " == *" force-prefix "* ]] || \
1150 case "$EAPI" in 0|1|2) local EPREFIX= ;; esac
1152 cd "${T}" || die "cd failed"
1153 local machine_name=$(uname -m)
1154 local dest_dir=${EPREFIX}/usr/src/rpm/RPMS/${machine_name}
1155 addwrite ${EPREFIX}/usr/src/rpm
1156 addwrite "${RPMDIR}"
1158 rpmbuild -bb --clean --rmsource "${PF}.spec" || die "Failed to integrate rpm spec file"
1159 install -D "${dest_dir}/${PN}-${PV}-${PR}.${machine_name}.rpm" \
1160 "${RPMDIR}/${CATEGORY}/${PN}-${PV}-${PR}.rpm" || \
1161 die "Failed to move rpm"
1165 [[ -f $PORTAGE_BUILDDIR/.die_hooks ]] && return
1167 for x in $EBUILD_DEATH_HOOKS ; do
1170 > "$PORTAGE_BUILDDIR/.die_hooks"
1175 for x in $EBUILD_SUCCESS_HOOKS ; do
1181 local hooks_dir="${PORTAGE_CONFIGROOT}etc/portage/hooks/install"
1185 for fp in "${hooks_dir}"/*; do
1186 if [ -x "$fp" ]; then
1188 ret=$(( $ret | $? ))
1195 if [ -n "${MISC_FUNCTIONS_ARGS}" ]; then
1197 [ "$PORTAGE_DEBUG" == "1" ] && set -x
1198 for x in ${MISC_FUNCTIONS_ARGS}; do
1202 [[ -n $PORTAGE_EBUILD_EXIT_FILE ]] && > "$PORTAGE_EBUILD_EXIT_FILE"
1203 if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
1204 [[ ! -s $SANDBOX_LOG ]]
1205 "$PORTAGE_BIN_PATH"/ebuild-ipc exit $?