Pyinstaller build for windows on linux

I'm trying to generate an executable from Linux for Windows. pyinstaller --onefile --windowed montecarlo.py I run this command and get a single executable that works on Linux just fine, I can o...

Well, let me just copy and paste what wikipedia says:

Binary compatible operating systems are OSes that aim to implement binary compatibility with another OS, or another variant of the same brand. This means that they are ABI-compatible (for application binary interface). As the job of an OS is to run programs, the instruction set architectures running the OSes have to be the same or compatible. Otherwise, programs can be employed within a CPU emulator or a faster dynamic translation mechanism to make them compatible.

For example, the Linux kernel is not compatible with Windows. This does not mean that Linux can’t be binary compatible with Windows applications. Additional software, Wine, is available that does that to some degree. The ReactOS OS development effort, seeks to create an open source, free software OS that is binary compatible with Microsoft’s Windows NT family of OSes using Wine for application compatibility and reimplementing the Windows kernel for additional compatibility such as for drivers whereas Linux would use Linux drivers not Windows drivers. FreeBSD and other members of the BSD family have binary compatibility with the Linux kernel in usermode by translating Linux system calls into BSD ones. This enables the application and libraries code that run on Linux-based OSes to be run on BSD as well.

Note that a binary compatible OS is different from running an alternative OS through virtualization or emulation, which is done to run software within the alternative OS in the case when the host OS isn’t compatible. Sometimes virtualization is provided with the host OS (or such software can be obtained), which effectively makes the host OS compatible with programs. For example, Windows XP Mode for Windows 7 allows users to run a 64-bit version of Windows 7 and enable old software to still work in a 32-bit virtual machine running Windows XP; VMware Workstation/VMware Fusion, Parallels Workstation, and Windows Virtual PC allow other OSes to be run on Windows, Linux, and OS X.

For another example, Mac OS X on the PowerPC had the ability to run Mac OS 9 and earlier application software through Classic—but this did not make OS X a binary compatible OS with Mac OS 9. Instead, the Classic environment was actually running Mac OS 9.1 in a virtual machine, running as a normal process inside of OS X.[1][2]

Рано или поздно перед Python программистом встает проблема распространения своего ПО на компьютерах без установленного интерпретатора Python. Наиболее рациональным способом при этом кажется упаковка кода в автономный бинарный файл. Для этого существует целый сомн фреймворков.

По прочтении обсуждений в разных местах, пришел к выводу, что PyInstaller лучше всего подходит для данных целей из-за простоты в использовании, своей кросс-платформенности и потому, что собранный им exe-файл легче переносится с одной версии Windows на другую. А так же позволяет без особых танцев собирать бинарники для Windows из-под других операционных систем.

Подготовка

Нам понадобятся:

  • Python2 — К сожалению PyInstaller работает только для Python-2.x.x
  • Сам Pyinstaller

Pywin32 — дополнения Python для Windows. Опять же последняя стабильная версия (216)
Wine — ну без него тут никуда.

Я тестировал кросс-сборку на Ubuntu 11.04 с Python 2.7.1 и Wine 1.3.20.

Ставим все необходимое:

#Wine
sudo apt-get install wine1.3-dev
#Python
wget http://python.org/ftp/python/2.7.1/python-2.7.1.msi
wine msiexec /i python-2.7.1.msi

#Pyinstaller
wget http://www.pyinstaller.org/static/source/1.5/pyinstaller-1.5.tar.bz2
tar xvf pyinstaller-1.5.tar.bz2

#Pywin32
wget http://downloads.sourceforge.net/project/pywin32/pywin32/Build216/pywin32-216.win32-py2.7.exe?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fpywin32%2Ffiles%2Fpywin32%2FBuild216%2F&ts=1305544745&use_mirror=citylan -o pywin32.exe
wine pywin32.exe

Настройка и запуск

Теперь необходимо настроить Pyinstaller с помощью скрипта Configure.py. Конфигурацию надо производить каждый раз когда меняется конфигурация Python, поэтому имеет смысл держать отдельную версию Pyinstaller для каждой версии Python. Сконфигурируем Pyinstaller под Windows-версию интерпретатора:

