How to use pyinstaller
How to use pyinstaller
How to use pyinstaller?
Okay so I’m a complete noob in programming and I’m trying to compile a simple program I wrote that takes in a string and prints out the string in morse code it’s called morse.py. I installed pyinstaller using
and I am trying to compile my program using pyinstaller.
Now I’ve searched a bit and it says that I need to write pyinstaller morse.py, but I don’t really know where to write that. I tried moving to the directory of my program and doing that in CMD but it didn’t work. I tried making a python program in the same directory and doing that and that also didn’t work. I couldn’t find anything very helpful to tell me exactly how to compile the file.
Can someone please help?
4 Answers 4
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
I would suggest to first read the Using Pyinstaller section in the documentation of the module itself.
You can also use some tutorials (e.g. Matt Borgerson’s one).
In order to recap you should:
run from the command line:
this command will generate a your_file_name.spec file where you can include all the dll required by your application and any custom settings (Using Spec Files)
\ pyinstaller [option1] [option2] your_file_name.py
You can create your exe file very easily also with py2exe.
Try to write full path to pyinstaller (for example = C:\Users\user\AppData\Local\Programs\Python\Python35-32\Scripts\pyinstaller.exe)
full cmd string must look like:
Hello i made a code in python, i used it to turn itself into a exe.
Make sure to have it in same directory as the file you want converted.
Hope this helps someone.
C:\Users\Ania>py Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 23:03:10) [MSC v.1916 64 bit (AM D64)] on win32 Type «help», «copyright», «credits» or «license» for more information.
Python 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)] on win32 Type «help», «copyright», «credits» or «license» for more information.
Now to work with your project you need to create a virtual environment for it. Remember to use the correct python version. First let’s make a folder for it.
Go to that folder:
Create the venv:
The first “venv” above is the name of a python module which we are using. The second “venv” is the name of the virtual environment which we are creating.
Activate the venv:
Now you can use pip to install whatever external packages your project needs.
Pip “knows” that you need packages for python 3.7. When you create your project files don’t put them in “venv” folder.
To run your project from the venv just type its name
To check what external packages you’ve already installed just type “pip list”:
altgraph 0.17 future 0.18.2 numpy 1.18.2 pandas 1.0.3 pefile 2019.4.18 pip 19.2.3 PyInstaller 3.6 python-dateutil 2.8.1 pytz 2019.3 pywin32-ctypes 0.2.0 setuptools 41.2.0 six 1.14.0
Using PyInstaller to Easily Distribute Python Applications
Table of Contents
Are you jealous of Go developers building an executable and easily shipping it to users? Wouldn’t it be great if your users could run your application without installing anything? That is the dream, and PyInstaller is one way to get there in the Python ecosystem.
There are countless tutorials on how to set up virtual environments, manage dependencies, avoid dependency pitfalls, and publish to PyPI, which is useful when you’re creating Python libraries. There is much less information for developers building Python applications. This tutorial is for developers who want to distribute applications to users who may or may not be Python developers.
In this tutorial, you’ll learn the following:
PyInstaller gives you the ability to create a folder or executable that users can immediately run without any extra installation. To fully appreciate PyInstaller’s power, it’s useful to revisit some of the distribution problems PyInstaller helps you avoid.
Free Bonus: 5 Thoughts On Python Mastery, a free course for Python developers that shows you the roadmap and the mindset you’ll need to take your Python skills to the next level.
Distribution Problems
Setting up a Python project can be frustrating, especially for non-developers. Often, the setup starts with opening a Terminal, which is a non-starter for a huge group of potential users. This roadblock stops users even before the installation guide delves into the complicated details of virtual environments, Python versions, and the myriad of potential dependencies.
Think about what you typically go through when setting up a new machine for Python development. It probably goes something like this:
Stop for a moment and consider if any of the above steps make any sense if you’re not a developer, let alone a Python developer. Probably not.
These problems explode if your user is lucky enough to get to the dependencies portion of the installation. This has gotten much better in the last few years with the prevalence of wheels, but some dependencies still require C/C++ or even FORTRAN compilers!
This barrier to entry is way too high if your goal is to make an application available to as many users as possible. As Raymond Hettinger often says in his excellent talks, “There has to be a better way.”
PyInstaller
PyInstaller abstracts these details from the user by finding all your dependencies and bundling them together. Your users won’t even know they’re running a Python project because the Python Interpreter itself is bundled into your application. Goodbye complicated installation instructions!
PyInstaller performs this amazing feat by introspecting your Python code, detecting your dependencies, and then packaging them into a suitable format depending on your Operating System.
There are lots of interesting details about PyInstaller, but for now you’ll learn the basics of how it works and how to use it. You can always refer to the excellent PyInstaller docs if you want more details.
Preparing Your Project
The entry-point script is a Python script. You can technically do anything you want in the entry-point script, but you should avoid using explicit relative imports. You can still use relative imports throughout the rest your application if that’s your preferred style.
Note: An entry-point is the code that starts your project or application.
You can give this a try with your own project or follow along with the Real Python feed reader project. For more detailed information on the reader project, check out the the tutorial on Publishing a Package on PyPI.
The first step to building an executable version of this project is to add the entry-point script. Luckily, the feed reader project is well structured, so all you need is a short script outside the package to run it. For example, you can create a file called cli.py alongside the reader package with the following code:
This cli.py script calls main() to start up the feed reader.
Creating this entry-point script is straightforward when you’re working on your own project because you’re familiar with the code. However, it’s not as easy to find the entry-point of another person’s code. In this case, you can start by looking at the setup.py file in the third-party project.
As you can see, the entry-point cli.py script calls the same function mentioned in the entry_points argument.
After this change, the reader project directory should look like this, assuming you checked it out into a folder called reader :
However, you’ll also want to look out for uses of __import__() or imports inside of functions. These are referred to as hidden imports in PyInstaller terminology.
You can manually specify the hidden imports to force PyInstaller to include those dependencies if changing the imports in your application is too difficult. You’ll see how to do this later in this tutorial.
Once you can launch your application with a Python script outside of your package, you’re ready to give PyInstaller a try at creating an executable.
Using PyInstaller
The first step is to install PyInstaller from PyPI. You can do this using pip like other Python packages:
You’ll use the library interface if you create your own hook files.
You’ll increase the likelihood of PyInstaller’s defaults creating an executable if you only have pure Python dependencies. However, don’t stress too much if you have more complicated dependencies with C/C++ extensions.
PyInstaller supports lots of popular packages like NumPy, PyQt, and Matplotlib without any additional work from you. You can see more about the list of packages that PyInstaller officially supports by referring to the PyInstaller documentation.
Don’t worry if some of your dependencies aren’t listed in the official docs. Many Python packages work fine. In fact, PyInstaller is popular enough that many projects have explanations on how to get things working with PyInstaller.
In short, the chances of your project working out of the box are high.
To try creating an executable with all the defaults, simply give PyInstaller the name of your main entry-point script.
First, cd in the folder with your entry-point and pass it as an argument to the pyinstaller command that was added to your PATH when PyInstaller was installed.
For example, type the following after you cd into the top-level reader directory if you’re following along with the feed reader project:
Don’t be alarmed if you see a lot of output while building your executable. PyInstaller is verbose by default, and the verbosity can be cranked way up for debugging, which you’ll see later.
Digging Into PyInstaller Artifacts
PyInstaller is complicated under the hood and will create a lot of output. So, it’s important to know what to focus on first. Namely, the executable you can distribute to your users and potential debugging information. By default, the pyinstaller command will create a few things of interest:
Spec File
This file will be automatically created by the pyinstaller command. Your version will have different paths, but the majority should be the same.
Don’t worry, you don’t need to understand the above code to effectively use PyInstaller!
This file can be modified and re-used to create executables later. You can make future builds a bit faster by providing this spec file instead of the entry-point script to the pyinstaller command.
There are a few specific use-cases for PyInstaller spec files. However, for simple projects, you won’t need to worry about those details unless you want to heavily customize how your project is built.
Build Folder
The build/ folder is where PyInstaller puts most of the metadata and internal bookkeeping for building your executable. The default contents will look something like this:
The build folder can be useful for debugging, but unless you have problems, this folder can largely be ignored. You’ll learn more about debugging later in this tutorial.
Dist Folder
After building, you’ll end up with a dist/ folder similar to the following:
The dist/ folder contains the final artifact you’ll want to ship to your users. Inside the dist/ folder, there is a folder named after your entry-point. So in this example, you’ll have a dist/cli folder that contains all the dependencies and executable for our application. The executable to run is dist/cli/cli or dist/cli/cli.exe if you’re on Windows.
You’ll want to distribute the entire dist/cli folder, but you can rename cli to anything that suits you.
At this point you can try running the dist/cli/cli executable if you’re following along with the feed reader example.
You’ll notice that running the executable results in errors mentioning the version.txt file. This is because the feed reader and its dependencies require some extra data files that PyInstaller doesn’t know about. To fix that, you’ll have to tell PyInstaller that version.txt is required, which you’ll learn about when testing your new executable.
Customizing Your Builds
PyInstaller comes with lots of options that can be provided as spec files or normal CLI options. Below, you’ll find some of the most common and useful options.
Change the name of your executable.
You can build an executable called realpython from the cli.py script with a command like this:
Package your entire application into a single executable file.
This option takes no arguments. To bundle your project into a single file, you can build with a command like this:
With the above command, your dist/ folder will only contain a single executable instead of a folder with all the dependencies in separate files.
List multiple top-level imports that PyInstaller was unable to detect automatically.
This option requires the name of the package that you want to include in your executable. For example, if your project imported the requests library inside of a function, then PyInstaller would not automatically include requests in your executable. You could use the following command to force requests to be included:
You can specify this multiple times in your build command, once for each hidden import.
Instruct PyInstaller to insert additional data or binary files into your build.
This is useful when you want to bundle in configuration files, examples, or other non-code data. You’ll see an example of this later if you’re following along with the feed reader project.
Exclude some modules from being included with your executable
This is useful to exclude developer-only requirements like testing frameworks. This is a great way to keep the artifact you give users as small as possible. For example, if you use pytest, you may want to exclude this from your executable:
Avoid automatically opening a console window for stdout logging.
This is only useful if you’re building a GUI-enabled application. This helps your hide the details of your implementation by allowing users to never see a terminal.
Since it’s a regular Python script, you can do almost anything inside of it. You can refer to the official PyInstaller Spec file documentation for more information on that API.
Testing Your New Executable
The best way to test your new executable is on a new machine. The new machine should have the same OS as your build machine. Ideally, this machine should be as similar as possible to what your users use. That may not always be possible, so the next best thing is testing on your own machine.
Picking up with the feed reader example, you’ll notice that running the default cli executable in the dist/cli folder fails. Luckily the error points you to the problem:
Note: The pyinstaller commands use the \ character to make the command easier to read. You can omit the \ when running commands on your own or copy and paste the commands as-is below provided you’re using the same paths.
You’ll want to adjust the path in the above command to match where you installed the feed reader dependencies.
Now running the new executable will result in a new error about a config.cfg file.
This file is required by the feed reader project, so you’ll need to make sure to include it in your build:
Again, you’ll need to adjust the path to the file based on where you have the feed reader project.
At this point, you should have a working executable that can be given directly to users!
Debugging PyInstaller Executables
As you saw above, you might encounter problems when running your executable. Depending on the complexity of your project, the fixes could be as simple as including data files like the feed reader example. However, sometimes you need more debugging techniques.
Below are a few common strategies that are in no particular order. Often times one of these strategies or a combination will lead to a break-through in tough debugging sessions.
Use the Terminal
First, try running the executable from a terminal so you can see all the output.
Debug Files
Inspect the build/cli/warn-cli.txt file for any problems. PyInstaller creates lots of output to help you understand exactly what it’s creating. Digging around in the build/ folder is a great place to start.
Single Directory Builds
Additional CLI Options
By using the above command, you’ll have a file called build.txt containing lots of additional DEBUG messages.
Here’s a sample of what your build.txt file might look like:
This file will have a lot of detailed information about what was included in your build, why something was not included, and how the executable was packaged.
Additional PyInstaller Docs
The PyInstaller GitHub Wiki has lots of useful links and debugging tips. Most notably are the sections on making sure everything is packaged correctly and what to do if things go wrong.
Assisting in Dependency Detection
Hook files are how PyInstaller itself works internally so you can find lots of example hook files in the PyInstaller source code.
Limitations
PyInstaller is incredibly powerful, but it does have some limitations. Some of the limitations were discussed previously: hidden imports and relative imports in entry-point scripts.
PyInstaller supports making executables for Windows, Linux, and macOS, but it cannot cross compile. Therefore, you cannot make an executable targeting one Operating System from another Operating System. So, to distribute executables for multiple types of OS, you’ll need a build machine for each supported OS.
For example, if you want to target a wide array of Linux machines, then you can build on an older version of CentOS. This will give you compatibility with most versions newer than the one you build on. This is the same strategy described in PEP 0513 and is what the PyPA recommends for building compatible wheels.
In fact, you might want to investigate using the PyPA’s manylinux docker image for your Linux build environment. You could start with the base image then install PyInstaller along with all your dependencies and have a build image that supports most variants of Linux.
Conclusion
PyInstaller can help make complicated installation documents unnecessary. Instead, your users can simply run your executable to get started as quickly as possible. The PyInstaller workflow can be summed up by doing the following:
Your users don’t have to know what version of Python you used or that your application uses Python at all!
Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.
About Luke Lee
Luke has professionally written software for applications ranging from Python desktop and web applications to embedded C drivers for Solid State Disks. He has also spoken at PyCon, PyTexas, PyArkansas, PyconDE, and meetup groups.
Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:
Master Real-World Python Skills With Unlimited Access to Real Python
Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:
Master Real-World Python Skills
With Unlimited Access to Real Python
Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:
What Do You Think?
What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.
Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. Get tips for asking good questions and get answers to common questions in our support portal. Looking for a real-time conversation? Visit the Real Python Community Chat or join the next “Office Hours” Live Q&A Session. Happy Pythoning!
pyinstaller¶
SYNOPSIS¶
DESCRIPTION¶
PyInstaller is a program that freezes (packages) Python programs into stand-alone executables, under Windows, GNU/Linux, macOS, FreeBSD, OpenBSD, Solaris and AIX. Its main advantages over similar tools are that PyInstaller works with Python 3.7-3.10, it builds smaller executables thanks to transparent compression, it is fully multi-platform, and use the OS support to load the dynamic libraries, thus ensuring full compatibility.
OPTIONS¶
Positional Arguments¶
Optional Arguments¶
show this help message and exit
Show program version info and exit.
Replace output directory (default: SPECPATH/dist/SPECNAME) without asking for confirmation
Path to UPX utility (default: search the execution path)
Do not include unicode encoding support (default: included if available)
Clean PyInstaller cache and remove temporary files before building.
Amount of detail in build-time console messages. LEVEL may be one of TRACE, DEBUG, INFO, WARN, ERROR, CRITICAL (default: INFO).
What To Generate¶
Create a one-folder bundle containing an executable (default)
Create a one-file bundled executable.
Folder to store the generated spec file (default: current directory)
Name to assign to the bundled app and spec file (default: first script’s basename)
What To Bundle, Where To Search¶
Additional non-binary files or folders to be added to the executable. The path separator is platform specific, os.pathsep (which is ; on Windows and : on most unix systems) is used. This option can be used multiple times.
Name an import not visible in the code of the script(s). This option can be used multiple times.
Collect all submodules from the specified package or module. This option can be used multiple times.
Collect all data from the specified package or module. This option can be used multiple times.
Collect all binaries from the specified package or module. This option can be used multiple times.
Collect all submodules, data files, and binaries from the specified package or module. This option can be used multiple times.
Copy metadata for the specified package. This option can be used multiple times.
Copy metadata for the specified package and all its dependencies. This option can be used multiple times.
An additional path to search for hooks. This option can be used multiple times.
Path to a custom runtime hook file. A runtime hook is code that is bundled with the executable and is executed before any other code or module to set up special features of the runtime environment. This option can be used multiple times.
Optional module or package (the Python name, not the path name) that will be ignored (as though it was not found). This option can be used multiple times.
The key used to encrypt Python bytecode.
(EXPERIMENTAL) Add an splash screen with the image IMAGE_FILE to the application. The splash screen can display progress updates while unpacking.
How To Generate¶
Specify a command-line option to pass to the Python interpreter at runtime. Currently supports “v” (equivalent to “–debug imports”), “u”, and “W ”.
Apply a symbol-table strip to the executable and shared libs (not recommended for Windows)
Do not use UPX even if it is available (works differently between Windows and *nix)
Prevent a binary from being compressed when using upx. This is typically used if upx corrupts certain binaries during compression. FILE is the filename of the binary without path. This option can be used multiple times.
Windows And Mac Os X Specific Options¶
Open a console window for standard i/o (default). On Windows this option has no effect if the first script is a ‘.pyw’ file.
Disable traceback dump of unhandled exception in windowed (noconsole) mode (Windows and macOS only), and instead display a message that this feature is disabled.
Windows Specific Options¶
Add a version resource from FILE to the exe.
Add manifest FILE or XML to the exe.
Add or update a resource to a Windows executable. The RESOURCE is one to four items, FILE[,TYPE[,NAME[,LANGUAGE]]]. FILE can be a data file or an exe/dll. For data files, at least TYPE and NAME must be specified. LANGUAGE defaults to 0 or may be specified as wildcard * to update all resources of the given TYPE and NAME. For exe/dll files, all resources from FILE will be added/updated to the final executable if TYPE, NAME and LANGUAGE are omitted or specified as wildcard *. This option can be used multiple times.
Using this option creates a Manifest that will request elevation upon application start.
Using this option allows an elevated application to work with Remote Desktop.
Windows Side-By-Side Assembly Searching Options (Advanced)¶
Any Shared Assemblies bundled into the application will be changed into Private Assemblies. This means the exact versions of these assemblies will always be used, and any newer versions installed on user machines at the system level will be ignored.
While searching for Shared or Private Assemblies to bundle into the application, PyInstaller will prefer not to follow policies that redirect to newer versions, and will try to bundle the exact versions of the assembly.
Mac Os Specific Options¶
Enable argv emulation for macOS app bundles. If enabled, the initial open document/URL event is processed by the bootloader and the passed file paths or URLs are appended to sys.argv.
Target architecture (macOS only; valid values: x86_64, arm64, universal2). Enables switching between universal2 and single-arch version of frozen application (provided python installation supports the target architecture). If not target architecture is not specified, the current running architecture is targeted.
Code signing identity (macOS only). Use the provided identity to sign collected binaries and generated executable. If signing identity is not provided, ad- hoc signing is performed instead.
Entitlements file to use when code-signing the collected binaries (macOS only).
Rarely Used Special Options¶
Tell the bootloader to ignore signals rather than forwarding them to the child process. Useful in situations where for example a supervisor process signals both the bootloader and the child (e.g., via a process group) to avoid signalling the child twice.
ENVIRONMENT VARIABLES¶
This changes the directory where PyInstaller caches some files. The default location for this is operating system dependent, but is typically a subdirectory of the home directory.
SEE ALSO¶
pyinstaller¶
SYNOPSIS¶
DESCRIPTION¶
PyInstaller is a program that freezes (packages) Python programs into stand-alone executables, under Windows, GNU/Linux, Mac OS X, FreeBSD, OpenBSD, Solaris and AIX. Its main advantages over similar tools are that PyInstaller works with Python 3.6-3.9, it builds smaller executables thanks to transparent compression, it is fully multi-platform, and use the OS support to load the dynamic libraries, thus ensuring full compatibility.
OPTIONS¶
Positional Arguments¶
Optional Arguments¶
show this help message and exit
Show program version info and exit.
Replace output directory (default: SPECPATH/dist/SPECNAME) without asking for confirmation
Path to UPX utility (default: search the execution path)
Do not include unicode encoding support (default: included if available)
Clean PyInstaller cache and remove temporary files before building.
Amount of detail in build-time console messages. LEVEL may be one of TRACE, DEBUG, INFO, WARN, ERROR, CRITICAL (default: INFO).
What To Generate¶
Create a one-folder bundle containing an executable (default)
Create a one-file bundled executable.
Folder to store the generated spec file (default: current directory)
Name to assign to the bundled app and spec file (default: first script’s basename)
What To Bundle, Where To Search¶
Additional non-binary files or folders to be added to the executable. The path separator is platform specific, os.pathsep (which is ; on Windows and : on most unix systems) is used. This option can be used multiple times.
Name an import not visible in the code of the script(s). This option can be used multiple times.
Collect all submodules from the specified package or module. This option can be used multiple times.
Collect all data from the specified package or module. This option can be used multiple times.
Collect all binaries from the specified package or module. This option can be used multiple times.
Collect all submodules, data files, and binaries from the specified package or module. This option can be used multiple times.
Copy metadata for the specified package. This option can be used multiple times.
Copy metadata for the specified package and all its dependencies. This option can be used multiple times.
An additional path to search for hooks. This option can be used multiple times.
Path to a custom runtime hook file. A runtime hook is code that is bundled with the executable and is executed before any other code or module to set up special features of the runtime environment. This option can be used multiple times.
Optional module or package (the Python name, not the path name) that will be ignored (as though it was not found). This option can be used multiple times.
The key used to encrypt Python bytecode.
(EXPERIMENTAL) Add an splash screen with the image IMAGE_FILE to the application. The splash screen can display progress updates while unpacking.
How To Generate¶
Specify a command-line option to pass to the Python interpreter at runtime. Currently supports “v” (equivalent to “–debug imports”), “u”, and “W ”.
Apply a symbol-table strip to the executable and shared libs (not recommended for Windows)
Do not use UPX even if it is available (works differently between Windows and *nix)
Prevent a binary from being compressed when using upx. This is typically used if upx corrupts certain binaries during compression. FILE is the filename of the binary without path. This option can be used multiple times.
Windows And Mac Os X Specific Options¶
Open a console window for standard i/o (default). On Windows this option has no effect if the first script is a ‘.pyw’ file.
Disable traceback dump of unhandled exception in windowed (noconsole) mode (Windows and macOS only), and instead display a message that this feature is disabled.
Windows Specific Options¶
Add a version resource from FILE to the exe.
Add manifest FILE or XML to the exe.
Add or update a resource to a Windows executable. The RESOURCE is one to four items, FILE[,TYPE[,NAME[,LANGUAGE]]]. FILE can be a data file or an exe/dll. For data files, at least TYPE and NAME must be specified. LANGUAGE defaults to 0 or may be specified as wildcard * to update all resources of the given TYPE and NAME. For exe/dll files, all resources from FILE will be added/updated to the final executable if TYPE, NAME and LANGUAGE are omitted or specified as wildcard *. This option can be used multiple times.
Using this option creates a Manifest that will request elevation upon application start.
Using this option allows an elevated application to work with Remote Desktop.
Windows Side-By-Side Assembly Searching Options (Advanced)¶
Any Shared Assemblies bundled into the application will be changed into Private Assemblies. This means the exact versions of these assemblies will always be used, and any newer versions installed on user machines at the system level will be ignored.
While searching for Shared or Private Assemblies to bundle into the application, PyInstaller will prefer not to follow policies that redirect to newer versions, and will try to bundle the exact versions of the assembly.
Mac Os Specific Options¶
Target architecture (macOS only; valid values: x86_64, arm64, universal2). Enables switching between universal2 and single-arch version of frozen application (provided python installation supports the target architecture). If not target architecture is not specified, the current running architecture is targeted.
Code signing identity (macOS only). Use the provided identity to sign collected binaries and generated executable. If signing identity is not provided, ad- hoc signing is performed instead.
Entitlements file to use when code-signing the collected binaries (macOS only).
Rarely Used Special Options¶
Tell the bootloader to ignore signals rather than forwarding them to the child process. Useful in situations where for example a supervisor process signals both the bootloader and the child (e.g., via a process group) to avoid signalling the child twice.
ENVIRONMENT VARIABLES¶
This changes the directory where PyInstaller caches some files. The default location for this is operating system dependent, but is typically a subdirectory of the home directory.
SEE ALSO¶
Using PyInstaller¶
The syntax of the pyinstaller command is:
pyinstaller [options] script [script …] | specfile
In the most simple case, set the current directory to the location of your program myscript.py and execute:
PyInstaller analyzes myscript.py and:
Writes myscript.spec in the same folder as the script.
Creates a folder build in the same folder as the script if it does not exist.
Writes some log files and working files in the build folder.
Creates a folder dist in the same folder as the script if it does not exist.
Writes the myscript executable folder in the dist folder.
In the dist folder you find the bundled app you distribute to your users.
Normally you name one script on the command line. If you name more, all are analyzed and included in the output. However, the first script named supplies the name for the spec file and for the executable folder or file. Its code is the first to execute at run-time.
For certain uses you may edit the contents of myscript.spec (described under Using Spec Files ). After you do this, you name the spec file to PyInstaller instead of the script:
The myscript.spec file contains most of the information provided by the options that were specified when pyinstaller (or pyi-makespec) was run with the script file as the argument. You typically do not need to specify any options when running pyinstaller with the spec file. Only a few command-line options have an effect when building from a spec file.
You may give a path to the script or spec file, for example
pyinstaller «C:\Documents and Settings\project\myscript.spec»
Options¶
A full list of the pyinstaller command’s options are as follows:
Positional Arguments¶
Optional Arguments¶
show this help message and exit
Show program version info and exit.
Replace output directory (default: SPECPATH/dist/SPECNAME) without asking for confirmation
Path to UPX utility (default: search the execution path)
Do not include unicode encoding support (default: included if available)
Clean PyInstaller cache and remove temporary files before building.
Amount of detail in build-time console messages. LEVEL may be one of TRACE, DEBUG, INFO, WARN, ERROR, CRITICAL (default: INFO).
What To Generate¶
Create a one-folder bundle containing an executable (default)
Create a one-file bundled executable.
Folder to store the generated spec file (default: current directory)
Name to assign to the bundled app and spec file (default: first script’s basename)
What To Bundle, Where To Search¶
Additional non-binary files or folders to be added to the executable. The path separator is platform specific, os.pathsep (which is ; on Windows and : on most unix systems) is used. This option can be used multiple times.
—add-binary or SRC:DEST> ¶
Name an import not visible in the code of the script(s). This option can be used multiple times.
Collect all submodules from the specified package or module. This option can be used multiple times.
Collect all data from the specified package or module. This option can be used multiple times.
Collect all binaries from the specified package or module. This option can be used multiple times.
Collect all submodules, data files, and binaries from the specified package or module. This option can be used multiple times.
Copy metadata for the specified package. This option can be used multiple times.
Copy metadata for the specified package and all its dependencies. This option can be used multiple times.
An additional path to search for hooks. This option can be used multiple times.
Path to a custom runtime hook file. A runtime hook is code that is bundled with the executable and is executed before any other code or module to set up special features of the runtime environment. This option can be used multiple times.
Optional module or package (the Python name, not the path name) that will be ignored (as though it was not found). This option can be used multiple times.
The key used to encrypt Python bytecode.
(EXPERIMENTAL) Add an splash screen with the image IMAGE_FILE to the application. The splash screen can display progress updates while unpacking.
How To Generate¶
Specify a command-line option to pass to the Python interpreter at runtime. Currently supports “v” (equivalent to “–debug imports”), “u”, and “W ”.
Apply a symbol-table strip to the executable and shared libs (not recommended for Windows)
Do not use UPX even if it is available (works differently between Windows and *nix)
Prevent a binary from being compressed when using upx. This is typically used if upx corrupts certain binaries during compression. FILE is the filename of the binary without path. This option can be used multiple times.
Windows And Mac Os X Specific Options¶
Open a console window for standard i/o (default). On Windows this option has no effect if the first script is a ‘.pyw’ file.
Disable traceback dump of unhandled exception in windowed (noconsole) mode (Windows and macOS only), and instead display a message that this feature is disabled.
Windows Specific Options¶
Add a version resource from FILE to the exe.
Add manifest FILE or XML to the exe.
Add or update a resource to a Windows executable. The RESOURCE is one to four items, FILE[,TYPE[,NAME[,LANGUAGE]]]. FILE can be a data file or an exe/dll. For data files, at least TYPE and NAME must be specified. LANGUAGE defaults to 0 or may be specified as wildcard * to update all resources of the given TYPE and NAME. For exe/dll files, all resources from FILE will be added/updated to the final executable if TYPE, NAME and LANGUAGE are omitted or specified as wildcard *. This option can be used multiple times.
Using this option creates a Manifest that will request elevation upon application start.
Using this option allows an elevated application to work with Remote Desktop.
Windows Side-By-Side Assembly Searching Options (Advanced)¶
Any Shared Assemblies bundled into the application will be changed into Private Assemblies. This means the exact versions of these assemblies will always be used, and any newer versions installed on user machines at the system level will be ignored.
While searching for Shared or Private Assemblies to bundle into the application, PyInstaller will prefer not to follow policies that redirect to newer versions, and will try to bundle the exact versions of the assembly.
Mac Os Specific Options¶
Enable argv emulation for macOS app bundles. If enabled, the initial open document/URL event is processed by the bootloader and the passed file paths or URLs are appended to sys.argv.
Target architecture (macOS only; valid values: x86_64, arm64, universal2). Enables switching between universal2 and single-arch version of frozen application (provided python installation supports the target architecture). If not target architecture is not specified, the current running architecture is targeted.
Code signing identity (macOS only). Use the provided identity to sign collected binaries and generated executable. If signing identity is not provided, ad- hoc signing is performed instead.
Entitlements file to use when code-signing the collected binaries (macOS only).
Rarely Used Special Options¶
Tell the bootloader to ignore signals rather than forwarding them to the child process. Useful in situations where for example a supervisor process signals both the bootloader and the child (e.g., via a process group) to avoid signalling the child twice.
Shortening the Command¶
Because of its numerous options, a full pyinstaller command can become very long. You will run the same command again and again as you develop your script. You can put the command in a shell script or batch file, using line continuations to make it readable. For example, in GNU/Linux:
Or in Windows, use the little-known BAT file line continuation:
Running PyInstaller from Python code¶
Is equivalent to:
Using UPX¶
UPX is a free utility for compressing executable files and libraries. It is available for most operating systems and can compress a large number of executable file formats. See the UPX home page for downloads, and for the list of supported file formats.
When UPX is available, PyInstaller uses it to individually compress each collected binary file (executable, shared library, or python extension) in order to reduce the overall size of the frozen application (the one-dir bundle directory, or the one-file executable). The frozen application’s executable itself is not UPX-compressed (regardless of one-dir or one-file mode), as most of its size comprises the embedded archive that already contains individually compressed files.
Excluding problematic files from UPX processing¶
Changed in version 4.2: PyInstaller detects CFG-enabled DLLs and automatically excludes them from UPX processing.
Changed in version 4.3: PyInstaller automatically excludes Qt5 and Qt6 plugins from UPX processing.
Although PyInstaller attempts to automatically detect and exclude some of the problematic files from UPX processing, there are cases where the UPX excludes need to be specified manually. For example, 32-bit Windows binaries from the PySide2 package (Qt5 DLLs and python extension modules) have been reported to be corrupted by UPX.
Changed in version 5.0: Unlike earlier releases that compared the provided UPX-exclude names against basenames of the collect binary files (and, due to incomplete case normalization, required provided exclude names to be lowercase on Windows), the UPX-exclude pattern matching now uses OS-default case sensitivity and supports the wildcard ( * ) operator. It also supports specifying (full or partial) parent path of the file.
The provided UPX exclude patterns are matched against source (origin) paths of the collected binary files, and the matching is performed from right to left.
Encrypting Python Bytecode¶
For this to work, you need to run:
The key-string is a string of 16 characters which is used to encrypt each file of Python byte-code before it is stored in the archive inside the executable file.
This feature uses the tinyaes module internally for the encryption.
Splash Screen (Experimental)¶
This feature is incompatible with macOS. In the current design, the splash screen operates in a secondary thread, which is disallowed by the Tcl/Tk (or rather, the underlying GUI toolkit) on macOS.
Some applications may require a splash screen as soon as the application (bootloader) has been started, because especially in onefile mode large applications may have long extraction/startup times, while the bootloader prepares everything, where the user cannot judge whether the application was started successfully or not.
The bootloader is able to display a one-image (i.e. only an image) splash screen, which is displayed before the actual main extraction process starts. The splash screen supports non-transparent and hard-cut-transparent images as background image, so non-rectangular splash screens can also be displayed.
This splash screen is based on Tcl/Tk, which is the same library used by the Python module tkinter. PyInstaller bundles the dynamic libraries of tcl and tk into the application at compile time. These are loaded into the bootloader at startup of the application after they have been extracted (if the program has been packaged as an onefile archive). Since the file sizes of the necessary dynamic libraries are very small, there is almost no delay between the start of the application and the splash screen. The compressed size of the files necessary for the splash screen is about 1.5 MB.
As an additional feature, text can optionally be displayed on the splash screen. This can be changed/updated from within Python. This offers the possibility to display the splash screen during longer startup procedures of a Python program (e.g. waiting for a network response or loading large files into memory). You can also start a GUI behind the splash screen, and only after it is completely initialized the splash screen can be closed. Optionally, the font, color and size of the text can be set. However, the font must be installed on the user system, as it is not bundled. If the font is not available, a fallback font is used.
If the splash screen is configured to show text, it will automatically (as onefile archive) display the name of the file that is currently being unpacked, this acts as a progress bar.
The pyi_splash Module¶
The splash screen is controlled from within Python by the pyi_splash module, which can be imported at runtime. This module cannot be installed by a package manager because it is part of PyInstaller and is included as needed. This module must be imported within the Python program. The usage is as follows:
Defining the Extraction Location¶
Supporting Multiple Platforms¶
If you distribute your application for only one combination of OS and Python, just install PyInstaller like any other package and use it in your normal development setup.
Supporting Multiple Python Environments¶
When you need to bundle your application within one OS but for different versions of Python and support libraries – for example, a Python 3.6 version and a Python 3.7 version; or a supported version that uses Qt4 and a development version that uses Qt5 – we recommend you use venv. With venv you can maintain different combinations of Python and installed packages, and switch from one combination to another easily. These are called virtual environments or venvs in short.
Use venv to create as many different development environments as you need, each with its unique combination of Python and installed packages.
Install PyInstaller in each virtual environment.
Use PyInstaller to build your application in each virtual environment.
Under Windows, the pip-Win package makes it especially easy to set up different environments and switch between them. Under GNU/Linux and macOS, you switch environments at the command line.
See PEP 405 and the official Python Tutorial on Virtual Environments and Packages for more information about Python virtual environments.
Supporting Multiple Operating Systems¶
If you need to distribute your application for more than one OS, for example both Windows and macOS, you must install PyInstaller on each platform and bundle your app separately on each.
You can do this from a single machine using virtualization. The free virtualBox or the paid VMWare and Parallels allow you to run another complete operating system as a “guest”. You set up a virtual machine for each “guest” OS. In it you install Python, the support packages your application needs, and PyInstaller.
A File Sync & Share system like NextCloud is useful with virtual machines. Install the synchronization client in each virtual machine, all linked to your synchronization account. Keep a single copy of your script(s) in a synchronized folder. Then on any virtual machine you can run PyInstaller thus:
PyInstaller reads scripts from the common synchronized folder, but writes its work files and the bundled app in folders that are local to the virtual machine.
If you share the same home directory on multiple platforms, for example GNU/Linux and macOS, you will need to set the PYINSTALLER_CONFIG_DIR environment variable to different values on each platform otherwise PyInstaller may cache files for one platform and use them on the other platform, as by default it uses a subdirectory of your home directory as its cache location.
It is said to be possible to cross-develop for Windows under GNU/Linux using the free Wine environment. Further details are needed, see How to Contribute.
Capturing Windows Version Data¶
A Windows app may require a Version resource file. A Version resource contains a group of data structures, some containing binary integers and some containing strings, that describe the properties of the executable. For details see the Microsoft Version Information Structures page.
Version resources are complex and some elements are optional, others required. When you view the version tab of a Properties dialog, there’s no simple relationship between the data displayed and the structure of the resource. For this reason PyInstaller includes the pyi-grab_version command. It is invoked with the full path name of any Windows executable that has a Version resource:
The command writes text that represents a Version resource in readable form to standard output. You can copy it from the console window or redirect it to a file. Then you can edit the version information to adapt it to your program. Using pyi-grab_version you can find an executable that displays the kind of information you want, copy its resource data, and modify it to suit your package.
The version text file is encoded UTF-8 and may contain non-ASCII characters. (Unicode characters are allowed in Version resource string fields.) Be sure to edit and save the text file in UTF-8 unless you are certain it contains only ASCII string values.
The elements of each tuple represent 16-bit values from most-significant to least-significant. For example the value (2, 0, 4, 0) resolves to 0002000000040000 in hex.
You can also install a Version resource from a text file after the bundled app has been created, using the pyi-set_version command:
pyi-set_version version_text_file executable_file
Building macOS App Bundles¶
As you probably know, an application is a special type of folder. The one built by PyInstaller contains a folder always named Contents which contains:
A folder Frameworks which is empty.
A folder Resources that contains an icon file.
A file Info.plist that describes the app.
You can add other items to the Info.plist by editing the spec file; see Spec File Options for a macOS Bundle below.
Platform-specific Notes¶
GNU/Linux¶
Making GNU/Linux Apps Forward-Compatible¶
For this reason, if you bundle your app on the current version of GNU/Linux, it may fail to execute (typically with a runtime dynamic link error) if it is executed on an older version of GNU/Linux.
The solution is to always build your app on the oldest version of GNU/Linux you mean to support. It should continue to work with the libc found on newer versions.
The GNU/Linux standard libraries such as glibc are distributed in 64-bit and 32-bit versions, and these are not compatible. As a result you cannot bundle your app on a 32-bit system and run it on a 64-bit installation, nor vice-versa. You must make a unique version of the app for each word-length supported.
Note that PyInstaller does bundle other shared libraries that are discovered via dependency analysis, such as libstdc++.so.6, libfontconfig.so.1, libfreetype.so.6. These libraries may be required on systems where older (and thus incompatible) versions of these libraries are available. On the other hand, the bundled libraries may cause issues when trying to load a system-provided shared library that is linked against a newer version of the system-provided library.
For example, system-installed mesa DRI drivers (e.g., radeonsi_dri.so) depend on the system-provided version of libstdc++.so.6. If the frozen application bundles an older version of libstdc++.so.6 (as collected from the build system), this will likely cause missing symbol errors and prevent the DRI drivers from loading. In this case, the bundled libstdc++.so.6 should be removed. However, this may not work on a different distribution that provides libstdc++.so.6 older than the one from the build system; in that case, the bundled version should be kept, because the system-provided version may lack the symbols required by other collected binaries that depend on libstdc++.so.6.
Windows¶
Build on Windows 7 which has been reported to work.
Include one of the VCRedist packages (the redistributable package files) into your application’s installer. This is Microsoft’s recommended way, see “Distributing Software that uses the Universal CRT“ in the above-mentioned link, numbers 2 and 3.
If you think, PyInstaller should do this by itself, please help improving PyInstaller.
macOS¶
Making macOS apps Forward-Compatible¶
On macOS, system components from one version of the OS are usually compatible with later versions, but they may not work with earlier versions. While PyInstaller does not collect system components of the OS, the collected 3rd party binaries (e.g., python extension modules) are built against specific version of the OS libraries, and may or may not support older OS versions.
As such, the only way to ensure that your frozen application supports an older version of the OS is to freeze it on the oldest version of the OS that you wish to support. This applies especially when building with Homebrew python, as its binaries usually explicitly target the running OS.
For example, to ensure compatibility with “Mojave” (10.14) and later versions, you should set up a full environment (i.e., install python, PyInstaller, your application’s code, and all its dependencies) in a copy of macOS 10.14, using a virtual machine if necessary. Then use PyInstaller to freeze your application in that environment; the generated frozen application should be compatible with that and later versions of macOS.
Building 32-bit Apps in macOS¶
This section is largely obsolete, as support for 32-bit application was removed in macOS 10.15 Catalina (for 64-bit multi-arch support on modern versions of macOS, see here ). However, PyInstaller still supports building 32-bit bootloader, and 32-bit/64-bit Python installers are still available from python.org for (some) versions of Python 3.7.
Older versions of macOS supported both 32-bit and 64-bit executables. PyInstaller builds an app using the the word-length of the Python used to execute it. That will typically be a 64-bit version of Python, resulting in a 64-bit executable. To create a 32-bit executable, run PyInstaller under a 32-bit Python.
To verify that the installed python version supports execution in either 64- or 32-bit mode, use the file command on the Python executable:
The OS chooses which architecture to run, and typically defaults to 64-bit. You can force the use of either architecture by name using the arch command:
Getting the Opened Document Names¶
When user double-clicks a document of a type that is registered with your application, or when a user drags a document and drops it on your application’s icon, macOS launches your application and provides the name(s) of the opened document(s) in the form of an OpenDocument AppleEvent.
When the answer is True (as above) Python was build as a 32-bit executable.
When working with a 32-bit Python executable proceed as follows:
When working with a 64-bit Python executable proceed as follows: