diff --git a/common/hooks/post-install/99-remove-empty-dirs.sh b/common/hooks/post-install/03-remove-empty-dirs.sh similarity index 100% rename from common/hooks/post-install/99-remove-empty-dirs.sh rename to common/hooks/post-install/03-remove-empty-dirs.sh diff --git a/common/hooks/post-install/03-strip-and-debug-pkgs.sh b/common/hooks/post-install/03-strip-and-debug-pkgs.sh new file mode 100644 index 0000000000..825b0520b5 --- /dev/null +++ b/common/hooks/post-install/03-strip-and-debug-pkgs.sh @@ -0,0 +1,128 @@ +# This hook executes the following tasks: +# - strips ELF binaries/libraries +# - generates -dbg pkgs +# - generates shlib-provides file for xbps-create(8) + +make_debug() { + local dname= fname= dbgfile= + + [ -n "$disable_debug" ] && return 0 + + dname=$(echo "$(dirname $1)"|sed -e "s|${PKGDESTDIR}||g") + fname="$(basename $1)" + dbgfile="${dname}/${fname}" + + mkdir -p "${PKGDESTDIR}/usr/lib/debug/${dname}" + $OBJCOPY --only-keep-debug --compress-debug-sections \ + "$1" "${PKGDESTDIR}/usr/lib/debug/${dbgfile}" + if [ $? -ne 0 ]; then + msg_red "${pkgver}: failed to create dbg file: ${dbgfile}\n" + return 1 + fi + chmod 644 "${PKGDESTDIR}/usr/lib/debug/${dbgfile}" +} + +attach_debug() { + local dname= fname= dbgfile= + + [ -n "$disable_debug" ] && return 0 + + dname=$(echo "$(dirname $1)"|sed -e "s|${PKGDESTDIR}||g") + fname="$(basename $1)" + dbgfile="${dname}/${fname}" + + $OBJCOPY --add-gnu-debuglink="${PKGDESTDIR}/usr/lib/debug/${dbgfile}" "$1" + if [ $? -ne 0 ]; then + msg_red "${pkgver}: failed to attach dbg to ${dbgfile}\n" + return 1 + fi +} + +create_debug_pkg() { + local _pkgname= _destdir= + + [ -n "$disable_debug" ] && return 0 + [ ! -d "${PKGDESTDIR}/usr/lib/debug" ] && return 0 + + _pkgname="${pkgname}-dbg-${version}" + _destdir="${XBPS_DESTDIR}/${XBPS_CROSS_TRIPLET}/${_pkgname}" + mkdir -p "${_destdir}/usr/lib" + mv ${PKGDESTDIR}/usr/lib/debug ${_destdir}/usr/lib + if [ $? -ne 0 ]; then + msg_red "$pkgver: failed to create debug pkg\n" + return 1 + fi + rmdir --ignore-fail-on-non-empty "${PKGDESTDIR}/usr/lib" 2>/dev/null + return 0 +} + +hook() { + local fname= x= f= _soname= + + find ${PKGDESTDIR} -type f | while read f; do + fname=$(basename "$f") + for x in ${nostrip_files}; do + if [ "$x" = "$fname" ]; then + found=1 + break + fi + done + if [ -n "$found" ]; then + unset found + continue + fi + case "$(file -bi "$f")" in + application/x-executable*) + if echo "$(file $f)" | grep -q "statically linked"; then + # static binary + $STRIP "$f" + if [ $? -ne 0 ]; then + msg_red "$pkgver: failed to strip ${f#$PKGDESTDIR}\n" + return 1 + fi + echo " Stripped static executable: ${f#$PKGDESTDIR}" + else + make_debug "$f" + $STRIP "$f" + if [ $? -ne 0 ]; then + msg_red "$pkgver: failed to strip ${f#$PKGDESTDIR}\n" + return 1 + fi + echo " Stripped executable: ${f#$PKGDESTDIR}" + attach_debug "$f" + fi + ;; + application/x-sharedlib*) + # shared library + make_debug "$f" + $STRIP --strip-unneeded "$f" + if [ $? -ne 0 ]; then + msg_red "$pkgver: failed to strip ${f#$PKGDESTDIR}\n" + return 1 + fi + echo " Stripped library: ${f#$PKGDESTDIR}" + _soname=$(objdump -p "$f"|grep SONAME|awk '{print $2}') + if [ -n "${_soname}" ]; then + echo "${_soname}" >> ${PKGDESTDIR}/.shlib-provides + fi + attach_debug "$f" + ;; + application/x-archive*) + $STRIP --strip-debug "$f" + if [ $? -ne 0 ]; then + msg_red "$pkgver: failed to strip ${f#$PKGDESTDIR}\n" + return 1 + fi + echo " Stripped static library: ${f#$PKGDESTDIR}";; + esac + done + + if [ -s "$PKGDESTDIR/.shlib-provides" ]; then + cat $PKGDESTDIR/.shlib-provides | tr '\n' ' ' > $PKGDESTDIR/shlib-provides + echo >> $PKGDESTDIR/shlib-provides + rm -f $PKGDESTDIR/.shlib-provides + fi + + create_debug_pkg + return $? +} diff --git a/common/hooks/post-install/04-generate-runtime-deps.sh b/common/hooks/post-install/04-generate-runtime-deps.sh new file mode 100644 index 0000000000..c54e632577 --- /dev/null +++ b/common/hooks/post-install/04-generate-runtime-deps.sh @@ -0,0 +1,153 @@ +# This hook executes the following tasks: +# - Generates rdeps file with run-time dependencies for xbps-create(8) +# - Generates shlib-requires file for xbps-create(8) + +add_rundep() { + local dep="$1" i= rpkgdep= _depname= _rdeps= found= + + _depname="$($XBPS_UHELPER_CMD getpkgdepname ${dep} 2>/dev/null)" + if [ -z "${_depname}" ]; then + _depname="$($XBPS_UHELPER_CMD getpkgname ${dep} 2>/dev/null)" + fi + + for i in ${run_depends}; do + rpkgdep="$($XBPS_UHELPER_CMD getpkgdepname $i 2>/dev/null)" + if [ -z "$rpkgdep" ]; then + rpkgdep="$($XBPS_UHELPER_CMD getpkgname $i 2>/dev/null)" + fi + if [ "${rpkgdep}" != "${_depname}" ]; then + continue + fi + $XBPS_UHELPER_CMD cmpver "$i" "$dep" + rval=$? + if [ $rval -eq 255 ]; then + run_depends="${run_depends/${i}/${dep}}" + fi + found=1 + done + if [ -z "$found" ]; then + run_depends+=" ${dep}" + fi +} + +hook() { + local depsftmp f j tmplf mapshlibs sorequires + + mapshlibs=$XBPS_COMMONDIR/shlibs + tmplf=$XBPS_SRCPKGDIR/$pkgname/template + + if [ -n "$noarch" -o -n "$noverifyrdeps" ]; then + echo "$run_depends" > ${PKGDESTDIR}/rdeps + return 0 + fi + + depsftmp=$(mktemp -t xbps_src_depstmp.XXXXXXXXXX) || return 1 + find ${PKGDESTDIR} -type f -perm -u+w > $depsftmp 2>/dev/null + + exec 3<&0 # save stdin + exec < $depsftmp + while read f; do + case "$(file -bi "$f")" in + application/x-executable*|application/x-sharedlib*) + for nlib in $($OBJDUMP -p "$f"|grep NEEDED|awk '{print $2}'); do + if [ -z "$verify_deps" ]; then + verify_deps="$nlib" + continue + fi + for j in ${verify_deps}; do + [ "$j" != "$nlib" ] && continue + found_dup=1 + break + done + if [ -z "$found_dup" ]; then + verify_deps="$verify_deps $nlib" + fi + unset found_dup + done + ;; + esac + done + exec 0<&3 # restore stdin + rm -f $depsftmp + + # + # Add required run time packages by using required shlibs resolved + # above, the mapping is done thru the mapping_shlib_binpkg.txt file. + # + for f in ${verify_deps}; do + unset _f j rdep _rdep rdepcnt soname _pkgname _rdepver found + _f=$(echo "$f"|sed 's|\+|\\+|g') + rdep="$(grep -E "^${_f}[[:blank:]]+.*$" $mapshlibs|awk '{print $2}')" + rdepcnt="$(grep -E "^${_f}[[:blank:]]+.*$" $mapshlibs|awk '{print $2}'|wc -l)" + if [ -z "$rdep" ]; then + # Ignore libs by current pkg + soname=$(find ${PKGDESTDIR} -name "$f") + if [ -z "$soname" ]; then + msg_red_nochroot " SONAME: $f <-> UNKNOWN PKG PLEASE FIX!\n" + broken=1 + else + echo " SONAME: $f <-> $pkgname (ignored)" + fi + continue + elif [ "$rdepcnt" -gt 1 ]; then + unset j found + # Check if shlib is provided by multiple pkgs. + for j in ${rdep}; do + _pkgname=$($XBPS_UHELPER_CMD getpkgname "$j") + # if there's a SONAME matching pkgname, use it. + [ "${pkgname}" != "${_pkgname}" ] && continue + found=1 + break + done + if [ -n "$found" ]; then + _rdep=$j + else + # otherwise pick up the first one. + for j in ${rdep}; do + [ -z "${_rdep}" ] && _rdep=$j + done + fi + else + _rdep=$rdep + fi + _pkgname=$($XBPS_UHELPER_CMD getpkgname "${_rdep}" 2>/dev/null) + _rdepver=$($XBPS_UHELPER_CMD getpkgversion "${_rdep}" 2>/dev/null) + if [ -z "${_pkgname}" -o -z "${_rdepver}" ]; then + msg_red_nochroot " SONAME: $f <-> UNKNOWN PKG PLEASE FIX!\n" + broken=1 + continue + fi + # Check if pkg is a subpkg of sourcepkg; if true, ignore version + # in common/shlibs. + _sdep="${_pkgname}>=${_rdepver}" + for _subpkg in ${subpackages}; do + if [ "${_subpkg}" = "${_pkgname}" ]; then + _sdep="${_pkgname}-${version}_${revision}" + break + fi + done + + if [ "${_pkgname}" != "${pkgname}" ]; then + echo " SONAME: $f <-> ${_sdep}" + sorequires+="${f} " + else + # Ignore libs by current pkg + echo " SONAME: $f <-> ${_rdep} (ignored)" + continue + fi + add_rundep "${_sdep}" + done + # + # If pkg uses any unknown SONAME error out. + # + if [ -n "$broken" -a -z "$allow_unknown_shlibs" ]; then + msg_error "$pkgver: cannot guess required shlibs, aborting!\n" + fi + + if [ -n "$run_depends" ]; then + echo "$run_depends" > ${PKGDESTDIR}/rdeps + fi + if [ -n "${sorequires}" ]; then + echo "${sorequires}" > ${PKGDESTDIR}/shlib-requires + fi +}