cd pyinstaller-1.5
wine ~/.wine/drive_c/Python27.exe Configure.py

Теперь можно собирать exe-файл. Сначала создаем spec-файл, в котором содержаться настройки упаковки проекта. Для наглядности назовем упаковываемый файл test.py (в случае, когда в проекте не один файл, указываем путь к главному).

wine ~/.wine/drive_c/Python27.exe Makespec.py test.py

По умолчанию папка со spec-фалом будет создана в папке Pyinstaller и будет иметь имя упаковываемого файла без расширения (в нашем случае test).

К команде создания spec-файла можно добавить полезные ключи, например:

  • —onefile — по умолчанию PyInstaller создает exe-файл и кладет в папку рядом с ним необходимые dll. Этот ключ форсирует упаковку всего в единый бинарник.
  • —out=DIR — позволяет задать определенную папку для spec-файла
  • —windowed — под Windows отключает консоль приложения

И наконец финальный этап — построение:

wine ~/.wine/drive_c/Python27/python.exe Build.py test/test.spec

Упакованное приложение можно найти в папке dist/ внутри папки со spec-файлом.

За сим все. Тестовая программа заработала под Wine, а затем под Windows XP и Windows 7 без малейших писков.

PyPI
PyPI - Python Version
Read the Docs (version)
PyPI - Downloads

PyInstaller bundles a Python application and all its dependencies into a single
package. The user can run the packaged app without installing a Python
interpreter or any modules.

Documentation:

https://pyinstaller.org/

Code:

https://github.com/pyinstaller/pyinstaller

PyInstaller reads a Python script written by you. It analyzes your code
to discover every other module and library your script needs in order to
execute. Then it collects copies of all those files – including the active
Python interpreter! – and puts them with your script in a single folder, or
optionally in a single executable file.

PyInstaller is tested against Windows, macOS, and GNU/Linux.
However, it is not a cross-compiler:
to make a Windows app you run PyInstaller in Windows; to make
a GNU/Linux app you run it in GNU/Linux, etc.
PyInstaller has been used successfully
with AIX, Solaris, FreeBSD and OpenBSD,
but is not tested against them as part of the continuous integration tests.

Main Advantages

  • Works out-of-the-box with any Python version 3.7-3.11.

  • Fully multi-platform, and uses the OS support to load the dynamic libraries,
    thus ensuring full compatibility.

  • Correctly bundles the major Python packages such as numpy, PyQt5,
    PySide2, PyQt6, PySide6, wxPython, matplotlib and others out-of-the-box.

  • Compatible with many 3rd-party packages out-of-the-box. (All the required
    tricks to make external packages work are already integrated.)

  • Works with code signing on macOS.

  • Bundles MS Visual C++ DLLs on Windows.

Installation

PyInstaller is available on PyPI. You can install it through pip:

pip install pyinstaller

Requirements and Tested Platforms

  • Python:
    • 3.7-3.11. Note that Python 3.10.0 contains a bug making it unsupportable by
      PyInstaller. PyInstaller will also not work with beta releases of Python
      3.12.

  • Windows (32bit/64bit):
    • PyInstaller should work on Windows 7 or newer, but we only officially support Windows 8+.

    • Support for Python installed from the Windows store without using virtual
      environments requires PyInstaller 4.4 or later.

    • Note that Windows on arm64 is not yet supported. If you have such a
      device and want to help us add arm64 support then please let us know on
      our issue tracker.

  • Linux:
    • GNU libc based distributions on architectures x86_64, aarch64,
      i686, ppc64le, s390x.

    • musl libc based distributions on architectures x86_64, aarch64.

    • ldd: Console application to print the shared libraries required
      by each program or shared library. This typically can be found in
      the distribution-package glibc or libc-bin.

    • objdump: Console application to display information from
      object files. This typically can be found in the
      distribution-package binutils.

    • objcopy: Console application to copy and translate object files.
      This typically can be found in the distribution-package binutils,
      too.

    • Raspberry Pi users on armv5armv7 should add piwheels as an extra
      index url then pip install pyinstaller
      as usual.

  • macOS (x86_64 or arm64):
    • macOS 10.15 (Catalina) or newer.

    • Supports building universal2 applications provided that your installation
      of Python and all your dependencies are also compiled universal2.

Usage

Basic usage is very simple, just run it against your main script:

pyinstaller /path/to/yourscript.py

For more details, see the manual.

Untested Platforms

The following platforms have been contributed and any feedback or
enhancements on these are welcome.

  • FreeBSD
    • ldd

  • Solaris
    • ldd

    • objdump

  • AIX
    • AIX 6.1 or newer. PyInstaller will not work with statically
      linked Python libraries.

    • ldd

  • Linux on any other libc implementation/architecture combination not listed
    above.

Before using any contributed platform, you need to build the PyInstaller
bootloader. This will happen automatically when you pip install pyinstaller provided that you have an appropriate C compiler (typically
either gcc or clang) and zlib’s development headers already installed.

Support

  • Official debugging guide: https://pyinstaller.org/en/v5.7.0/when-things-go-wrong.html

  • Assorted user contributed help topics: https://github.com/pyinstaller/pyinstaller/wiki

  • Web based Q&A forums: https://github.com/pyinstaller/pyinstaller/discussions

  • Email based Q&A forums: https://groups.google.com/g/pyinstaller

Changes in this Release

You can find a detailed list of changes in this release
in the Changelog section of the manual.

Using Wine and Pyinstaller.

Pyinstaller is a program that packages Python programs into stand-alone executables, under the most used OSs (Windows, Linux, Mac OS X, FreeBSD, Solaris and AIX).
Initially Pyinstaller had a beta feature that allows the cross-compilation of a windows executable under Linux.
However, due the instability of the feature, it has been removed since version 1.5.

Fortunately, is still possible to package a Windows executable using PyInstaller under Wine.

1. Install wine and Python

$ sudo apt-get install wine
$ wget https://www.python.org/ftp/python/2.7.9/python-2.7.9.amd64.msi
$ wine msiexec /i python-2.7.9.amd64.msi /qb

If you need to compile a 32bit executable, you need to install wine32:

sudo dpkg --add-architecture i386 && sudo apt-get update && sudo apt-get install wine32

2. Install PyInstaller on wine

$ cd ~/.wine/drive_c/Python27
$ wine python.exe Scripts/pip.exe install pyinstaller

3. Package a python scripts

Package Python scripts (e.g., helloworld.py) with pyinstaller.

$ cat helloworld.py
#!/usr/bin/env python
print('Hello World!')

$ wine ~/.wine/drive_c/Python27/Scripts/pyinstaller.exe --onefile helloworld.py

The Windows executable file is located in dist/.

$ wine dist/helloworld.exe
Hello World!

Finally, transfer the executable on a windows box and test it:


References

  • http://www.pyinstaller.org/
  • https://www.winehq.org/

I’m trying to generate an executable from Linux for Windows using pyinstaller.

pyinstaller --onefile --windowed montecarlo.py

I run this command and get a single executable that works on Linux just fine, but if I try on Windows, it’s just a simple file. Why?

asked May 17, 2017 at 2:13

Drakota's user avatar

2

I was trying to do this same thing today and ran across this answer. It pointed to the FAQ, which says cross-compiling is not supported. It recommends using Wine.

answered Jul 12, 2017 at 18:28

Jack's user avatar

JackJack

2,7212 gold badges23 silver badges32 bronze badges

1

www.makeworld.space

Oct 4th, 2021
by makeworld

Packaging a Python project into a standalone executable is often a struggle. Thankfully we
have tools like PyInstaller to make this easier. Recently
I ran into another struggle of my own, which was that it seemed impossible to “cross-compile”
with PyInstaller. That is to say, run PyInstaller on one OS, and have it generate an executable
for another. It was hinted at that Linux → Windows was possible using Wine, but I couldn’t find any guides on it.

Eventually, I got it working, so here is that guide. Hope this helps! This guide might also work
on macOS, but I have not tested it.


Thanks to Noah Broyles for the script that helped me figure this all out.


