diff options
| author | Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> | 2022-10-27 15:43:35 +0200 |
|---|---|---|
| committer | Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> | 2022-11-16 11:50:30 +0100 |
| commit | 43109854a2966afe2e0cf29961157a6f54d5775c (patch) | |
| tree | 19ee00969da875e0ab8ecd836fa31c0a39faba55 | |
| parent | 0bd80c41e1eb4c0c0ef9e490b9a6bf9b054f9aea (diff) | |
PySideTools: install tool only if corresponding Qt tool exists
- PySide tools which are wrappers around Qt tools are now only installed
if the corresponding Qt tool exists.
- PySide6 entry points for the Qt tool are now only created if the Qt
tool exists in the corresponding Qt installation.
- Incase the console entrypoint still exists and the corresponding Qt
tool does not exist, the tool would exit stating that the Qt tool does
not exist.
eg: 'pyside6-uic' is run and 'uic' does not exist. The the tool
outputs that the 'uic' does not exist.
Ideally as per this change, PySide6 entrypoints for missing Qt tools
should not exist at all.
- versions.py deleted and contents moved to __init__.py.
- Adds warning from Python incase if the tool does not exist. This
is in addition to the CMake warning.
Fixes: PYSIDE-2097
Pick-to: 6.4 6.2
Change-Id: I3f1b26d103679f7425d9ad85dfed8d9ad17f6fbf
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
| -rw-r--r-- | build_scripts/__init__.py | 27 | ||||
| -rw-r--r-- | build_scripts/build_scripts.pyproject | 3 | ||||
| -rw-r--r-- | build_scripts/config.py | 12 | ||||
| -rw-r--r-- | build_scripts/main.py | 2 | ||||
| -rw-r--r-- | build_scripts/platforms/linux.py | 2 | ||||
| -rw-r--r-- | build_scripts/platforms/macos.py | 2 | ||||
| -rw-r--r-- | build_scripts/platforms/unix.py | 2 | ||||
| -rw-r--r-- | build_scripts/platforms/windows_desktop.py | 2 | ||||
| -rw-r--r-- | build_scripts/setup_runner.py | 14 | ||||
| -rw-r--r-- | build_scripts/utils.py | 48 | ||||
| -rw-r--r-- | build_scripts/versions.py | 7 | ||||
| -rw-r--r-- | build_scripts/wheel_utils.py | 2 | ||||
| -rw-r--r-- | create_wheels.py | 30 | ||||
| -rw-r--r-- | sources/pyside-tools/CMakeLists.txt | 16 | ||||
| -rw-r--r-- | sources/pyside-tools/pyside_tool.py | 2 |
15 files changed, 119 insertions, 52 deletions
diff --git a/build_scripts/__init__.py b/build_scripts/__init__.py new file mode 100644 index 000000000..a1d1f0c07 --- /dev/null +++ b/build_scripts/__init__.py @@ -0,0 +1,27 @@ +# 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 + +PYSIDE = 'pyside6' +PYSIDE_MODULE = 'PySide6' +SHIBOKEN = 'shiboken6' + +PYSIDE_PYTHON_TOOLS = ["metaobjectdump", + "deploy", + "project", + "qml", + "qtpy2cpp", + "genpyi"] +PYSIDE_LINUX_BIN_TOOLS = ["lupdate", + "lrelease", + "qmllint", + "qmlformat", + "qmlls", + "assistant", + "designer", + "linguist"] +PYSIDE_LINUX_LIBEXEC_TOOLS = ["uic", + "rcc", + "qmltyperegistrar", + "qmlimportscanner"] +# all Qt tools are in 'bin' folder in Windows +PYSIDE_WINDOWS_BIN_TOOLS = PYSIDE_LINUX_LIBEXEC_TOOLS + PYSIDE_LINUX_BIN_TOOLS diff --git a/build_scripts/build_scripts.pyproject b/build_scripts/build_scripts.pyproject index f236b602f..77f1d0485 100644 --- a/build_scripts/build_scripts.pyproject +++ b/build_scripts/build_scripts.pyproject @@ -2,8 +2,7 @@ "files": ["main.py", "__init__.py", "build_info_collector.py", "config.py", "options.py", "qtinfo.py", "setup_runner.py", "utils.py", - "wheel_files.py", "wheel_override.py", - "versions.py", "wheel_utils.py", + "wheel_files.py", "wheel_override.py", "wheel_utils.py", "platforms/__init__.py", "platforms/linux.py", "platforms/macos.py", "platforms/unix.py", "platforms/windows_desktop.py", diff --git a/build_scripts/config.py b/build_scripts/config.py index 6590dcc9d..98dc23042 100644 --- a/build_scripts/config.py +++ b/build_scripts/config.py @@ -6,7 +6,8 @@ import os from .log import log from pathlib import Path -from .versions import PYSIDE, PYSIDE_MODULE, SHIBOKEN +from . import PYSIDE, PYSIDE_MODULE, SHIBOKEN +from .utils import available_pyside_tools class Config(object): @@ -78,7 +79,8 @@ class Config(object): ext_modules=None, setup_script_dir=None, cmake_toolchain_file=None, - quiet=False): + quiet=False, + qt_install_path: Path = None): """ Sets up the global singleton config which is used in many parts of the setup process. @@ -199,11 +201,7 @@ class Config(object): setup_kwargs['install_requires'] = [ f"{self.shiboken_module_st_name}=={package_version}" ] - _pyside_tools = ["uic", "rcc", "assistant", "designer", "linguist", - "lupdate", "lrelease", "genpyi", "metaobjectdump", - "project", "qml", "qmltyperegistrar", "qmllint", "qmlformat", "qmlls", - "qtpy2cpp", "deploy", "qmlimportscanner"] - + _pyside_tools = available_pyside_tools(qt_tools_path=qt_install_path) setup_kwargs['entry_points'] = { 'console_scripts': [f'{PYSIDE}-{tool} = {package_name}.scripts.pyside_tool:{tool}' for tool in _pyside_tools] diff --git a/build_scripts/main.py b/build_scripts/main.py index f1a151caa..6decdb111 100644 --- a/build_scripts/main.py +++ b/build_scripts/main.py @@ -43,7 +43,7 @@ from .utils import (copydir, copyfile, detect_clang, filter_match, linux_fix_rpaths_for_library, macos_fix_rpaths_for_library, platform_cmake_options, remove_tree, run_process, run_process_output, update_env_path, which) -from .versions import PYSIDE, PYSIDE_MODULE, SHIBOKEN +from . import PYSIDE, PYSIDE_MODULE, SHIBOKEN from .wheel_override import get_bdist_wheel_override, wheel_module_exists from .wheel_utils import (get_package_timestamp, get_package_version, macos_plat_name, macos_pyside_min_deployment_target) diff --git a/build_scripts/platforms/linux.py b/build_scripts/platforms/linux.py index ab4acc274..d1de03730 100644 --- a/build_scripts/platforms/linux.py +++ b/build_scripts/platforms/linux.py @@ -8,7 +8,7 @@ from ..config import config from ..options import OPTION from ..utils import (copy_icu_libs, copydir, copyfile, find_files_using_glob, linux_patch_executable) -from ..versions import PYSIDE +from .. import PYSIDE def prepare_standalone_package_linux(pyside_build, _vars, cross_build=False): diff --git a/build_scripts/platforms/macos.py b/build_scripts/platforms/macos.py index a6423e1c1..dc54d559b 100644 --- a/build_scripts/platforms/macos.py +++ b/build_scripts/platforms/macos.py @@ -9,7 +9,7 @@ from ..config import config from ..options import OPTION from ..utils import (copydir, copyfile, macos_add_rpath, macos_fix_rpaths_for_library) -from ..versions import PYSIDE +from .. import PYSIDE def _macos_patch_executable(name, _vars=None): diff --git a/build_scripts/platforms/unix.py b/build_scripts/platforms/unix.py index f1bc5d2bc..0dd0917cc 100644 --- a/build_scripts/platforms/unix.py +++ b/build_scripts/platforms/unix.py @@ -8,7 +8,7 @@ import sys from ..config import config from ..options import OPTION from ..utils import copydir, copyfile, makefile -from ..versions import PYSIDE, SHIBOKEN +from .. import PYSIDE, SHIBOKEN from .linux import prepare_standalone_package_linux from .macos import prepare_standalone_package_macos diff --git a/build_scripts/platforms/windows_desktop.py b/build_scripts/platforms/windows_desktop.py index 4b5e15335..294913d96 100644 --- a/build_scripts/platforms/windows_desktop.py +++ b/build_scripts/platforms/windows_desktop.py @@ -11,7 +11,7 @@ from ..config import config from ..options import OPTION from ..utils import (copydir, copyfile, download_and_extract_7z, filter_match, makefile) -from ..versions import PYSIDE, SHIBOKEN +from .. import PYSIDE, SHIBOKEN def prepare_packages_win32(pyside_build, _vars): diff --git a/build_scripts/setup_runner.py b/build_scripts/setup_runner.py index ae5005f4a..73e986d5b 100644 --- a/build_scripts/setup_runner.py +++ b/build_scripts/setup_runner.py @@ -1,6 +1,7 @@ # 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 +import re import os import sys import tempfile @@ -14,7 +15,7 @@ from build_scripts.config import config from build_scripts.main import (cmd_class_dict, get_package_version, get_setuptools_extension_modules) from build_scripts.options import ADDITIONAL_OPTIONS, OPTION -from build_scripts.utils import run_process +from build_scripts.utils import run_process, find_qt_install_path from build_scripts.log import log @@ -175,6 +176,14 @@ class SetupRunner(object): # These files are generated anyway on their import. sys.dont_write_bytecode = True + # find qtpaths + arg_qt = list(filter(lambda v: v.startswith("--qtpaths"), sys.argv)) + if len(arg_qt) != 0: + qt_install_path = arg_qt[0].replace("--qtpaths=", "") + qt_install_path = Path(qt_install_path).absolute().parents[1] + else: + qt_install_path = find_qt_install_path() + # Prepare initial config. config.init_config(build_type=OPTION["BUILD_TYPE"], internal_build_type=OPTION["INTERNAL_BUILD_TYPE"], @@ -183,7 +192,8 @@ class SetupRunner(object): ext_modules=get_setuptools_extension_modules(), setup_script_dir=self.setup_script_dir, cmake_toolchain_file=OPTION["CMAKE_TOOLCHAIN_FILE"], - quiet=OPTION["QUIET"]) + quiet=OPTION["QUIET"], + qt_install_path=qt_install_path) # Enable logging for both the top-level invocation of setup.py # as well as for child invocations. We we now use diff --git a/build_scripts/utils.py b/build_scripts/utils.py index 0f5c2ef00..c7c4b5866 100644 --- a/build_scripts/utils.py +++ b/build_scripts/utils.py @@ -18,6 +18,8 @@ from pathlib import Path from textwrap import dedent, indent from .log import log +from . import (PYSIDE_PYTHON_TOOLS, PYSIDE_LINUX_BIN_TOOLS, PYSIDE_LINUX_LIBEXEC_TOOLS, + PYSIDE_WINDOWS_BIN_TOOLS) try: # Using the distutils implementation within setuptools @@ -34,6 +36,7 @@ try: except NameError: WindowsError = None + def which(name): """ Like shutil.which, but accepts a string or a PathLike and returns a Path @@ -50,6 +53,7 @@ def which(name): log.error(f"{name} was not found in PATH: {e}") return path + def is_64bit(): return sys.maxsize > 2147483647 @@ -1350,3 +1354,47 @@ def parse_cmake_project_message_info(output): value = found.group(3).strip() result[category][key] = str(value) return result + + +def available_pyside_tools(qt_tools_path: Path, package_for_wheels: bool = False): + pyside_tools = PYSIDE_PYTHON_TOOLS.copy() + lib_exec_path = qt_tools_path / "libexec" + + if package_for_wheels: + # Qt wrappers in build/{python_env_name}/package_for_wheels/PySide6 + bin_path = qt_tools_path + else: + bin_path = qt_tools_path / "bin" + + def tool_exist(tool_path: Path): + if tool_path.exists(): + return True + else: + log.warning(f"{tool_path} not found. pyside-{tool_path.name} not included.") + return False + + if sys.platform == 'win32': + pyside_tools.extend([tool for tool in PYSIDE_WINDOWS_BIN_TOOLS + if tool_exist(bin_path / f"{tool}.exe")]) + else: + pyside_tools.extend([tool for tool in PYSIDE_LINUX_LIBEXEC_TOOLS + if tool_exist(lib_exec_path / tool)]) + pyside_tools.extend([tool for tool in PYSIDE_LINUX_BIN_TOOLS + if tool_exist(bin_path / tool)]) + + return pyside_tools + + +def find_qt_install_path() -> Path: + """ + Find Qt installation path + """ + + def where_is(x): + return Path(which(x)) + + qtpaths = where_is("qtpaths") if where_is("qtpaths") else where_is("qtpaths6") + if not qtpaths: + raise RuntimeError("qtpaths not found") + else: + return qtpaths.parents[1] diff --git a/build_scripts/versions.py b/build_scripts/versions.py deleted file mode 100644 index 632838007..000000000 --- a/build_scripts/versions.py +++ /dev/null @@ -1,7 +0,0 @@ -# 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 - - -PYSIDE = 'pyside6' -PYSIDE_MODULE = 'PySide6' -SHIBOKEN = 'shiboken6' diff --git a/build_scripts/wheel_utils.py b/build_scripts/wheel_utils.py index a6ccebcdc..6e5c88afc 100644 --- a/build_scripts/wheel_utils.py +++ b/build_scripts/wheel_utils.py @@ -12,7 +12,7 @@ from setuptools.errors import SetupError from .options import OPTION from .qtinfo import QtInfo from .utils import memoize, parse_cmake_conf_assignments_by_key -from .versions import PYSIDE +from . import PYSIDE @memoize diff --git a/create_wheels.py b/create_wheels.py index 6b0f0887d..53e04607a 100644 --- a/create_wheels.py +++ b/create_wheels.py @@ -15,6 +15,7 @@ import build # type: ignore from build_scripts.wheel_files import (ModuleData, # type: ignore wheel_files_pyside_addons, wheel_files_pyside_essentials) +from build_scripts.utils import available_pyside_tools @dataclass @@ -187,32 +188,16 @@ def wheel_shiboken_module() -> Tuple[SetupData, None]: return setup, None -def wheel_pyside6_essentials() -> Tuple[SetupData, List[ModuleData]]: +def wheel_pyside6_essentials(packaged_qt_tools_path: Path) -> Tuple[SetupData, List[ModuleData]]: + _pyside_tools = available_pyside_tools(packaged_qt_tools_path, package_for_wheels=True) + _console_scripts = [f"pyside6-{tool} = PySide6.scripts.pyside_tool:{tool}" + for tool in _pyside_tools] setup = SetupData( name="PySide6_Essentials", version=get_version_from_package("PySide6"), # we use 'PySide6' here description="Python bindings for the Qt cross-platform application and UI framework (Essentials)", long_description="README.pyside6_essentials.md", - console_scripts=[ - "pyside6-uic = PySide6.scripts.pyside_tool:uic", - "pyside6-rcc = PySide6.scripts.pyside_tool:rcc", - "pyside6-assistant = PySide6.scripts.pyside_tool:assistant", - "pyside6-designer= PySide6.scripts.pyside_tool:designer", - "pyside6-linguist = PySide6.scripts.pyside_tool:linguist", - "pyside6-lupdate = PySide6.scripts.pyside_tool:lupdate", - "pyside6-lrelease = PySide6.scripts.pyside_tool:lrelease", - "pyside6-genpyi = PySide6.scripts.pyside_tool:genpyi", - "pyside6-metaobjectdump = PySide6.scripts.pyside_tool:metaobjectdump", - "pyside6-project = PySide6.scripts.pyside_tool:project", - "pyside6-qmltyperegistrar = PySide6.scripts.pyside_tool:qmltyperegistrar", - "pyside6-qmlimportscanner = PySide6.scripts.pyside_tool:qmlimportscanner", - "pyside6-qmllint = PySide6.scripts.pyside_tool:qmllint", - "pyside6-qml = PySide6.scripts.pyside_tool:qml", - "pyside6-qmlformat = PySide6.scripts.pyside_tool:qmlformat", - "pyside6-qmlls = PySide6.scripts.pyside_tool:qmlls", - "pyside6-qtpy2cpp = PySide6.scripts.pyside_tool:qtpy2cpp", - "pyside6-deploy = PySide6.scripts.pyside_tool:deploy" - ], + console_scripts=_console_scripts ) data = wheel_files_pyside_essentials() @@ -319,7 +304,8 @@ if __name__ == "__main__": for name, wheel_info in wheels.items(): print(f"Starting process for: {name}") - setup, data = wheel_info() + setup, data = wheel_info() if not name=="PySide6_Essentials" else \ + wheel_pyside6_essentials(package_path / "PySide6") # 1. Generate 'setup.cfg' print("-- Generating setup.cfg") diff --git a/sources/pyside-tools/CMakeLists.txt b/sources/pyside-tools/CMakeLists.txt index 87c33926c..0853b9ed4 100644 --- a/sources/pyside-tools/CMakeLists.txt +++ b/sources/pyside-tools/CMakeLists.txt @@ -43,12 +43,16 @@ list(APPEND directories ${CMAKE_CURRENT_SOURCE_DIR}/qtpy2cpp_lib) # pyside6-rcc, pyside6-uic, pyside6-designer, shiboken and pyside6-lupdate entrypoints foreach(file ${files}) - install(FILES "${file}" - DESTINATION bin - PERMISSIONS - OWNER_EXECUTE OWNER_WRITE OWNER_READ - GROUP_EXECUTE GROUP_READ - WORLD_EXECUTE WORLD_READ) + if(EXISTS ${file}) + install(FILES "${file}" + DESTINATION bin + PERMISSIONS + OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) + else() + message(WARNING "${file} does not exist. Hence, pyside6-${file} will not work") + endif() endforeach() foreach(directory ${directories}) diff --git a/sources/pyside-tools/pyside_tool.py b/sources/pyside-tools/pyside_tool.py index a70f26d24..8e4d1aac7 100644 --- a/sources/pyside-tools/pyside_tool.py +++ b/sources/pyside-tools/pyside_tool.py @@ -29,6 +29,7 @@ def qt_tool_wrapper(qt_tool, args, libexec=False): exe = pyside_dir / 'Qt' / 'libexec' / qt_tool else: exe = pyside_dir / qt_tool + cmd = [os.fspath(exe)] + args proc = Popen(cmd, stderr=PIPE) out, err = proc.communicate() @@ -39,6 +40,7 @@ def qt_tool_wrapper(qt_tool, args, libexec=False): sys.exit(proc.returncode) + def pyside_script_wrapper(script_name): """Launch a script shipped with PySide.""" script = Path(__file__).resolve().parent / script_name |
