I'm trying to generate a bundle for macOS for this project. The .spec
file from the repository works fine on Windows, but when I try to use it for macOS, it fails.
I've tried to fix it for MacOS by modifying it, resulting in the following:
# -*- mode: python ; coding: utf-8 -*-
import os.path
from pathlib import Path
from PyInstaller.compat import is_darwin, is_win
from PyInstaller.utils.hooks import copy_metadata, collect_data_files, collect_all
datas = []
datas += collect_data_files("transformers", include_py_files=True)
datas += collect_data_files("lightning")
datas += collect_data_files("lightning_fabric")
datas += collect_data_files("speechbrain")
datas += collect_data_files("pyannote")
datas += collect_data_files("asteroid_filterbanks")
datas += collect_data_files("whisperx")
datas += collect_data_files("librosa")
datas += copy_metadata("tqdm")
datas += copy_metadata("regex")
datas += copy_metadata("requests")
datas += copy_metadata("packaging")
datas += copy_metadata("filelock")
datas += copy_metadata("numpy")
datas += copy_metadata("tokenizers")
datas += copy_metadata("pillow")
datas += copy_metadata("huggingface_hub")
datas += copy_metadata("safetensors")
datas += copy_metadata("pyyaml")
datas += [("res", "res")]
datas += [("config.ini", ".")]
datas += [(".env", ".")]
datas += [("venv/lib/python3.10/site-packages/customtkinter", "customtkinter")]
datas += [("venv/lib/python3.10/site-packages/torch", "torch")]
datas += [("venv/lib/python3.10/site-packages/torchgen", "torchgen")]
datas += [("venv/lib/python3.10/site-packages/speech_recognition", "speech_recognition")]
datas += [("venv/lib/python3.10/site-packages/moviepy", "moviepy")]
datas += [("venv/lib/python3.10/site-packages/dotenv", "dotenv")]
datas += [("venv/lib/python3.10/site-packages/openai", "openai")]
hiddenimports = [
"huggingface_hub.repository",
"pytorch",
"sklearn.utils._cython_blas",
"sklearn.neighbors.typedefs",
"sklearn.neighbors.quad_tree",
"sklearn.tree",
"sklearn.tree._utils",
"darkdetect",
"tkinter.font",
"tkinter.ttk",
"cmath",
"pickletools",
"unittest.mock",
"aifc",
"proglog",
"imageio",
"decorator",
]
block_cipher = None
debug = True
if debug:
options = [("v", None, "OPTION")]
else:
options = []
a = Analysis(
["src/app.py"],
pathex=[],
binaries=[],
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
macos_icon = "res/macos/icon.icns"
windows_icon = "res/windows/icon.ico"
exe = EXE(
pyz,
a.scripts,
options,
exclude_binaries=True, #NEW
name="Audiotext",
debug=debug,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=debug,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file="res/macos/entitlements.plist" if is_darwin else None,
icon=windows_icon if is_win else macos_icon,
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name="Audiotext",
)
app = BUNDLE(
coll,
name="Audiotext.app",
icon=macos_icon,
bundle_identifier="com.henestrosadev.audiotext",
version="2.3.0",
info_plist={
"NSPrincipalClass": "NSApplication",
"NSAppleScriptEnabed": False,
"NSHighResolutionCapable": True,
"NSMicrophoneUsageDescription": "Allow Audiotext to record audio from your microphone to generate transcriptions.",
}
)
Now, it generates the bundle, but when I open the generated file, I always get a ModuleNotFoundError
. For example, the error I have now is ModuleNotFoundError: No module named 'openai'
. I've fixed it by adding this line, as I've done with te rest of the previous missing modules:
datas += [("venv/lib/python3.10/site-packages/openai", "openai")]
Now, the error I get is ModuleNotFoundError: No module named 'pydantic'
. Something is wrong, because it doesn't make sense to manually add all of the program's packages.
The problem was related to the pathex
, because for some reason PyInstaller only took the src
directory of the project. I added the site-packages
directory from the venv
directory to the pathex
.
The file is now as follows:
# -*- mode: python ; coding: utf-8 -*-
import os.path
from pathlib import Path
from PyInstaller.compat import is_darwin, is_win
import sys ; sys.setrecursionlimit(sys.getrecursionlimit() * 5)
relative_site_packages_path = "venv/Lib/site-packages" if is_win else "venv/lib/python3.10/site-packages"
datas = [
(f"{relative_site_packages_path}/customtkinter", "customtkinter"),
(f"{relative_site_packages_path}/transformers", "transformers"),
(f"{relative_site_packages_path}/lightning", "lightning"),
(f"{relative_site_packages_path}/lightning_fabric", "lightning_fabric"),
(f"{relative_site_packages_path}/speechbrain", "speechbrain"),
(f"{relative_site_packages_path}/pyannote", "pyannote"),
(f"{relative_site_packages_path}/asteroid_filterbanks", "asteroid_filterbanks"),
(f"{relative_site_packages_path}/whisperx", "whisperx"),
(f"{relative_site_packages_path}/librosa", "librosa"),
("res", "res"),
("config.ini", "."),
(".env", "."),
]
hiddenimports = [
"huggingface_hub.repository",
"sklearn.utils._cython_blas",
"sklearn.neighbors.quad_tree",
"sklearn.tree",
"sklearn.tree._utils",
]
block_cipher = None
debug = False
if debug:
options = [("v", None, "OPTION")]
else:
options = []
a = Analysis(
["src/app.py"],
pathex=[relative_site_packages_path],
binaries=[],
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
macos_icon = "res/macos/icon.icns"
windows_icon = "res/windows/icon.ico"
exe = EXE(
pyz,
a.scripts,
options,
exclude_binaries=True, #NEW
name="Audiotext",
debug=debug,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=debug,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file="res/macos/entitlements.plist" if is_darwin else None,
icon=windows_icon if is_win else macos_icon,
)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name="Audiotext",
)
app = BUNDLE(
coll,
name="Audiotext.app",
icon=macos_icon,
bundle_identifier="com.henestrosadev.audiotext",
version="2.3.0",
info_plist={
"NSPrincipalClass": "NSApplication",
"NSAppleScriptEnabed": False,
"NSHighResolutionCapable": True,
"NSMicrophoneUsageDescription": "Allow Audiotext to record audio from your microphone to generate transcriptions.",
}
)
This solves the issue. However, I have another problem now because the Audiotext.app
file won't open, while the Audiotext
executable from the dist/Audiotext
directory does. But it is not related to this topic, so I'll mark this as the answer.