compile python script in linux - python

So I have a python script that relies on a couple modules. Specifically pexpect and pyinoitify. I know you can compile a python script into a .exe in windows, but is there something relatively equivalent in linux? I don't care about it being a binary, I'd just like to be able to distribute my script without requiring the separate installation of pexpect and pyinotify. Is that possible/worthwhile?

cx_Freeze is a cross-platform way to "freeze" a Python script into standalone binary form. According to their site:
cx_Freeze is a set of scripts and
modules for freezing Python scripts
into executables in much the same way
that py2exe and py2app do. Unlike
these two tools, cx_Freeze is cross
platform and should work on any
platform that Python itself works on.
It requires Python 2.3 or higher since
it makes use of the zip import
facility which was introduced in that
version.

Generally, if the first line is
#!/usr/bin/env python
And the file has "x" mode set (chmod +x yourfile.py)
Then it's executable. No compiling required.
And yes, folks have to install the things on which you depend. It's (a) simpler and (b) less surprising if they actually do the installation, so they know what's really going on.

In linux, try to avoid such things. Most package managers handle dependencies quite fine, just distribute your script and tell what dependencies it needs.

Related

Run python .exe on any computer [duplicate]

This question already has answers here:
Create a single executable from a Python project [closed]
(3 answers)
Closed 1 year ago.
I'm building a Python application and don't want to force my clients to install Python and modules.
So, is there a way to compile a Python script to be a standalone executable?
You can use PyInstaller to package Python programs as standalone executables. It works on Windows, Linux, and Mac.
PyInstaller Quickstart
Install PyInstaller from PyPI:
pip install pyinstaller
Go to your program’s directory and run:
pyinstaller yourprogram.py
This will generate the bundle in a subdirectory called dist.
pyinstaller -F yourprogram.py
Adding -F (or --onefile) parameter will pack everything into single "exe".
pyinstaller -F --paths=<your_path>\Lib\site-packages yourprogram.py
running into "ImportError" you might consider side-packages.
pip install pynput==1.6.8
still runing in Import-Erorr - try to downgrade pyinstaller - see Getting error when using pynput with pyinstaller
For a more detailed walkthrough, see the manual.
You can use py2exe as already answered and use Cython to convert your key .py files in .pyc, C compiled files, like .dll in Windows and .so on Linux.
It is much harder to revert than common .pyo and .pyc files (and also gain in performance!).
You might wish to investigate Nuitka. It takes Python source code and converts it in to C++ API calls. Then it compiles into an executable binary (ELF on Linux). It has been around for a few years now and supports a wide range of Python versions.
You will probably also get a performance improvement if you use it. It is recommended.
Yes, it is possible to compile Python scripts into standalone executables.
PyInstaller can be used to convert Python programs into stand-alone executables, under Windows, Linux, Mac OS X, FreeBSD, Solaris, and AIX. It is one of the recommended converters.
py2exe converts Python scripts into only executable on the Windows platform.
Cython is a static compiler for both the Python programming language and the extended Cython programming language.
I would like to compile some useful information about creating standalone files on Windows using Python 2.7.
I have used py2exe and it works, but I had some problems.
It has shown some problems for creating single files in Windows 64 bits: Using bundle_files = 1 with py2exe is not working;
It is necessary to create a setup.py file for it to work. http://www.py2exe.org/index.cgi/Tutorial#Step2;
I have had problems with dependencies that you have to solve by importing packages in the setup file;
I was not able to make it work together with PyQt.
This last reason made me try PyInstaller http://www.pyinstaller.org/.
In my opinion, it is much better because:
It is easier to use.
I suggest creating a .bat file with the following lines for example (pyinstaller.exe must be in in the Windows path):
pyinstaller.exe --onefile MyCode.py
You can create a single file, among other options (https://pyinstaller.readthedocs.io/en/stable/usage.html#options).
I had only one problem using PyInstaller and multiprocessing package that was solved by using this recipe: https://github.com/pyinstaller/pyinstaller/wiki/Recipe-Multiprocessing.
So, I think that, at least for python 2.7, a better and simpler option is PyInstaller.
And a third option is cx_Freeze, which is cross-platform.
pyinstaller yourfile.py -F --onefile
This creates a standalone EXE file on Windows.
Important note 1: The EXE file will be generated in a folder named 'dist'.
Important note 2: Do not forget --onefile flag
You can install PyInstaller using pip install PyInstaller
NOTE: In rare cases there are hidden dependencies...so if you run the EXE file and get missing library error (win32timezone in the example below) then use something like this:
pyinstaller --hiddenimport win32timezone -F "Backup Program.py"
I like PyInstaller - especially the "windowed" variant:
pyinstaller --onefile --windowed myscript.py
It will create one single *.exe file in a distination/folder.
You may like py2exe. You'll also find information in there for doing it on Linux.
Use py2exe.... use the below set up files:
from distutils.core import setup
import py2exe
from distutils.filelist import findall
import matplotlib
setup(
console = ['PlotMemInfo.py'],
options = {
'py2exe': {
'packages': ['matplotlib'],
'dll_excludes': ['libgdk-win32-2.0-0.dll',
'libgobject-2.0-0.dll',
'libgdk_pixbuf-2.0-0.dll']
}
},
data_files = matplotlib.get_py2exe_datafiles()
)
I also recommend PyInstaller for better backward compatibility such as Python 2.3 - 2.7.
For py2exe, you have to have Python 2.6.
For Python 3.2 scripts, the only choice is cx_Freeze. Build it from sources; otherwise it won't work.
For Python 2.x I suggest PyInstaller as it can package a Python program in a single executable, unlike cx_Freeze which outputs also libraries.
Since it seems to be missing from the current list of answers, I think it is worth mentioning that the standard library includes a zipapp module that can be used for this purpose. Its basic usage is just compressing a bunch of Python files into a zip file with extension .pyz than can be directly executed as python myapp.pyz, but you can also make a self-contained package from a requirements.txt file:
$ python -m pip install -r requirements.txt --target myapp
$ python -m zipapp -p "interpreter" myapp
Where interpreter can be something like /usr/bin/env python (see Specifying the Interpreter).
Usually, the generated .pyz / .pyzw file should be executable, in Unix because it gets marked as such and in Windows because Python installation usually registers those extensions. However, it is relatively easy to make a Windows executable that should work as long as the user has python3.dll in the path.
If you don't want to require the end user to install Python, you can distribute the application along with the embeddable Python package.
py2exe will make the EXE file you want, but you need to have the same version of MSVCR90.dll on the machine you're going to use your new EXE file.
See Tutorial for more information.
You can find the list of distribution utilities listed at Distribution Utilities.
I use bbfreeze and it has been working very well (yet to have Python 3 support though).
Not exactly a packaging of the Python code, but there is now also Grumpy from Google, which transpiles the code to Go.
It doesn't support the Python C API, so it may not work for all projects.
Using PyInstaller, I found a better method using shortcut to the .exe rather than making --onefile. Anyway, there are probably some data files around and if you're running a site-based app then your program depends on HTML, JavaScript, and CSS files too. There isn't any point in moving all these files somewhere... Instead what if we move the working path up?
Make a shortcut to the EXE file, move it at top and set the target and start-in paths as specified, to have relative paths going to dist\folder:
Target: %windir%\system32\cmd.exe /c start dist\web_wrapper\web_wrapper.exe
Start in: "%windir%\system32\cmd.exe /c start dist\web_wrapper\"
We can rename the shortcut to anything, so renaming to "GTFS-Manager".
Now when I double-click the shortcut, it's as if I python-ran the file! I found this approach better than the --onefile one as:
In onefile's case, there's a problem with a .dll missing for the Windows 7 OS which needs some prior installation, etc. Yawn. With the usual build with multiple files, no such issues.
All the files that my Python script uses (it's deploying a tornado web server and needs a whole freakin' website worth of files to be there!) don't need to be moved anywhere: I simply create the shortcut at top.
I can actually use this exact same folder on Ubuntu (run python3 myfile.py) and Windows (double-click the shortcut).
I don't need to bother with the overly complicated hacking of .spec file to include data files, etc.
Oh, remember to delete off the build folder after building. It will save on size.
Use Cython to convert to C, compile, and link with GCC.
Another could be, make the core functions in C (the ones you want to make hard to reverse), compile them and use Boost.Python to import the compiled code (plus you get a much faster code execution). Then use any tool mentioned to distribute.
I'm told that PyRun is also an option. It currently supports Linux, FreeBSD and Mac OS X.

Using pyinstaller on c compiled python code

I am trying to convert one single c file into an executable with pyinstaller. Now the reason why I want to compile with pyinstaller is because of the fact, that the exe file is supposed to be run on both a mac as well as a windows machine.
Now, how can this be done?
You can include Cython/C modules in a Pyinstaller executable.
However, Pyinstaller is not suitable for your goal of making a single executable that works on Mac and Windows. From the first question of the Pyinstaller FAQs:
Can I use PyInstaller as a cross-compiler?
Can I package Windows binaries while running under OS X?
No, this is not supported. [...]
It seems like you've fundamentally misunderstood what Pyinstaller does: it packages a Python script with Python and its libraries to allow you to use the Python script without having to install Python separately. To do this though it needs to package a version of Python specific to the platform, and so the executable will only work on the same operating system that it was created on.
In addition, it deals with compiled libraries (like Cython modules) by zipping them up and the extracting them into a temporary folder when run. Therefore, even if Pyinstaller somehow managed to bundle two versions of Python to work on both Windows and Mac your C compiled module would still only be compiled for a single platform, so by doing it they way you describe you've actually made your code less portable.
I don't believe there are any obvious tools to do what you're asking.

How to include python with script package? [duplicate]

I need to package my Python application, its dependencies, and Python itself into a single MSI installer for distribution to users. The end result should desirably be:
Python is installed in the standard location
the package and its dependencies are installed in a separate directory (possibly site-packages)
the installation directory should contain the Python uncompressed and a standalone executable is not required
Kind of a dup of this question about how to make a python into an executable.
It boils down to:
py2exe on windows, Freeze on Linux, and
py2app on Mac.
I use PyInstaller (the svn version) to create a stand-alone version of my program that includes Python and all the dependencies. It takes a little fiddling to get it to work right and include everything (as does py2exe and other similar programs, see this question), but then it works very well.
You then need to create an installer. NSIS Works great for that and is free, but it creates .exe files not .msi. If .msi is not necessary, I highly recommend it. Otherwise check out the answers to this question for other options.
My company uses the free InnoSetup tool. It is a moderately complex program that has tons of flexibility for building installers for windows. I believe that it creates .exe and not .msi files, however. InnoSetup is not python specific but we have created an installer for one of our products that installs python along with dependencies to locations specified by the user at install time.
I've had much better results with dependencies and custom folder structures using pyinstaller, and it lets you find and specify hidden imports and hooks for larger dependencies like numpy and scipy. Also a PITA, though.
py2exe will make windows executables with python bundled in.
py2exe is the best way to do this. It's a bit of a PITA to use, but the end result works very well.
Ok, I have used py2exe before and it works perfectly except for one thing... It only works on executable windows machines. I then learned about Jython which turn a python script into a .Jar file. Which as you know is executable from any machine that has Java ("To your latest running version") installed. Which is great because both unix, windows, and ios (Most of the time) Run java. That means its executable from all of the following machines. As long as they run Java. No need for "py2mac + py2exe + freeze" just to run on all operating systems. Just Jython
For more information on how it works and how you can use it click here.
http://www.jython.org/

Port a multi-version python application to Windows

I have written a program in Python 3 that relies on another program in Python 2.7 for some core tasks. It works seamlessly on gnunux since most distribution have already 2.7 installed, I just have to require Python 3, and it's all good.
But now I want to port the bundle to Windows, and I don't know how to manage this. I have the following issues
Most Windows don't have Python installed, never mention both 2.7 and 3 series.
The scripts invoke various utilities (executables, Python 2.7 & 3 scripts) with subprocess.call(... shell=True) and relies on Python scripts' shebangs to use the right version. As far as I know, there is no way to emulate such behaviour on Windows.
I use dynamic imports to implement some kind of plugin behavior, it is perhaps not the best possible design, but it would be sweet if I had not to refactor this for now
I have the source code for everything I use, and everything is under libre licenses, so I don't have issues with compiling to PE or porting 2.7 scripts to 3, but it would be a tedious work. The only solution I have found so far is to port everything to Python 3. Can you think of another one?
The recent Python Launcher for Windows (see also PEP 397) could be used to simulate the shebang/version behaviour. However, if you want to do this, the different versions of python must be installed on the system of course (and the launcher as well, registered as the default application for .py files)
Tools like PyInstaller and py2exe can bundle dynamically imported modules, only not discover them all by itself: you'll have to specify them yourself. I think your problem with these tools will be that they do not make applications with different versions of Python at the same time.
So I guess you're left with either requiring installation of python 2.7 and python 3 on the target system, or making separate exe's for your 2.7 and 3 scripts, and changing your subprocess calls to call these instead. (you could bundle the python installations with your own instead of using standard system-wide python installs, but you'd still have to
change your subprocess calls instead of relying on windows default application for file extensions)
How about using PyInstaller? Never used it myself but:
PyInstaller is a program that converts (packages) Python programs into stand-alone executables, under Windows, Linux, and Mac OS X.
http://www.pyinstaller.org/
So you could convert both your programs to executables and then call one from inside the other.

Install Python 2.6 without using installer on Win32

I need to run a Python script on a machine that doesn't have Python installed. I use Python as a part of a software package, and Python runs behind the curtain without the user's notice of it.
What I did was as follows.
Copy python.exe, python26.dll, msvcr90.dll and Microsoft.VC90.CRT.manifest
Zip all the directory in LIBs directory as the python26.zip
Copy all the necessary dll/pyd files inside the DLL directory.
It seems to work, but when I change the python26.zip to the other name such as pythonlib.zip, it cannot find the Python library any more.
Question 1: What's the magic behind the python26.zip name? Python automatically finds a library inside a python26.zip, but not with different name?
Question 2: If I have python26.zip at the same directory where python.exe/python26.dll is, I don't need to add path sys.path.append (THE PATH TO python26.zip). Is it correct?
Python has built-in libraries, and sys is one of them. I thought that I could use sys.path to point to whatever Python library in the ZIP file I needed. But, surprisingly, if I use the library name as Python26.zip, it just worked. Why is this so?
I have been using PortablePython for a year now, and I find it great as it is working on my locked-down work-notebook.
There is a Python 2.5.4, 2.6.1 and a 3.0.1 version.
From Sylvain Pointeau's blog:
The procedure is actually very simple, just download the msi installer from
http://www.python.org/getit/ and type the command:
C:\development\apps>msiexec /a python-3.3.2.msi /qb
TARGETDIR=C:\development\apps\python33
His example uses msiexec (aka MSI Administrative Installer for you UniExtract people) to force an extract to TARGETDIR. You'll notice that there is an internal installer which you delete.
EDIT: Also you can make it silent as well, but doing this every time you want to use python seems dumb. Just extract to a tempdir and then cleanup when they uninstall it.
PS: I didn't see how old this was! :D
I looked into the Python interpreter source code, and I did some experiments. And I found that the Python interpreter prepend the "THE DIRECTORY OF PYTHONXXX.DLL + pythonXXX.zip" no matter what. XXX is the version of the Python interpreter.
As a result, if there is a python26.zip in the same directory as the python26.dll. I could use all of the Python library automatically.
Another option is installing WinPython. It uses an installer, but it doesn't require admin rights (tested on Windows 7). Unlike Portable Python, it even has a Python 3.3.5 version.
py2exe will allow you to compile your Python script into a Windows executable. It may or may not work better than PortablePython, but perhaps it could be a little cleaner with regard to the number of files you need to distribute for your "behind the curtain" program.
Another option might be to consider PyInstaller which will create stand-alone Python applications cross-platform. From the home page:
PyInstaller is a program that converts (packages) Python programs into stand-alone executables, under Windows, Linux, and Mac OS X. [...] The main goal of PyInstaller is to be compatible with 3rd-party packages out-of-the-box. This means that, with PyInstaller, all the required tricks to make external packages work are already integrated within PyInstaller itself so that there is no user intervention required. You'll never be required to look for tricks in wikis and apply custom modification to your files or your setup scripts. As an example, libraries like PyQt and Matplotlib are fully supported, without having to handle plugins or external data files manually. Check our compatibility list of SupportedPackages.

Categories