compile python application with setup.py - python

I already pointed at the problem of exporting my pygame into an executable for distribution purpose. I still have the problem that when I run the setup.py (I use python version 3.7.0) and build the app, the app directly crashes and I cannot open the unix executable either.
Here is exactly what I did so far:
my setup.py:
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need
# fine tuning.
build_exe_options = {"include_files" : ["pic.png", "sound.wav"]} # there are more files, i.e. all pics and audio files used
import sys
base = 'Win32GUI' if sys.platform=='win32' else None
executables = [
Executable('pythonGame.py', base=base)
]
setup(name='MyGame',
version = '1.0',
description = 'blabla',
options = dict(build_exe = build_exe_options),
executables = executables)
when I run the setup.py to create stand-alone app via:
python setup.py bdist_mac
I get (many) error messages (cf. last 3 lines of terminal output):
> error: /Library/Developer/CommandLineTools/usr/bin/install_name_tool:
> input file:
> build/GesaGame-1.0.app/Contents/MacOS/lib/pygame/pygame_icon.icns is
> not a Mach-O file #loader_path/.dylibs/libSDL-1.2.0.dylib error: can't
> copy '#loader_path/.dylibs/libSDL-1.2.0.dylib': doesn't exist or not a
> regular file
or further above
> error: /Library/Developer/CommandLineTools/usr/bin/install_name_tool:
> input file: build/GesaGame-1.0.app/Contents/MacOS/RunningCleats.wav is
> not a Mach-O file
Nevertheless, the build folder has been created. When opening it I find the specified program, but it directly crashes after starting it.
What am I doing wrong here? I suspect it has something to do with the included files, but I am not able to make sense of it.

As I don't know the macos environment and don't have any system to test, I can only guess potential problems with your setup script.
cx_Freeze does not yet support Python 3.7, it has a bug. A bugfix exists but has not yet been released, however you can apply it manually, see What could be the reason for fatal python error:initfsencoding:unable to load the file system codec? and Cx_freeze crashing Python3.7.0. Or you can rollback to Python 3.6 if this is an option for you.
Dynamically imported packages as well as DLL resources (.dll/.so/.dylib) often do no get included automatically by cx_Freeze, you need to tell cx_Freeze to include them using the build_exe options packages and include_files. Or they get included into the wrong place (see next point).
cx_Freeze version 5.1.1 (the current version) freezes the packages into a lib subdirectory of the build directory, whereas the main script and all dependent files in the directory of the main script get frozen directly into the build directory. Thus, the relative path between any file in a package and the directory of the main script or executable changes in the frozen application (it gets an additional lib/). This means that if a package tries to find a file located in a package directory using a relative path from the directory of the main application or vice versa, this mechanism will fail in the frozen application. Go through the stack trace of the error message and for every file reported missing check whether this file is in the build directory and whether the frozen application looks for it at the right place. Make manual copies of the "missing" files into the build directory or into its lib subdirectory as necessary until it works. Once you have identified the correct place for the file, you can use a tuple (source, destination) as item in the include_files list to let cx_Freeze include a file from source to a specific destination into the build directory. See also the FAQ Using data files in the cx_Freeze documentation.
As a general advice, reduce your main script to a minimal application using only a minimal GUI and no further package and make it work on your system. Re-add then the packages and dependencies (icons, pictures, sounds, videos, ...) you need one by one and check that the unfrozen and frozen applications work at each step.

Related

build a .exe for Windows from a python 3 script

