Python tools to create macOS bundles and bundle dynamic libraries.
Project description
macbundler
A Python toolkit for creating self-contained macOS application bundles with properly configured dynamic library dependencies.
Features
- Create complete
.appbundles from executables - Bundle dynamic libraries (dylibs) with correct install names
- Handle rpath, @executable_path, and @loader_path resolution
- Recursive dependency collection
- Ad-hoc code signing support
- Both CLI and programmatic APIs
Installation
# Using uv
uv add macbundler
# Using pip
pip install macbundler
Quick Start
Command Line
# Create a new .app bundle from an executable
macbundler create myapp
# Bundle dylibs for an existing app
macbundler fix My.app/Contents/MacOS/main -d My.app/Contents/libs/
Python API
from macbundler import Bundle, make_bundle
# High-level: create bundle with one call
bundle_path = make_bundle("/path/to/myapp", version="1.0")
# Or use the Bundle class for more control
bundle = Bundle(
"/path/to/myapp",
version="2.0",
base_id="com.example",
add_to_resources=["/path/to/resources"],
)
bundle.create()
CLI Reference
The CLI has two subcommands: create and fix.
macbundler create
Create a new macOS .app bundle from an executable.
macbundler create <executable> [options]
Options:
-v, --version VERSION Bundle version (default: 1.0)
-i, --id ID Bundle identifier prefix (default: org.me)
-e, --extension EXT Bundle extension (default: .app)
-r, --resource PATH Add resource to bundle (repeatable)
--no-sign Disable ad-hoc codesigning
--verbose Enable debug logging
--no-color Disable colored output
Examples:
macbundler create myapp
macbundler create myapp --version 2.0 --id com.example.myapp
macbundler create myapp -e .plugin
macbundler create myapp -r ./resources -r ./data
macbundler fix
Bundle dynamic libraries and fix paths in existing files.
macbundler fix <files...> -d <dest> [options]
Options:
-d, --dest DIR Destination for bundled libraries (required)
-p, --prefix PATH Library path prefix (default: @executable_path/../libs/)
-s, --search DIR Additional search path (repeatable)
-x, --exclude DIR Exclude libraries from directory (repeatable)
-f, --force Overwrite destination directory
--no-sign Disable ad-hoc codesigning
--verbose Enable debug logging
--no-color Disable colored output
Examples:
macbundler fix My.app/Contents/MacOS/main -d My.app/Contents/libs/
macbundler fix main -d ./libs/ -s /opt/local/lib
macbundler fix main plugin.so -d ./libs/ --force
macbundler fix main -d ./libs/ -x /opt/local/lib
Python API Reference
Bundle
Creates a complete macOS .app bundle structure.
from macbundler import Bundle
bundle = Bundle(
target="/path/to/executable", # Path to the executable
version="1.0", # Bundle version string
add_to_resources=None, # List of paths to add to Resources/
base_id="org.me", # Bundle identifier prefix
extension=".app", # Bundle extension
codesign=True, # Apply ad-hoc code signing
)
# Create the bundle
bundle_path = bundle.create()
DylibBundler
Low-level control over dynamic library bundling.
from macbundler import DylibBundler
from pathlib import Path
dylib_bundler = DylibBundler(
dest_dir=Path("./libs/"),
overwrite_dir=True,
create_dir=True,
codesign=True,
inside_lib_path="@executable_path/../libs/",
files_to_fix=[Path("my_executable")],
prefixes_to_ignore=[Path("/opt/local/lib")],
search_paths=[Path("/usr/local/lib")],
)
# Collect and process dependencies
for file in dylib_bundler.files_to_fix:
dylib_bundler.collect_dependencies(file)
dylib_bundler.collect_sub_dependencies()
dylib_bundler.process_collected_deps()
make_bundle
Convenience function for simple bundle creation.
from macbundler import make_bundle
bundle_path = make_bundle(
target="/path/to/myapp",
version="1.0",
add_to_resources=["/path/to/data"],
base_id="com.example",
)
Bundle Structure
The created .app bundle follows the standard macOS structure:
MyApp.app/
Contents/
Info.plist # Bundle metadata
PkgInfo # Package type identifier
MacOS/
myapp # Main executable
libs/ # Bundled dynamic libraries
libfoo.dylib
libbar.dylib
Resources/ # Optional resources
data/
Frameworks/ # Optional frameworks
How It Works
-
Dependency Collection: Uses
otool -lto analyze Mach-O binaries and extract LC_LOAD_DYLIB and LC_RPATH entries. -
Path Resolution: Resolves @rpath, @loader_path, and @executable_path references to find actual library locations.
-
Library Copying: Copies non-system libraries to the bundle's libs directory.
-
Install Name Modification: Uses
install_name_toolto update library paths to use @executable_path-relative paths. -
Code Signing: Applies ad-hoc signatures to modified binaries (required for ARM Macs).
Credits
The dylib bundling functionality is based on macdylibbundler by Marianne Gagnon.
Links
- Apple Bundle Programming Guide
- How to create a mac application bundle
- Converting a commandline app to a bundle
- BundleBuilder
- mgmacbundle
- macdylibbundler
License
See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file macbundler-0.2.1.tar.gz.
File metadata
- Download URL: macbundler-0.2.1.tar.gz
- Upload date:
- Size: 38.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
533ab3a8ff32ced866dcb1ac155982193895bf3f1b6551b795a69f3edceb5607
|
|
| MD5 |
24db9a1deba1dcbe0f2fd9a9db51e132
|
|
| BLAKE2b-256 |
767ec9de1ed205736d6f6690998eeaec31e09fdc5be40f5c50fca5ead9299090
|
File details
Details for the file macbundler-0.2.1-py3-none-any.whl.
File metadata
- Download URL: macbundler-0.2.1-py3-none-any.whl
- Upload date:
- Size: 26.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
769874b629c1331d414c03f9b33aab714b6a57b704762bfa807b54185faa8348
|
|
| MD5 |
d5f1c8f29f00209801cd311dec956530
|
|
| BLAKE2b-256 |
011d47d0eb38e00eeb6229285adc28eee1fb661a520c859a0fc29ad1375a3daf
|