Enforcing library version in a port Makefile?

Peter Pentchev roam at ringlet.net
Fri Oct 16 09:13:09 UTC 2009

On Sun, Oct 11, 2009 at 09:49:28AM -0500, Alex Stangl wrote:
> On Sun, Oct 11, 2009 at 05:15:58AM +0000, b. f. wrote:
> > Alex Stangl wrote:
> > >I am trying to create a new port. The software I am trying to port uses
> > >scons which calls out to pkg-config to check for certain minimal library
> > >version #s (e.g., sndfile >= 1.0.18, libcurl >= 7).
> > 
> > >I would like to enforce these same checks upfront in the Makefile rather
> > >than letting the build potentially blow up in scons. Section 5.7.8 of the
> > >Porter's Handbook says that all of the _DEPENDS variables *except
> > >LIB_DEPENDS* can enforce minimal dependency versions. It's not clear why
> > >LIB_DEPENDS is excluded here, or what the correct alternative approach
> > >is. It doesn't seem like putting LIB_DEPENDS= curl.5 is equivalent to
> > >libcurl >= 7. Hopefully there's a straightforward way to accomplish
> > >this, without having to patch or scrap the scons config file.
> > >Unfortunately I have not been able to find the answers from
> > >searching the net, so I hope somebody here can help.
> > 
> > It's not enforced in quite the same way, but there is a check on the
> > version of the library if you specify it, only the check is for an
> > exact match, not an inequality.  You can see the precise means by
> > which this is accomplished by looking at the lib-depends target in
> > /usr/ports/Mk/bsd.port.mk   (beginning on line 5102 of version 1.629
> > of this file).  For example,
> > 
>  <snip>
> >
> > /sbin/ldconfig  -r | /usr/bin/grep -vwF -e "/usr/local/lib/compat/pkg"
> > | /usr/bin/grep -wE -e "-lblas\\.2"
> > 
> > which is version-specific.  Probably an inequality check was not
> > implemented because libraries with different major versions are
> > expected to have different and incompatible ABI/APIs.  The
> > corresponding version numbers of the port as a whole are not usually
> > relevant for LIB_DEPENDS, only the version of the shared library
> > itself, as the upstream maintainers are supposed to change a shared
> > library version if and only if they change the API/ABI of the library.
> It seems like there are 2 numbering schemes for shared libraries:
> 1. Version stored in /usr/local/libdata/pkgconfig/*.pc (same as
> 2. Major version number stored as part of the library filename.
> I realized I could check for exact match for #2 (mentioned LIB_DEPENDS=
> curl.5 in my message), however I would like to ideally check for #1
> since that's what the scons config seems to be looking at.
> It seems like checking #2 is only a rough proxy for #1 and is likely to
> make for a fragile port. For instance, say scons config is checking
> for >= X.Y in scheme #1, but all I can do is put a check
> for M in scheme #2. Then we have these problematic scenarios:
> 1. If there are versions of the lib.M that have version #s in scheme #1
> less than X.Y, then the build will fail in scons, leaving the user
> confused and unhappy.

Hmmm.  Have you actually come across such a case?  IMHO that should
be quite rare, at least with the FreeBSD Ports Collection.  Of course,
if this should *really* happen, you always have the option to specify
a version in BUILD_DEPENDS and RUN_DEPENDS...  but again, I think this
should be quite rare.  I'm not saying it won't happen, mind :)  It is
always possible for a library developer to add a new interface and not
bump the major library version, and then such a check could be appropriate.
Although, honestly, I don't think it should be much needed in the FreeBSD
Ports Collection, because one of the basic ideas is that a user should
keep all of her ports synchronized at all times (synchronized, *not*
necessarily up-to-date) - and when a new version of scons comes out
that needs a feature available in a recent cURL version, it stands to
reason that the update of the Ports Collection that will bring the new
scons version will *also* bring in the new cURL version, so the build
should succeed.

> 2. If user upgrades ports and gets lib.M+1, make fails because the exact
> match is no longer satisfied. (Porter's Handbook says you can use
> LIB_DEPENDS regular expressions like curl.[5-9] so this shouldn't be as
> much of a problem, at least not until it breaks years later on curl.10)

Actually, in the FreeBSD Ports Collection, this is the responsibility of
the maintainer of the library port.  Specifically for the cURL port that
you mentioned, I'm the maintainer :)  And I follow the established
policy - whenever a port is upgraded to a new major library version,
the maintainer should test all the dependent ports (at least to see if
they build), then maybe contact some of the maintainers so they can
*really* test the upgrade before it is committed, and then, at commit
time, the library port's maintainer must go through all the ports that
specify an exact dependency and bump this dependency himself, so that
the users see a smooth transition.

The users of the ports collection see two commits - one that updates
the library port so it installs a new version, and then, immediately
afterwards, a second commit to lots of other ports updating their
LIB_DEPENDS lines and, usually, bumping their PORTREVISION.  Thus,
when the end user updates her Ports Collection, she just sees that
she needs to update both the curl and scons ports, and everything
Just Works(tm) :)

> >  If you are relying upon some feature of a port that may change while
> > it's relevant shared library versions remain the same, then you should
> > add the port to the other *_DEPENDS as needed, with appropriate checks
> > on the port version number in those variables.
> I suspect this is what I shall have to do. Is this what all other port
> authors do in similar circumstances? It seems kind of a hackish
> workaround, especially if the library in question doesn't have a
> corresponding executable to list in RUN_DEPENDS. Do I force a library
> name into RUN_DEPENDS?

It is, indeed, a hackish workaround, and it should only be used in
extreme cases, when the build really fails *and* you, as the maintainer
of the port, really see a need to allow the users to build it with
older versions of ports that it depends on - see my comments about
the synchronized ports collection above.  In general, it should be
really, really rare.

> It would be nice to be able to express the real dependency as precisely
> and accurately as possible, say I want >= X.Y (in numbering scheme Z) of
> this library, rather than have to obfuscate intent by using some proxy.

True, it would be nice, yet it might require some more work to implement,
since it would change the way the checks are done.  Somebody(tm) ought
to do the work to implement it - maybe :)


Peter Pentchev	roam at ringlet.net    roam at space.bg    roam at FreeBSD.org
PGP key:	http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint	FDBA FD79 C26F 3C51 C95E  DF9E ED18 B68D 1619 4553
This would easier understand fewer had omitted.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-ports/attachments/20091016/442bdc71/attachment.pgp

More information about the freebsd-ports mailing list