diff --git a/Mk/Scripts/qa.sh b/Mk/Scripts/qa.sh index c54010a15500..d9736ef03552 100644 --- a/Mk/Scripts/qa.sh +++ b/Mk/Scripts/qa.sh @@ -1,183 +1,194 @@ #!/bin/sh # MAINTAINER: portmgr@FreeBSD.org # $FreeBSD$ if [ -z "${STAGEDIR}" -o -z "${PREFIX}" -o -z "${LOCALBASE}" ]; then echo "STAGEDIR, PREFIX, LOCALBASE required in environment." >&2 exit 1 fi LF=$(printf '\nX') LF=${LF%X} warn() { echo "Warning: $@" >&2 } err() { echo "Error: $@" >&2 } shebangonefile() { local f interp rc f="$@" rc=0 interp=$(sed -n -e '1s/^#![[:space:]]*\([^[:space:]]*\).*/\1/p;2q' "$f") case "$interp" in "") ;; /usr/bin/env) ;; ${LOCALBASE}/*) ;; ${PREFIX}/*) ;; /usr/bin/awk) ;; /usr/bin/sed) ;; /usr/bin/nawk) ;; /bin/csh) ;; /bin/sh) ;; *) err "${interp} is an invalid shebang you need USES=shebangfix for ${f#${STAGEDIR}${PREFIX}/}" rc=1 ;; esac return ${rc} } shebang() { local f l link rc rc=0 while read f; do [ -z "${f}" ] && continue shebangonefile "${f}" || rc=1 # Use heredoc to avoid losing rc from find|while subshell done << EOF $(find ${STAGEDIR}${PREFIX}/bin ${STAGEDIR}${PREFIX}/sbin ${STAGEDIR}${PREFIX}/libexec -type f -perm +111 2>/dev/null) EOF while read l link; do [ -z "${l}" ] && continue case "${link}" in /*) f="${STAGEDIR}${link}" ;; *) f="${l%/*}/${link}" ;; esac if [ -f "${f}" ]; then shebangonefile "${f}" || rc=1 fi # Use heredoc to avoid losing rc from find|while subshell done << EOF $(find ${STAGEDIR}${PREFIX}/bin ${STAGEDIR}${PREFIX}/sbin ${STAGEDIR}${PREFIX}/libexec -type l -exec stat -f "%N %Y" {} + 2>/dev/null) EOF return ${rc} } symlinks() { local rc rc=0 while read l link; do [ -z "${l}" ] && continue case "${link}" in ${STAGEDIR}*) err "Bad symlinks ${l#${STAGEDIR}${PREFIX}/} pointing inside the stage directory" rc=1 ;; esac # Use heredoc to avoid losing rc from find|while subshell done << EOF $(find ${STAGEDIR} -type l -exec stat -f "%N %Y" {} +) EOF return ${rc} } paths() { local rc rc=0 while read f; do [ -z "${f}" ] && continue # Ignore false-positive/harmless files case "${f}" in */lib/ruby/gems/*/Makefile) continue ;; */lib/ruby/gems/*/Makefile.html) continue ;; */lib/ruby/gems/*/mkmf.log) continue ;; esac err "${f#${STAGEDIR}${PREFIX}/} is referring to ${STAGEDIR}" rc=1 # Use heredoc to avoid losing rc from find|while subshell done << EOF $(find ${STAGEDIR} -type f -exec grep -l "${STAGEDIR}" {} +) EOF return ${rc} } # For now do not raise an error, just warnings stripped() { [ -x /usr/bin/file ] || return # this is fatal [ -n "${STRIP}" ] || return 0 find ${STAGEDIR} -type f -exec /usr/bin/file -nNF '' {} + | while read f output; do case "${output}" in ELF\ *\ executable,\ *FreeBSD*,\ not\ stripped*|ELF\ *\ shared\ object,\ *FreeBSD*,\ not\ stripped*) warn "${f#${STAGEDIR}${PREFIX}/} is not stripped consider using \${STRIP_CMD}" ;; esac done } desktopfileutils() { if [ -z "${USESDESKTOPFILEUTILS}" ]; then grep -q MimeType= ${STAGEDIR}${PREFIX}/share/applications/*.desktop 2>/dev/null && warn "you need USES=desktop-file-utils" else grep -q MimeType= ${STAGEDIR}${PREFIX}/share/applications/*.desktop 2>/dev/null || warn "you may not need USES=desktop-file-utils" fi return 0 } sharedmimeinfo() { local f found found=0 for f in ${STAGEDIR}${PREFIX}/share/mime/packages/*.xml; do [ "${f}" = "${STAGEDIR}${PREFIX}/share/mime/packages/*.xml" ] && break #no matches [ "${f}" = "${STAGEDIR}${PREFIX}/share/mime/packages/freedesktop.org.xml" ] && continue found=1 break done if [ -z "${USESSHAREDMIMEINFO}" -a ${found} -eq 1 ]; then warn "you need USES=shared-mime-info" elif [ -n "${USESSHAREDMIMEINFO}" -a ${found} -eq 0 ]; then warn "you may not need USES=shared-mime-info" fi return 0 } suidfiles() { local filelist filelist=`find ${STAGEDIR} -type f \ \( -perm -u+x -or -perm -g+x -or -perm -o+x \) \ \( -perm -u+s -or -perm -g+s \)` if [ -n "${filelist}" ]; then warn "setuid files in the stage directory (are these necessary?):" ls -liTd ${filelist} fi return 0 } -checks="shebang symlinks paths stripped desktopfileutils sharedmimeinfo suidfiles" +libtool() { + if [ -z "${USESLIBTOOL}" ]; then + find ${STAGEDIR} -type f -name '*.la' | while read f; do + grep -q 'libtool library' "${f}" && + warn ".la libraries found, port needs USES=libtool" && + return 0 || true + done + # The return above continues here. + fi +} + +checks="shebang symlinks paths stripped desktopfileutils sharedmimeinfo suidfiles libtool" ret=0 cd ${STAGEDIR} for check in ${checks}; do ${check} || ret=1 done exit $ret diff --git a/Mk/bsd.stage.mk b/Mk/bsd.stage.mk index d05e7718f97b..64e674b3185e 100644 --- a/Mk/bsd.stage.mk +++ b/Mk/bsd.stage.mk @@ -1,110 +1,113 @@ # # $FreeBSD$ # STAGEDIR?= ${WRKDIR}/stage DESTDIRNAME?= DESTDIR .if defined(_DESTDIR_VIA_ENV) MAKE_ENV+= ${DESTDIRNAME}=${STAGEDIR} .else MAKE_ARGS+= ${DESTDIRNAME}=${STAGEDIR} .endif QA_ENV+= STAGEDIR=${STAGEDIR} \ PREFIX=${PREFIX} \ LOCALBASE=${LOCALBASE} \ "STRIP=${STRIP}" .if !empty(USES:Mdesktop-file-utils) QA_ENV+= USESDESKTOPFILEUTILS=yes .endif +.if !empty(USES:Mlibtool*) +QA_ENV+= USESLIBTOOL=yes +.endif .if !empty(USES:Mshared-mime-info) QA_ENV+= USESSHAREDMIMEINFO=yes .endif CO_ENV+= STAGEDIR=${STAGEDIR} \ PREFIX=${PREFIX} \ LOCALBASE=${LOCALBASE} \ WRKDIR=${WRKDIR} \ WRKSRC=${WRKSRC} \ MTREE_FILE=${MTREE_FILE} \ GNOME_MTREE_FILE=${GNOME_MTREE_FILE} \ TMPPLIST=${TMPPLIST} \ SCRIPTSDIR=${SCRIPTSDIR} \ WITH_PKGNG=${WITH_PKGNG} \ PLIST_SUB_SED="${PLIST_SUB_SED}" \ PORT_OPTIONS="${PORT_OPTIONS}" \ PORTSDIR="${PORTSDIR}" .if defined(WITH_PKGNG) CO_ENV+= PACKAGE_DEPENDS="${_LIB_RUN_DEPENDS:C,[^:]*:([^:]*):?.*,\1,:C,${PORTSDIR}/,,}" \ PKG_QUERY="${PKG_QUERY}" .else CO_ENV+= PACKAGE_DEPENDS=${ACTUAL-PACKAGE-DEPENDS:Q} \ PKG_QUERY="${PKG_INFO}" .endif .if defined(NO_PREFIX_RMDIR) CO_ENV+= NO_PREFIX_RMDIR=1 .else CO_ENV+= NO_PREFIX_RMDIR=0 .endif .if !target(stage-dir) stage-dir: @${MKDIR} ${STAGEDIR}${PREFIX} .if !defined(NO_MTREE) @${MTREE_CMD} ${MTREE_ARGS} ${STAGEDIR}${PREFIX} > /dev/null .endif .endif # Compress all manpage not already compressed which are not hardlinks # Find all manpages which are not compressed and are hadlinks, and only get the list of inodes concerned, for each of them compress the first one found and recreate the hardlinks for the others # Fixes all dead symlinks left by the previous round .if !target(compress-man) compress-man: @${ECHO_MSG} "====> Compressing man pages (compress-man)" @mdirs= ; \ for dir in ${MANDIRS:S/^/${STAGEDIR}/} ; do \ [ -d $$dir ] && mdirs="$$mdirs $$dir" ;\ done ; \ for dir in $$mdirs; do \ ${FIND} $$dir -type f \! -name "*.gz" -links 1 -exec ${GZIP_CMD} {} \; ; \ ${FIND} $$dir -type f \! -name "*.gz" \! -links 1 -exec ${STAT} -f '%i' {} \; | \ ${SORT} -u | while read inode ; do \ unset ref ; \ for f in $$(${FIND} $$dir -type f -inum $${inode} -print); do \ if [ -z $$ref ]; then \ ref=$${f}.gz ; \ ${GZIP_CMD} $${f} ; \ continue ; \ fi ; \ ${RM} -f $${f} ; \ (cd $${f%/*}; ${LN} -f $${ref##*/} $${f##*/}.gz) ; \ done ; \ done ; \ ${FIND} $$dir -type l \! -name "*.gz" | while read link ; do \ dest=$$(readlink $$link) ; \ rm -f $$link ; \ (cd $${link%/*} ; ${LN} -sf $${dest##*/}.gz $${link##*/}.gz) ;\ done; \ done .endif .if !target(makeplist) makeplist: stage @${SETENV} ${CO_ENV} ${SH} ${SCRIPTSDIR}/check-stagedir.sh makeplist .endif .if !target(check-plist) check-plist: stage @${ECHO_MSG} "====> Checking for pkg-plist issues (check-plist)" @${SETENV} ${CO_ENV} ${SH} ${SCRIPTSDIR}/check-stagedir.sh checkplist @${ECHO_MSG} "===> No pkg-plist issues found (check-plist)" .endif .if !target(check-orphans) check-orphans: check-plist .endif .if !target(stage-qa) stage-qa: @${ECHO_MSG} "====> Running Q/A tests (stage-qa)" @${SETENV} ${QA_ENV} ${SH} ${SCRIPTSDIR}/qa.sh .endif