tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Summary of implicit DEPENDS problem



Here's my attempt to summarise the issue with implicit depends.

Before listing the general issues, I should point out that I discovered that my environment was exacerbating the problem. Our GCC packages set --with-local-prefix to PREFIX, so that users can build software using libraries installed by pkgsrc easily outside of a pkgsrc environment.

Unfortunately this effectively bypasses the buildlink wrappers. pbulk helps to ensure only dependencies are available during each package build, but due to the issues enumerated below, we can still end up linking against libraries that are installed as dependencies but not buildlinked and have it pass check-shlibs, resulting in shipping broken packages.

I've since fixed this part at least by enhancing our gcc-libs specs files to set link_* to sanitised library paths:

  https://github.com/TritonDataCenter/pkgsrc-extra/commit/83ec13fb4ade1c115334fa7e73f0cdd3284c5aae

Ok, onto the issues.

 * Problem 1: check-shlibs is insufficient.

   In its current form, mk/check/check-shlibs-elf.awk only checks packages
   that are listed in the depends file, and the depends file only contains
   direct dependencies.  If a file is linked against a library from an
   indirect dependency then it is ignored, even though that library may not
   be a runtime dependency.

   For a concrete example, nodejs had a build dependency on python which
   included python's buildlink3.mk, which in turn pulled in libiconv.
   nodejs then linked against libiconv, but as libiconv wasn't listed in
   the depends file at all, check-shlibs simply ignored it.  We ended up
   shipping a broken node package that failed at runtime because it was
   missing a dependency on libiconv.

   One might ask why we don't just uncomment the "Not yet" that would
   enable checking all packages:

     https://github.com/TritonDataCenter/pkgsrc/blob/trunk/mk/check/check-shlibs-elf.awk#L99-L100

   The simple answer is because it breaks a huge amount of packages.  I
   tried this in a bulk build and gave up pretty quickly.  Outside of a
   pbulk environment where there may be lots of random packages installed
   for the build to pick up, the results would only be worse.

 * Problem 2: BUILDLINK_DEPMETHOD doesn't propagate correctly

   BUILDLINK_DEPMETHOD for each package defaults to "full", unless it is
   overridden somewhere.  This means that dependencies that are included
   by a package with DEPMETHOD set to "build" are incorrectly tagged as
   "full".  For example consider the following:

    category/package/Makefile:
     BUILDLINK_DEPMETHOD.foo= build
     .include "../../category/foo/buildlink3.mk"

    category/foo/buildlink3.mk:
     .include "../../category/bar/buildlink3.mk"

   BUILDLINK_DEPMETHOD.foo will be set to "build", but
   BUILDLINK_DEPMETHOD.bar will be set to "full".

   This causes problems with check-shlibs, as it will think bar is a full
   dependency, but in reality it is not and won't be available at runtime.

   My current patch-set fixes this by using pushing depmethod onto a stack
   while the buildlink tree is parsed, similar to how USE_BUILTIN is
   correctly propagated, but we then run into the next problem.

 * Problem 3: buildlink3.mk inclusion guards

   Every buildlink3.mk file contains the following form:

    .if !defined(FOO_BUILDLINK3_MK)
    FOO_BUILDLINK3_MK:=
    ..logic to .include other bl3, set DEPMETHOD, etc.
    .endif

   This means that packages never see the full dependency graph, they only
   see direct dependencies, and unique indirect dependencies.  Let's use
   harfbuzz as a real-world example of how this breaks things, using the
   tree prior to my commit to work around the problem.

     $ cd fonts/harfbuzz
     $ bmake show-buildlink3
     gtk-doc
         glib2
             iconv
             gettext
                 iconv
             libffi
             pcre2
             zlib
             pthread
     glib2
     gobject-introspection
     ...

   gtk-doc's buildlink3.mk explicitly sets DEPMETHOD=build, which is
   reasonable as it's only ever used at build time.  It in turn includes
   glib2, which is then tagged as "build" too.

   Later, harfbuzz also directly includes glib2 as it is required as a full
   dependency.  However, because of the buildlink3 inclusion guards, while
   glib2 will now correctly be set to "full" (because that's the default for
   top-level inclusions), none of its .includes will be re-parsed and also
   tagged as "full".  You can see that clearly in the "show-buildlink3"
   output as the second "glib2" never descends into its dependencies again.

   This is why my hacky fix for now is to include glib2 prior to gtk-doc,
   so that glib2 and all its dependencies are correctly logged as "full",
   before including gtk-doc as "build".

   I don't know how to fix this without a radical overhaul of buildlink3.mk
   files.  Joerg suggested including additional metadata in BUILDLINK_TREE
   identifiers, but I still don't see how this gets around the inclusion
   guard problem.

My current patch to resolve the issues that I'm able to at this time is available here:

  https://github.com/TritonDataCenter/pkgsrc/commit/b6c52a5e078640b9b768d08e760c4f897ca3aedc

This:

  * Fixes problem #2, but is incomplete due to problem #3.

  * Adds IMPLICIT_DEPENDS and IMPLICIT_BUILD_DEPENDS, ensuring that the
    depends file includes them too.

  * Enhances check-shlibs to account for implicit dependencies, and fails if
    a package links against any file that is not either a "full" or
    "implicit-full" dependency.

As per the commit message, this isn't ready for integrating into pkgsrc yet though. Due to problem #3 we see occasional false positives if an indirect dependency is tagged as "build" when it is later correctly tagged as "full".

I'm happy to keep this in my tree for now and commit workarounds as I find them, as I don't think other folks would be happy with any false positives.

Ideas on how to solve this completely would be appreciated. For now I'm mainly focussed on ensuring my binary packages are not broken as I consider that to be a critical failure that I'm pretty embarrassed about :/

Cheers,

--
Jonathan Perkin   -   mnx.io   -   pkgsrc.smartos.org
Open Source Complete Cloud   www.tritondatacenter.com


Home | Main Index | Thread Index | Old Index