fatuhoku
fatuhoku

Reputation: 4911

How can I make PyInstaller's .spec files actually portable? (woes absolute path for 'pathex' parameter)

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

Answers (3)

Marcel Stör
Marcel Stör

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 before sys.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

Juan
Juan

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

Bill Tutt
Bill Tutt

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

Related Questions