macos-latest and universal2 build error: cpython-312-darwin.so is not a fat binary!
Description:
:sos: Unable to produce universal2 build (x86 + arm64 combined into one) with pyinstaller on macos-latest runner
I'm getting the following error:
poetry run pyinstaller --target-architecture universal2 --add-data "ksso/success_message.html:ksso" --onefile ksso/main.py --name ksso-$os_name-$os_arch-$version
produces the error:
PyInstaller.utils.osx.IncompatibleBinaryArchError: /Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/markupsafe/_speedups.cpython-312-darwin.so is not a fat binary! For details about this error message, see: https://pyinstaller.org/en/stable/feature-notes.html#macos-multi-arch-support
Action version: ctions/setup-python@v4
Platform:
- [ ] Ubuntu
- [X] macOS
- [ ] Windows
Runner type:
- [X] Hosted
- [ ] Self-hosted
Tools version:
- Python 3.12
- macos-latest runner
Repro steps:
A description with steps to reproduce the issue. If your have a public example or repo to share, please provide the link.
Pipeline code:
---
name: KSSO
on:
push:
branches:
- main
pull_request:
jobs:
# ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
# │ BUILD JOB │
# │ --- │
# │ │
# │ The 'build' job compiles and packages the KSSO py application for different OS and Python versions. │
# │ It uses a matrix strategy to run builds. │
# │ The reason we need a matrix build, because we are using pyinstaller to produce executable binary │
# │ and in order to do so, it should be executed in the target OS. │
# │ │
# │ Outputs: │
# │ - `version`: Extracted from the project version and passed to the `release` job. │
# │ │
# └────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
build:
name: Build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- macos-latest
- ubuntu-latest
- windows-latest
- macos-13
python-version:
- 3.12
timeout-minutes: 30
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Cache poetry dependencies
id: cache
uses: actions/cache@v3
with:
path: |
~/.cache/pypoetry
~/Library/Caches/pypoetry
C:\Users\runneradmin\AppData\Local\pypoetry\Cache
key: ${{ runner.os }}-${{ runner.arch }}-poetry-${{ hashFiles('**/poetry.lock')
}}
restore-keys: |
${{ runner.os }}-${{ runner.arch }}-poetry-
- name: Install poetry
run: |
python -m pip install poetry
- name: Install dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-ansi
- name: Determine version
id: version
run: |
version=$(poetry version --short)
echo "version=$version" >> $GITHUB_ENV
echo "::set-output name=version::$version"
shell: bash
- name: Build binary with pyinstaller
run: |
source $GITHUB_ENV
os_name=$(echo ${{ runner.os }} | tr '[:upper:]' '[:lower:]')
os_arch=$(echo ${{ runner.arch }} | tr '[:upper:]' '[:lower:]')
if [[ "${{ matrix.os }}" == "ubuntu-latest" ]]; then
poetry run pyinstaller --add-data "ksso/success_message.html:ksso" --onefile ksso/main.py --name ksso-$os_name-$os_arch-$version
elif [[ "${{ matrix.os }}" == "macos-latest" ]]; then
poetry run pyinstaller --target-architecture universal2 --add-data "ksso/success_message.html:ksso" --onefile ksso/main.py --name ksso-$os_name-$os_arch-$version
elif [[ "${{ matrix.os }}" == "macos-13" ]]; then
poetry run pyinstaller --target-architecture x86_64 --add-data "ksso/success_message.html:ksso" --onefile ksso/main.py --name ksso-$os_name-$os_arch-$version
elif [[ "${{ matrix.os }}" == "windows-latest" ]]; then
poetry run pyinstaller --add-data "ksso/success_message.html;ksso" --onefile ksso/main.py --name ksso-$os_name-$os_arch-$version
fi
shell: bash
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ksso-${{ matrix.os }}-${{ env.version }}
path: dist/ksso*
Expected behavior:
A universal2 build to be produced without errors on macos-latest runner
Actual behavior:
Build fails with the error
Error log
58 INFO: PyInstaller: 6.11.1, contrib hooks: 2024.11
58 INFO: Python: 3.12.8
71 INFO: Platform: macOS-14.7.2-arm64-arm-64bit
71 INFO: Python environment: /Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12
72 INFO: wrote /Users/runner/work/ksso/ksso/ksso-macos-arm64-0.1.0.spec
75 INFO: Module search paths (PYTHONPATH):
['/Library/Frameworks/Python.framework/Versions/3.12/lib/python312.zip',
'/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12',
'/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/lib-dynload',
'/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages',
'/Users/runner/work/ksso/ksso',
'/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/setuptools/_vendor',
'/Users/runner/work/ksso/ksso']
194 INFO: Appending 'datas' from .spec
194 INFO: checking Analysis
194 INFO: Building Analysis because Analysis-00.toc is non existent
194 INFO: Running Analysis Analysis-00.toc
194 INFO: Target bytecode optimization level: 0
194 INFO: Initializing module dependency graph...
195 INFO: Initializing module graph hook caches...
200 INFO: Analyzing base_library.zip ...
649 INFO: Processing standard module hook 'hook-heapq.py' from '/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/hooks'
705 INFO: Processing standard module hook 'hook-encodings.py' from '/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/hooks'
1663 INFO: Processing standard module hook 'hook-pickle.py' from '/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/hooks'
2438 INFO: Caching module dependency graph...
2482 INFO: Looking for Python shared library...
2485 INFO: Using Python shared library: /Library/Frameworks/Python.framework/Versions/3.12/Python
2485 INFO: Analyzing /Users/runner/work/ksso/ksso/ksso/main.py
10620 INFO: Including run-time hook 'pyi_rth_pkgutil.py' from '/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/hooks/rthooks'
10621 INFO: Including run-time hook 'pyi_rth_multiprocessing.py' from '/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/hooks/rthooks'
10622 INFO: Including run-time hook 'pyi_rth_pkgres.py' from '/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/hooks/rthooks'
10664 INFO: Looking for dynamic libraries
10822 INFO: Warnings written to /Users/runner/work/ksso/ksso/build/ksso-macos-arm64-0.1.0/warn-ksso-macos-arm64-0.1.0.txt
10845 INFO: Graph cross-reference written to /Users/runner/work/ksso/ksso/build/ksso-macos-arm64-0.1.0/xref-ksso-macos-arm64-0.1.0.html
10945 INFO: checking PYZ
10945 INFO: Building PYZ because PYZ-00.toc is non existent
10945 INFO: Building PYZ (ZlibArchive) /Users/runner/work/ksso/ksso/build/ksso-macos-arm64-0.1.0/PYZ-00.pyz
11522 INFO: Building PYZ (ZlibArchive) /Users/runner/work/ksso/ksso/build/ksso-macos-arm64-0.1.0/PYZ-00.pyz completed successfully.
11529 INFO: EXE target arch: universal2
11529 INFO: Code signing identity: None
11563 INFO: checking PKG
11563 INFO: Building PKG because PKG-00.toc is non existent
11563 INFO: Building PKG (CArchive) ksso-macos-arm64-0.1.0.pkg
Traceback (most recent call last):
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/bin/pyinstaller", line 8, in <module>
sys.exit(_console_script_run())
^^^^^^^^^^^^^^^^^^^^^
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/__main__.py", line [23](https://github.com/saritasa-nest/ksso/actions/runs/12577738363/job/35055540388?pr=3#step:8:24)1, in _console_script_run
run()
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/__main__.py", line 215, in run
run_build(pyi_config, spec_file, **vars(args))
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/__main__.py", line 70, in run_build
PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/building/build_main.py", line 1[25](https://github.com/saritasa-nest/ksso/actions/runs/12577738363/job/35055540388?pr=3#step:8:26)2, in main
build(specfile, distpath, workpath, clean_build)
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/building/build_main.py", line 1192, in build
exec(code, spec_namespace)
File "/Users/runner/work/ksso/ksso/ksso-macos-arm64-0.1.0.spec", line 19, in <module>
exe = EXE(
^^^^
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/building/api.py", line 639, in __init__
self.pkg = PKG(
^^^^
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/building/api.py", line 254, in __init__
self.__postinit__()
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/building/datastruct.py", line 184, in __postinit__
self.assemble()
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/building/api.py", line 314, in assemble
src_name = process_collected_binary(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/building/utils.py", line [30](https://github.com/saritasa-nest/ksso/actions/runs/12577738363/job/35055540388?pr=3#step:8:31)9, in process_collected_binary
osxutils.binary_to_target_arch(cached_name, target_arch, display_name=src_name)
File "/Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/PyInstaller/utils/osx.py", line 342, in binary_to_target_arch
raise IncompatibleBinaryArchError(f"{display_name} is not a fat binary!")
PyInstaller.utils.osx.IncompatibleBinaryArchError: /Users/runner/Library/Caches/pypoetry/virtualenvs/ksso-REv962lH-py3.12/lib/python3.12/site-packages/markupsafe/_speedups.cpython-[31](https://github.com/saritasa-nest/ksso/actions/runs/12577738363/job/35055540388?pr=3#step:8:32)2-darwin.so is not a fat binary! For details about this error message, see: https://pyinstaller.org/en/stable/feature-notes.html#macos-multi-arch-support
Error: Process completed with exit code 1.
Hello @dmitry-mightydevops , Thank you for creating this issue. We will investigate it and provide feedback as soon as we have some updates.
Hi @dmitry-mightydevops,
We have investigated the issue and were able to successfully run the script on our end without reproducing the error.
To help us investigate further, could you please provide the following information:
- Details about your public repository link and any additional configuration files.
- Any other relevant logs or error messages you may have encountered.
Thank you!
Hello @dmitry-mightydevops ,
Just a gentle reminder! Could you please let us know if there are any updates from your side regarding this issue?
Thank you!
Seconding @dmitry-mightydevops having this issue. Can't provide a public repo atm, though
@lmvysakh sorry for the delay, it fails on this repo for me https://github.com/saritasa-nest/ksso
In case it helps here's my CI yaml:
name: Build with PyInstaller
on:
release:
types: [published]
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11' # Change to your required Python version
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pyinstaller
pip install -r requirements.txt
- name: Build executable
if: runner.os != 'macOS'
run: |
pyinstaller --onefile --paths=app app/app.py
- name: Build macOS universal executable
if: runner.os == 'macOS'
run: |
pyinstaller --onefile --paths=app --target-arch universal2 app/app.py
- name: Archive executable (Linux)
if: runner.os == 'Linux'
run: tar -czvf dist/linux-build.tar.gz dist/app
- name: Archive executable (macOS)
if: runner.os == 'macOS'
run: tar -czvf dist/macos-build.tar.gz dist/app
- name: Archive executable (Windows)
if: runner.os == 'Windows'
run: Compress-Archive -Path dist\app.exe -DestinationPath dist\windows-build.zip
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.os }}-build
path: |
dist/linux-build.tar.gz
dist/macos-build.tar.gz
dist/windows-build.zip
- name: Upload Linux build as release asset
if: runner.os == 'Linux'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: dist/linux-build.tar.gz
asset_name: linux-build.tar.gz
asset_content_type: application/gzip
- name: Upload macOS build as release asset
if: runner.os == 'macOS'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: dist/macos-build.tar.gz
asset_name: macos-build.tar.gz
asset_content_type: application/gzip
- name: Upload Windows build as release asset
if: runner.os == 'Windows'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: dist/windows-build.zip
asset_name: windows-build.zip
asset_content_type: application/zip
Hello @dmitry-mightydevops,
The PyInstaller.utils.osx.IncompatibleBinaryArchError error typically occurs because universal2 targets both Intel (x86_64) and Apple Silicon (arm64) architectures, but there might be a mismatch in the architecture of the Python interpreter or dependencies being used. Possible causes for the dependency Incompatibility, is as some dependencies or libraries might not support universal2 and cause conflicts during the build process. Therefore we can implement the solution by specifying target architecture. i.e, Instead of using universal2, specify the exact architecture you are targeting (e.g., x86_64 or arm64).
Updated Workflow Configuration Code Snippet
elif [[ "${{ matrix.os }}" == "macos-latest" ]]; then
poetry run pyinstaller --target-architecture $os_arch --add-data "ksso/success_message.html:ksso" --onefile ksso/main.py --name ksso-$os_name-$os_arch-$version
Here, we can adjust the target architecture for macOS to match the architecture of the runner.
- macos-latest: Uses $os_arch to match the runner's architecture.
By specifying the architecture explicitly, you can avoid the IncompatibleBinaryArchError and ensure compatibility between the Python interpreter and the PyInstaller settings.
Hi @adrianleh,
Thank you for your valuable input. We have run the workflow you shared from our end but were unable to reproduce the error related to macos-latest universal2 build. Here is a screenshot for the workflow run.
Could you please provide more details such as details about your public repository link and any additional configuration files that might help us identify the issue?
Hello @dmitry-mightydevops ,
Just a gentle reminder! Could you please let us know if there are any updates from your side regarding this issue?
Thank you!
Hello @dmitry-mightydevops, Just checking in to see if there are any updates regarding this issue. Thank you!
Hello @dmitry-mightydevops,
Due to not receiving a response for a long time, we are going to close this issue for now. Please feel free to reach us in case of any concerns or further clarifications are required to reopen this issue. Thank you!