aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside-tools/deploy_lib
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside-tools/deploy_lib')
-rw-r--r--sources/pyside-tools/deploy_lib/__init__.py2
-rw-r--r--sources/pyside-tools/deploy_lib/commands.py46
-rw-r--r--sources/pyside-tools/deploy_lib/config.py34
-rw-r--r--sources/pyside-tools/deploy_lib/default.spec6
-rw-r--r--sources/pyside-tools/deploy_lib/nuitka_helper.py18
-rw-r--r--sources/pyside-tools/deploy_lib/python_helper.py3
6 files changed, 89 insertions, 20 deletions
diff --git a/sources/pyside-tools/deploy_lib/__init__.py b/sources/pyside-tools/deploy_lib/__init__.py
index b94bc665b..2ba281d78 100644
--- a/sources/pyside-tools/deploy_lib/__init__.py
+++ b/sources/pyside-tools/deploy_lib/__init__.py
@@ -1,6 +1,8 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+MAJOR_VERSION = 6
+
from .commands import run_command
from .nuitka_helper import Nuitka
from .config import Config
diff --git a/sources/pyside-tools/deploy_lib/commands.py b/sources/pyside-tools/deploy_lib/commands.py
index 2733dd4c1..53ad633ea 100644
--- a/sources/pyside-tools/deploy_lib/commands.py
+++ b/sources/pyside-tools/deploy_lib/commands.py
@@ -4,29 +4,61 @@
import subprocess
import sys
import logging
+from typing import List
+
+import json
+from pathlib import Path
"""
All utility functions for deployment
"""
-def run_command(command, dry_run: bool):
+def run_command(command, dry_run: bool, fetch_output: bool = False):
command_str = " ".join([str(cmd) for cmd in command])
+ output = None
+ is_windows = (sys.platform == "win32")
try:
if not dry_run:
- subprocess.check_call(command, shell=(sys.platform == "win32"))
+ if fetch_output:
+ output = subprocess.check_output(command, shell=is_windows)
+ else:
+ subprocess.check_call(command, shell=is_windows)
else:
print(command_str + "\n")
except FileNotFoundError as error:
- logging.exception(f"[DEPLOY]: {error.filename} not found")
+ logging.exception(f"[DEPLOY] {error.filename} not found")
raise
except subprocess.CalledProcessError as error:
logging.exception(
- f"[DEPLOY]: Command {command_str} failed with error {error} and return_code"
- f"{error.returncode}"
+ f"[DEPLOY] Command {command_str} failed with error {error} and return_code"
+ f"{error.returncode}"
)
raise
except Exception as error:
- logging.exception(f"[DEPLOY]: Command {command_str} failed with error {error}")
+ logging.exception(f"[DEPLOY] Command {command_str} failed with error {error}")
raise
- return command_str
+ return command_str, output
+
+
+def run_qmlimportscanner(qml_files: List[Path], dry_run: bool):
+ """
+ Runs pyside6-qmlimportscanner to find all the imported qml modules
+ """
+ if not qml_files:
+ return []
+
+ qml_modules = []
+ cmd = ["pyside6-qmlimportscanner", "-qmlFiles"]
+ cmd.extend([str(qml_file) for qml_file in qml_files])
+
+ if dry_run:
+ run_command(command=cmd, dry_run=True)
+
+ # we need to run qmlimportscanner during dry_run as well to complete the
+ # command being run by nuitka
+ _, json_string = run_command(command=cmd, dry_run=False, fetch_output=True)
+ json_string = json_string.decode("utf-8")
+ json_array = json.loads(json_string)
+ qml_modules = [item['name'] for item in json_array if item['type'] == "module"]
+ return qml_modules
diff --git a/sources/pyside-tools/deploy_lib/config.py b/sources/pyside-tools/deploy_lib/config.py
index d02558cca..ba165d20b 100644
--- a/sources/pyside-tools/deploy_lib/config.py
+++ b/sources/pyside-tools/deploy_lib/config.py
@@ -8,6 +8,11 @@ import shutil
import logging
from project import ProjectData
+from .commands import run_qmlimportscanner
+
+# Some QML plugins like QtCore are excluded from this list as they don't contribute much to
+# executable size. Excluding them saves the extra processing of checking for them in files
+EXCLUDED_QML_PLUGINS = {"QtQuick", "QtQuick3D", "QtCharts", "QtWebEngine", "QtTest", "QtSensors"}
class Config:
@@ -60,8 +65,14 @@ class Config:
else:
self._find_and_set_qml_files()
+ self.excluded_qml_plugins = []
+ if self.get_value("qt", "excluded_qml_plugins"):
+ self.excluded_qml_plugins = self.get_value("qt", "excluded_qml_plugins").split(",")
+ else:
+ self._find_and_set_excluded_qml_plugins()
+
def update_config(self):
- logging.info("[DEPLOY] Creating {config_file}")
+ logging.info(f"[DEPLOY] Creating {self.config_file}")
with open(self.config_file, "w+") as config_file:
self.parser.write(config_file, space_around_delimiters=True)
@@ -97,7 +108,7 @@ class Config:
return self.get_value(config_property_group, config_property_key)
else:
logging.exception(
- f"[DEPLOY]: No {config_property_key} specified in config file or as cli option"
+ f"[DEPLOY] No {config_property_key} specified in config file or as cli option"
)
raise
@@ -133,6 +144,14 @@ class Config:
def python_path(self, python_path):
self._python_path = python_path
+ @property
+ def excluded_qml_plugins(self):
+ return self._excluded_qml_plugins
+
+ @excluded_qml_plugins.setter
+ def excluded_qml_plugins(self, excluded_qml_plugins):
+ self._excluded_qml_plugins = excluded_qml_plugins
+
def _find_and_set_qml_files(self):
"""Fetches all the qml_files in the folder and sets them if the
field qml_files is empty in the config_dir"""
@@ -224,3 +243,14 @@ class Config:
self.set_value("app", "project_file", str(files[0].relative_to(self.project_dir)))
logging.info(f"[DEPLOY] Project file {files[0]} found and set in config file")
+ def _find_and_set_excluded_qml_plugins(self):
+ if self.qml_files:
+ included_qml_modules = set(run_qmlimportscanner(qml_files=self.qml_files,
+ dry_run=self.dry_run))
+ self.excluded_qml_plugins = EXCLUDED_QML_PLUGINS.difference(included_qml_modules)
+
+ # needed for dry_run testing
+ self.excluded_qml_plugins = sorted(self.excluded_qml_plugins)
+
+ if self.excluded_qml_plugins:
+ self.set_value("qt", "excluded_qml_plugins", ",".join(self.excluded_qml_plugins))
diff --git a/sources/pyside-tools/deploy_lib/default.spec b/sources/pyside-tools/deploy_lib/default.spec
index 4558ae161..909b44d73 100644
--- a/sources/pyside-tools/deploy_lib/default.spec
+++ b/sources/pyside-tools/deploy_lib/default.spec
@@ -16,7 +16,6 @@ exec_directory =
# Path to .pyproject project file
project_file =
-
[python]
# Python path
@@ -33,8 +32,11 @@ packages = nuitka,ordered_set,zstandard
# normally all the QML files are added automatically
qml_files =
+# excluded qml plugin binaries
+excluded_qml_plugins =
+
[nuitka]
# (str) specify any extra nuitka arguments
# eg: extra_args = --show-modules --follow-stdlib
-extra_args = --quiet
+extra_args = --quiet --noinclude-qt-translations=True
diff --git a/sources/pyside-tools/deploy_lib/nuitka_helper.py b/sources/pyside-tools/deploy_lib/nuitka_helper.py
index 1f4e434c5..83144c7fe 100644
--- a/sources/pyside-tools/deploy_lib/nuitka_helper.py
+++ b/sources/pyside-tools/deploy_lib/nuitka_helper.py
@@ -6,7 +6,7 @@ import sys
from pathlib import Path
from typing import List
-from . import run_command
+from . import run_command, MAJOR_VERSION
class Nuitka:
@@ -17,20 +17,22 @@ class Nuitka:
def __init__(self, nuitka):
self.nuitka = nuitka
- def create_executable(
- self, source_file: Path, extra_args: str, qml_files: List[Path], dry_run: bool
- ):
+ def create_executable(self, source_file: Path, extra_args: str, qml_files: List[Path],
+ excluded_qml_plugins, dry_run: bool):
extra_args = extra_args.split()
qml_args = []
if qml_files:
- # this includes "all" the plugins
- # FIXME: adding the "qml" plugin is equivalent to "all" because of dependencies
- # Ideally it should only add the specific qml plugins. eg: quick window, quick controls
qml_args.append("--include-qt-plugins=all")
qml_args.extend(
[f"--include-data-files={qml_file}=./{qml_file.name}" for qml_file in qml_files]
)
+ if excluded_qml_plugins:
+ prefix = "lib" if sys.platform != "win32" else ""
+ for plugin in excluded_qml_plugins:
+ dll_name = plugin.replace("Qt", f"Qt{MAJOR_VERSION}")
+ qml_args.append(f"--noinclude-dlls={prefix}{dll_name}*")
+
output_dir = source_file.parent / "deployment"
if not dry_run:
output_dir.mkdir(parents=True, exist_ok=True)
@@ -48,5 +50,5 @@ class Nuitka:
linux_icon = str(Path(__file__).parent / "pyside_icon.jpg")
command.append(f"--linux-onefile-icon={linux_icon}")
- command_str = run_command(command=command, dry_run=dry_run)
+ command_str, _ = run_command(command=command, dry_run=dry_run)
return command_str
diff --git a/sources/pyside-tools/deploy_lib/python_helper.py b/sources/pyside-tools/deploy_lib/python_helper.py
index e92ce8e0c..0c1978a9d 100644
--- a/sources/pyside-tools/deploy_lib/python_helper.py
+++ b/sources/pyside-tools/deploy_lib/python_helper.py
@@ -60,7 +60,7 @@ class PythonExecutable:
dry_run=self.dry_run,
)
else:
- logging.info(f"[DEPLOY]: Upgrading package: {package}")
+ logging.info(f"[DEPLOY] Upgrading package: {package}")
run_command(
command=[self.exe, "-m", "pip", "install", "--upgrade", package],
dry_run=self.dry_run,
@@ -77,6 +77,7 @@ class PythonExecutable:
source_file=source_file,
extra_args=extra_args,
qml_files=config.qml_files,
+ excluded_qml_plugins=config.excluded_qml_plugins,
dry_run=self.dry_run,
)