mit neuen venv und exe-Files

This commit is contained in:
2024-11-03 17:26:54 +01:00
parent 07c05a338a
commit 0c373ff593
15115 changed files with 1998469 additions and 0 deletions

View File

@@ -0,0 +1,142 @@
"""A collection of functions which are triggered automatically by finder when
PyQt5 package is included.
"""
from __future__ import annotations
from textwrap import dedent
from typing import TYPE_CHECKING
from cx_Freeze._compat import IS_MACOS
from cx_Freeze.common import get_resource_file_path
from cx_Freeze.hooks._qthooks import copy_qt_files
from cx_Freeze.hooks._qthooks import load_qt_qtcore as load_pyqt5_qtcore
from cx_Freeze.hooks._qthooks import (
load_qt_qtdesigner as load_pyqt5_qtdesigner,
)
from cx_Freeze.hooks._qthooks import load_qt_qtgui as load_pyqt5_qtgui
from cx_Freeze.hooks._qthooks import (
load_qt_qtmultimedia as load_pyqt5_qtmultimedia,
)
from cx_Freeze.hooks._qthooks import load_qt_qtnetwork as load_pyqt5_qtnetwork
from cx_Freeze.hooks._qthooks import (
load_qt_qtpositioning as load_pyqt5_qtpositioning,
)
from cx_Freeze.hooks._qthooks import (
load_qt_qtprintsupport as load_pyqt5_qtprintsupport,
)
from cx_Freeze.hooks._qthooks import load_qt_qtqml as load_pyqt5_qtqml
from cx_Freeze.hooks._qthooks import load_qt_qtsql as load_pyqt5_qtsql
from cx_Freeze.hooks._qthooks import (
load_qt_qtwebenginecore as _load_qt_qtwebenginecore,
)
from cx_Freeze.hooks._qthooks import (
load_qt_qtwebenginewidgets as load_pyqt5_qtwebenginewidgets,
)
from cx_Freeze.hooks._qthooks import load_qt_qtwidgets as load_pyqt5_qtwidgets
from cx_Freeze.hooks._qthooks import load_qt_uic as load_pyqt5_uic
if TYPE_CHECKING:
from cx_Freeze.finder import ModuleFinder
from cx_Freeze.module import Module
def load_pyqt5(finder: ModuleFinder, module: Module) -> None:
"""Inject code in PyQt5 __init__ to locate and load plugins and
resources. Also, this fixes issues with conda-forge versions.
"""
distribution = module.distribution
environment = (distribution and distribution.installer) or "pip"
# Activate the optimized mode by default in pip environments
if environment == "pip":
if module.name in finder.zip_exclude_packages:
print(f"WARNING: zip_exclude_packages={module.name} ignored.")
if module.name in finder.zip_include_packages:
print(f"WARNING: zip_include_packages={module.name} ignored.")
module.in_file_system = 2
# Include a module that fix an issue
qt_debug = get_resource_file_path("hooks/pyqt5", "_append_to_init", ".py")
finder.include_file_as_module(qt_debug, "PyQt5._cx_freeze_append_to_init")
# Include a module that inject an optional debug code
qt_debug = get_resource_file_path("hooks/pyqt5", "debug", ".py")
finder.include_file_as_module(qt_debug, "PyQt5._cx_freeze_debug")
# Include a resource with qt.conf (Prefix = lib/PyQt5) for conda-forge
if environment == "conda":
resource = get_resource_file_path("hooks/pyqt5", "resource", ".py")
finder.include_file_as_module(resource, "PyQt5._cx_freeze_resource")
# Include an optional qt.conf to be used by QtWebEngine (Prefix = ..)
copy_qt_files(finder, "PyQt5", "LibraryExecutablesPath", "qt.conf")
# Inject code to the end of init
code_string = module.file.read_text(encoding="utf_8")
code_string += dedent(
f"""
# cx_Freeze patch start
import os, sys
if {environment == "conda"}: # conda-forge linux, macos and windows
import PyQt5._cx_freeze_resource
elif {IS_MACOS}: # macos using 'pip install pyqt5'
# Support for QtWebEngine (bdist_mac differs from build_exe)
helpers = os.path.join(os.path.dirname(sys.frozen_dir), "Helpers")
if not os.path.isdir(helpers):
helpers = os.path.join(sys.frozen_dir, "share")
os.environ["QTWEBENGINEPROCESS_PATH"] = os.path.join(
helpers,
"QtWebEngineProcess.app/Contents/MacOS/QtWebEngineProcess"
)
os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--single-process"
else:
# Support for QtWebEngine (linux and windows using pip)
os.environ["QTWEBENGINE_DISABLE_SANDBOX"] = "1"
import PyQt5._cx_freeze_append_to_init
import PyQt5._cx_freeze_debug
# cx_Freeze patch end
"""
)
module.code = compile(
code_string,
module.file.as_posix(),
"exec",
dont_inherit=True,
optimize=finder.optimize,
)
def load_pyqt5_qtwebenginecore(finder: ModuleFinder, module: Module) -> None:
"""Include module dependency and QtWebEngineProcess files."""
_load_qt_qtwebenginecore(finder, module)
distribution = module.parent.distribution
environment = (distribution and distribution.installer) or "pip"
if IS_MACOS and environment == "pip":
# duplicate resource files
for source, target in finder.included_files[:]:
if any(
filter(source.match, ("Resources/*.pak", "Resources/*.dat"))
):
finder.include_files(
source,
target.parent.parent / target.name,
copy_dependent_files=False,
)
__all__ = [
"load_pyqt5",
"load_pyqt5_qtcore",
"load_pyqt5_qtdesigner",
"load_pyqt5_qtgui",
"load_pyqt5_qtmultimedia",
"load_pyqt5_qtnetwork",
"load_pyqt5_qtpositioning",
"load_pyqt5_qtprintsupport",
"load_pyqt5_qtqml",
"load_pyqt5_qtsql",
"load_pyqt5_qtwebenginecore",
"load_pyqt5_qtwebenginewidgets",
"load_pyqt5_qtwidgets",
"load_pyqt5_uic",
]