First off, I was only able to use Python 3.8. I tried with 3.9, but I was not able to install it
under WINE. If you are able to, feel free to use that, and change references to 38 in this post
to 39. I was also using PyInstaller 4.5.1, but other versions should work fine.

The first step is to install WINE for your Linux system. WINE is a compatibility layer that allows
the running of Windows software on non-Windows systems. You can install WINE easily enough from
your distro’s package manager. I am using wine-6.16, but most likely your distro’s version will
work fine.

Next, download the Python 3.8 Windows installer. You can download that directly from the official
Python Software Foundation here. With
it downloaded, you can run wine python-3.8.9.exe to begin the installation. WINE may prompt you
to install something like .NET or Mono, you should click Yes and let it install.

You should not use the default installation, follow these steps:

  1. Check “Add Python 3.8 to PATH”
  2. Click “Customize installation
  3. Click “Next”
  4. Click “Install for all users”
  5. Set the install location as C:\Python38
  6. Click “Install”
  7. Close the window.

Using the C:\Python38 path helps keep things standard for this blog post.

Now Python 3.8 should be successfully installed in WINE. You can check this by running
wine C:/Python38/python.exe --version, which will run Windows Python through WINE. Amazing!

Next we’ll need to upgrade pip, to make sure things will install fine. Run
wine C:/Python38/python.exe -m pip install --upgrade pip. WINE might spit out a lot of warnings
about libgnutls or something or other, but as long as Pip doesn’t report any errors it’s fine.

Now if your project has any dependencies, you should export them into the standard Python
requirements.txt file. You can then install them into your WINE Python with this command:

wine C:/Python38/python.exe -m pip install -r requirements.txt

If you’re using a superior dependency
manager like Poetry, you should be able to install and use that in WINE,
although I haven’t tested that.

In any case, you’ll need PyInstaller to be installed, so run this command if PyInstaller wasn’t in
requirements.txt already:

wine C:/Python38/python.exe -m pip install pyinstaller

Now you can run PyInstaller and an EXE will be built! Just run

wine C:/Python38/Scripts/pyinstaller.exe ...

and replace ... with whatever arguments you used
to build a Linux executable.

Enjoy!

I created a game using pygame, and I wish to export it to a .exe file. I’ve used pyinstaller for this, as it is available for Ubuntu. When I run the --onefile game, it works perfectly fine (on my ubuntu computer). However, when I send it to my friend who has windows, it is NOT a Windows executable, but simply a «file» without any extension. He cannot run it. Renaming it Game.exe has not worked either.

I’m out of ideas… can anyone help?

David Foerster's user avatar

asked Feb 26, 2016 at 23:24

ruyili's user avatar

6

Obviously the binary executable generated by PyInstaller on Linux only runs on Linux and not on other operating systems like Windows. The file name extension is irrelevant here.

According to the PyInstall FAQ you cannot use it to cross-compile for different platforms either, but running PyInstall inside Wine is supposed to achieve what you want:

  1. Can I use PyInstaller as a cross-compiler?
    1. Can I package Windows binaries while running under Linux?

      No, this is not supported. Please use Wine for this, PyInstaller runs fine in Wine. You may also want to have a look at this thread in the mailinglist. In version 1.4 we had build in some support for this, but it showed to work only half. It would require some Windows system on another partition and would only work for pure Python programs. As soon as you want a decent GUI (gtk, qt, wx), you would need to install Windows libraries anyhow. So it’s much easier to just use Wine.

From what I understand, you’ll need to install PyInstall inside a Wine environment like you would in Windows and then use it like you would on a native Windows system.
Please refer to How can I install Windows software or games? for an overview of how to get started with Wine on Ubuntu.

answered Feb 28, 2016 at 9:49

David Foerster's user avatar

David FoersterDavid Foerster

35.3k54 gold badges90 silver badges143 bronze badges

1

You can try Python Packager

The git homepage gives the instruction (python 2.7):

wget "http://www.python.org/ftp/python/2.7.3/python-2.7.3.msi" 
wget "http://nchc.dl.sourceforge.net/project/pywin32/pywin32/Build%20218/pywin32-218.win32-py2.7.exe"
build_environment/create.sh
export WINEPREFIX=/tmp/path-outputted-from-create
wine start python-2.7.3.msi
wine pywin32-218.win32-py2.7.exe
build_environment/freeze.sh
./package sample-application/src/main.py MySampleProgram

