Warning
For the sake of honesty, it's important to say that most of the code in this package was written by Claude. Although I reviewed the code in general, I didn't review every single line in detail. Please use it accordingly and report any issues you find.
A modern, probe-first replacement for flatpak-pip-generator.
Instead of resolving dependencies statically on the host, pfmg installs the package inside a real Flatpak build sandbox, runs ldd on every compiled extension, checks pkg-config, and tests the import. The result is a Flatpak module JSON that you can drop directly into your manifest — with native dependency errors caught before you ever run flatpak-builder.
- Python 3.11+
flatpakinstalled on the host (forgenerateandinspect)pip3oruvavailable on the host (for source collection)
pip install pfmgpfmg generate numpy
│
├─ 1. Install package inside org.freedesktop.Sdk sandbox
├─ 2. Run ldd on every .so file → detect missing native libs
├─ 3. Run pkg-config on declared deps → detect missing headers / pc files
├─ 4. Test the Python import
├─ 5. Build-test the generated module (flatpak-builder dry run)
│ └─ if a build dep is missing and resolvable on PyPI → probe it
│ and retry automatically (up to 5 times)
└─ 6. Write module JSON
Errors are matched against a local dataset of SDK profiles, extension profiles, and ready-to-use recipes, so you get actionable suggestions ("add org.freedesktop.Sdk.Extension.rust-stable") instead of raw linker output.
pfmg ships with — and continuously grows — a dataset of:
| Directory | Contents |
|---|---|
data/sdk-profiles/ |
Profiles of base SDKs (libraries, pkgconfig, executables) |
data/ext-profiles/ |
Profiles of SDK extensions |
data/nat-recipes/ |
Ready-to-use Flatpak module JSON for native libraries (zlib, openssl, …) |
data/pip-recipes/ |
Ready-to-use module JSON for Python packages with known native deps |
When pfmg generate encounters an error it queries this dataset and suggests concrete actions: which SDK extension to add, which recipe to prepend to the manifest, or which --build-dep flag to pass.
Use pfmg import, pfmg inspect, and pfmg inspect-all to grow the dataset for your own extensions or SDK versions.
Probe one or more Python packages and generate Flatpak module JSON files.
pfmg generate <package> [<package> ...] [OPTIONS]
| Option | Default | Description |
|---|---|---|
--sdk, -s |
org.freedesktop.Sdk |
Base SDK to use |
--runtime |
org.freedesktop.Platform |
Runtime ID |
--sdk-version, -V |
24.08 |
SDK branch |
--extension, -e |
— | SDK extension to activate (repeatable) |
--build-dep, -b |
— | Explicit build-time PyPI dep (repeatable) |
--output-dir, -o |
— | Directory to write module JSON files |
--format, -f |
json |
Output format: json or yaml |
--uv / --pip |
--uv |
Package installer to use inside the sandbox |
--keep |
off | Keep the sandbox work directory after probing |
--raw-output, -r |
off | Print raw sandbox stdout/stderr |
--verbose, -v |
off | Enable debug logging |
Examples:
# Simplest case — latest numpy
pfmg generate numpy
# Pin a version, save the result
pfmg generate numpy==1.26.4 --output-dir ./modules
# Package that needs the Rust toolchain
pfmg generate cryptography \
--extension org.freedesktop.Sdk.Extension.rust-stable \
--output-dir ./modules
# Several packages at once on SDK 24.08
pfmg generate pillow lxml --sdk-version 24.08 --output-dir ./modules
# Manually hint a build-time dep (pfmg tries to auto-resolve these,
# but you can be explicit)
pfmg generate some-package --build-dep meson-python --build-dep ninjaWhen --output-dir is omitted the module JSON is printed to stdout. If pfmg detects errors it prints a resolution table with suggestions from the local dataset.
Search the local dataset for a library, package name, or executable.
pfmg search <query> [OPTIONS]
| Option | Default | Description |
|---|---|---|
--kind, -k |
all | Filter: nat, pip, sdk, ext |
--module, -m |
off | Print the full module JSON for matching recipes |
pfmg search openssl
pfmg search numpy --kind pip
pfmg search libz --kind nat
pfmg search clang --kind ext --moduleSearches SDK profiles, extension profiles, nat-recipes, and pip-recipes using the same fuzzy matching as the error resolver.
List all entries in the local dataset.
pfmg list [OPTIONS]
| Option | Default | Description |
|---|---|---|
--kind, -k |
all | Filter: nat, pip, sdk, ext |
--limit, -n |
50 |
Maximum rows per table |
pfmg list
pfmg list --kind nat
pfmg list --kind pip --limit 100Show the full content of a recipe by its exact ID.
pfmg show <recipe-id> [OPTIONS]
| Option | Default | Description |
|---|---|---|
--kind, -k |
both | Restrict to nat or pip |
pfmg show zlib
pfmg show numpy --kind pipPrint counts of recipes and profiles in the local dataset.
pfmg summarizeIntrospect a Flatpak SDK or extension and write a static profile JSON to the local dataset. Profiles are used by the resolver to match errors against known providers.
pfmg inspect <sdk-or-extension-id> [OPTIONS]
| Option | Default | Description |
|---|---|---|
--sdk-branch, -B |
25.08 |
Branch of the base SDK |
--ext-branch, -X |
— | Branch of the extension when it differs from --sdk-branch |
--output-dir, -o |
— | Override the default profile output directory |
--nocleanup |
off | Don't uninstall the extension after probing |
--override |
off | Re-probe and overwrite an existing profile |
pfmg auto-detects whether the target is a base SDK or an extension by looking for .Extension. in the ID.
Examples:
# Base SDK
pfmg inspect org.freedesktop.Sdk --sdk-branch 24.08
# Extension on the same branch as the SDK
pfmg inspect org.freedesktop.Sdk.Extension.node24 --sdk-branch 25.08
# Extension with its own branch
pfmg inspect org.freedesktop.Sdk.Extension.gcc8 --sdk-branch 24.08 --ext-branch 1.6Profiles are written to:
data/sdk-profiles/<shortname>.<branch>.json # base SDKs
data/ext-profiles/<shortname>.<branch>.json # extensions
Discover every extension available on a Flatpak remote for the given SDK branches and probe them all.
pfmg inspect-all [OPTIONS]
| Option | Default | Description |
|---|---|---|
--sdk-branch, -B |
24.08, 25.08 |
Branches to probe (repeatable) |
--remote, -r |
flathub |
Flatpak remote to query |
--output-dir, -o |
— | Override profile output directory |
--nocleanup |
off | Don't uninstall extensions after probing |
--override |
off | Re-probe profiles that already exist |
Intended to be run once a year when a new SDK generation ships:
# Update profiles for the two current branches
pfmg inspect-all
# When 26.08 ships
pfmg inspect-all -B 25.08 -B 26.08Extensions whose profile already exists are skipped unless --override is given.
Import native library and Python recipes from a shared-modules directory (e.g. a checkout of flathub/shared-modules).
pfmg import <modules-dir> [OPTIONS]
| Option | Default | Description |
|---|---|---|
--repo-root, -r |
. |
Root of the pfmg repository |
--verbose, -v |
off | Enable debug logging |
pfmg import ~/src/shared-modules