How to Statically Compile a Python Program into a Binary Executable File
Creating a statically compiled binary for your Python program ensures it can run independently of the target system’s libraries. Here’s a step-by-step guide:
1. Install Necessary Tools
Ensure the following tools are installed:
PyInstaller - Create standalone executables
PyInstaller bundles the Python interpreter and all required libraries into a single, self-contained executable.
pip install pyinstaller
Staticx - Make binaries fully static
Staticx wraps the PyInstaller-generated executable with a minimal runtime, bundling shared libraries into the binary.
pip install staticx
patchelf - Modify ELF binaries (Linux only)
Patchelf is used to manipulate ELF (Executable and Linkable Format) binaries, which is useful for making dynamically linked executables more portable.
- Install on Ubuntu/Debian:
sudo apt install patchelf
2. Create an Executable with PyInstaller
- Generate a single-file executable:
pyinstaller --onefile Lio2CSV.py
- If your script depends on shared libraries (like
libpython
), locate and include them:- Find the
libpython
file:find /usr -name "libpython*.so*"
- Add it to the binary:
pyinstaller --onefile --add-binary "/path/to/libpython.so:." Lio2CSV.py
- Find the
3. Make the Executable Fully Static
- Use
Staticx
to convert the PyInstaller output into a static binary:staticx dist/Lio2CSV dist/Lio2CSV-static
- Verify that the binary is fully static:
ldd dist/Lio2CSV-static
- If successful, the output should be:
not a dynamic executable
.
- If successful, the output should be:
4. Debug Missing Dependencies
If the static binary fails to run:
- Inspect dependencies of the intermediate binary:
ldd dist/Lio2CSV
- Use
strace
to debug runtime issues:strace ./Lio2CSV-static
Alternative/Optional Steps
1. Alternative: Use a Musl-Based Python (Linux Only)
For full static linking on Linux, you can use a Musl-based Python:
- Install Musl libc and Python:
apk add python3 py3-pip musl-dev
- Compile your Python program in this environment using PyInstaller.
2. Optional: Containerize for Maximum Portability
If static compilation is too complex, package the program in a Docker container:
- Create a
Dockerfile
:FROM python:3.10-slim COPY Lio2CSV.py . RUN pip install pyinstaller && pyinstaller --onefile Lio2CSV.py CMD ["dist/Lio2CSV"]
- Build and run the container:
docker build -t lio2csv . docker run --rm lio2csv
Summary
- Use PyInstaller to create a single-file executable (
--onefile
). - Use Staticx to make it fully static.
- Debug shared library issues with
ldd
orstrace
if necessary. - Alternatively, use Musl libc for static linking or Docker for easy portability.
This process ensures you get a robust, standalone executable that runs on most systems without dependency issues.