This will build a separate wine environment and installs Python 2.7 as mentioned. In case you need another version, got to the python homepage and download your version.

You can also follow this instruction which downloads a wine-clone:

git clone https://github.com/paulfurley/python-windows-packager
./python-windows-packager/package.sh /path/to/myProject

answered Jul 9, 2018 at 13:45

abu_bua's user avatar

abu_buaabu_bua

10.1k10 gold badges41 silver badges60 bronze badges

1

My main development platform is Ubuntu. The cross-compilation feature is removed from PyInstaller since 1.5. In this article, I’ll show you how to package a Windows executable from Python scripts using PyInstaller under wine.

Table of Contents

  • 1. Build a Windows excutable on Ubuntu
    • Step 1: Install wine and Python
    • Step 2: Install PyInstaller on wine
    • Step 3: Package Python scripts
  • 2. Troubleshooting
    • 2.1 ImportError: No module named

1. Build a Windows excutable on Ubuntu

Step 1: Install wine and Python

sudo apt-get install wine winetricks
winetricks python 

# Python installation directory 
$ cd ~/.wine/drive_c/Python26

Note that python26 is installed, not including pip (is used to install pyinstaller). Fortunately, newer Python versions already include pip. Choose the proper version from Download Python (for me, python-2.7.10.msi) and install it on wine by:

$ wine msiexec /i python-2.7.10.msi /L*v log.txt

Step 2: Install PyInstaller on wine

$ cd ~/.wine/drive_c/Python27
$ wine python.exe Scripts/pip.exe install pyinstaller

Successfully installed pyinstaller-3.1.1 pypiwin32-219

Step 3: Package Python scripts

Package Python scripts (e.g., HelloWorld.py) with pyinstaller.

# run `pyinstaller` under the same directory as Python scripts
$ wine ~/.wine/drive_c/Python27/Scripts/pyinstaller.exe --onefile HelloWorld.py

# filename: HelloWorld.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

print('Hello World!')

The Windows executable file is located in dist/.

$ wine dist/HelloWorld.exe 
Hello World!
fixme:msvcrt:__clean_type_info_names_internal (0x1e24e5b8) stub

2. Troubleshooting

2.1 ImportError: No module named

I package a Python script imported openpyxl, but encounter the issue ImportError: No module named openpyxl while running the Windows exculable.

$ cd ~/.wine/drive_c/Python27/Scripts/dist
$ wine ProcessSpreadsheet.exe 
Traceback (most recent call last):
  File "<string>", line 4, in <module>
ImportError: No module named openpyxl
ProcessSpreadsheet returned -1
fixme:msvcrt:__clean_type_info_names_internal (0x1e24e5b8) stub

To tackle this issue, append the openpyxl path (~/.wine/drive_c/Python27/Lib/site-packages) to pathex in the Analysis object in the application spec file (ProcessSpreadsheet.spec).

# Step 1: install the python module, openpyxl
$ wine python.exe Scripts/pip.exe install openpyxl

# Step 2: add the `openpyxl` path 
a = Analysis(['ProcessSpreadsheet.py'],
             pathex=['C:\Python27\Scripts', '~/.wine/drive_c/Python27/Lib/site-packages'],
             binaries=None,
             datas=None,
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)

# Step 3: rebuild
$ wine pyinstaller.exe ProcessSpreadsheet.spec

References:
[1]AskUbuntu: Install Python in Wine
[2]StackOverflow: pyInstaller: Import Error
[3]StackOverflow: Cross-compiling a Python script on Linux into a Windows executable

赞赏

微信赞赏支付宝赞赏

Table of contents:

  • Install the PyInstaller
  • Experiment: creating the installation
  • What will PyInstaller do?
  • When PyInstaller output is not a single file
  • Command line arguments
    • Basic switches:
    • Output to generate:

Thanks to PyInstaller it is now easy to create the installation for a Python based project you distribute to: Linux, Windows or MacOS. In here I will examine the PyInstaller on Linux.

