Dependency Discovery
Introduction
"Slackware users typically prefer their method of manual dependency resolution, citing the level of system control it grants them." - as the ArchWiki says. This total control over the system is one of the main strength of the Slackware distribution.
If the administrator of the system knows every package on the system and ensures their every dependencies, then the system is stable, well usable. If the administrator installs a new, (until now) unknown application, then he/she needs to discover its dependencies via the attached README or documentations, or from starting the application (if something is not installed on the system, then the application won't start).
Dependency resolution at package installation
The dependency resolution can be performed at package installation, if we use a third party package manager, see Third_Party_Package_Managers. This is very easy, but we should use that third party package manager and maybe we don't want to do it just for a simple package installation. We would like a more Slackware like solution.
Dependency discovery as a separate task
We can discover the dependencies of our system in separate task using the 'ldd
' command. This is not third party application, it is the part of our system.
We can scan the binaries in our PATH:
#!/bin/bash ECHO=/usr/bin/echo SED=/usr/bin/sed FILE=/usr/bin/file CUT=/usr/bin/cut LDD=/usr/bin/ldd GREP=/usr/bin/grep AWK=/usr/bin/awk for p in `$ECHO $PATH | $SED 's/:/ /g'` do for f in $p/* do if [ 'ELF' == `$FILE -b $f | $CUT -d' ' -f1` ]; then if $LDD $f | $GREP -q 'not found'; then $ECHO "$f" $LDD $f | $GREP 'not found' | $AWK '{print "Not found:", $1}' fi fi done done
Or, we can print the missing package names instead of the missing library names, so we have to install only the given packages mentioned by this script (I used the concatenated MANIFEST file of 'slackpkg
' on Slackware64, this file list is more friendlier for scripting):
#!/bin/bash # This is the concatenated MANIFEST file of slackpkg on Slackware64 MANIFEST=/var/lib/slackpkg/slackware64-filelist.gz # Do not trust in any command in PATH, shell builtins, etc. ECHO=/usr/bin/echo PRINTF=/usr/bin/printf CUT=/usr/bin/cut SORT=/usr/bin/sort GREP=/usr/bin/grep ZGREP=/usr/bin/zgrep SED=/usr/bin/sed AWK=/usr/bin/awk FILE=/usr/bin/file LDD=/usr/bin/ldd NULL=/dev/null # Check all directories in PATH for directory in `$ECHO $PATH | $SED 's/:/ /g'` do # Check all binaries in PATH directories for binary in $directory/* do # If it is true ELF binary if [ 'ELF' == `$FILE -b $binary | $CUT -d' ' -f1` ]; then # Show the progress by printing of actual filename on standard error $PRINTF "%-70s\r" $binary >&2 # Check the missing shared library dependencies $LDD $binary 2>$NULL | $GREP 'not found' | $AWK '{print $1}' | while read missing_lib do # Print the package name of the missing library $ZGREP $missing_lib $MANIFEST | $AWK '{print $1}' done fi done # Clear the progress info $PRINTF "%-80s\r" "" >&2 # Ignore the duplicated package names done | $SORT -u
If we would like to scan the binaries of the PATH and the shared libraries of our system, then we need a deeper directory discovery:
#!/bin/bash # This is the concatenated MANIFEST file of slackpkg on Slackware64 MANIFEST=/var/lib/slackpkg/slackware64-filelist.gz # Do not trust in any command in PATH, shell builtins, etc. SYSPATH=$PATH PATH=/bin:/usr/bin:/usr/sbin ECHO=/usr/bin/echo PRINTF=/usr/bin/printf # Check all directories in PATH and ld.so.conf # If it is true ELF binary find `$ECHO $SYSPATH | sed 's/:/ /g'` \ `sed 's/\(\/.*\/.*\)\/.*/\1/' /etc/ld.so.conf | sort -u` \ -perm -100 -a -type f \ -exec sh -c 'filename="{}"; /usr/bin/echo -n "." >&2; \ [ "ELF" = `file -b $filename | cut -d" " -f1` ] && \ ldd $filename 2>/dev/null | fgrep "not found" \ | cut -d" " -f1' \; | while read missing_lib do # Print the missing library and its package name $ECHO $missing_lib ": `zgrep $missing_lib $MANIFEST | cut -d" " -f1`" done | sort -u
This small script will browse huge amount of directories and will scan a lot of ELF binaries, so it can run for a long time. There are more effective ways of the dependency discovery, this is only a very simple solution for a natural system administrator need. It demonstrates that a Slackware user does not need a package manager with dependency resolution, but even so can have a stable, well configured system.