Reputation: 4911
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?
Upvotes: 23
Views: 22637
Reputation: 23535
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']
Upvotes: 20
Reputation: 5768
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.
Upvotes: 9
Reputation: 449
pathex now appears to be converted into a list of absolute paths if it isn't one already.
See PyInstaller build.py line #426
The .spec file is certainly portable in that it's literally Python source code. :) So you can write whatever logic you need inside your .spec file.
For example, my spec files call helper routines that exclude most of the encoding.* data that I don't care about, _ssl, etc...
Upvotes: 2