I would like building an executable for a python 3 script that:
imports pyqtgraph (with pyqt5)
imports theano and pymc3
also imports numpy, scipy, sys, os
opens a simple GUI made with qt designer and stored in a ‘.ui' file
will be distributed on machines with Windows 7+
I tried several tools (py2exe, pyinstaller, pynsist, cx_Freeze) during hours but failed each time. my 'less worse’ result was with pyinstaller (see below) without theano part (and so without a part of the script). Can anyone help me ?
I have 3 files: 2 '.py' files (1 with the main and the other with a bunch of definitions) and a '.ui' describing the GUI. The script makes some statistical analyses, then plots some curves.
Here is an example of my failure with python 3.5 and cx_Freeze (which I think is the most advanced try I had, but I’m not restricted to those tools in particular): I put my 3 files in a directory on a windows machine where everything was painfully installed (with anaconda). I add a file ’setup.py’, which for cx_Freeze is:
from cx_Freeze import setup, Executable
import os
os.environ['TCL_LIBRARY'] = r'C:\Program Files\Python 3.5\tcl\tcl8.6'
os.environ['TK_LIBRARY'] = r'C:\Program Files\Python 3.5\tcl\tk8.6'
os.environ['PYQTGRAPH_QT_LIB'] = 'PyQt5'
setup(
name = ‘concentrationprofiles',
version = '0.1',
description = 'simple tool to simulate concentration profiles. preliminary',
author = 'SPH',
options = dict(
build_exe = dict(
packages = ['os','sys','numpy','theano','pymc3','pyqtgraph'],#omitting ‘scipy’ ! for some reason when I put ’scipy’ in this list the building fails, but it works without… probably the ‘import scipy’ inside the code is properly interpreted
includes = ['numpy.core._methods','numpy.lib.format',
'pyqtgraph.debug','pyqtgraph.functions',
'pyqtgraph.ThreadsafeTimer','cp_util_jul17'],
include_files = ['GUI_cprofiles_jul17.ui']
)),
executables = [Executable(
script='cprofiles_jul17.py',
base='Win32GUI',
targetName=‘concentprofiles.exe'
)]
)
I then execute the command line ’python setup.py build’ in the anaconda prompt (equivalent to the command prompt to my knowledge) in the directory with the 4 files. After a lot of episodes and hours of fighting, the building looks fine (100s lines with no error message and going until the end), it creates a ‘build’ directory with a ‘exe.win-amd64-3.5’ subdirectory containing everything needed + the .exe. But when I try and run this .exe I get nothing: no error message, no console or window opening, no fast opening-closing and I can’t find a log… just nothing
I tried to change the ‘base’ option from ‘Win32GUI’ to base=’Console’ and base=None. In these cases I guess there is a fast console-opening-closing that I cannot read since I don’t find the log.
Here are few other bad results during other tries:
py2exe: turns out to be incompatible with my usual python 3.6, so I downgraded to 3.5. But even in 3.5, after a few lines it froze: once again no error message, no console or window opening, no fast opening-closing and I can’t find a log… just nothing. not even a ‘build’ directory. Another time I also tried an alternative with python 3.4 but I got an error concerning a missing ‘msvcr100.dll’ that I tried to install following instructions on forums. When I eventually got the permission to modify system directories, an instruction ‘regsvr32’ failed (isn’t this for 32 bits only ? but there is no ‘regsvr64’…). I eventually gave up
pyinstaller: see updates
pynsist: The principle of pynsist is that you don’t get an executable but an installer only. Why not ? I don’t need a .exe as long as I can distribute the code. Unfortunately, after building the installer (with no error) and installing it (again with no visible error), the program gives nothing, like in the cx_Freeze case.
I can add a link to the script files if you want/need.
update august, 18, 2017, 9:20am
Following the suggestion, I opened a new post concerning pyinstaller: build a .exe for Windows from a python 3 script importing theano with pyinstaller.
I invite you to answer the pyinstaller concerns there. This question will be marked as answered if my problem is solved with py2exe or cx_freeze.
update september, 2, 2pm:
I eventually managed to build a .exe with pyinstaller after many episodes.
Unfortunately I failed to deal with the ‘theano’ module (that is required in my case by the ‘pymc3’ module) and I had to modify the .py files and give up part of the application. Could anyone help me building a .exe for windows 7+, with the ‘theano’ module ?
To create an executable file of your Python program, run the following command in CMD.First you need to install pyinstaller, with the following command:
pip install pyinstaller
And then do the following to create one executable file of your Python program, first, Go to your program path, (with cd) where your Python (.py) file is, and then:
pyinstaller -w -F YourPyFile

Compiling a non-standard module into an executable file with PyInstaller

