Skip to main content

xppb (cross-platform python bundler)

v1.1.1


xppb is a fast(when compared to PyInstaller and Nuitka) and cross-platform binary bundler designed to compile, prune, and bundle Python programmes for Linux, Winslop and macOS. Unlike traditional bundlers that are severely limited by their host operating system, xppb supports cross-compilation out of the box. By temporarily spoofing the Python interpreter's global state and relying on standard archives, a developer on Linux can easily build a signed Windows .exe and a fully notarized macOS .app bundle simultaneously in a single execution from a single machine in a matter of seconds(takes a lot configuration and 20-30 min in Nuitka for reference).

The build size in this tool is also very minimal(with v1.1.0, it kinda beats Nuitka in output sizes), by using a strict 'default-deny' whitelist approach, deleting every file in site-packages and the standard library that is not explicitly resolved by the dependency graph. It safely preserves only the structural __init__.py files, compiled extensions, and active metadata blocks (like .dist-info).

xppb also have built-in features of code signing for Mac and Winslop, hence letting the user straightforwardly sign or notarize a program for macOS or Winslop from other OSes(eg, Linux) or machines.

It also checks if the user is having uv and if so, will resort to installation with it, as uv provides an absurdly fast deps resolution than the standard pip.

On Using It

Through uv:

uv pip install xppb

Through pip:

just remove the uv from the above command.

GIT Clone:

git clone https://github.com/nulsie/xppb.git
cd xppb

Prerequisites

  • Python 3.11+

  • pip install modulegraph

  • (Optional but Recommended): Install uv for absurdly accelerated wheel downloads.

Configuration (projconf.toml)

Like others, a build in xppb is governed by a config file(TOML is supported because it is pre-packaged with Python). Create a file named projconf.toml in your project root. Here is a complete reference of the required layout:

[project]
name = "MyAwesomeApp"
version = "1.0.0"
python_version = "3.11"
entry_point = "main.py"
source_files = ["main.py", "assets/"]
dependencies = ["requests", "rich", "numpy"]
hidden_imports = ["pkg_resources.extern"]
collect_all = []
preserve_extensions = [".png", ".ico"]
launch_command = "{ENTRY_POINT}"
upx_exclude = [] # this is a new thing, as if you have anything to exclude from UPX compressing, write it here

[runtimes]
# URLs pointing to standalone python standard libraries (.tar.gz)
windows-x64 = "https://example.com/python-3.11-win64.tar.gz"
macos-arm64 = "https://example.com/python-3.11-macos-arm64.tar.gz"
linux-x64 = "https://example.com/python-3.11-linux64.tar.gz"

[windows]
hide_console = true
pfx_certificate = "certs/win_cert.pfx"
pfx_password = "SuperSecretPassword123"
hidden_imports = ["winreg"]

[macos]
p12_certificate = "certs/mac_cert.p12"
p12_password = "SuperSecretPassword123"
api_key_path = "certs/AuthKey_ABCD123.p8"
api_issuer_id = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
api_key_id = "ABCD123"

Usage

Once your projconf.toml is configured, simply run xppb in your working directory and execute it:

xppb

xppb utilizes a ProcessPoolExecutor to spin up a concurrent build thread for every OS target defined in your [runtimes] configuration block.

  • Build artifacts are processed temporarily in a build/ directory.

  • Final, compressed distribution assets (ready to be uploaded) are deposited into dist/.


v1.1.0

This update is focused on fixing past version's(v1.0.0) bottlenencks, bugs and other issues(obviously) and reducing the output sixe to as small as it can get. This update also features a major refactoring where i've replaced all the C used with the better Nim.

Fix(es):

  • The race conditions in ProcessPoolExecutor

  • The unbound local variable in generate_runtime_whitelist()

  • Package false negatives in binary scanner(also in generate_runtime_whitelist())

Add(s):

  • Bytecode optimization & source stripping

  • Tightened extension preservations & pruning heavy directories, i had to refavtor wipe_runtime_bloat_strict for this

  • Zips the pure-python stdlib, this function iterates through the standard library, collects all pure Python .py and .pyc files, bundles them into a single compressed pythonXX.zip archive, and removes the original loose files while strictly leaving native C-extensions (.so, .pyd, .dll) and site-packages intact on the disk

  • Binary symbol stripping & UPX compression(only in places where UPX can be correctly used)

  • Upgrade final archive compression (LZMA / XZ). Here i've switched to xz (LZMA), which yields significantly higher compression ratios than the past basic gzip and deflate algorithms

Change(s):

  • The launcher_stub has been re-written from C to Nim for easier and better maintainance, and now instead og how the stub worked before, it uses the EOF (End-of-File) payload appending method. Note: Appending payloads to the end of a signed executable and doing it via CreateProcessA (especially with WindowStyle Hidden or CREATE_NO_WINDOW) closely mirrors techniques used by malware packers. While completely legitimate here, be prepared for false-positive flags from Windows Defender or EDRs on the generated .exe, a patch for this will be there soon.

  • The generate_window_launcher method has been refactored for the new Nim stub and EOF method.


Author: nulsie License: MIT

Metadata

Release files for xppb 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for xppb 1.1.1
File Size Uploaded
xppb-1.1.1.tar.gz 35.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for xppb 1.1.1
File Interpreter ABI Platform
xppb-1.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 70.0 kB

Release files / xppb-1.1.1.tar.gz

Download URL xppb-1.1.1.tar.gz
Size 35.8 kB
Tags Source
SHA-256 checksum
How to use checksums
8aeb1cc48f19c9eb1c01b5475a756a04f1a52e8835dd64b90e676ad7cbe08c7f
BLAKE2b-256 checksum
How to use checksums
f27105dd96551b44268b0ab1acbeedb9ac8663a7ef833a9bdbec5e23a4e1ebfc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.32.5

Release files / xppb-1.1.1-py3-none-any.whl

Download URL xppb-1.1.1-py3-none-any.whl
Size 34.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
99877a33810abe45c620c9161c7963cb055729cdcdde0da13f17013f4a040c51
BLAKE2b-256 checksum
How to use checksums
d843462f37e543ef9b09a3d276728e0e334c6aa8b193ff437817dbb7cc952bbf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.32.5

Release history Release notifications | RSS feed

This release

1.1.1 This release

2 release files

1.1.0

2 release files

1.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page