Create standalone executables from Python scripts
—
Direct access to cx_Freeze's core freezing engine provides programmatic control over module discovery, dependency analysis, and executable creation. This enables custom build workflows, integration with other tools, and fine-grained control over the freezing process.
The core Freezer class orchestrates the entire freezing process with platform-specific implementations and extensive configuration options.
class Freezer:
"""Core freezing engine with platform-specific implementations."""
def __new__(
cls, *args, **kwargs
) -> WinFreezer | DarwinFreezer | LinuxFreezer:
"""Create appropriate platform-specific freezer instance."""
def __init__(
self,
executables: Sequence[Executable, Mapping[str, str], str],
constants_module: ConstantsModule | None = None,
includes: list[str] | None = None,
excludes: list[str] | None = None,
packages: list[str] | None = None,
replace_paths: list[str] | None = None,
compress: bool | None = True,
optimize: int = 0,
path: list[str | Path] | None = None,
target_dir: str | Path | None = None,
bin_includes: list[str] | None = None,
bin_excludes: list[str] | None = None,
bin_path_includes: list[str] | None = None,
bin_path_excludes: list[str] | None = None,
include_files: list[tuple[str, str]] | None = None,
zip_includes: list[tuple[str, str]] | None = None,
silent: bool | int = 0,
metadata: Any = None,
include_msvcr: bool = False,
include_msvcr_version: str | None = None,
zip_include_packages: Sequence[str] | None = None,
zip_exclude_packages: Sequence[str] | None = None,
zip_filename: Path | str | None = None,
):
"""
Initialize freezer with comprehensive configuration options.
Parameters:
- executables: List of Executable objects, dicts, or script strings
- constants_module: Custom constants module for frozen app
- includes: Modules to force include
- excludes: Modules to force exclude
- packages: Packages to include with all submodules
- replace_paths: Path replacements for included modules
- compress: Compress bytecode in zip archive
- optimize: Bytecode optimization level (0, 1, 2)
- path: Module search paths
- target_dir: Directory for built executables and dependent files
- bin_includes: Binary files to include
- bin_excludes: Binary files to exclude
- bin_path_includes: Binary search paths to include
- bin_path_excludes: Binary search paths to exclude
- include_files: Additional files to copy [(source, dest), ...]
- zip_includes: Files to include in zip [(source, archive_name), ...]
- silent: Suppress output during freezing (bool or int level)
- metadata: Custom metadata for frozen application
- include_msvcr: Include Microsoft Visual C++ runtime (Windows)
- include_msvcr_version: Specific MSVCR version to include (Windows)
- zip_include_packages: Packages to store in zip
- zip_exclude_packages: Packages to exclude from zip
- zip_filename: Custom zip filename
"""ModuleFinder provides the core module discovery engine that analyzes import dependencies and determines required modules.
class ModuleFinder:
"""Discovers required modules through import analysis."""
def __init__(
self,
constants_module: ConstantsModule,
excludes: list[str] | None = None,
include_files: IncludesList | None = None,
path: list[str | Path] | None = None,
replace_paths: list[tuple[str, str]] | None = None,
zip_exclude_packages: Sequence[str] | None = None,
zip_include_packages: Sequence[str] | None = None,
zip_include_all_packages: bool = False,
zip_includes: IncludesList | None = None,
):
"""
Initialize module finder with search configuration.
Parameters:
- constants_module: Constants module for frozen application
- excludes: Modules to force exclude from discovery
- include_files: Additional files to include [(source, dest), ...]
- path: Module search paths
- replace_paths: Path replacements for included modules
- zip_exclude_packages: Packages to exclude from zip
- zip_include_packages: Packages to store in zip
- zip_include_all_packages: Store all packages in zip by default
- zip_includes: Files to include in zip [(source, archive_name), ...]
"""
def include_module(self, name: str) -> Module:
"""Force include a module by name."""
def exclude_module(self, name: str) -> None:
"""Force exclude a module by name."""
def include_package(self, name: str) -> None:
"""Include package with all submodules."""
def add_zip_file(self, filename: str) -> None:
"""Add zip file to module search path."""
def find_module(self, name: str, path: list[str] | None = None) -> Module:
"""Find and analyze a specific module."""
def load_module(
self,
name: str,
deferreds: list[str] | None = None,
parent: Module | None = None
) -> Module:
"""Load module and analyze its dependencies."""
@cached_property
def modules(self) -> list[Module]:
"""Get list of all discovered modules."""
@cached_property
def _modules(self) -> dict[str, Module]:
"""Internal module registry."""The Module class represents individual Python modules with their metadata, dependencies, and file information.
class Module:
"""Represents a Python module in the frozen application."""
def __init__(
self,
name: str,
path: Sequence[Path | str] | None = None,
filename: Path | str | None = None,
parent: Module | None = None,
):
"""
Initialize module representation.
Parameters:
- name: Module name (dotted import name)
- path: Module search paths
- filename: Path to module file
- parent: Parent module for submodules/packages
"""
@property
def name(self) -> str:
"""Module name (dotted import name)."""
@property
def file(self) -> Path | None:
"""Path to module file."""
@property
def path(self) -> list[str]:
"""Module search path."""
@property
def code(self) -> CodeType | None:
"""Compiled module code object."""
@property
def parent(self) -> Module | None:
"""Parent module (for submodules)."""
@property
def distribution(self) -> DistributionCache | None:
"""Package distribution metadata."""
def in_file_system(self) -> int:
"""Check if module exists in filesystem (0=no, 1=yes, 2=namespace)."""
def store_in_file_system(self) -> bool:
"""Whether module should be stored as file vs in zip."""ConstantsModule provides a way to inject custom constants and configuration into frozen applications.
class ConstantsModule:
"""Module for storing constants used by frozen executables."""
def __init__(self, release_string: str | None = None, constants: list = None):
"""
Initialize constants module.
Parameters:
- release_string: Version/release information
- constants: List of (name, value) tuples to inject
"""
@property
def values(self) -> dict[str, Any]:
"""Dictionary of constant name -> value mappings."""
def create(self, modules: dict[str, Module]) -> Module:
"""Create Module object containing the constants."""Freezer automatically creates platform-specific instances with specialized handling for each operating system.
# Platform-specific freezer classes (internal)
class WinFreezer(Freezer):
"""Windows-specific freezing implementation."""
# Handles DLL dependencies, resource compilation, MSVCR inclusion
class DarwinFreezer(Freezer):
"""macOS-specific freezing implementation."""
# Handles framework bundling, library path fixing, code signing prep
class LinuxFreezer(Freezer):
"""Linux-specific freezing implementation."""
# Handles shared library dependencies, RPATH configurationfrom cx_Freeze import Freezer, Executable, ConstantsModule
# Custom constants injection
constants = ConstantsModule(
release_string="MyApp v1.0.0",
constants=[
("BUILD_TIME", "2024-01-15"),
("DEBUG_MODE", False),
("API_ENDPOINT", "https://api.example.com")
]
)
# Advanced freezer configuration
freezer = Freezer(
executables=[
Executable("main.py", base="gui", icon="app.ico"),
Executable("cli.py", base="console", target_name="mytool")
],
constants_module=constants,
includes=["tkinter", "sqlite3", "json"],
excludes=["unittest", "doctest", "pdb"],
packages=["requests", "numpy.core"],
replace_paths=[
("C:\\dev\\myapp", "/app"),
("/usr/local/lib/python3.x", "/lib")
],
include_files=[
("data/config.ini", "config.ini"),
("resources/", "resources/"),
("README.txt", "README.txt")
],
zip_includes=[
("templates/", "templates/"),
("static/", "static/")
],
zip_include_packages=["jinja2", "markupsafe"],
bin_excludes=["libc.so*", "libX11*"],
metadata={
"author": "Your Name",
"version": "1.0.0",
"description": "My Application"
},
optimize=2,
compress=True,
silent=False
)
# Execute freezing process
freezer.freeze()cx_Freeze includes an extensive hook system for handling special requirements of popular packages.
# Hook system integration (automatic)
# Hooks located in cx_Freeze.hooks package
# Available hooks for major packages:
hooks = [
"tkinter", "PyQt5", "PyQt6", "PySide2", "PySide6",
"numpy", "scipy", "pandas", "matplotlib", "sklearn",
"cv2", "PIL", "tensorflow", "torch", "requests",
# ... 60+ hooks total
]
# Custom hook development
def load_my_package(finder, module):
"""Custom hook for handling special package requirements."""
finder.include_module("my_package.submodule")
finder.add_zip_file("my_package_data.zip")Advanced control over binary dependencies and shared libraries.
# Binary handling options
bin_includes = [
"libspecial.so", # Specific library
"custom.dll", # Windows DLL
"framework.dylib" # macOS library
]
bin_excludes = [
"libc.so*", # Exclude system libraries
"kernel32.dll", # Windows system DLLs
"libX11*" # X11 libraries
]
bin_path_includes = [
"/opt/custom/lib", # Custom library paths
"C:\\Program Files\\MyLib" # Windows library paths
]
bin_path_excludes = [
"/usr/lib/python*/lib-dynload", # Python stdlib extensions
"/System/Library" # macOS system libraries
]Advanced freezing provides detailed error reporting and debugging capabilities.
# Exception types for advanced freezing
class ModuleError(Exception):
"""Module loading or metadata errors."""
class FileError(Exception):
"""File or resource not found errors."""
class OptionError(Exception):
"""Configuration or option errors."""
# Debugging and introspection
freezer = Freezer(executables=[], silent=False)
# Access internal state
modules = freezer.finder.modules # All discovered modules
missing = freezer.finder.bad_modules # Failed module imports
excluded = freezer.finder.excluded_modules # Explicitly excluded
# Platform-specific debugging
if hasattr(freezer, 'get_dependent_files'): # Windows
deps = freezer.get_dependent_files("myapp.exe")
# Module analysis
for module in modules:
print(f"Module: {module.name}")
print(f" File: {module.file}")
print(f" In filesystem: {module.in_file_system()}")
print(f" Store in filesystem: {module.store_in_file_system()}")Advanced freezing can be integrated with custom build systems and workflows.
import os
import sys
from pathlib import Path
from cx_Freeze import Freezer, Executable
def custom_build_workflow():
"""Custom build workflow with pre/post processing."""
# Pre-processing
print("Preparing build environment...")
os.makedirs("dist", exist_ok=True)
# Custom executable configuration
exe = Executable(
script="main.py",
base="gui" if "--gui" in sys.argv else "console",
icon=find_best_icon(),
target_name=get_version_name()
)
# Advanced freezer setup
freezer = Freezer(
executables=[exe],
includes=get_required_modules(),
exclude=get_excluded_modules(),
include_files=collect_data_files(),
optimize=2 if "--release" in sys.argv else 0,
silent="--verbose" not in sys.argv
)
# Execute freezing
print("Freezing application...")
freezer.freeze()
# Post-processing
print("Finalizing build...")
sign_executables("dist/")
create_checksums("dist/")
print("Build complete!")
def find_best_icon():
"""Find appropriate icon for platform."""
platform_icons = {
"win32": "app.ico",
"darwin": "app.icns",
"linux": "app.png"
}
return platform_icons.get(sys.platform, "app.png")Install with Tessl CLI
npx tessl i tessl/pypi-cx-freeze