Background: I have had success in the past installing and using Pyinstaller to transform my python projects into one-file executables. I don't think it is an issue with my source code or pyinstaller files.
Problem: I used a free, open-source library/module called easygui imported into my source code to build an application. The application works perfectly run natively or through the Python IDE. I am pretty sure the problem is that Pyinstaller is not finding the EasyGUI module to import (it automatically includes and compiles any libraries you import in the script).
Actions: My python folder is not in the C:\ drive, it is in the E:\ drive. I'm able to access the pyinstaller path in "E:\program files\python" but it is not reading the easygui library, I don't think. I installed pyinstaller and easygui using pip.
Reading a LOT of pyinstaller's documentation i tried to run it to include a paths dir like:
E:\Program Files Hard Disk\Python\Scripts>pyinstaller --paths
DIR "E:\Program Files Hard Disk\Python" --onefile "E:\Program Files\Python"
It does output the single executable in the build file but does not launch correctly. From what I can see in the console window the brief moment it's up, it looks like an easygui issue. Here is the result of attempting to launch the executable from the command-line:
Here is the compiling in the command window:
Please help

Fatal Python error when trying to run an executable Python script

I have a Python script that I have turned into an executable using cx-freeze-4.3.4.win32-py3.4. I have Python 3.4 installed on a Windows 7 64-bit machine.
Here is my simple setup.py file:
from cx_Freeze import setup, Executable
setup( name = "myfilename" ,
version = "0.1" ,
description = "This is my file" ,
executables = [Executable("myfilename.py")] , )
I ran python setup.py build from command prompt in the C:\Python34 folder with both the script I was trying to convert and the setup.py file.
This created another folder called build within was another folder called exe.win32-3.4. In that folder I found my executable file, a bunch of .pyd files, a single .dll file, and a zipped archive called library of a bunch of .pyc files.
If I run the executable from within the exe.win32-3.4 with the library zip archive it executes fine. However, without the library archive of .pyc files (basically if I try just to run the .exe by itself, which is what I am supposed to be able to do) the executable throws out this error:
Fatal Python error: cannot get zipimpirter instance
Current thread 0x000001b48 (most recet call first):
I did some preliminary searching around the web for potential resolutions to the issue but could not find anything substantial. If anyone knows how to troubleshoot this issue that would be much appreciated.
From the docs:
Single-file executables
cx_Freeze does not support building a single file exe, where all of the libraries for your application are embedded in one executable file.
For a single-file solution using py2exe and others, see this question.
In 3.5 there is also the new zipapp module, although the basic functionality has been around for a while.

cx_freeze, mpl_toolkits/basemap/ how include the data folder in the build library.zip

I am struggling a lot trying to create a .exe for my Gui originaly coded with opensuse. I am trying to make the .exe for windows (under XP). cx_freeze seems to work better for my case. The build folder is created properly but when I try to run .exe I have the following error :
"proj data directory not found. Expecting it at C:\Python\build\exe.win32-2.7\library.zip\mpl_toolkits\basemap\data "
So do you know how I could do my setup.py in order to copy the folder mpl_toolkits\basemap\data to library.zip?
Here I posted my working solution for the same issue: https://stackoverflow.com/a/26519937/2741329
My fix requires 2 changes:
- Adding the files to include in the cx_freeze setup script
- Adding an OS environment variable in the user script
A similar issue with the same fix was also adressed here by simply adding in the setup file a list of tuple for include_files as [("C:\\Python31\\Lib\\site-packages\\PyQt4\\mpl-data", "mpl-data")]
This is not enough for Basemap since cx_freeze put by default its scripts into a zipped file.

How to build a single python file from multiple scripts?

