-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pyinstaller doesn't work #83
Comments
if you just run
does it work? I tried on my PC, just got
I can make sure I installed pywry, but maybe need more dynamic library |
No, you error simply means you don't have the package at all. Refradless of dynamic library. |
Works on macOS but fails on Windows |
Since the PyWry backend runs in a subprocess the main.exe is To fix this and get it working with pyinstaller you'd create a spec file and do a folder build # -*- mode: python ; coding: utf-8 -*- # noqa
import os
import sys
from pathlib import Path
from PyInstaller.building.api import COLLECT, EXE, PYZ
from PyInstaller.building.build_main import Analysis
from PyInstaller.compat import is_darwin
NAME = "Executable Name" # Change this to the name of your executable
cwd_path = Path(os.getcwd()).resolve()
# Local python environment packages folder
venv_path = Path(sys.executable).parent.parent.resolve()
# Check if we are running in a conda environment
if is_darwin:
pathex = os.path.join(os.path.dirname(os.__file__), "site-packages")
elif "site-packages" in list(venv_path.iterdir()):
pathex = str(venv_path / "site-packages")
else:
pathex = str(venv_path / "lib" / "site-packages")
pathex = Path(pathex).resolve()
# Files that are explicitly pulled into the bundle
added_files = [
(str(cwd_path / "folder_path"), "folder_path"),
]
# Python libraries that are explicitly pulled into the bundle
hidden_imports = ["pywry.pywry"]
# Entry point
analysis_kwargs = dict(
scripts=[str(cwd_path / "main.py")],
pathex=[str(pathex), "."],
binaries=[],
datas=added_files,
hiddenimports=hidden_imports,
hooksconfig={},
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=None,
noarchive=False,
)
a = Analysis(**analysis_kwargs)
pyz = PYZ(a.pure, a.zipped_data, cipher=analysis_kwargs["cipher"])
block_cipher = None
# PyWry
pywry_a = Analysis(
[str(pathex / "pywry/backend.py")],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pywry_pyz = PYZ(pywry_a.pure, pywry_a.zipped_data, cipher=block_cipher)
# PyWry EXE
pywry_exe = EXE(
pywry_pyz,
pywry_a.scripts,
[],
exclude_binaries=True,
name="PyWry",
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
console=True,
disable_windowed_traceback=False,
target_arch="x86_64",
codesign_identity=None,
entitlements_file=None,
)
exe_args = [
pyz,
a.scripts,
[],
]
exe_kwargs = dict(
name=NAME,
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=False,
upx_exclude=[],
console=True,
disable_windowed_traceback=False,
target_arch="x86_64",
codesign_identity=None,
entitlements_file=None,
)
# Packaging settings
exe_kwargs["exclude_binaries"] = True
collect_args = [
a.binaries,
a.zipfiles,
a.datas,
]
collect_kwargs = dict(
strip=False,
upx=True,
upx_exclude=[],
name=NAME,
)
if is_darwin:
exe_kwargs["argv_emulation"] = True
exe = EXE(*exe_args, **exe_kwargs)
pywry_collect_args = [
pywry_a.binaries,
pywry_a.zipfiles,
pywry_a.datas,
]
coll = COLLECT(
*([exe] + collect_args + [pywry_exe] + pywry_collect_args),
**collect_kwargs,
) If you change the PyWry exe name, In your import os
os.environ["PYWRY_EXECUTABLE"] = "NewName" Then in cmdline call Hope that helps! |
Oh, I see why it didn't worked |
We run it as a subprocess due to Wry needing to run in main thread on the rust side, and that created issues of blocking python GUI when we initially started PyWry development🥲. |
If you already create and what about running |
🤦🏻♂️you're right and got me thinking why we kept the pyo3 extension if we weren't even using it anymore 🤣 So I went ahead and got rid of it and now we use pure compiled binary . Here's how to test
And the updated pyinstaller spec file# -*- mode: python ; coding: utf-8 -*- # noqa
import os
from shutil import which
import sys
from pathlib import Path
from PyInstaller.building.api import COLLECT, EXE, PYZ
from PyInstaller.building.build_main import Analysis
from PyInstaller.compat import is_darwin
NAME = "Executable Name" # Change this to the name of your executable
cwd_path = Path(os.getcwd()).resolve()
# Local python environment packages folder
venv_path = Path(sys.executable).parent.parent.resolve()
# Check if we are running in a conda environment
if is_darwin:
pathex = os.path.join(os.path.dirname(os.__file__), "site-packages")
elif "site-packages" in list(venv_path.iterdir()):
pathex = str(venv_path / "site-packages")
else:
pathex = str(venv_path / "lib" / "site-packages")
pathex = Path(pathex).resolve()
# Files that are explicitly pulled into the bundle
added_files = [
(str(cwd_path / "folder_path"), "folder_path"),
(which("pywry"), "."),
]
# Python libraries that are explicitly pulled into the bundle
hidden_imports = ["pywry"]
# Entry point
analysis_kwargs = dict(
scripts=[str(cwd_path / "main.py")],
pathex=[str(pathex), "."],
binaries=[],
datas=added_files,
hiddenimports=hidden_imports,
hooksconfig={},
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=None,
noarchive=False,
)
a = Analysis(**analysis_kwargs)
pyz = PYZ(a.pure, a.zipped_data, cipher=analysis_kwargs["cipher"])
exe_args = [
pyz,
a.scripts,
[],
]
exe_kwargs = dict(
name=NAME,
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=False,
upx_exclude=[],
console=True,
disable_windowed_traceback=False,
target_arch="x86_64",
codesign_identity=None,
entitlements_file=None,
)
# Packaging settings
exe_kwargs["exclude_binaries"] = True
collect_args = [
a.binaries,
a.zipfiles,
a.datas,
]
collect_kwargs = dict(
strip=False,
upx=True,
upx_exclude=[],
name=NAME,
)
if is_darwin:
exe_kwargs["argv_emulation"] = True
exe = EXE(*exe_args, **exe_kwargs)
coll = COLLECT(
*([exe] + collect_args),
**collect_kwargs,
) Thank you for the suggestion and wake up call haha! .🚀 |
Thanks. If you want to make it easy to use with I tested your nighly build, it works. the only thing which needs to be copied to the compiled python program is UpdateI created the hook:
import ctypes
from os.path import join, exists
from PyInstaller.compat import is_win, getsitepackages
name = 'pywry.exe' if is_win else 'pywry'
binary = ctypes.util.find_library(name)
datas = []
if binary:
datas = [(binary, '.')]
else:
for sitepack in getsitepackages():
library = join(sitepack, 'lib', binary)
if exists(library):
datas = [(library, '.')]
if not datas:
raise Exception(binary + ' not found') then just run pyinstaller --onefile main.py --additional-hooks-dir=. |
When compiling the example to
exe
using pyinstallerand then opening the compiled
exe
file the app starts but no window is opened and no errorThe text was updated successfully, but these errors were encountered: