Abstract
The LIB_DEPENDS macro uses ldconfig -r to check for library dependencies within the ports tree. There is a slowly increasing set of ports that create shared libraries, which do not use a shared library version, ldconfig can handle.
In order to support LIB_DEPENDS properly for those ports, it is necessasry for maintainers to create non-trivial patches within the port's build framework, which increases the maintenance efforts and risk to break the port and dependent ports on doing it wrong.
A better approach is needed that can handle and detect shared libraries with the upstream-provided library version-scheme.
Limitations
At the moment the output of ldconfig -r is limited to lib<name>.so.X, where X indicates the shared library version. Since there is no way to fix the output of ldconfig -r on a short term across all supported FreeBSD versions, a different or enhanced approach is necessary.
Requirements
Maintainers need to be able to
- ignore any specific shared library version as dependency, if the dependent port does not require a specific interface version
- provide an exact shared library version as dependency, if the dependent port requires this
- or if multiple versions of the library might be installed through the ports tree (e.g. audio/portaudio*)
The syntax and creation of a LIB_DEPENDS must be
- as backwards-compatible as possible
- intuitive
The library detection code must be
- fast
- bullet-proof
- libA.so.1, libA.so.2, libA.so.1.1, libA-1.so, libA-1.so.1 might different libraries or different versions of the same library
User Input
Status Quo
The following naming schemes for LIB_DEPENDS exist:
<name>:${PORTSDIR}/category/port <name>.<version(single digit)>:${PORTSDIR}/category/port <name>-<version(dot-separated digits)>.<shversion>:${PORTSDIR}/category/port
If only a library name is provided, lib-depends: will search for a library lib<name>.so within the output of ldconfig -r If a library name with a version is provided, lib-depends: will search for either
lib<name>.so.<version> or
lib<name>.<version>.so
If a library name with a version and shversion is provided, lib-depends: will search for either
lib<name>-<version>.so.<shversion> or
lib<name>-<version>.<shversion>.so
Proposal
The following naming schemes for LIB_DEPENDS shall be introduced:
<name>:${PORTSDIR}/category/port <name>.<version(single digit)>:${PORTSDIR}/category/port <name>.<version(dot-separated digits)>:${PORTSDIR}/category/port lib<name>.so[<suffix>]:${PORTSDIR}/category/port
<name>:${PORTSDIR}/category/port shall provide the following behaviour:
look for lib<name>.so
<name>.<version(single digit)>:${PORTSDIR}/category/port shall provide the following behaviour:
- look for
lib<name>.<version(single digit)>.so or
lib<name>.so.<version(single digit)>
- look for
<name>.<version(dot-separated digits)>:${PORTSDIR}/category/port shall provide the following behaviour:
look for lib<name>.so.<version(dot-separated digits)>
lib<name>.so[<suffix>]:${PORTSDIR}/category/port shall provide the following behaviour:
look for lib<name>.so[<suffix>]
Examples
LIB_DEPENDS= foo:${PORTSDIR}/devel/foo
lib-depends: searches for libfoo.so
LIB_DEPENDS= foo.3:${PORTSDIR}/devel/foo
lib-depends: searches for libfoo.3.so. If no such file could be found, libfoo.so.3 is searched for.
LIB_DEPENDS= foo.1.2.3:${PORTSDIR}/devel/foo \ bar.4.5::${PORTSDIR}/devel/bar
lib-depends: searches for libfoo.so.1.2.3 and libbar.so.4.5
LIB_DEPENDS= libfoo.so.77:${PORTSDIR}/devel/foo \ libbar-1.2.so:${PORTSDIR}/devel/bar
lib-depends: searches for libfoo.so.77 and libbar-1.2.so
Directories
The lib-depends: target shall search the following directories for availability of the LIB_DEPENDS:
- ${LOCALBASE}/lib
- the directories listed in all files available under ${LDCONFIG_DIR}
- ${PKGCOMPATDIR}
in the specific order listed above.
TODO: what about ${LDCONFIG32_DIR}?
Incompatibilities
<name>-<version(dot-separated digits)>.<shversion>:${PORTSDIR}/category/port will be removed with this proposal, which requires all ports using that specific scheme to be updated on implementation. This however solves issues with library version updates such as
libfoo-2.0.so.0 --> libfoo-2.0.1.so.0
which would require users to write non-intuitive entries such as
LIB_DEPENDS= foo-2.0.0:${PORTSDIR}/category/port --> LIB_DEPENDS= foo-2.0.1.0:${PORTSDIR}/category/port
Instead of the scheme, a qualified library name can be provided using the explicit lib prefix from lib<name>.so[<suffix>]:${PORTSDIR}/category/port. Although this doe not save typing work or eases chasing library updates, the library dependency is easier to understand:
LIB_DEPENDS= libfoo-2.0.so.0:${PORTSDIR}/category/port --> LIB_DEPENDS= libfoo-2.0.1.so.0:${PORTSDIR}/category/port
Scope
The change to LIB_DEPENDS (or more specifically the lib-depends: target) will not provide any logic to verify that the specified library name can be actually used by the linker. This however might be provided by tools or functions outside of the scope of this proposal (e.g. portlint).