Subject: The infamous hidden dependencies problem
To: None <tech-pkg@netbsd.org>
From: Johnny C. Lam <lamj@stat.cmu.edu>
List: tech-pkg
Date: 06/07/2001 17:19:59
So there have been several PRs related to so-called "hidden dependencies"
that occur when a package build finds pkgsrc-installed libraries or
headers and proceeds to use them or to link against them even though they
are only optional and aren't listed in the package dependencies.  This
has been an annoying problem, as the fixes to date have involved patching
configure scripts to remove checks for all libraries and headers for
packages not explicitly listed in the dependencies.  The problem also
tends not to be noticed until someone with a sufficiently large number
of packages installed tries to build a sufficiently complex package.

Hidden dependencies seem to occur primarily with packages that use GNU
configure scripts, and they seem to mainly occur with pkgsrc-installed
libraries being found due to the -L${LOCALBASE}/lib flag passed via
LDFLAGS.  I'd like to propose the following solution, though it may
involve some work.

Some of you may have noticed some commits related to buildlink.mk files.
The idea behind them is that they define targets that are meant to be
called at pre-configure time that link libraries and headers for that
package into ${BUILDLINK_LIBDIR} (${WRKDIR}/lib) and ${BUILDLINK_INCDIR}
(${WRKDIR}/include).  The package that needs to use those headers and
libraries then passes -I${BUILDLINK_INCDIR} to CFLAGS and/or CPPFLAGS and
-L${BUILDLINK_LIBDIR} to LDFLAGS.  To prevent accidental linkage against
libraries already installed under ${LOCALBASE}, we only pass the rpath
flags to LDFLAGS, so instead of:

	LDFLAGS+=	-Wl,-R${LOCALBASE}/lib -L${LOCALBASE}/lib

we have:

	LDFLAGS+=	-Wl,-R${LOCALBASE}/lib
	LDFLAGS+=	-L${BUILDLINK_LIBDIR}

The thing that needs doing is for all the packages that install libraries
and headers, create a buildlink.mk file, then for all the packages that
use libraries and headers, change them to use buildlink.mk files.  For
an example, see pkgsrc/print/cups.

The problem with this is that it doesn't protect against libraries
installed in ${X11BASE}.  This isn't an issue if you use xpkgwedge, as all
the package libraries are installed under ${LOCALBASE}, but if you do
install libraries under ${X11BASE}, then if a package has USE_X11 defined,
then any package libraries installed under ${X11BASE} may be accidentally
found by the configure script.

I'm willing to do the majority of the work to implement this solution,
but I'm hoping for some discussion on my theory of how to solve this
problem.

Does anyone have any thoughts on this?  Is this too involved?  Is this a
good or a bad way to solve the hidden dependency problem?

	Thanks,

     -- Johnny C. Lam <lamj@stat.cmu.edu>
        Department of Statistics, Carnegie Mellon University
        http://www.stat.cmu.edu/~lamj/