How to pass commands to gcc through cx_Freeze 'disutils.core.setup()' arguments?
Specifically, i want my .exe file to use relative paths in traceback messages, rather than the path where i build .exe file
Here is my setup.py file:
setup(
name="test",
packages=['test'],
package_data={'': ['*.py', '*.txt', '*.sample', '*.mo', 'README.rst']},
options={"build_exe": {
"icon": r"test\resources\test.ico",
"compressed": True,
"create_shared_zip": True,
"copy_dependent_files": True,
"include_files": [
('test/i18n/', 'i18n/'),
('test/resources/', 'resources/'),
('test/client.conf.sample', 'client.conf.sample'),
],
"excludes": [
'urllib.sys',
'urllib._sre',
'urllib.array',
'urllib._locale',
'urllib.datetime',
'urllib._functools',
]
}
},
executables=Executable(script=script),)
You need to add one additional option to the ones you already have:
replace_paths = [("*", "")]
That will replace all paths with relative paths. You can also do more interesting things like:
replace_paths = [
("/path/to/python/lib", "<Python>"),
("/path/to/my/script", "<Script>")
]
In essence, the first element of the tuple is the part of the path which is to be replaced with the value in the second element of the tuple. A value of * in the search value results in all paths being replaced with the replacement value.
Related
I've built an app using Tkinter, and when compiling it with cx_Freeze I get no issues.
When I run the .exe generated on my machine, and my virtual test machine, I have no issues. However, someone currently testing my app is encountering this issue:
Previously they had been encountering this issue:
I fixed the issue of 'brotlicffi' not being found by bypassing py7zr by throwing it into a try statement, as it's not completely essential for the app to function. However, cefpython3 is.
What I find very confusing is that the paths in the traceback errors are all my paths, I've encountered this before with cx_Freeze, which threw me off at first but dismissed it as a possible quirk of cx_Freeze/Python.
Here is my cx_Freeze setup.py:
dir_path = os.getcwd()
interface_path = os.path.join(dir_path, "interface")
base = None
if sys.platform == 'win32':
base = 'Win32GUI'
options = {"build_exe": {
"packages": [
"base64",
"re",
"os",
"inspect",
"_winapi",
"json",
"time",
"selenium",
"webdriver_manager",
"tqdm",
"pdfrw",
"cefpython3",
"customtkinter",
"tkinter",
"pyglet",
"urllib",
"py7zr",
"brotli",
"brotlicffi", # Needed for py7zr
"winreg",
"requests",
"shutil",
"stat",
"inspect"
],
# "path": [
# "C:\\Users\\aaron\\PycharmProjects\\slowly scraper\\venv\\Lib\\site-packages"
# ],
"include_files": [
# "yellow.json",
("venv\\Lib\\site-packages\\brotli.py", "lib\\brotli.py"),
"interface"
# "cefpython3"
]
# "replace_paths": [("*", "")]
}
}
executables = [cx_Freeze.Executable(
"main.py",
base=base,
target_name="SLD.exe",
icon=os.path.join(interface_path, "SLD_icon.ico")
)
]
cx_Freeze.setup(
name="Slowly Letter Downloader",
options=options,
author="PastaSource",
version="0.1",
description="Automates the downloading of letters from Slowly",
executables=executables
)
If it helps, I'm running this all in Pycharm, the includes the compilation of the cx_Freeze application.
In setup.py I can put something like this:
import setuptools
setuptools.setup(
name = "my_project",
version = "1.2.3.4",
packages = [ "my_project" ],
entry_points = {
"console_scripts": [
"my_project = my_project.__main__:main" ] } )
To create an entry point/executable, my_project, that I can call from the console.
Is it possible to create these entry points manually, in a normal Python script, outside of setup.py?
(I'm interested in creating these the same way setup.py does, so not using system-specific hashbang scripts, etc.)
I want to compile a python script using the cx_Freeze module. For this I write the following setup.py file:
from cx_Freeze import setup, Executable
executables = Executable(script = "Example5.py",icon = "icon.ico")
zip_include_packages = ["collections", "importlib", "encodings"]
excludes = [
'unicodedata', 'logging', 'unittest', 'email', 'html', 'http', 'urllib',
'bz2'
]
options = {
"build_exe": {
"include_msvcr": True,
"excludes": excludes,
"zip_include_packages":zip_include_packages,
"build_exe": "Test compiling",
}
}
setup(
name='Test',
version='1.0.0',
description='Testing compile',
executables=[executables],
options=options
)
This script doesn't want to compile, cx_Freeze is failing with error:
Fatal Python error: Py_Initalize: unable to load the file system codec
ModuleNotFoundError: No module named 'encodings'
Current thread 0x00000bf4 (most recent call first)
But if I replace this line:
executables = Executable(script = "Example5.py",icon = "icon.ico")
by:
executables = Executable(script = "Example5.py")
the script is working and creates a .exe file.
I don't understand why the icon is not set.
Source code: https://github.com/Bus-Artyom/Test_compile
Thank you in advance.
It seems that your icon.ico is not a valid .ico file (but rather a .png file which has been renamed to .ico?).
Try with a valid .ico file.
At present I am using pyinstaller for bundling my python application. I am equally migrating to pyGObject (due to pygtk being depreciated).
Now pyinstaller does not support pyGObject and I have as of yet not figured out the required hooks... One of the other downsides of pyinstaller is how it bundles into a single executable - it causes the company installed virus scanner to check quite intensively every time the exe is run ==> quite slow startup.
Looking into using cx_freeze due to the pyGObject & py3 support I note it does not have a single-executable option. That in itself isn't an issue if the working directory can be cleaned up, be it via the pyd/dll being bundled into a second zip or into a subdirectory.
Searching around (stackoverflow and other sites), it is illuded to that it can be done, but I am not getting the expected results. Any idea#s?
setup.py is based around this one: http://wiki.wxpython.org/cx_freeze
ok solved:
1) setup.py
import sys
from cx_Freeze import setup, Executable
EXE1 = Executable(
# what to build
script = "foo.py",
initScript = None,
base = 'Win32GUI',
targetDir = "dist",
targetName = "foo.exe",
compress = True,
copyDependentFiles = True,
appendScriptToExe = True,
appendScriptToLibrary = False,
icon = 'foo.ico'
)
setup(
version = "9999",
description = "...",
author = "...",
name = "...",
options = {"build_exe": {"includes": includes,
"excludes": excludes,
"packages": packages,
"path": sys.path,
"append_script_to_exe":False,
"build_exe":"dist/bin",
"compressed":True,
"copy_dependent_files":True,
"create_shared_zip":True,
"include_in_shared_zip":True,
"optimize":2,
}
},
executables = [EXE1]
)
2) foo.py header:
import os
import sys
if getattr(sys,'frozen',False):
# if trap for frozen script wrapping
sys.path.append(os.path.join(os.path.dirname(sys.executable),'bin'))
sys.path.append(os.path.join(os.path.dirname(sys.executable),'bin\\library.zip'))
os.environ['TCL_LIBRARY'] = os.path.join(os.path.dirname(sys.executable),'bin\\tcl')
os.environ['TK_LIBRARY'] = os.path.join(os.path.dirname(sys.executable),'bin\\tk')
os.environ['MATPLOTLIBDATA'] = os.path.join(os.path.dirname(sys.executable),'bin\\mpl-data')
I want to create a .exe file. I'm using Python 2.7.3 with wxPython for the GUI. I've installed py2exe for Python 2.7 and tried to create a .exe file following the tutorial at http://www.py2exe.org/index.cgi/Tutorial
When I try to run my created .exe file, I get following error:
File "wx\_gdi.pyc",line823, in BitmapFromImage wx._core.PyAssertionError:
C++ assertion "image.OK()" failed at ..\..\src\msw\bitmap.cpp(802) in
wxBitmap::CreateFromImage(): invalid image
So I looked into my code and the following line is causing the problem:
self.bmpSun = wx.StaticBitmap(self, wx.ID_ANY, wx.BitmapFromImage(wx.Image('images/sun.gif', wx.BITMAP_TYPE_ANY)), pos = (0,0))
When I browse to the source folder and run the main.py file myself, my app runs fine. I haven't found any help online so far. Can anybody solve this problem/suggest reliable alternatives for py2exe? Thank you.
The line that errors out is looking for an image in the Images folder. That's a path relative to the .exe file created by py2exe. So you need to be sure that that folder exists in correct position relative to the exe, and that it is populated with the images you are going to use. You can do this 2 ways. Either copy the folder to where the exe will reside, or use the data_files keyword arg in the script that makes the .exe. Here's the pertinent part of one of my setup scripts, showing a data_files list of tuples and use of the data_files keyword arg later:
data_files = [('Images', glob('Images/*.*')),
]
includes = ['win32com.decimal_23', 'datetime']
excludes = ['_gtkagg', '_tkagg', 'bsddb', 'curses', 'pywin.debugger',
'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl',
'Tkconstants', 'Tkinter', 'unittest']
packages = []
dll_excludes = ['libgdk-win32-2.0-0.dll', 'libgobject-2.0-0.dll', 'tcl84.dll',
'tk84.dll','MSVCP90.dll']
setup(
data_files = data_files,
options = {"py2exe": {"compressed": 2,
"optimize": 2,
"includes": includes,
"excludes": excludes,
"packages": packages,
"dll_excludes": dll_excludes,
"bundle_files": 1,
"dist_dir": "dist",
"xref": False,
"skip_archive": False,
"ascii": False,
"custom_boot_script": '',
}
},
zipfile = None,
windows = [filename]
)