When on Linux, you cannot create the final executable for Windows or MacOS, that would be the PyInstaller limitation.

This is why for each OS (Operating System) you should build separate distributable executable.

In other words, PyInstaller doesn’t have the platform switch, like Python Kivy or C# Unity tools that are cross platform.

Install the PyInstaller

First step would be to download PyInstaller from PyPi, but it is even easier to install it using pip:

If you are not sure you have the latest PyInstaller version already you can try to install and upgrade:

pip install --upgrade pyinstaller

From now on, you can call pyinstaller from the command line.

Experiment: creating the installation

Let’s make our fingers dirty with some code. Let’s create a program you can distribute to any Linux platform even if Python is not installed. In other words we will create the Linux standalone executable as the output of this experiment.

First we create a folder called /content to hold our experiment. In there we create a file called getdatetime.py:

# save as getdatetime.py
import datetime
now = datetime.datetime.now()
print ("Current date and time : ")
print (now.strftime("%Y-%m-%d %H:%M:%S"))

Check here how to work with Python date and time in detail.

Assuming we installed the PyInstaller already, we are now ready to create the one-file standalone executable.

pyinstaller --onefile getdatetime.py

If we list the /content folder, we will get the following output. Wow!

list of files

If we now execute the file command to check the file type for the getdatetime:

file /content/dist/getdatetime

We get the output this is ELF Linux executable:

/content/dist/getdatetime: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=294d1f19a085a730da19a6c55788ec08c2187039, stripped

To run the executable we simple type from the command line:

/content/dist/getdatetime

Output:

Date and time is: 
2020-02-22 11:35:15

This is how simple it is; to create independent executable you may run on any Linux, with or without Python installed.

What will PyInstaller do?

We had originally just a single detdatetime.py file, and after the PyInstaller command we have several files and folders more:

build/ 
dist/
getdatetime.py
getdatetime.spec
__pycache__/

build/ folder is where PyInstaller prepares the distribution executable and stores that to dist/ folder. The getdatetime.spec is a specification file that PyInstaller creates the first time you run it.

You can edit the getdatetime.spec file and name your output executable other way.

When PyInstaller output is not a single file

There is another way. You can run PyInstaller with this command:

pyinstaller --onedir getdatetime.py

This time we use --onedir switch. Inside the dist folder we now have different output. Recall that with the --onefile option we had just a single file output.

list of files

There are many .so files inside our dist folder. Files with .so extension are Shared Objects files. In Windows these would be .dlls. Under Linux you can get some feedback on .so files using ldd command.

To run the final executable and to get the output we should call from the command line:

/content/dist/getdatetime/getdatetime

Output:

Date and time is: 
2020-02-22 12:02:15

Command line arguments

Basic switches:

 
-h, –help show this help message and exit  
-v, –version Show program version info and exit.  
–distpath DIR Where to put the bundled app (default: ./dist)  
–workpath WORKPATH Where to put all the temporary work files, .log, .pyz and etc. (default: ./build)  
-y, –noconfirm Replace output directory –upx-dir UPX_DIR Path to UPX utility (default: search the execution path)
-a, –ascii Do not include unicode encoding support (default: included if available)  
–clean Clean PyInstaller cache and remove temporary files before building.  
–log-level LEVEL Amount of detail in build-time console messages. LEVEL may be one of TRACE, DEBUG, INFO, WARN, ERROR, CRITICAL (default: INFO).  

Output to generate:

-D, –onedir Create a one-folder bundle containing an executable (default)
-F, –onefile Create a one-file bundled executable.
–specpath DIR Folder to store the generated spec file (default: current directory)
-n NAME, –name NAME Name to assign to the bundled app and spec file (default: first script’s basename)

tags: installinstallerlinux
&
category: python

Понравилась статья? Поделить с друзьями:
  • Pygame скачать для windows 10 64 bit
  • Pyconfig h no such file or directory windows
  • Pycharm скачать бесплатно для windows 10 64 bit
  • Pycharm скачать 32 bit windows 7 2017
  • Pycharm не запускается на windows 10