I'm trying to compile a Tkinter app as an executable for MacOs. I tried to use py2app
and pyinstaller
. I almost succeed using py2app
, but it returns the following error:
Traceback
The Info.plist file must have a PyRuntimeLocations array containing string values for preferred Python runtime locations.
These strings should be "otool -L" style mach ids; "@executable_stub" and "~" prefixes will be translated accordingly.
This is how the setup.py
looks like:
from setuptools import setup
APP = ['main.py']
DATA_FILES = ['config.json']
OPTIONS = {
'argv_emulation': True
}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
And this is the directory structure:
-modules/---__init.py__
| |
| -- gui_module.py
| |
| -- scraper_module.py
| |
| -- app.ico
|
-config.json
|
-countries_list.txt
|
-main.py
|
-requirements.txt
|
-setup.py
I'm happy to share more details and the files if you need them.
CodePudding user response:
The problem was that you need to give an executable path for the python framework you have on your MacOs. So I modify the setup.py
setup.py
from setuptools import setup
class CONFIG:
VERSION = 'v1.0.1'
platform = 'darwin-x86_64'
executable_stub = '/opt/homebrew/Frameworks/Python.framework/Versions/3.10/lib/libpython3.10.dylib' # this is important, check where is your Python framework and get the `dylib`
APP_NAME = f'your_app_{VERSION}_{platform}'
APP = ['main.py']
DATA_FILES = [
'config.json',
'countries_list.txt',
('modules', ['modules/app.ico']),
# this modules are automatically added if you use __init__.py in your folder
# ('modules', ['modules/scraper_module.py']),
# ('modules', ['modules/gui_module.py']),
]
OPTIONS = {
'argv_emulation': False,
'iconfile': 'modules/app.ico',
'plist': {
'CFBundleName': APP_NAME,
'CFBundleDisplayName': APP_NAME,
'CFBundleGetInfoString': APP_NAME,
'CFBundleVersion': VERSION,
'CFBundleShortVersionString': VERSION,
'PyRuntimeLocations': [
executable_stub,
# also the executable can look like this:
#'@executable_path/../Frameworks/libpython3.4m.dylib',
]
}
}
def main():
setup(
name=CONFIG.APP_NAME,
app=CONFIG.APP,
data_files=CONFIG.DATA_FILES,
options={'py2app': CONFIG.OPTIONS},
setup_requires=['py2app'],
maintainer='foo bar',
author_email='[email protected]',
)
if __name__ == '__main__':
main()
Then you need to run python3 setup.py py2app
and now you can go and just double click on your_app_{VERSION}_{platform}.app
.
Recomendations by the py2app
docs:
- Make sure not to use the -A flag
- Do not use
--argv-emulation
when the program uses a GUI toolkit (as Tkinter) py2app options docs