Subject: [PATCH] reducing the number of redundant dependencies
To: None <tech-pkg@NetBSD.org>
From: Johnny C. Lam <jlam@buildlink.org>
List: tech-pkg
Date: 01/28/2004 02:11:26
--fdj2RfSjLxBAspz7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

The attached patch is a proof-of-concept for a way to reduce the number
of redundant dependencies added to the DEPENDS or BUILD_DEPENDS of a
package.  There is more work to do to remove more instances of
redundancies, particularly in the run-depends-list target, but the patch
will take:

	BUILDLINK_DEPENDS.zlib+=	zlib>=1.2.0
	BUILDLINK_DEPENDS.zlib+=	zlib>=1.1.4
	BUILDLINK_DEPENDS.zlib+=	zlib>=1.3.1
	BUILDLINK_DEPENDS.zlib+=	zlib>=1.0.2

and add only the strictest dependency, zlib>=1.3.1, to the *DEPENDS line.
The patch will also handle exact dependencies if they are specified, e.g.
BUILDLINK_DEPENDS.zlib+=zlib-1.1.4nb1.

I'm putting this out for comments on ways to improve the algorithm used.

	Cheers,

	-- Johnny Lam <jlam@buildlink.org>

--fdj2RfSjLxBAspz7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="dep_reduce.diff"

Index: bsd.buildlink3.mk
===================================================================
RCS file: /cvsroot/pkgsrc/mk/buildlink3/bsd.buildlink3.mk,v
retrieving revision 1.64
diff -u -r1.64 bsd.buildlink3.mk
--- bsd.buildlink3.mk	27 Jan 2004 12:19:03 -0000	1.64
+++ bsd.buildlink3.mk	28 Jan 2004 02:08:42 -0000
@@ -124,7 +124,58 @@
 .  endif
 .    if defined(BUILDLINK_DEPENDS.${_pkg_}) && \
         defined(BUILDLINK_PKGSRCDIR.${_pkg_})
-.      for _depend_ in ${BUILDLINK_DEPENDS.${_pkg_}}
+#
+# BEGIN dependency reduction
+#
+# This next block of code sets _BLNK_DEPENDS.<pkg> to the strictest set of
+# dependencies it can derive from ${BUILDLINK_DEPENDS.<pkg>}.  It only
+# understands dependencies of the form foo>=1.0, and foo-1.0, and leaves
+# the other dependencies undisturbed.
+#
+# The algorithm takes dependencies of the form foo{>=,-}1.0 and converts
+# them to foo-1.0.  It then compares this pkg name against each dependency
+# to see if it satisfies them all.  The key fact is the the strictest
+# dependency, when converted to a pkg name, will satisfy every dependency.
+#
+_BLNK_DEPENDS.${_pkg_}=		\
+	${BUILDLINK_DEPENDS.${_pkg_}:N[a-zA-Z0-9]*-[0-9]*:N[a-zA-Z0-9]*>=[0-9]*}
+_BLNK_GE_DEPENDS.${_pkg_}=	\
+	${BUILDLINK_DEPENDS.${_pkg_}:M[a-zA-Z0-9]*-[0-9]*}		\
+	${BUILDLINK_DEPENDS.${_pkg_}:M[a-zA-Z0-9]*>=[0-9]*}
+_BLNK_STRICTEST_DEPENDS.${_pkg_}?=	none
+.      for _depend_ in ${_BLNK_GE_DEPENDS.${_pkg_}}
+.        for _dep2pkg_ in ${_depend_:S/>=/-/}
+.          if ${_BLNK_STRICTEST_DEPENDS.${_pkg_}} == "none"
+_BLNK_PKG_SATISFIES_DEP.${_pkg_}=	YES
+.            for _dep_ in ${_BLNK_GE_DEPENDS.${_pkg_}}
+.              if !empty(_BLNK_PKG_SATISFIES_DEP.${_pkg_}:M[yY][eE][sS])
+_BLNK_PKG_SATISFIES_DEP.${_pkg_}!=	\
+	if ${PKG_ADMIN} pmatch '${_dep_}' ${_dep2pkg_}; then		\
+		${ECHO} "YES";						\
+	else								\
+		${ECHO} "NO";						\
+	fi
+.              endif
+.            endfor
+.            if !empty(_BLNK_PKG_SATISFIES_DEP.${_pkg_}:M[yY][eE][sS])
+_BLNK_STRICTEST_DEPENDS.${_pkg_}=	${_depend_}
+.            endif
+.          endif
+.        endfor
+.      endfor
+.      if ${_BLNK_STRICTEST_DEPENDS.${_pkg_}} == "none"
+#
+# If the dependencies simply conflict, then pass them on through to the
+# normal dependency handling code.
+#
+_BLNK_DEPENDS.${_pkg_}=		${BUILDLINK_DEPENDS.${_pkg_}}
+.      else
+_BLNK_DEPENDS.${_pkg_}+=	${_BLNK_STRICTEST_DEPENDS.${_pkg_}}
+.      endif
+#
+# END dependency reduction
+#
+.      for _depend_ in ${_BLNK_DEPENDS.${_pkg_}}
 .        if empty(${_BLNK_DEPMETHOD.${_pkg_}}:M${_depend_}\:*)
 ${_BLNK_DEPMETHOD.${_pkg_}}+=	${_depend_}:${BUILDLINK_PKGSRCDIR.${_pkg_}}
 .        endif

--fdj2RfSjLxBAspz7--