View File

@@ -0,0 +1,23 @@
"""Module used to inject a code to guessing and set the plugins directory."""
import sys
from pathlib import Path
def _run() -> None:
qtcore = __import__("PyQt5", fromlist=["QtCore"]).QtCore
# With PyQt5 5.15.4, if the folder name contains non-ascii characters, the
# libraryPaths returns empty. Prior to this version, this doesn't happen.
executable_dir = Path(sys.executable).parent
qt_root_dir = executable_dir / "lib" / "PyQt5"
plugins_dir = qt_root_dir / "Qt5" / "plugins" # PyQt5 5.15.4
if not plugins_dir.is_dir():
plugins_dir = qt_root_dir / "Qt" / "plugins"
if not plugins_dir.is_dir():
plugins_dir = qt_root_dir / "plugins"
if plugins_dir.is_dir():
qtcore.QCoreApplication.addLibraryPath(plugins_dir.as_posix())
_run()

View File

@@ -0,0 +1,28 @@
"""Module used to inject a debug code to show QLibraryInfo paths if environment
variable QT_DEBUG is set.
"""
import os
import sys
from pathlib import Path
def _debug() -> None:
# Inject a option to debug if environment variable QT_DEBUG is set.
if not os.environ.get("QT_DEBUG"):
return
# Show QLibraryInfo paths.
qtcore = __import__("PyQt5", fromlist=["QtCore"]).QtCore
data = {}
for key, value in qtcore.QLibraryInfo.__dict__.items():
if isinstance(value, (qtcore.QLibraryInfo.LibraryLocation, int)):
data[key] = Path(qtcore.QLibraryInfo.location(value))
print("QLibraryInfo:", file=sys.stderr)
for key, value in data.items():
print(" ", key, value, file=sys.stderr)
print("LibraryPaths:", file=sys.stderr)
print(" ", qtcore.QCoreApplication.libraryPaths(), file=sys.stderr)
print("FrozenDir:", sys.frozen_dir, file=sys.stderr)
_debug()

View File

@@ -0,0 +1,2 @@
[Paths]
Prefix = lib/PyQt5

View File

@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
# Resource object code
#
# Created by: The Resource Compiler for PyQt5 (Qt v5.15.8)
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore
qt_resource_data = b"\
\x00\x00\x00\x1b\
\x5b\
\x50\x61\x74\x68\x73\x5d\x0a\x50\x72\x65\x66\x69\x78\x20\x3d\x20\
\x6c\x69\x62\x2f\x50\x79\x51\x74\x35\x0a\
"
qt_resource_name = b"\
\x00\x02\
\x00\x00\x07\x84\
\x00\x71\
\x00\x74\
\x00\x03\
\x00\x00\x6c\xa3\
\x00\x65\
\x00\x74\x00\x63\
\x00\x07\
\x08\x74\xa6\xa6\
\x00\x71\
\x00\x74\x00\x2e\x00\x63\x00\x6f\x00\x6e\x00\x66\
"
qt_resource_struct_v1 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x0a\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\
\x00\x00\x00\x16\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
"
qt_resource_struct_v2 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x0a\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x16\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01\x89\xa4\x57\x42\x57\
"
qt_version = [int(v) for v in QtCore.qVersion().split('.')]
if qt_version < [5, 8, 0]:
rcc_version = 1
qt_resource_struct = qt_resource_struct_v1
else:
rcc_version = 2
qt_resource_struct = qt_resource_struct_v2
def qInitResources():
QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
def qCleanupResources():
QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
qInitResources()

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/qt/etc">
<file>qt.conf</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,8 @@
#!/bin/bash
# Get script directory (without using /usr/bin/realpath)
THIS_DIR=$(cd `dirname "${BASH_SOURCE[0]}"` && pwd)
pushd $THIS_DIR
pyrcc5 -o resource.py resource.qrc
popd