Creating fewer files when freezing a Python application - python

I'm using cxFreeze to freeze my Python application. All seems to be working as expected but peering into the build directory got me thinking...
Is there a way I could have fewer files in the build directory?
Currently, there's a bunch of PYD files and the necessary DLL files lying around. Then I have some configuration files (custom) and the rest of the stuff is thrown into a library.zip file. Is there a way I could bundle pretty much everything into the library.zip file so I could have fewer files in there?
(This seems to be more a-nice-clean-directory fetish than a real "issue" but nonetheless, sometimes you've just got to fulfill the curiosity/fetish)
Thanks a ton guys (in advance).

PyInstaller is cross-platform too, and has more features than cx_Freeze, but doesn't support Python 3. See also py2exe - generate single executable file.

Related

How can I import a module from a pyc file or so file in Pypy?

This i my scenario:
I have a python project that runs in cPython.
and I have some .pyc, .so files in this project, and I don't have these files's source code.
This project runs well in cPython.
But if I change the interpreter to pypy, it can't import these modules which contained by the .pyc files and .so files.
Is there any way that I can solve this problem?
You would need to decompile the code to get back some semblance of *.py files. There are various projects out there to do this: search for "python decompile". Sponsoring one of the efforts would probably go a long way towards getting a working decompiler.

Dynamically importing .py files after compiling

I've tried looking online and I'm honestly lost at this point.
I'm trying to find if there's a way to import python scripts and run them AFTER my Python program has been compiled.
For an example, let's say I have a main.py such that:
import modules.NewModule
a = NewModuleClass()
a.showYouWork()
then I compile main.py with pyinstaller so that my directory looks like:
main.exe
modules/NewModule.py
My end goal is to make a program that can dynamically read new Python files in a folder (this will be coded in) and use them (the part I'm struggling with). I know it's possible, since that's how add-ons work in Blender 3D but I've struggled for many hours to figure this out. I think I'm just bad at choosing the correct terms in Google.
Maybe I just need to convert all of the Python files in the modules directory to .pyc files? Then, how would I use them?
Also, if this is a duplicate on here (it probably is), please let me know. I couldn't find this issue on this site either.
You may find no detailed answer simply because there is no problem. PyInstaller does not really compile Python scripts into machine code executables. It just assembles then into a folder along with an embedded Python interpretor, or alternatively creates a compressed single file executable that will automatically uncompress itself at run time into a temporary folder containing that.
From then on, you have an almost standard Python environment, with normal .pyc file which can contain normal Python instructions like calls to importlib to dynamically load other Python modules. You have just to append the directory containing the modules to sys.path before importing them. An other possible caveat, is that pyinstaller only gets required modules and not a full Python installation, so you must either make sure that the dynamic modules do not rely on missing standard modules, or be prepared to face an ImportError.

How to package a Python 3 console application as a windows binary?

I am doing this practice project to implement a LISP interpreter in Python, using help from here. I wanted to create an exe file for the project, executing which would start a REPL.
I tried using py2exe and pyInstaller but an error is thrown when I execute the output binary, saying that this script cannot run.
Where did I go wrong with my approach and what alternative ways can I use?
Thank you.
It is hard to know for sure but have you checked that all of the required dependencies for your project are either in the same folder as the created executable or (at least) in your path?
The other alternative that I am aware of (and use) is cx_Freeze. This particular exe builder has cross platform support.
cx_Freeze will attempt to automatically find all dependent python modules and include them in the final build. I imagine that the other two options work in the same manner. Packages that cannot be automatically located and binary dependencies (eg dlls, sos) must be explicitly specified in the build configuration scripts.
One method I have for debugging for missing dependencies is to manually copy the suspected missing dependency into the same folder as the .exe to see if it fixes the issue. If it does then I will specify it in the build configuration script.
See https://cx-freeze.readthedocs.io/en/latest/distutils.html for cx_Freeze documentation, in particular section titled build_exe.
Here is a good example of a non-trival setup.py for cx_Freeze: http://www.pythonexample.com/code/cx_freeze-setup/

Bundling an application, hide sources/libs?

This question is not about how to bundle a python application into a exe, or a binary. I can (almost) figure that by myself, with all the doc on the internet.
My question is more about what the final user will be able to see about my program. And for my personal culture.
For example, with cx_freeze, if I try to compile my app, I end up with a build directory. Inside, I have the binary of my app, let's call it "gui". But around, I have a bunch of *.so files.
Basically, the user can see every lib I used to build my app. I thought (maybe naively) that if I could create a unique binary file, all the libs would be included in the binary, and so, not "visible" by the user.
Do I think right or is it completely wrong ? Is it possible to bundle all the libs into one single binary, and mask them ? (I know cx_freeze can't handle a single bundle file).
You may want to consider pyinstaller. With the --onefile switch you can bundle everything into one file. However, it only fully supports python X2. This is a good tutorial to get started with it .
If you cannot use pyinstaller, you may want to try to use the answer posted here.
EDIT:
After having read the cx_freeze documentation, it turns out that you cannot bundle everything into a single exe. You will have to create a self extracting file with 7zip or IEXPRESS (if you are on Windows) that just unpacks all of your .so files.

Solutions for freezing a pyqt4 application in Windows?

Is there a workable and proven way to freeze a pyqt4 application in windows? I heard that there are some issues for py2exe.
I used py2exe for a PyQt4 project at work but ended up switching to PyInstaller.
py2exe worked great for the most part. I remember having to manually tell it to include the sip libraries in my setup.py file along with some others depending on the program. PyInstaller seems to handle this better in my opinion, although I often find myself removing DLL files from the final folders' qt4_plugins folder that it has decided to include that I don't actually need. For example, qt4_plugins\imageformats\qjpeg4.dll when I'm not using JPEG files at all. This does not hinder the frozen application in any way, it'll just increases the filesize.
The manual for PyInstaller is pretty good as well and with it's 'Getting Started' section you should quickly be able to get things set up. It's as simple as creating a .spec file per project which is automatically generated but is also a normal Python file so that you have the option to tweak it or add any extra tasks such as code signing or maybe creating a setup.exe program using NSIS.
I have a windows batch file named pybuild.bat in my path who's contents consist of:
python -O c:\python27\pyinstaller-1.5\build.py "%~f1"
so that I can easily build a project from the command line by running 'pybuild projectname.spec' on the projects .spec file. I've also added this to the registry's entry for the .spec file so that I can freeze a project quickly from Explorer:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.SPEC\shell\Freeze\command]
#="C:\\Python27\\Scripts\\pybuild.bat \"%1\""
My main reason for switching from py2exe though is that some users complained that the frozen apps would not run on their machines. I kept running into the error:
The application has failed to start
because the application configuration
is incorrect. Reinstalling the
application may fix the problem.
but only on some machines, usually running Windows XP. I found that getting the user to install the Microsoft Visual C++ 2008 Runtimes made the problem go away.
Frozen apps created with PyInstaller didn't have this problem as it seems to package these runtimes into the output folder. If UPX is available somewhere in your path it will compress your DLL and PYD files as well, resulting in a smaller output folder.
Long story short - both py2exe and PyInstaller work fine. I hit a few issues with py2exe when using it and although there may be workarounds for these if you hunt around I found that PyInstaller worked better without any modifications. I've distributed frozen apps from PyInstaller that make use of image and database libraries from PyQt4 as well as a few other third party libraries and haven't hit any problems yet.

Categories

Resources