I'm trying to create a executable binary for a python codebase using pyinstaller. When running pyinstaller on Linux it creates the binary, but the binary fails to run because pyinstaller doesn't properly include QtMultimedia. It worked fine when I used the same procedure on Windows.
The following code reproduces the issue:
from PyQt5 import QtMultimedia, QtWidgets
import sys
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
test_sound = QtMultimedia.QSound("test_sound.wav")
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
Running Pyinstaller
.../install_tester$ pyinstaller test.py --onefile --hidden-import=PyQt5.QtMultimedia
875 INFO: PyInstaller: 4.8
875 INFO: Python: 3.8.8 (conda)
896 INFO: Platform: Linux-5.13.0-37-generic-x86_64-with-glibc2.10
896 INFO: wrote ...install_tester/test.spec
899 INFO: UPX is not available.
900 INFO: Extending PYTHONPATH with paths
['...install_tester']
1093 INFO: checking Analysis
1096 INFO: Building because hiddenimports changed
1096 INFO: Initializing module dependency graph...
1097 INFO: Caching module graph hooks...
1103 INFO: Analyzing base_library.zip ...
2980 INFO: Processing pre-find module path hook distutils from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks/pre_find_module_path/hook-distutils.py'.
2980 INFO: distutils: retargeting to non-venv dir '~anaconda3/lib/python3.8'
5648 INFO: Caching module dependency graph...
5749 INFO: running Analysis Analysis-00.toc
5771 INFO: Analyzing ...install_tester/test.py
5814 INFO: Processing module hooks...
5814 INFO: Loading module hook 'hook-difflib.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
5816 INFO: Loading module hook 'hook-multiprocessing.util.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
5816 INFO: Loading module hook 'hook-distutils.util.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
5817 INFO: Loading module hook 'hook-pickle.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
5818 INFO: Loading module hook 'hook-xml.etree.cElementTree.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
5819 INFO: Loading module hook 'hook-encodings.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
5857 INFO: Loading module hook 'hook-heapq.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
5858 INFO: Loading module hook 'hook-PyQt5.QtWidgets.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
6157 INFO: Loading module hook 'hook-_tkinter.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
6218 INFO: checking Tree
6222 INFO: checking Tree
6258 INFO: checking Tree
6259 INFO: Loading module hook 'hook-distutils.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
6265 INFO: Loading module hook 'hook-sysconfig.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
6265 INFO: Loading module hook 'hook-lib2to3.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
6281 INFO: Loading module hook 'hook-xml.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
6345 INFO: Loading module hook 'hook-PyQt5.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
7478 WARNING: Hidden import "PyQt5.sip" not found!
7478 INFO: Loading module hook 'hook-PyQt5.QtGui.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
7531 INFO: Loading module hook 'hook-PyQt5.QtCore.py' from '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks'...
7566 INFO: Looking for ctypes DLLs
7602 INFO: Analyzing run-time hooks ...
7606 INFO: Including run-time hook '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks/rthooks/pyi_rth_subprocess.py'
7607 INFO: Including run-time hook '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pkgutil.py'
7608 INFO: Including run-time hook '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks/rthooks/pyi_rth_multiprocessing.py'
7610 INFO: Including run-time hook '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks/rthooks/pyi_rth_inspect.py'
7611 INFO: Including run-time hook '~anaconda3/lib/python3.8/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pyqt5.py'
7615 INFO: Looking for dynamic libraries
8880 INFO: Looking for eggs
8880 INFO: Python library not in binary dependencies. Doing additional searching...
8892 INFO: Using Python library ~anaconda3/lib/libpython3.8.so
8898 INFO: Warnings written to ...install_tester/build/test/warn-test.txt
8919 INFO: Graph cross-reference written to ...install_tester/build/test/xref-test.html
8926 INFO: checking PYZ
8928 INFO: Building because toc changed
8928 INFO: Building PYZ (ZlibArchive) ...install_tester/build/test/PYZ-00.pyz
9198 INFO: Building PYZ (ZlibArchive) ...install_tester/build/test/PYZ-00.pyz completed successfully.
9202 INFO: checking PKG
9202 INFO: Building because toc changed
9202 INFO: Building PKG (CArchive) test.pkg
28025 INFO: Building PKG (CArchive) test.pkg completed successfully.
28028 INFO: Bootloader ~anaconda3/lib/python3.8/site-packages/PyInstaller/bootloader/Linux-64bit-intel/run
28029 INFO: checking EXE
28029 INFO: Building because name changed
28029 INFO: Building EXE from EXE-00.toc
WARNING: The output directory "...install_tester/dist/test" and ALL ITS CONTENTS will be REMOVED! Continue? (y/N)y
On your own risk, you can use the option `--noconfirm` to get rid of this question.
33016 INFO: Removing dir ...install_tester/dist/test
33038 INFO: Copying bootloader EXE to ...install_tester/dist/test
33039 INFO: Appending PKG archive to custom ELF section in EXE
33419 INFO: Building EXE from EXE-00.toc completed successfully.
Running the binary file:
...install_tester/dist$ ./test
Traceback (most recent call last):
File "test.py", line 1, in <module>
ImportError: cannot import name 'QtMultimedia' from 'PyQt5' (/tmp/_MEIVI98hn/PyQt5/__init__.pyc)
[33541] Failed to execute script 'test' due to unhandled exception!
I've tried with and without `--hidden-import=PyQt5.QtMultimedia`
I've tried it with and without the --hidden-import flag.
If I discard the --onefile flag, then the folder dist/PyQt5 contains:
install_tester/dist/test/PyQt5$ ls
Qt QtCore.so QtGui.so QtWidgets.so
Noticeably missing QtMultimedia.so, if I try to copy this file from the virtual environment folder, the error message changes to this:
install_tester/dist/test$ ./test
Traceback (most recent call last):
File "test.py", line 1, in <module>
ImportError: .../install_tester/dist/test/libQt5Core.so.5: version `Qt_5.15' not found (required by .../install_tester/dist/test/PyQt5/QtMultimedia.abi3.so)
[35195] Failed to execute script 'test' due to unhandled exception!
I know there have been other questions here regarding hidden imports, following some comments from those posts I've also tried changing test.spec to include this line:
pathex=['.../install_tester/venv/lib/python3.8/site-packages/PyQt5/QtMultimedia.abi3.so'],
But that also doesn't work.
Edit 24-03-22: This issue is caused by using virtual python environments. The exact problem with my virtual environment I'm not entirely sure of, but I successfully compiled a linux binary by creating a Ubuntu virtual machine (fresh install, and yes... on an Ubuntu host) then installing the python libraries with pip, no conda or other virtual environments. I then ran pyinstaller and copied the binary back to my host machine... it works perfectly!