aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside-tools/android_deploy.py
diff options
context:
space:
mode:
authorShyamnath Premnadh <Shyamnath.Premnadh@qt.io>2023-05-17 10:04:18 +0200
committerShyamnath Premnadh <Shyamnath.Premnadh@qt.io>2023-09-08 09:05:06 +0200
commitf14077be7a60751599e786fe647d823dc3f91ee3 (patch)
tree2bca5135d68c2ecbc393a3fa615d28aed8daa550 /sources/pyside-tools/android_deploy.py
parent9b3d266aab68e28cd230b1587f233d74af84e629 (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.py69
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)