1

Before I create a PKGBUILD I always double check the required libraries of an application with the ldd utility. Software developers frequently omit required packages from their README/INSTALL files and package names frequently differ between distributions. Some packages may be required on one distribution while being unnecessary on other distributions. I've found ldd to be invaluable for determining the essential list of package dependencies.

However, there are so many core packages and other common packages displayed that it seems unnecessary to include them all in a PKGBUILD. How many of these libraries are safe to exclude from the depends list? For example, nearly every gui application will list the same x11 libraries. I haven't personally used Wayland but I would assume that if an application was compiled on a wayland system then those x11 libs would be replaced by wayland libs. So it probably wouldn't make sense to include x11 or wayland libs as dependencies.

Examples: libx11, libxau, libxcb, libxdamage, libxdmcp, libxext, libxfixes, libxshmfence, libxxf86vm

How many libraries listed by ldd are actually relevant to a PKGBUILD? I see libdrm and libgl listed for nearly every application. What if a user is using xrender instead of GL? What if libdrm isn't installed and the user doesn't want it installed?

Are there any core packages that should be listed as dependencies? The application might not be able to run without zlib, systemd or glibc but I would assume that those packages are present on nearly every system. It seems redundant to include those packages as dependencies.

If you've successfully compiled an application on your system and you're unsure if you've listed all of the dependencies, what is the best way to determine the complete list of package dependencies?


To help illustrate my questions I put together this bash script. It will detect all required libraries for any given binary file. It will then resolve them to package names. It requires readlink, ldd, pkgfile and sort.

Usage: getdepends -i /usr/bin/ark -f -e

The -f will format the output to paste directly into a PKGBUILD. The -e will skip core packages (may not work on all arch-based distributions).

#!/bin/bash

usage() { echo "Usage: $0 [-i <input file path>] [-f <format output for PKGBUILD>] [-e <exclude core packages>]" 1>&2; exit 0; }

while getopts ":i:fe" o; do
    case "${o}" in
        i)
            i=${OPTARG}
            INPATH=$(readlink -mn "$i")
            ;;
        f)
            FMT=1
            ;;
        e)
            EXC=1
            ;;
        *)
            usage
            ;;
    esac
done
shift $((OPTIND-1))

if [ ! -e "$INPATH" ]; then
    echo "The specified input path does not exist."
    usage
fi

LIBS=$(ldd "$INPATH" | sort)

TAB=$'\t'
IFS=$'\n'
PKGS=()

for l in $LIBS; do
    # strip all characters from ldd output up to "=> "
    l="${l#*=> }"

    # strip all characters from ldd output from " (" to end of string
    l="${l% (*}"

    # continue if library path doesn't exist
    if [ ! -e "$l" ]; then continue; fi

    # get name of package that contains library file path
    PKG=$(pkgfile -ri "$l")

    # continue if no package found
    if [ -z "$PKG" ]; then continue; fi

    # exclude option detected. skip core packages.
    if [ ! -z "$EXC" ] && [[ "${PKG}" =~ ^core/ ]]; then continue; fi

    # strip all characters up to leading slash (i.e., core/readline)
    PKG="${PKG#*/}"

    # strip all characters following a new line. this may occur
    # if the same file and path are found in multiple packages.
    # since there's no way of determining which package the app
    # requires when there are duplicates of the same file we just
    # take the first package listed.
    PKG=${PKG%%"$IFS"*}

    if [ ! -z "$FMT" ]; then
        # format option detected. add tabs and single quotes.
        PKGS+=("$TAB'${PKG}'")
    else
        # do not format output
        PKGS+=("${PKG}")
    fi
done

# sort a-z and remove duplicates
PKGSORT=($(sort -u <<< "${PKGS[*]}"))

if [ ! -z "$FMT" ]; then
    # format option detected. declare depends array.
    echo "depends=("
fi

printf '%s\n' "${PKGSORT[@]}"

if [ ! -z "$FMT" ]; then
    # format option detected. close depends array.
    echo -n ")"
fi

unset IFS

If you were to run that script on the ark binary you'd notice that there are quite a few packages displayed that aren't included in the arch PKGBUILD. So how does someone determine which packages to include as dependencies?

ark PKGBUILD

  • glibc could totally be missing if they've instead gone with musl or some other libc implementation. Who are the users of the app, and would they know what to do if libz errors popped up? – thrig Feb 27 '17 at 22:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.