I'm looking to create a cross-platform executable of my commandline application. The application is using poetry
as the package manager, and I'm running this on MacOS.
First we need to install PyInstaller:
$ poetry add pyinstaller --dev
Then it should be as simple as running the following:
$ poetry shell
$ pyinstaller --onefile app/app.py
Macho Libre
However, this resulted in the following error:
ModuleNotFoundError: No module named 'macholib'
macholib can be used to analyze and edit Mach-O headers, the executable format used by Mac OS X.
It’s typically used as a dependency analysis tool, and also to rewrite dylib references in Mach-O headers to be @executable_path relative.
Manually adding this dependency to the project addresses this:
$ poetry add macholib --dev
NLTK
However, now calling pyinstaller again throws up a new error:
Unable to find "nltk_data" when adding binary and data files.
NLTK is a leading platform for building Python programs to work with human language data. It provides easy-to-use interfaces to over 50 corpora and lexical resources such as WordNet, along with a suite of text processing libraries for classification, tokenization, stemming, tagging, parsing, and semantic reasoning, wrappers for industrial-strength NLP libraries [...].
Fortunately we can download the missing data as follows (from within the poetry shell):
$ python
>>> import nltk
>>> nltk.download()
Press the download button on the window that pops up and make sure the installation path matches the error message path.
Then fix the path to NLTK in PyInstaller according to this StackOverflow answer. To get to the right location, ask poetry:
$ poetry env list --full-path
$ cd <path>/lib/python3.7/site-packages/PyInstaller/hooks
Rerunning the pyinstaller command after this produced an executable! However it's 1.2GB, propably due to including the macholib library.
I will update this post when I've figured this out.