diff options
author | Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> | 2023-10-23 13:50:08 +0200 |
---|---|---|
committer | Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> | 2023-11-28 15:58:37 +0100 |
commit | 120a14487c86c96cf4818e04b9e919be6495151d (patch) | |
tree | 00f1515dac19c32d5e50134d924e3980eb090e8f /sources/pyside-tools | |
parent | 782c0757f43651e25f17cd28cda07f8293c3c107 (diff) |
Deployment: Code Refactoring
- Move android related configurations into a new class AndroidConfig.
This class inherits from the class Config.
- Move configuration related code sections from `android_deploy.py`
to `android_config.py`
- get_config() renamed to create_config_file().
This simplifies a lot of code and makes Android deployment independent
of Desktop deployment.
- Move `generated_files_path` to `config.py`. As a result,
`generated_files_path` does not need to be passed as parameter to
to functions like `cleanup()`, `finalize()`, `Buildozer.initialize()`
as config is already passed.
- generated_files_path expression changed.
This is because we assume the project_dir is always the parent of the
source_file (i.e. main.py)
- `Buildozer` import removed from `android/__init__.py` to prevent
circular import issues.
- Change buildozer commands to use "python -m" as prefix.
Pick-to: 6.6
Task-number: PYSIDE-1612
Change-Id: Ie460dc459908dab44de82c3e269b806aff2c27c5
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/pyside-tools')
-rw-r--r-- | sources/pyside-tools/android_deploy.py | 71 | ||||
-rw-r--r-- | sources/pyside-tools/deploy.py | 28 | ||||
-rw-r--r-- | sources/pyside-tools/deploy_lib/__init__.py | 6 | ||||
-rw-r--r-- | sources/pyside-tools/deploy_lib/android/__init__.py | 8 | ||||
-rw-r--r-- | sources/pyside-tools/deploy_lib/android/android_config.py | 242 | ||||
-rw-r--r-- | sources/pyside-tools/deploy_lib/android/buildozer.py | 19 | ||||
-rw-r--r-- | sources/pyside-tools/deploy_lib/config.py | 199 | ||||
-rw-r--r-- | sources/pyside-tools/deploy_lib/deploy_util.py | 34 | ||||
-rw-r--r-- | sources/pyside-tools/deploy_lib/python_helper.py | 4 |
9 files changed, 327 insertions, 284 deletions
diff --git a/sources/pyside-tools/android_deploy.py b/sources/pyside-tools/android_deploy.py index 8ac8aa510..ef39d66b4 100644 --- a/sources/pyside-tools/android_deploy.py +++ b/sources/pyside-tools/android_deploy.py @@ -8,11 +8,11 @@ import traceback from pathlib import Path from textwrap import dedent -from deploy_lib import (MAJOR_VERSION, cleanup, config_option_exists, - find_pyside_modules, get_config, - install_python_dependencies, setup_python) -from deploy_lib.android import (AndroidData, Buildozer, extract_and_copy_jar, - get_wheel_android_arch) +from deploy_lib import (setup_python, create_config_file, cleanup, install_python_dependencies, + config_option_exists, MAJOR_VERSION) +from deploy_lib.android import AndroidData, AndroidConfig +from deploy_lib.android.buildozer import Buildozer + """ pyside6-android-deploy deployment tool @@ -87,7 +87,6 @@ def main(name: str = None, pyside_wheel: Path = None, shiboken_wheel: Path = Non extra_modules.append(extra_module) main_file = Path.cwd() / "main.py" - generated_files_path = None if not main_file.exists(): raise RuntimeError(("[DEPLOY] For Android deployment to work, the main" " entrypoint Python file should be named 'main.py'" @@ -98,16 +97,25 @@ def main(name: str = None, pyside_wheel: Path = None, shiboken_wheel: Path = Non ndk_path=ndk_path, sdk_path=sdk_path) python = setup_python(dry_run=dry_run, force=force, init=init) - config = get_config(python_exe=python.exe, dry_run=dry_run, config_file=config_file, - main_file=main_file, android_data=android_data, is_android=True) + + config_file_exists = config_file and Path(config_file).exists() + + if config_file_exists: + logging.info(f"[DEPLOY] Using existing config file {config_file}") + else: + config_file = create_config_file(dry_run=dry_run, config_file=config_file, + main_file=main_file) + + config = AndroidConfig(config_file=config_file, source_file=main_file, + python_exe=python.exe, dry_run=dry_run, android_data=android_data, + existing_config_file=config_file_exists, + extra_ignore_dirs=extra_ignore_dirs) if not config.wheel_pyside and not config.wheel_shiboken: raise RuntimeError(f"[DEPLOY] No PySide{MAJOR_VERSION} and Shiboken{MAJOR_VERSION} wheels" "found") - source_file = config.project_dir / config.source_file - generated_files_path = source_file.parent / "deployment" - cleanup(generated_files_path=generated_files_path, config=config, is_android=True) + cleanup(config=config, is_android=True) install_python_dependencies(config=config, python=python, init=init, packages="android_packages", is_android=True) @@ -117,29 +125,11 @@ def main(name: str = None, pyside_wheel: Path = None, shiboken_wheel: Path = Non config.title = name try: - # check which modules are needed - if not config.modules: - config.modules = find_pyside_modules(project_dir=config.project_dir, - extra_ignore_dirs=extra_ignore_dirs, - project_data=config.project_data) - logging.info("The following PySide modules were found from the python files of " - f"the project {config.modules}") - config.modules.extend(extra_modules) - - # extract out and copy .jar files to {generated_files_path} - if not config.jars_dir or not Path(config.jars_dir).exists() and not dry_run: - logging.info("[DEPLOY] Extract and copy jar files from PySide6 wheel to " - f"{generated_files_path}") - config.jars_dir = extract_and_copy_jar(wheel_path=config.wheel_pyside, - generated_files_path=generated_files_path) - - # find architecture from wheel name - if not config.arch: - arch = get_wheel_android_arch(wheel=config.wheel_pyside) - if not arch: - raise RuntimeError("[DEPLOY] PySide wheel corrupted. Wheel name should end with" - "platform name") - config.arch = arch + config.modules += extra_modules + + # this cannot be done when config file is initialized because cleanup() removes it + # so this can only be done after the cleanup() + config.find_and_set_jars_dir() # TODO: include qml files from pysidedeploy.spec rather than from extensions # buildozer currently includes all the files with .qml extension @@ -147,7 +137,7 @@ def main(name: str = None, pyside_wheel: Path = None, shiboken_wheel: Path = Non # init buildozer Buildozer.dry_run = dry_run logging.info("[DEPLOY] Creating buildozer.spec file") - Buildozer.initialize(pysidedeploy_config=config, generated_files_path=generated_files_path) + Buildozer.initialize(pysidedeploy_config=config) # writing config file if not dry_run: @@ -167,17 +157,16 @@ def main(name: str = None, pyside_wheel: Path = None, shiboken_wheel: Path = Non buildozer_build_dir = config.project_dir / ".buildozer" if not buildozer_build_dir.exists(): logging.info(f"[DEPLOY] Unable to copy {buildozer_build_dir} to " - f"{generated_files_path}. {buildozer_build_dir} does not exist") - logging.info(f"[DEPLOY] Copying {str(buildozer_build_dir)} to " - f"{str(generated_files_path)}") - shutil.move(buildozer_build_dir, generated_files_path) + f"{config.generated_files_path}. {buildozer_build_dir} does not exist") + logging.info(f"[DEPLOY] copy {buildozer_build_dir} to {config.generated_files_path}") + shutil.move(buildozer_build_dir, config.generated_files_path) logging.info(f"[DEPLOY] apk created in {config.exe_dir}") except Exception: print(f"Exception occurred: {traceback.format_exc()}") finally: - if generated_files_path and config and not keep_deployment_files: - cleanup(generated_files_path=generated_files_path, config=config, is_android=True) + if config.generated_files_path and config and not keep_deployment_files: + cleanup(config=config, is_android=True) logging.info("[DEPLOY] End") diff --git a/sources/pyside-tools/deploy.py b/sources/pyside-tools/deploy.py index b19fbb0d1..f5197b6cf 100644 --- a/sources/pyside-tools/deploy.py +++ b/sources/pyside-tools/deploy.py @@ -35,7 +35,7 @@ from pathlib import Path from textwrap import dedent from deploy_lib import (MAJOR_VERSION, Config, cleanup, config_option_exists, - finalize, get_config, install_python_dependencies, + finalize, create_config_file, install_python_dependencies, setup_python) @@ -54,22 +54,26 @@ def main(main_file: Path = None, name: str = None, config_file: Path = None, ini # Nuitka command to run command_str = None - generated_files_path = None config = None logging.info("[DEPLOY] Start") python = setup_python(dry_run=dry_run, force=force, init=init) - config = get_config(python_exe=python.exe, dry_run=dry_run, config_file=config_file, - main_file=main_file) + config_file_exists = config_file and Path(config_file).exists() + + if config_file_exists: + logging.info(f"[DEPLOY] Using existing config file {config_file}") + else: + config_file = create_config_file(dry_run=dry_run, config_file=config_file, + main_file=main_file) + + config = Config(config_file=config_file, source_file=main_file, python_exe=python.exe, + dry_run=dry_run, existing_config_file=config_file_exists) # set application name if name: config.title = name - source_file = config.project_dir / config.source_file - - generated_files_path = source_file.parent / "deployment" - cleanup(generated_files_path=generated_files_path, config=config) + cleanup(config=config) install_python_dependencies(config=config, python=python, init=init, packages="packages") @@ -96,17 +100,17 @@ def main(main_file: Path = None, name: str = None, config_file: Path = None, ini logging.info("[DEPLOY] Deploying application") command_str = python.create_executable( - source_file=source_file, + source_file=config.source_file, extra_args=config.extra_args, config=config, ) except Exception: print(f"[DEPLOY] Exception occurred: {traceback.format_exc()}") finally: - if generated_files_path and config: - finalize(generated_files_path=generated_files_path, config=config) + if config.generated_files_path and config: + finalize(config=config) if not keep_deployment_files: - cleanup(generated_files_path=generated_files_path, config=Config) + cleanup(config=config) logging.info("[DEPLOY] End") return command_str diff --git a/sources/pyside-tools/deploy_lib/__init__.py b/sources/pyside-tools/deploy_lib/__init__.py index 468a03673..a8ac99bde 100644 --- a/sources/pyside-tools/deploy_lib/__init__.py +++ b/sources/pyside-tools/deploy_lib/__init__.py @@ -6,8 +6,8 @@ MAJOR_VERSION = 6 EXE_FORMAT = ".exe" if sys.platform == "win32" else ".bin" from .commands import run_command -from .config import BaseConfig, Config from .nuitka_helper import Nuitka -from .deploy_util import (cleanup, config_option_exists, finalize, get_config, - install_python_dependencies, setup_python) from .python_helper import PythonExecutable, find_pyside_modules +from .config import BaseConfig, Config +from .deploy_util import (cleanup, finalize, create_config_file, setup_python, + install_python_dependencies, config_option_exists) diff --git a/sources/pyside-tools/deploy_lib/android/__init__.py b/sources/pyside-tools/deploy_lib/android/__init__.py index 907e12e1f..ba7a2b4e9 100644 --- a/sources/pyside-tools/deploy_lib/android/__init__.py +++ b/sources/pyside-tools/deploy_lib/android/__init__.py @@ -1,7 +1,7 @@ # Copyright (C) 2023 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 -from .android_helper import (AndroidData, create_recipe, extract_and_copy_jar, - find_lib_dependencies, find_qtlibs_in_wheel, - get_llvm_readobj, get_wheel_android_arch) -from .buildozer import Buildozer +from .android_helper import (create_recipe, extract_and_copy_jar, get_wheel_android_arch, + AndroidData, get_llvm_readobj, find_lib_dependencies, + find_qtlibs_in_wheel) +from .android_config import AndroidConfig diff --git a/sources/pyside-tools/deploy_lib/android/android_config.py b/sources/pyside-tools/deploy_lib/android/android_config.py new file mode 100644 index 000000000..a6b2cf052 --- /dev/null +++ b/sources/pyside-tools/deploy_lib/android/android_config.py @@ -0,0 +1,242 @@ +# Copyright (C) 2023 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 +import logging + +from typing import List +from pathlib import Path + +from . import extract_and_copy_jar, get_wheel_android_arch +from .. import Config, find_pyside_modules + +ANDROID_NDK_VERSION = "25c" +ANDROID_DEPLOY_CACHE = Path.home() / ".pyside6_android_deploy" + + +class AndroidConfig(Config): + """ + Wrapper class around pysidedeploy.spec file for pyside6-android-deploy + """ + def __init__(self, config_file: Path, source_file: Path, python_exe: Path, dry_run: bool, + android_data, existing_config_file: bool = False, + extra_ignore_dirs: List[str] = None): + super().__init__(config_file=config_file, source_file=source_file, python_exe=python_exe, + dry_run=dry_run, existing_config_file=existing_config_file) + + self.extra_ignore_dirs = extra_ignore_dirs + + if android_data.wheel_pyside: + self.wheel_pyside = android_data.wheel_pyside + else: + wheel_pyside_temp = self.get_value("qt", "wheel_pyside") + if not wheel_pyside_temp: + raise RuntimeError("[DEPLOY] Unable to find PySide6 Android wheel") + self.wheel_pyside = Path(wheel_pyside_temp).resolve() + + if android_data.wheel_shiboken: + self.wheel_shiboken = android_data.wheel_shiboken + else: + wheel_shiboken_temp = self.get_value("qt", "wheel_shiboken") + if not wheel_shiboken_temp: + raise RuntimeError("[DEPLOY] Unable to find shiboken6 Android wheel") + self.wheel_shiboken = Path(wheel_shiboken_temp).resolve() + + self.ndk_path = None + if android_data.ndk_path: + # from cli + self.ndk_path = android_data.ndk_path + else: + # from config + ndk_path_temp = self.get_value("buildozer", "ndk_path") + if ndk_path_temp: + self.ndk_path = Path(ndk_path_temp) + else: + ndk_path_temp = (ANDROID_DEPLOY_CACHE / "android-ndk" + / f"android-ndk-r{ANDROID_NDK_VERSION}") + if ndk_path_temp.exists(): + self.ndk_path = ndk_path_temp + + if self.ndk_path: + print(f"Using Android NDK: {str(self.ndk_path)}") + else: + raise FileNotFoundError("[DEPLOY] Unable to find Android NDK. Please pass the NDK " + "path either from the CLI or from pysidedeploy.spec") + + self.sdk_path = None + if android_data.sdk_path: + self.sdk_path = android_data.sdk_path + else: + sdk_path_temp = self.get_value("buildozer", "sdk_path") + if sdk_path_temp: + self.sdk_path = Path(sdk_path_temp) + else: + sdk_path_temp = ANDROID_DEPLOY_CACHE / "android-sdk" + if sdk_path_temp.exists(): + self.sdk_path = sdk_path_temp + else: + logging.info("[DEPLOY] Use default SDK from buildozer") + + if self.sdk_path: + print(f"Using Android SDK: {str(self.sdk_path)}") + + recipe_dir_temp = self.get_value("buildozer", "recipe_dir") + self.recipe_dir = Path(recipe_dir_temp) if recipe_dir_temp else None + + self._jars_dir = [] + jars_dir_temp = self.get_value("buildozer", "jars_dir") + if jars_dir_temp and Path(jars_dir_temp).resolve().exists(): + self.jars_dir = Path(jars_dir_temp).resolve() + + self._modules = [] + if self.get_value("buildozer", "modules"): + self.modules = self.get_value("buildozer", "modules").split(",") + else: + self._find_and_set_pysidemodules() + + self._arch = None + if self.get_value("buildozer", "arch"): + self.arch = self.get_value("buildozer", "arch") + else: + self._find_and_set_arch() + + self._local_libs = [] + if self.get_value("buildozer", "local_libs"): + self.local_libs = self.get_value("buildozer", "local_libs").split(",") + + self._qt_plugins = [] + if self.get_value("qt", "plugins"): + self._qt_plugins = self.get_value("qt", "plugins").split(",") + + self._mode = self.get_value("buildozer", "mode") + + @property + def qt_plugins(self): + return self._qt_plugins + + @qt_plugins.setter + def qt_plugins(self, qt_plugins): + self._qt_plugins = qt_plugins + self.set_value("qt", "plugins", ",".join(qt_plugins)) + + @property + def ndk_path(self): + return self._ndk_path + + @ndk_path.setter + def ndk_path(self, ndk_path: Path): + self._ndk_path = ndk_path.resolve() if ndk_path else None + if self._ndk_path: + self.set_value("buildozer", "ndk_path", str(self._ndk_path)) + + @property + def sdk_path(self) -> Path: + return self._sdk_path + + @sdk_path.setter + def sdk_path(self, sdk_path: Path): + self._sdk_path = sdk_path.resolve() if sdk_path else None + if self._sdk_path: + self.set_value("buildozer", "sdk_path", str(self._sdk_path)) + + @property + def arch(self): + return self._arch + + @arch.setter + def arch(self, arch): + self._arch = arch + self.set_value("buildozer", "arch", arch) + + @property + def mode(self): + return self._mode + + @property + def modules(self): + return self._modules + + @modules.setter + def modules(self, modules): + self._modules = modules + self.set_value("buildozer", "modules", ",".join(modules)) + + @property + def local_libs(self): + return self._local_libs + + @local_libs.setter + def local_libs(self, local_libs): + self._local_libs = local_libs + self.set_value("buildozer", "local_libs", ",".join(local_libs)) + + @property + def recipe_dir(self): + return self._recipe_dir + + @recipe_dir.setter + def recipe_dir(self, recipe_dir: Path): + self._recipe_dir = recipe_dir.resolve() if recipe_dir else None + if self._recipe_dir: + self.set_value("buildozer", "recipe_dir", str(self._recipe_dir)) + + def recipes_exist(self): + if not self._recipe_dir: + return False + + pyside_recipe_dir = Path(self.recipe_dir) / "PySide6" + shiboken_recipe_dir = Path(self.recipe_dir) / "shiboken6" + + return pyside_recipe_dir.is_dir() and shiboken_recipe_dir.is_dir() + + @property + def jars_dir(self) -> Path: + return self._jars_dir + + @jars_dir.setter + def jars_dir(self, jars_dir: Path): + self._jars_dir = jars_dir.resolve() if jars_dir else None + if self._jars_dir: + self.set_value("buildozer", "jars_dir", str(self._jars_dir)) + + @property + def wheel_pyside(self) -> Path: + return self._wheel_pyside + + @wheel_pyside.setter + def wheel_pyside(self, wheel_pyside: Path): + self._wheel_pyside = wheel_pyside.resolve() if wheel_pyside else None + if self._wheel_pyside: + self.set_value("qt", "wheel_pyside", str(self._wheel_pyside)) + + @property + def wheel_shiboken(self) -> Path: + return self._wheel_shiboken + + @wheel_shiboken.setter + def wheel_shiboken(self, wheel_shiboken: Path): + self._wheel_shiboken = wheel_shiboken.resolve() if wheel_shiboken else None + if self._wheel_shiboken: + self.set_value("qt", "wheel_shiboken", str(self._wheel_shiboken)) + + def _find_and_set_pysidemodules(self): + self.modules = find_pyside_modules(project_dir=self.project_dir, + extra_ignore_dirs=self.extra_ignore_dirs, + project_data=self.project_data) + logging.info("The following PySide modules were found from the python files of " + f"the project {self.modules}") + + def find_and_set_jars_dir(self): + """Extract out and copy .jar files to {generated_files_path} + """ + if not self.dry_run: + logging.info("[DEPLOY] Extract and copy jar files from PySide6 wheel to " + f"{self.generated_files_path}") + self.jars_dir = extract_and_copy_jar(wheel_path=self.wheel_pyside, + generated_files_path=self.generated_files_path) + + def _find_and_set_arch(self): + """Find architecture from wheel name + """ + self.arch = get_wheel_android_arch(wheel=self.wheel_pyside) + if not self.arch: + raise RuntimeError("[DEPLOY] PySide wheel corrupted. Wheel name should end with" + "platform name") diff --git a/sources/pyside-tools/deploy_lib/android/buildozer.py b/sources/pyside-tools/deploy_lib/android/buildozer.py index f66a4b01c..f17ffd116 100644 --- a/sources/pyside-tools/deploy_lib/android/buildozer.py +++ b/sources/pyside-tools/deploy_lib/android/buildozer.py @@ -1,6 +1,7 @@ # Copyright (C) 2023 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 +import sys import logging import re import tempfile @@ -22,8 +23,7 @@ ALL_PYSIDE_MODULES = [module[2:] for module in PySide6.__all__] class BuildozerConfig(BaseConfig): - def __init__(self, buildozer_spec_file: Path, pysidedeploy_config: Config, - generated_files_path: Path): + def __init__(self, buildozer_spec_file: Path, pysidedeploy_config: Config): super().__init__(buildozer_spec_file, comment_prefixes="#") self.set_value("app", "title", pysidedeploy_config.title) self.set_value("app", "package.name", pysidedeploy_config.title) @@ -97,14 +97,15 @@ class BuildozerConfig(BaseConfig): version = Wheel(pysidedeploy_config.wheel_pyside).version create_recipe(version=version, component=f"PySide{MAJOR_VERSION}", wheel_path=pysidedeploy_config.wheel_pyside, - generated_files_path=generated_files_path, + generated_files_path=pysidedeploy_config.generated_files_path, qt_modules=pysidedeploy_config.modules, local_libs=pysidedeploy_config.local_libs, plugins=pysidedeploy_config.qt_plugins) create_recipe(version=version, component=f"shiboken{MAJOR_VERSION}", wheel_path=pysidedeploy_config.wheel_shiboken, - generated_files_path=generated_files_path) - pysidedeploy_config.recipe_dir = (generated_files_path / "recipes").resolve() + generated_files_path=pysidedeploy_config.generated_files_path) + pysidedeploy_config.recipe_dir = ((pysidedeploy_config.generated_files_path + / "recipes").resolve()) self.set_value('app', "p4a.local_recipes", str(pysidedeploy_config.recipe_dir)) # add permissions @@ -332,7 +333,7 @@ class Buildozer: dry_run = False @staticmethod - def initialize(pysidedeploy_config: Config, generated_files_path: Path): + def initialize(pysidedeploy_config: Config): project_dir = Path(pysidedeploy_config.project_dir) buildozer_spec = project_dir / "buildozer.spec" if buildozer_spec.exists(): @@ -341,14 +342,14 @@ class Buildozer: return # creates buildozer.spec config file - command = ["buildozer", "init"] + command = [sys.executable, "-m", "buildozer", "init"] run_command(command=command, dry_run=Buildozer.dry_run) if not Buildozer.dry_run: if not buildozer_spec.exists(): raise RuntimeError(f"buildozer.spec not found in {Path.cwd()}") - BuildozerConfig(buildozer_spec, pysidedeploy_config, generated_files_path) + BuildozerConfig(buildozer_spec, pysidedeploy_config) @staticmethod def create_executable(mode: str): - command = ["buildozer", "android", mode] + command = [sys.executable, "-m", "buildozer", "android", mode] run_command(command=command, dry_run=Buildozer.dry_run) diff --git a/sources/pyside-tools/deploy_lib/config.py b/sources/pyside-tools/deploy_lib/config.py index f6898ad72..94a287eaf 100644 --- a/sources/pyside-tools/deploy_lib/config.py +++ b/sources/pyside-tools/deploy_lib/config.py @@ -6,6 +6,7 @@ import logging import warnings from configparser import ConfigParser from pathlib import Path +from typing import List from project import ProjectData @@ -14,9 +15,6 @@ 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"} -# TODO: Move this to android module. Fix circular import. -ANDROID_NDK_VERSION = "25c" -ANDROID_DEPLOY_CACHE = Path.home() / ".pyside6_android_deploy" class BaseConfig: @@ -63,14 +61,14 @@ class Config(BaseConfig): """ def __init__(self, config_file: Path, source_file: Path, python_exe: Path, dry_run: bool, - android_data, is_android: bool, existing_config_file: bool = False): + existing_config_file: bool = False): super().__init__(config_file=config_file, existing_config_file=existing_config_file) self._dry_run = dry_run # set source_file self.source_file = Path( self.set_or_fetch(config_property_val=source_file, config_property_key="input_file") - ) + ).resolve() # set python path self.python_path = Path( @@ -115,83 +113,7 @@ class Config(BaseConfig): else: self._find_and_set_excluded_qml_plugins() - # Android - if is_android: - if android_data.wheel_pyside: - self.wheel_pyside = android_data.wheel_pyside - else: - wheel_pyside_temp = self.get_value("qt", "wheel_pyside") - if not wheel_pyside_temp: - raise RuntimeError("[DEPLOY] Unable to find PySide6 Android wheel") - self.wheel_pyside = Path(wheel_pyside_temp).resolve() - - if android_data.wheel_shiboken: - self.wheel_shiboken = android_data.wheel_shiboken - else: - wheel_shiboken_temp = self.get_value("qt", "wheel_shiboken") - if not wheel_shiboken_temp: - raise RuntimeError("[DEPLOY] Unable to find shiboken6 Android wheel") - self.wheel_shiboken = Path(wheel_shiboken_temp).resolve() - - self.ndk_path = None - if android_data.ndk_path: - # from cli - self.ndk_path = android_data.ndk_path - else: - # from config - ndk_path_temp = self.get_value("buildozer", "ndk_path") - if ndk_path_temp: - self.ndk_path = Path(ndk_path_temp) - else: - ndk_path_temp = (ANDROID_DEPLOY_CACHE / "android-ndk" - / f"android-ndk-r{ANDROID_NDK_VERSION}") - if ndk_path_temp.exists(): - self.ndk_path = ndk_path_temp - - if self.ndk_path: - print(f"Using Android NDK: {str(self.ndk_path)}") - else: - raise FileNotFoundError("[DEPLOY] Unable to find Android NDK. Please pass the NDK " - "path either from the CLI or from pysidedeploy.spec") - - self.sdk_path = None - if android_data.sdk_path: - self.sdk_path = android_data.sdk_path - else: - sdk_path_temp = self.get_value("buildozer", "sdk_path") - if sdk_path_temp: - self.sdk_path = Path(sdk_path_temp) - else: - sdk_path_temp = ANDROID_DEPLOY_CACHE / "android-sdk" - if sdk_path_temp.exists(): - self.sdk_path = sdk_path_temp - else: - logging.info("[DEPLOY] Use default SDK from buildozer") - - if self.sdk_path: - print(f"Using Android SDK: {str(self.sdk_path)}") - - recipe_dir_temp = self.get_value("buildozer", "recipe_dir") - self.recipe_dir = Path(recipe_dir_temp) if recipe_dir_temp else None - - jars_dir_temp = self.get_value("buildozer", "jars_dir") - self.jars_dir = Path(jars_dir_temp) if jars_dir_temp else None - - self._modules = [] - if self.get_value("buildozer", "modules"): - self.modules = self.get_value("buildozer", "modules").split(",") - - self.arch = self.get_value("buildozer", "arch") - - self._local_libs = [] - if self.get_value("buildozer", "local_libs"): - self.local_libs = self.get_value("buildozer", "local_libs").split(",") - - self._qt_plugins = [] - if self.get_value("qt", "plugins"): - self._qt_plugins = self.get_value("qt", "plugins").split(",") - - self._mode = self.get_value("buildozer", "mode") + self._generated_files_path = self.project_dir / "deployment" def set_or_fetch(self, config_property_val, config_property_key, config_property_group="app"): """ @@ -215,6 +137,10 @@ class Config(BaseConfig): return self._dry_run @property + def generated_files_path(self): + return self._generated_files_path + + @property def qml_files(self): return self._qml_files @@ -272,95 +198,6 @@ class Config(BaseConfig): self._excluded_qml_plugins = excluded_qml_plugins @property - def recipe_dir(self): - return self._recipe_dir - - @recipe_dir.setter - def recipe_dir(self, recipe_dir: Path): - self._recipe_dir = recipe_dir.resolve() if recipe_dir else None - if self._recipe_dir: - self.set_value("buildozer", "recipe_dir", str(self._recipe_dir)) - - def recipes_exist(self): - if not self._recipe_dir: - return False - - pyside_recipe_dir = Path(self.recipe_dir) / "PySide6" - shiboken_recipe_dir = Path(self.recipe_dir) / "shiboken6" - - return pyside_recipe_dir.is_dir() and shiboken_recipe_dir.is_dir() - - @property - def jars_dir(self) -> Path: - return self._jars_dir - - @jars_dir.setter - def jars_dir(self, jars_dir: Path): - self._jars_dir = jars_dir.resolve() if jars_dir else None - if self._jars_dir: - self.set_value("buildozer", "jars_dir", str(self._jars_dir)) - - @property - def modules(self): - return self._modules - - @modules.setter - def modules(self, modules): - self._modules = modules - self.set_value("buildozer", "modules", ",".join(modules)) - - @property - def local_libs(self): - return self._local_libs - - @local_libs.setter - def local_libs(self, local_libs): - self._local_libs = local_libs - self.set_value("buildozer", "local_libs", ",".join(local_libs)) - - @property - def qt_plugins(self): - return self._qt_plugins - - @qt_plugins.setter - def qt_plugins(self, qt_plugins): - self._qt_plugins = qt_plugins - self.set_value("qt", "plugins", ",".join(qt_plugins)) - - @property - def ndk_path(self): - return self._ndk_path - - @ndk_path.setter - def ndk_path(self, ndk_path: Path): - self._ndk_path = ndk_path.resolve() if ndk_path else None - if self._ndk_path: - self.set_value("buildozer", "ndk_path", str(self._ndk_path)) - - @property - def sdk_path(self) -> Path: - return self._sdk_path - - @sdk_path.setter - def sdk_path(self, sdk_path: Path): - self._sdk_path = sdk_path.resolve() if sdk_path else None - if self._sdk_path: - self.set_value("buildozer", "sdk_path", str(self._sdk_path)) - - @property - def arch(self): - return self._arch - - @arch.setter - def arch(self, arch): - self._arch = arch - self.set_value("buildozer", "arch", arch) - - @property - def mode(self): - return self._mode - - @property def exe_dir(self): return self._exe_dir @@ -368,26 +205,6 @@ class Config(BaseConfig): def exe_dir(self, exe_dir: Path): self._exe_dir = exe_dir - @property - def wheel_pyside(self) -> Path: - return self._wheel_pyside - - @wheel_pyside.setter - def wheel_pyside(self, wheel_pyside: Path): - self._wheel_pyside = wheel_pyside.resolve() if wheel_pyside else None - if self._wheel_pyside: - self.set_value("qt", "wheel_pyside", str(self._wheel_pyside)) - - @property - def wheel_shiboken(self) -> Path: - return self._wheel_shiboken - - @wheel_shiboken.setter - def wheel_shiboken(self, wheel_shiboken: Path): - self._wheel_shiboken = wheel_shiboken.resolve() if wheel_shiboken else None - if self._wheel_shiboken: - self.set_value("qt", "wheel_shiboken", str(self._wheel_shiboken)) - 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""" diff --git a/sources/pyside-tools/deploy_lib/deploy_util.py b/sources/pyside-tools/deploy_lib/deploy_util.py index a73ccb0eb..368ad682e 100644 --- a/sources/pyside-tools/deploy_lib/deploy_util.py +++ b/sources/pyside-tools/deploy_lib/deploy_util.py @@ -19,12 +19,12 @@ def config_option_exists(): return False -def cleanup(generated_files_path: Path, config: Config, is_android: bool = False): +def cleanup(config: Config, is_android: bool = False): """ Cleanup the generated build folders/files """ - if generated_files_path.exists(): - shutil.rmtree(generated_files_path) + if config.generated_files_path.exists(): + shutil.rmtree(config.generated_files_path) logging.info("[DEPLOY] Deployment directory purged") if is_android: @@ -39,37 +39,27 @@ def cleanup(generated_files_path: Path, config: Config, is_android: bool = False logging.info(f"[DEPLOY] {str(buildozer_build)} removed") -def get_config(python_exe: Path, dry_run: bool = False, config_file: Path = None, main_file: - Path = None, android_data=None, is_android: bool = False): +def create_config_file(dry_run: bool = False, config_file: Path = None, main_file: Path = None): """ Sets up a new pysidedeploy.spec or use an existing config file """ - config_file_exists = config_file and Path(config_file).exists() - - if main_file and not config_file_exists: + if main_file: if main_file.parent != Path.cwd(): config_file = main_file.parent / "pysidedeploy.spec" else: config_file = Path.cwd() / "pysidedeploy.spec" - if config_file_exists: - logging.info(f"[DEPLOY] Using existing config file {config_file}") - else: - logging.info(f"[DEPLOY] Creating config file {config_file}") - if not dry_run: - shutil.copy(Path(__file__).parent / "default.spec", config_file) + logging.info(f"[DEPLOY] Creating config file {config_file}") + if not dry_run: + shutil.copy(Path(__file__).parent / "default.spec", config_file) # the config parser needs a reference to parse. So, in the case of --dry-run # use the default.spec file. - if dry_run and not config_file_exists: + if dry_run: config_file = Path(__file__).parent / "default.spec" - config = Config(config_file=config_file, source_file=main_file, python_exe=python_exe, - dry_run=dry_run, android_data=android_data, is_android=is_android, - existing_config_file=config_file_exists) - - return config + return config_file def setup_python(dry_run: bool, force: bool, init: bool): @@ -109,12 +99,12 @@ def install_python_dependencies(config: Config, python: PythonExecutable, init: python.install(packages=["patchelf"]) -def finalize(generated_files_path: Path, config: Config): +def finalize(config: Config): """ Copy the executable into the final location For Android deployment, this is done through buildozer """ - generated_exec_path = generated_files_path / (config.source_file.stem + EXE_FORMAT) + generated_exec_path = config.generated_files_path / (config.source_file.stem + EXE_FORMAT) if generated_exec_path.exists() and config.exe_dir: shutil.copy(generated_exec_path, config.exe_dir) print("[DEPLOY] Executed file created in " diff --git a/sources/pyside-tools/deploy_lib/python_helper.py b/sources/pyside-tools/deploy_lib/python_helper.py index f403b2d47..1e5f77b78 100644 --- a/sources/pyside-tools/deploy_lib/python_helper.py +++ b/sources/pyside-tools/deploy_lib/python_helper.py @@ -12,7 +12,7 @@ from importlib import util from importlib.metadata import version from pathlib import Path -from . import Config, Nuitka, run_command +from . import Nuitka, run_command IMPORT_WARNING_PYSIDE = (f"[DEPLOY] Found 'import PySide6' in file {0}" ". Use 'from PySide6 import <module>' or pass the module" @@ -193,7 +193,7 @@ class PythonExecutable: def is_installed(self, package): return bool(util.find_spec(package)) - def create_executable(self, source_file: Path, extra_args: str, config: Config): + def create_executable(self, source_file: Path, extra_args: str, config): if config.qml_files: logging.info(f"[DEPLOY] Included QML files: {config.qml_files}") |