如何确定包的依赖关系

如何确定包的依赖关系

在创建 PKGBUILD 之前,我总是使用 ldd 实用程序仔细检查应用程序所需的库。软件开发人员经常从自述/安装文件中省略所需的包,并且包名称在发行版之间经常有所不同。某些软件包可能在一个发行版上需要,而在其他发行版上则不需要。我发现 ldd 对于确定包依赖项的基本列表非常有用。

然而,显示的核心包和其他常见包如此之多,似乎没有必要将它们全部包含在 PKGBUILD 中。其中有多少库可以安全地从依赖项列表中排除?例如,几乎每个 GUI 应用程序都会列出相同的 x11 库。我个人没有使用过 Wayland,但我假设如果应用程序是在 Wayland 系统上编译的,那么这些 x11 库将被 Wayland 库替换。因此,包含 x11 或 wayland 库作为依赖项可能没有意义。

示例:libx11、libxau、libxcb、libxdamage、libxdmcp、libxext、libxfixes、libxshmfence、libxxf86vm

ldd 列出的库中有多少实际上与 PKGBUILD 相关?我看到几乎每个应用程序都列出了 libdrm 和 libgl。如果用户使用 xrender 而不是 GL 怎么办?如果未安装 libdrm 并且用户不想安装它怎么办?

是否有任何核心包应列为依赖项?如果没有 zlib、systemd 或 glibc,应用程序可能无法运行,但我假设这些包几乎存在于每个系统上。将这些包作为依赖项包含进来似乎是多余的。

如果您已在系统上成功编译了应用程序,并且不确定是否列出了所有依赖项,那么确定包依赖项的完整列表的最佳方法是什么?


为了帮助说明我的问题,我整理了这个 bash 脚本。它将检测任何给定二进制文件所需的所有库。然后它将它们解析为包名称。它需要 readlink、ldd、pkgfile 和 sort。

用法: getdepends -i /usr/bin/ark -f -e

-f 将格式化输出以直接粘贴到 PKGBUILD 中。 -e 将跳过核心包(可能不适用于所有基于架构的发行版)。

#!/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

如果您要在 ark 二进制文件上运行该脚本,您会注意到显示的相当多的软件包未包含在 arch PKGBUILD 中。那么,如何确定将哪些包作为依赖项包含在内呢?

方舟PKGBUILD

相关内容