There are several reasons to do this:
- Keeping proposals scoped tightly and on a single topic makes it easier to move them forward,
- There are a number of types of users of metadata on native dependencies; things like static analysis tools will only need the metadata itself, not the dependency discovery at build time or runtime,
- There are multiple ways of doing dependency discovery.
pkg-config
is the most prominent one, but certainly not the only one. I think it should be better supported, but I wouldn’t want to venture into making its use mandatory at this point. As a package author, I should be able to write something likedependency('mylib')
in my build config files, and have the build system use pkg-config, CMake, configtool, or its own custom code to act as the “dependency provider” to discovermylib
.
A separate backend isn’t needed for using pkg-config at build time. Any good build system/backend dealing with compiled code should be able to do this. If it’s about using pkg-config
with ctypes.util.find_library
at runtime specifically, then no build backend should be involved at all. find_library
already has platform-specific behavior, and its semantics are pretty vague, basically “do your best to find this library”. pkg-config
could be added to that directly as one of the ways to try and locate the library in case pkg-config
is already installed. That would be backwards compatible and a sensible thing to do.
I agree, with the note that if the patch tries to use pkg-config
when installed, it should be more generic and work for Nix and a number of other distros/scenarios.
I had a look at the list of patches @domenkozar linked to. The first one I recognized is psycopg
, and that’s a great example here. It ships only a pure Python package/wheel, does not declare any dependencies in its pyproject.toml, but in its README has sudo apt install libpq5
and does this inside the package:
libname = find_libpq_full_path() # uses ctypes.util.find_library
if not libname:
raise ImportError("libpq library not found")
pq = ctypes.cdll.LoadLibrary(libname)
That is indeed pretty fragile. However, I think we indeed have all the ingredients to fix the issue:
- PostgresQL (which provides the needed
libpq
) has to be declared as an external dependency in pyproject.toml[1], - distros can then use that info to have their packaging tooling add
postgresql
as a runtime dependency ofpsycopg
(or at least, the packager has an easier time when reading the metadata and handling it manually), - this may already be enough for many distros (and indeed, on Arch Linux,
ctypes.util.find_library('pq')
returns a path tolibpq.so.5
) - distros with non-standard path can implement a rule to automatically add
pkg-config
as a runtime dependency too if there are any external dependencies in pyproject.toml, - that will fix the issue for Nix when
find_library
is actually trying to use pkg-config in addition to its current methods.
I think it’d be feasible to extend find_library
now. Where it hits return None
because it can’t find any library, the code could check if pkg-config
is installed and if so, run pkg-config --libs libname
in a subprocess call, then if that return a -L/path/to/some/libdir
check that dir for the library. It’s pretty straightforward and should be backwards compatible, so would that even require a PEP?