diff options
| author | Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> | 2023-05-17 10:04:18 +0200 |
|---|---|---|
| committer | Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> | 2023-09-08 09:05:06 +0200 |
| commit | f14077be7a60751599e786fe647d823dc3f91ee3 (patch) | |
| tree | 2bca5135d68c2ecbc393a3fa615d28aed8daa550 /sources/pyside-tools/android_deploy.py | |
| parent | 9b3d266aab68e28cd230b1587f233d74af84e629 (diff) | |
Android Deployment: find PySide and Qt dependencies
- Use llvm-readelf to recursively find the dependencies of a dependent
Qt binary.
All the Qt dependencies are loaded at startup when loading the Android
application.
- Parse the revelant Python files of the project into ast, and
find the used Python modules. Once the Python file is parsed
into an ast, we find the imports of the following form:
from PySide6 import Qt<module>
from PySide6.Qt<module> import <classname>
This is then used to identify the module used, and we try to
load the binaries of this module. If the modules does not exist
in Qt for Android, then an error is thrown.
- The easiest way to find the relevant Python files in the project is
using a .pyproject file which lists all the relevant files. If this
is not there, then we find all the Python files in the project
folder excluding the following folders:
[".hg", ".svn", ".git", ".tox", "__pycache__", "env", "venv",
"deployment",".buildozer"]
- A new cli argument --extra-ignore-dirs, that lists the extra
directories to ignore when searching for all the relevant python
files in the project.
- A new cli argument --extra-modules, that lists the extra modules
to be added manually to the application incase they are not found
by `pyside6-android-deploy` automatically. Adding a module using
this argument means that the module binary is loaded by the Android
application on startup.
- sdk and ndk cli options are now mandatory to find the dependencies.
These two options will be removed later when pyside6-android-deploy
can automatically download them.
Task-number: PYSIDE-1612
Change-Id: Ifbdc20cbc70ab0935a23157ccc8cb7fde6992df2
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/pyside-tools/android_deploy.py')
| -rw-r--r-- | sources/pyside-tools/android_deploy.py | 69 |
1 files changed, 51 insertions, 18 deletions
diff --git a/sources/pyside-tools/android_deploy.py b/sources/pyside-tools/android_deploy.py index b1ea32064..97ac523b4 100644 --- a/sources/pyside-tools/android_deploy.py +++ b/sources/pyside-tools/android_deploy.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only import argparse -import sys import logging import shutil import traceback @@ -12,10 +11,9 @@ from textwrap import dedent from pkginfo import Wheel from deploy_lib import (setup_python, get_config, cleanup, install_python_dependencies, - config_option_exists, MAJOR_VERSION) + config_option_exists, find_pyside_modules, MAJOR_VERSION) from deploy_lib.android import (create_recipe, extract_and_copy_jar, get_wheel_android_arch, - Buildozer, AndroidData, WIDGET_APPLICATION_MODULES, - QUICK_APPLICATION_MODULES) + Buildozer, AndroidData) """ pyside6-android-deploy deployment tool @@ -39,8 +37,6 @@ from deploy_lib.android import (create_recipe, extract_and_copy_jar, get_wheel_a Platforms Supported: aarch64, armv7a, i686, x86_64 - Supported Modules: Core, Gui, Widgets, Network, OpenGL, Qml, Quick, QuickControls2 - Config file: On the first run of the tool, it creates a config file called pysidedeploy.spec which controls the various characteristic of the deployment. Users can simply change the value @@ -50,13 +46,46 @@ from deploy_lib.android import (create_recipe, extract_and_copy_jar, get_wheel_a Note: This file is used by both pyside6-deploy and pyside6-android-deploy """ +HELP_EXTRA_IGNORE_DIRS = dedent(""" + Comma separated directory names inside the project dir. These + directories will be skipped when searching for python files + relevant to the project. + + Example usage: --extra-ignore-dirs=doc,translations + """) + +HELP_EXTRA_MODULES = dedent(""" + Comma separated list of Qt modules to be added to the application, + in case they are not found automatically. + + This occurs when you have 'import PySide6' in your code instead + 'from PySide6 import <module>'. The module name is specified + with either omitting the prefix of Qt or with it. + + Example usage 1: --extra-modules=Network,Svg + Example usage 2: --extra-modules=QtNetwork,QtSvg + """) + def main(name: str = None, pyside_wheel: Path = None, shiboken_wheel: Path = None, ndk_path: Path = None, sdk_path: Path = None, config_file: Path = None, init: bool = False, loglevel=logging.WARNING, dry_run: bool = False, keep_deployment_files: bool = False, - force: bool = False): + force: bool = False, extra_ignore_dirs: str = None, extra_modules_grouped: str = None): logging.basicConfig(level=loglevel) + + if extra_ignore_dirs: + extra_ignore_dirs = extra_ignore_dirs.split(",") + + extra_modules = [] + if extra_modules_grouped: + tmp_extra_modules = extra_modules_grouped.split(",") + for extra_module in tmp_extra_modules: + if extra_module.startswith("Qt"): + extra_modules.append(extra_module[2:]) + else: + extra_modules.append(extra_module) + main_file = Path.cwd() / "main.py" generated_files_path = None if not main_file.exists(): @@ -65,12 +94,6 @@ def main(name: str = None, pyside_wheel: Path = None, shiboken_wheel: Path = Non 'main.py' and it should be run from the application directory """)) - # check if ndk and sdk path given, else use default - if ndk_path and sdk_path: - logging.warning("[DEPLOY] May not work with custom Ndk and Sdk versions." - "Use the default by leaving out --ndk-path and --sdk-path cl" - "arguments") - android_data = AndroidData(wheel_pyside=pyside_wheel, wheel_shiboken=shiboken_wheel, ndk_path=ndk_path, sdk_path=sdk_path) @@ -121,8 +144,13 @@ def main(name: str = None, pyside_wheel: Path = None, shiboken_wheel: Path = Non # TODO: Optimize this based on the modules needed # check if other modules not supported by Android used and raise error if not config.modules: - config.modules = (QUICK_APPLICATION_MODULES if config.qml_files else - WIDGET_APPLICATION_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) # find architecture from wheel name if not config.arch: @@ -211,16 +239,21 @@ if __name__ == "__main__": help=f"Path to shiboken{MAJOR_VERSION} Android Wheel", required=not config_option_exists()) + #TODO: --ndk-path and --sdk-path will be removed when automatic download of sdk and ndk is added parser.add_argument("--ndk-path", type=lambda p: Path(p).resolve(), help=("Path to Android Ndk. If omitted, the default from buildozer is used") - , required="--sdk-path" in sys.argv) + , required=True) parser.add_argument("--sdk-path", type=lambda p: Path(p).resolve(), help=("Path to Android Sdk. If omitted, the default from buildozer is used") - , required="--ndk-path" in sys.argv) + , required=True) + + parser.add_argument("--extra-ignore-dirs", type=str, help=HELP_EXTRA_IGNORE_DIRS) + + parser.add_argument("--extra-modules", type=str, help=HELP_EXTRA_MODULES) args = parser.parse_args() main(args.name, args.wheel_pyside, args.wheel_shiboken, args.ndk_path, args.sdk_path, args.config_file, args.init, args.loglevel, args.dry_run, args.keep_deployment_files, - args.force) + args.force, args.extra_ignore_dirs, args.extra_modules) |
