![如何确定包的依赖关系](https://linux22.com/image/106494/%E5%A6%82%E4%BD%95%E7%A1%AE%E5%AE%9A%E5%8C%85%E7%9A%84%E4%BE%9D%E8%B5%96%E5%85%B3%E7%B3%BB.png)
在创建 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 中。那么,如何确定将哪些包作为依赖项包含在内呢?