pkgconf-pypi

The pkgconf PyPI package provides a pre-built pkgconf binary, as well as an optional integration layer for Python packages.

It provides the following executables:

pkgconf/pkg-config

These executables provide the “vanilla” pkgconf functionality, with a limitation — they don’t have any knowledge of the system .pc files. This means, they rely on the user setting PKG_CONFIG_PATH (or using the equivalent --with-path CLI option).

Setting the the FORCE_PKGCONF_PYPI environment variable forces them to behave the same as pkgconf-pypi.

pkgconf-pypi

This is a pkgconf wrapper that integrates with the Python packaging system, as documented below. It enables Python packages to add locations to the search path. On lookup failures, it tries to fallback to the system pkgconf/pkg-config executables. Please refer to the documentation below for the full behavior details.

Changed in version 2.5.1-2: Following feedback from real-world usage of this package, the Python integration layer was removed from the pkgconf/pkg-config executables, and moved to a new pkgconf-pypi executable.

For backwards compatibility, or in scenarios where it is not possible to specify the pkg-config executable name to build tools, the old behavior can be enabled by setting the FORCE_PKGCONF_PYPI environment variable.

Python package integration

Using the integration layer, Python packages can register their own pkg-config paths, which will be searched by the pkgconf-pypi executable shipped by this package.

Registering pkg-config paths

You can register search paths via the pkg_config entrypoint group. You should create an entry that points to the Python module which contains your .pc files. The name of the entrypoint does not matter.

Example

Using our header-only-library example package.

$ tree
.
├── example
│   ├── include
│      └── example.h
│   └── pkgconf
│       └── example.pc
└── pyproject.toml

4 directories, 3 files

Here, we have our pkg-config file in example/pkgconf`, so we need to create an entrypoint for the module example.pkgconf.

pyproject.toml
 1[build-system]
 2build-backend = 'hatchling.build'
 3requires = ['hatchling']
 4
 5[project]
 6name = 'example'
 7version = '1.0.0'
 8
 9[project.entry-points.pkg_config]
10example = 'example.pkgconf'
11
12[tool.hatch.build.targets.wheel]
13packages = ['example']

And in our example.pc file, we use ${pcfiledir} to make it relocatable.

example.pc
1prefix=${pcfiledir}/..
2includedir=${prefix}/include
3
4Name: example
5Description: Example header library
6Version: 1.0.0
7Cflags: -I${includedir}
8Libs:

Package search path

When you run the pkgconf-pypi executable provided by this package, the PKG_CONFIG_PATH environment variable will be set so that it can find the .pc files registered by the pkg-config entrypoints. If the PKG_CONFIG_PATH environment variable is already set, the locations registered by Python packages will be appended.

If pkgconf-pypi cannot find a package, by default it will fallback to the system pkgconf/pkg-config, which may find packages present on the system. To disable this behavior, set the PKGCONF_PYPI_EMBEDDED_ONLY=1 environment variable.

To enable debug output to syserr, set PYPI_PKGCONF_DEBUG=1.

API

exception pkgconf.PathWarning(message: str, entrypoint: EntryPoint)

Bases: Warning

pkgconf.get_executable() Path

Get the pkgconf executable.

pkgconf.get_pkg_config_path() list[str]

Calculate PKG_CONFIG_PATH for Python packages in the current environment.

Python packages may register a directory for their pkg-config files by specifying a “pkg-config” entrypoint.

TODO: Document the entrypoint creation and point to that here. [project.entry-points.pkg-config] entrypoint-name = ‘project.package’

pkgconf.run_pkgconf(*args: str, **subprocess_kwargs: Any) CompletedProcess[bytes | str]

Run the pkgconf executable.

Parameters:
  • args – Arguments to pass to the pkgconf call.

  • subprocess_kwargs – Keyword arguments to pass to the subprocess.run call.