The PyInstaller .spec
file is mean to be portable across the three platforms that it supports: Windows, Mac OS X and Linux.
I find it much easier to generate the .spec
file once and modify it at will before building an executable from it.
In every example on the Internet (e.g. this one), the .spec
file would always define an absolute path in for the pathex
parameter in the ANALYSIS section. This makes the build non-portable, because the absolute path is not only specific to the machine the build runs on, but also the platform.
Does this always have to be an absolute path or is there a way to make it completely portable?
Add the path for the 'pyinstaller.exe' to your Windows environment variables. Open a instance of File Explorer and navigate to C:\Program Files\Python37\Scripts or C:\Users\USER_NAME\AppData\Roaming\Python\Python37\Scripts and look for the executable. Once you find the file make sure to get its full path.
After installation, the pyinstaller binary is located in your virtual environment's bin/ directory, or where your Python executable is located. If that directory isn't in your PATH , include the whole path when you run pyinstaller .
pathex : a list of paths to search for imports (like using PYTHONPATH ), including paths given by the --paths option. binaries : non-python modules needed by the scripts, including names given by the --add-binary option; datas : non-binary files included in the app, including names given by the --add-data option.
getcwd() method to get Python Script location. The os. getcwd() method is used for getting the Current Working Directory in Python. The absolute path to the current working directory is returned in a string by this function of the Python OS module.
If you place the .spec
file in its default location you can simply remove pathex
from the spec because 'current directory'
and 'your-configured-pathex-here'
are identical.
Explanation
pathex
is an optional list of paths to be searched beforesys.path
Source: https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/building/build_main.py#L123
The spec file is actually executable Python code. PyInstaller builds the app by executing the contents of the spec file.
Source: https://github.com/pyinstaller/pyinstaller/blob/develop/doc/spec-files.rst#using-spec-files
This leads to the conclusion that you should be able either hardcode each path for the three environments like so
pathex=["/Users/fatuhoku/Python/myapp", "C:\\Python\\myapp", "/home/fatuhoku/Python/myapp"],
or call a handwoven Python function that just returns a list with a single element that is the current working directory.
If you run PyInstaller it tells you something like this:
46 INFO: Extending PYTHONPATH with paths
['current directory', 'your-configured-pathex-here']
As others have pointed out, the .spec
file is Python code. What you want is for pathex
to be an absolute path on the machine currently executing the code. You can do this with the help of the SPECPATH
global variable that is defined within the .spec
file. (See all available globals listed in the PyInstaller docs here.)
In our case, I used:
import os
spec_root = os.path.abspath(SPECPATH)
...
pathex=[spec_root]
If your .spec
is not in the same directory as your package/script, you can use os.path.abspath(os.path.join(SPECPATH, '..'))
or something similar to find your pathex from your spec file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With