I have a simple python script, which imports various other modules I've written (and so on). Due to my environment, my PYTHONPATH is quite long. I'm also using Python 2.4.
What I need to do is somehow package up my script and all the dependencies that aren't part of the standard python, so that I can email a single file to another system where I want to execute it. I know the target version of python is the same, but it's on linux where I'm on Windows. Otherwise I'd just use py2exe.
Ideally I'd like to send a .py file that somehow embeds all the required modules, but I'd settle for automatically building a zip I can just unzip, with the required modules all in a single directory.
I've had a look at various packaging solutions, but I can't seem to find a suitable way of doing this. Have I missed something?
[edit] I appear to be quite unclear in what I'm after. I'm basically looking for something like py2exe that will produce a single file (or 2 files) from a given python script, automatically including all the imported modules.
For example, if I have the following two files:
[\foo\module.py]
def example():
print "Hello"
[\bar\program.py]
import module
module.example()
And I run:
cd \bar
set PYTHONPATH=\foo
program.py
Then it will work. What I want is to be able to say:
magic program.py
and end up with a single file, or possibly a file and a zip, that I can then copy to linux and run. I don't want to be installing my modules on the target linux system.
I found this useful:
http://blog.ablepear.com/2012/10/bundling-python-files-into-stand-alone.html
In short, you can .zip your modules and include a __main__.py file inside, which will enable you to run it like so:
python3 app.zip
Since my app is small I made a link from my main script to __main__.py.
Addendum:
You can also make the zip self-executable on UNIX-like systems by adding a single line at the top of the file. This may be important for scripts using Python3.
echo '#!/usr/bin/env python3' | cat - app.zip > app
chmod a+x app
Which can now be executed without specifying python
./app
Use stickytape module
stickytape scripts/blah --add-python-path . > /tmp/blah-standalone
This will result with a functioning script, but not necessarily human-readable.
You can try converting the script into an executable file.
First, use:
pip install pyinstaller
After installation type ( Be sure you are in your file of interest directory):
pyinstaller --onefile --windowed filename.py
This will create an executable version of your script containing all the necessary modules. You can then transfer (copy and paste) this executable to the PC or machine you want to run your script.
I hope this helps.
You should create an egg file. This is an archive of python files.
See this question for guidance: How to create Python egg file
Update: Consider wheels in 2019
The only way to send a single .py is if the code from all of the various modules were moved into the single script and they your'd have to redo everything to reference the new locations.
A better way of doing it would be to move the modules in question into subdirectories under the same directory as your command. You can then make sure that the subdirectory containing the module has a __init__.py that imports the primary module file. At that point you can then reference things through it.
For example:
App Directory: /test
Module Directory: /test/hello
/test/hello/__init__.py contents:
import sayhello
/test/hello/sayhello.py contents:
def print_hello():
print 'hello!'
/test/test.py contents:
#!/usr/bin/python2.7
import hello
hello.sayhello.print_hello()
If you run /test/test.py you will see that it runs the print_hello function from the module directory under the existing directory, no changes to your PYTHONPATH required.
If you want to package your script with all its dependencies into a single file (it won't be a .py file) you should look into virtualenv. This is a tool that lets you build a sandbox environment to install Python packages into, and manages all the PATH, PYTHONPATH, and LD_LIBRARY_PATH issues to make sure that the sandbox is completely self-contained.
If you start with a virgin Python with no additional libraries installed, then easy_install your dependencies into the virtual environment, you will end up with a built project in the virtualenv that requires only Python to run.
The sandbox is a directory tree, not a single file, but for distribution you can tar/zip it. I have never tried distributing the env so there may be path dependencies, I'm not sure.
You may need to, instead, distribute a build script that builds out a virtual environment on the target machine. zc.buildout is a tool that helps automate that process, sort of like a "make install" that is tightly integrated with the Python package system and PyPI.
I've come up with a solution involving modulefinder, the compiler, and the zip function that works well. Unfortunately I can't paste a working program here as it's intermingled with other irrelevant code, but here are some snippets:
zipfile = ZipFile(os.path.join(dest_dir, zip_name), 'w', ZIP_DEFLATED)
sys.path.insert(0, '.')
finder = ModuleFinder()
finder.run_script(source_name)
for name, mod in finder.modules.iteritems():
filename = mod.__file__
if filename is None:
continue
if "python" in filename.lower():
continue
subprocess.call('"%s" -OO -m py_compile "%s"' % (python_exe, filename))
zipfile.write(filename, dest_path)
Have you taken into considerations Automatic script creation of distribute the official packaging solution.
What you do is create a setup.py for you program and provide entry points that will be turned into executables that you will be able run. This way you don't have to change your source layout while still having the possibility to easily distribute and run you program.
You will find an example on a real app of this system in gunicorn's setup.py

Categories

Resources