From 9693c85f5291d527db6828f29221324028f05aa8 Mon Sep 17 00:00:00 2001 From: Alexey Tourbin Date: Fri, 9 Mar 2007 21:11:03 +0300 Subject: [PATCH] implemented symlinks.req Consider R-devel package, which has its own private bin/ directory, where it keeps certain scripts. $ rpm -ql R-devel |grep libtool /usr/lib/R/bin/libtool $ rpm -ql R-devel |grep texi2dvi /usr/lib/R/bin/texi2dvi $ I replace some scripts, such as libtool, with wrappers: $ tail -1 /usr/lib/R/bin/libtool exec /usr/bin/libtool "$@" $ R-devel now has a libtool dependency, generated by shell.req: $ rpm -qR R-devel |grep libtool libtool-common $ rpm -qf /usr/bin/libtool libtool-common-0.2-alt1 $ However, I want the very same dependency SIMPLY BY PLACING SYMBOLIC LINK to /usr/bin/libtool. My new script symlinks.req implements this idea. It works as follows: 1) We check all absolute symbolic links, e.g. -> /usr/bin/libtool. If symbolic link is absolute, we fetch its value and feed to FindPackage. Note that FindPackage will first check whether e.g. /usr/bin/libtool is available under RPM_BUILD_ROOT. 2) We also check all broken symbolic links, e.g. -> ../../../bin/libtool. The fact that symbolic link is broken means that it cannot be resolved into buildroot and otherwise must be resolved in the host system after the package is installed, which is the dependency on where it would point to after install. This means we must canonicalize the link value, strip RPM_BUILD_ROOT, and then call FindPackage. Here is what happens: $ cd `mktemp -d` $ RPM_BUILD_ROOT=$PWD $ mkdir -p ./usr/lib/R/bin/ $ ln -s `relative /usr/bin/libtool /usr/lib/R/bin/libtool` $RPM_BUILD_ROOT/usr/lib/R/bin/libtool $ l $RPM_BUILD_ROOT/usr/lib/R/bin/libtool lrwxrwxrwx 1 at at 20 Mar 9 22:14 /tmp/.private/at/tmp.AHnBX26473/usr/lib/R/bin/libtool -> ../../../bin/libtool $ [ -e $RPM_BUILD_ROOT/usr/lib/R/bin/libtool ] || echo broken broken $ readlink -vm $RPM_BUILD_ROOT/usr/lib/R/bin/libtool /tmp/.private/at/tmp.AHnBX26473/usr/bin/libtool $ to=`!!`; echo ${to#$RPM_BUILD_ROOT} /usr/bin/libtool $ And then FindPackage is called with "/usr/bin/libtool". Now note that if FindPackage is not able to associate e.g. /usr/bin/libtool with any particular rpm package, it will just place raw dependency on /usr/bin/libtool. So, this new type of dependencies is a bit dangerous: basically for each really broken symbolic link there will be an unmet dependency. On the other hand, this can be viewed as a means of protection from packages with really broken symbolic links. If you are frightened with this brand new and dangerous type of dependencies, please also note that this new type of dependencies is not much more dangerous than absolute paths to executables in plain shell scripts. $ /usr/lib/rpm/shell.req -v /dev/stdin << /i/am/unmet (raw, not found) /i/am/unmet $ --- configure.in | 1 + rpm-4_0.spec | 1 + scripts/Makefile.am | 2 ++ scripts/symlinks.req.files | 9 +++++++++ scripts/symlinks.req.in | 22 ++++++++++++++++++++++ 5 files changed, 35 insertions(+) create mode 100755 scripts/symlinks.req.files create mode 100644 scripts/symlinks.req.in diff --git a/configure.in b/configure.in index 1ed61cc..ce8b41b 100644 --- a/configure.in +++ b/configure.in @@ -1009,6 +1009,7 @@ AC_OUTPUT([ Doxyfile Makefile rpmrc macros platform rpmpopt rpm.spec scripts/shell.req scripts/static.req scripts/strip_files + scripts/symlinks.req scripts/verify-elf tests/Makefile tests/rpmrc tests/macros tests/hello-test/Makefile po/Makefile.in diff --git a/rpm-4_0.spec b/rpm-4_0.spec index 7fb8cde..38232be 100644 --- a/rpm-4_0.spec +++ b/rpm-4_0.spec @@ -476,6 +476,7 @@ fi %rpmattr %_rpmlibdir/shell.* %rpmattr %_rpmlibdir/shebang.* %rpmattr %_rpmlibdir/static.* +%rpmattr %_rpmlibdir/symlinks.* %rpmattr %_rpmlibdir/verify-elf %rpmattr %_rpmlibdir/Specfile.pm %rpmattr %_rpmlibdir/*.awk diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 0045d99..1e1e27c 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -20,6 +20,7 @@ EXTRA_DIST = \ shell.req shell.req.files shell.prov shell.prov.files \ sql.prov sql.req strip_files \ static.req static.req.files \ + symlinks.req symlinks.req.files \ tcl.req trpm u_pkg.sh verify-elf vpkg-provides.sh vpkg-provides2.sh installprefix = $(DESTDIR) @@ -45,4 +46,5 @@ config_SCRIPTS = \ shell.req shell.req.files shell.prov shell.prov.files \ sql.prov sql.req strip_files \ static.req static.req.files \ + symlinks.req symlinks.req.files \ tcl.req trpm u_pkg.sh verify-elf vpkg-provides.sh vpkg-provides2.sh diff --git a/scripts/symlinks.req.files b/scripts/symlinks.req.files new file mode 100755 index 0000000..84167a8 --- /dev/null +++ b/scripts/symlinks.req.files @@ -0,0 +1,9 @@ +#!/bin/sh -efu +while IFS=$'\t' read -r f t; do + case "$t" in + *'symbolic link to `/'*) + echo "$f"; continue ;; + *'broken symbolic link to '*) + echo "$f"; continue ;; + esac +done diff --git a/scripts/symlinks.req.in b/scripts/symlinks.req.in new file mode 100644 index 0000000..03dfcc8 --- /dev/null +++ b/scripts/symlinks.req.in @@ -0,0 +1,22 @@ +#!/bin/sh -efu + +. @RPMCONFIGDIR@/functions +. @RPMCONFIGDIR@/find-package +[ -n "${RPM_BUILD_ROOT-}" ] || Fatal "I do need RPM_BUILD_ROOT" +real_buildroot=$(cd "$RPM_BUILD_ROOT" && /bin/pwd) || exit 1 + +SymlinkReq() +{ + local f="$1"; shift + [ -L "$f" ] || return 0 + local to=; to=$(readlink -v "$f") + if [ -n "$to" -a -z "${to##/*}" ]; then + FindPackage "$f" "$to" + elif ! [ -e "$f" ]; then + to=$(readlink -vm "$f") + to=${to#$real_buildroot} + FindPackage "$f" "$to" + fi +} + +ArgvFileAction SymlinkReq "$@"