From 6cbcaae4ae36912a7812e9c3930bbb2434bbf736 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 5 Oct 2020 09:55:05 +0200 Subject: setup.py: Fix check for limited API Check for "yes"/"no", consistently. Task-number: PYSIDE-807 Change-Id: Id9f2ba125acb9ea8e811fd6cb5994bbb070605de Reviewed-by: Cristian Maureira-Fredes --- build_scripts/main.py | 2 +- build_scripts/wheel_override.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'build_scripts') diff --git a/build_scripts/main.py b/build_scripts/main.py index 73e667839..cec822d7c 100644 --- a/build_scripts/main.py +++ b/build_scripts/main.py @@ -95,7 +95,7 @@ def get_setuptools_extension_modules(): # future. extension_args = ('QtCore', []) extension_kwargs = {} - if OPTION["LIMITED_API"]: + if OPTION["LIMITED_API"] == 'yes': extension_kwargs['py_limited_api'] = True extension_modules = [Extension(*extension_args, **extension_kwargs)] return extension_modules diff --git a/build_scripts/wheel_override.py b/build_scripts/wheel_override.py index 298287429..0a3cb0dbf 100644 --- a/build_scripts/wheel_override.py +++ b/build_scripts/wheel_override.py @@ -87,7 +87,8 @@ class PysideBuildWheel(_bdist_wheel): # When limited API is requested, notify bdist_wheel to # create a properly named package. - limited_api_enabled = OPTION["LIMITED_API"] and sys.version_info[0] >= 3 + limited_api_enabled = (OPTION["LIMITED_API"] == 'yes' + and sys.version_info[0] >= 3) if limited_api_enabled: self.py_limited_api = "cp35.cp36.cp37.cp38.cp39" -- cgit v1.2.3 From 776789ef3ccaf4b09fcc02754c6725379ce45651 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 5 Oct 2020 10:57:21 +0200 Subject: setup.py: Make it possible to access QtInfo from several sources - Turn it into a singleton. - Move the qtchooser resolving code into QtInfo. - Delay-initialize the dictionary. Task-number: PYSIDE-807 Change-Id: I3be2f3d0e0e9bc8aa61e1ec90ea37f7078c7f0bb Reviewed-by: Cristian Maureira-Fredes --- build_scripts/main.py | 21 +-- build_scripts/qtinfo.py | 391 +++++++++++++++++++++++++----------------------- 2 files changed, 212 insertions(+), 200 deletions(-) (limited to 'build_scripts') diff --git a/build_scripts/main.py b/build_scripts/main.py index cec822d7c..84f839b78 100644 --- a/build_scripts/main.py +++ b/build_scripts/main.py @@ -180,23 +180,13 @@ if OPTION["QMAKE"] is not None and os.path.exists(OPTION["QMAKE"]): if OPTION["CMAKE"] is not None and os.path.exists(OPTION["CMAKE"]): OPTION["CMAKE"] = os.path.abspath(OPTION["CMAKE"]) -QMAKE_COMMAND = None -# Checking whether qmake executable exists -if OPTION["QMAKE"] is not None and os.path.exists(OPTION["QMAKE"]): - # Looking whether qmake path is a link and whether the link exists - if os.path.islink(OPTION["QMAKE"]) and os.path.lexists(OPTION["QMAKE"]): - # Set -qt=X here. - if "qtchooser" in os.readlink(OPTION["QMAKE"]): - QMAKE_COMMAND = [OPTION["QMAKE"], "-qt={}".format(OPTION["QT_VERSION"])] -if not QMAKE_COMMAND: - QMAKE_COMMAND = [OPTION["QMAKE"]] - -if len(QMAKE_COMMAND) == 0 or QMAKE_COMMAND[0] is None: +if len(OPTION["QMAKE"]) == 0: print("qmake could not be found.") sys.exit(1) -if not os.path.exists(QMAKE_COMMAND[0]): - print("'{}' does not exist.".format(QMAKE_COMMAND[0])) +if not os.path.exists(OPTION["QMAKE"]): + print("'{}' does not exist.".format(OPTION["QMAKE"])) sys.exit(1) + if OPTION["CMAKE"] is None: OPTION["CMAKE"] = find_executable("cmake") @@ -289,7 +279,8 @@ def prepare_sub_modules(): # Single global instance of QtInfo to be used later in multiple code # paths. -qtinfo = QtInfo(QMAKE_COMMAND) +qtinfo = QtInfo() +qtinfo.setup(OPTION["QMAKE"], OPTION["QT_VERSION"]) def get_qt_version(): diff --git a/build_scripts/qtinfo.py b/build_scripts/qtinfo.py index 4dc976360..fa2d771b2 100644 --- a/build_scripts/qtinfo.py +++ b/build_scripts/qtinfo.py @@ -41,201 +41,222 @@ import os import sys import re import subprocess -from distutils.spawn import find_executable -class QtInfo(object): - def __init__(self, qmake_command=None): - self.initialized = False - - if qmake_command: - self._qmake_command = qmake_command - else: - self._qmake_command = [find_executable("qmake"), ] - - # Dict to cache qmake values. - self._query_dict = {} - # Dict to cache mkspecs variables. - self._mkspecs_dict = {} - # Initialize the properties. - self._init_properties() - - def get_qmake_command(self): - qmake_command_string = self._qmake_command[0] - for entry in self._qmake_command[1:]: - qmake_command_string += " {}".format(entry) - return qmake_command_string - - def get_version(self): - return self.get_property("QT_VERSION") - - def get_bins_path(self): - return self.get_property("QT_INSTALL_BINS") - - def get_libs_path(self): - return self.get_property("QT_INSTALL_LIBS") +def _effective_qmake_command(qmake, qt_version): + """Check whether qmake path is a link to qtchooser and append the + desired Qt version in that case""" + result = [qmake] + # Looking whether qmake path is a link to qtchooser and whether the link + # exists + if os.path.islink(qmake) and os.path.lexists(qmake): + if not qt_version: + print('--qt must be specified when using qtchooser.') + sys.exit(-1) + # Set -qt=X here. + if "qtchooser" in os.readlink(qmake): + result.append("-qt={}".format(qt_version)) + return result - def get_libs_execs_path(self): - return self.get_property("QT_INSTALL_LIBEXECS") - def get_plugins_path(self): - return self.get_property("QT_INSTALL_PLUGINS") - - def get_prefix_path(self): - return self.get_property("QT_INSTALL_PREFIX") - - def get_imports_path(self): - return self.get_property("QT_INSTALL_IMPORTS") - - def get_translations_path(self): - return self.get_property("QT_INSTALL_TRANSLATIONS") +class QtInfo(object): + class __QtInfo: # Python singleton + def __init__(self): + self._qmake_command = None + # Dict to cache qmake values. + self._query_dict = {} + # Dict to cache mkspecs variables. + self._mkspecs_dict = {} + + def setup(self, qmake, qt_version): + self._qmake_command = _effective_qmake_command(qmake, qt_version) + + def get_qmake_command(self): + qmake_command_string = self._qmake_command[0] + for entry in self._qmake_command[1:]: + qmake_command_string += " {}".format(entry) + return qmake_command_string + + def get_version(self): + return self.get_property("QT_VERSION") + + def get_bins_path(self): + return self.get_property("QT_INSTALL_BINS") + + def get_libs_path(self): + return self.get_property("QT_INSTALL_LIBS") + + def get_libs_execs_path(self): + return self.get_property("QT_INSTALL_LIBEXECS") + + def get_plugins_path(self): + return self.get_property("QT_INSTALL_PLUGINS") + + def get_prefix_path(self): + return self.get_property("QT_INSTALL_PREFIX") + + def get_imports_path(self): + return self.get_property("QT_INSTALL_IMPORTS") + + def get_translations_path(self): + return self.get_property("QT_INSTALL_TRANSLATIONS") + + def get_headers_path(self): + return self.get_property("QT_INSTALL_HEADERS") + + def get_docs_path(self): + return self.get_property("QT_INSTALL_DOCS") + + def get_qml_path(self): + return self.get_property("QT_INSTALL_QML") + + def get_macos_deployment_target(self): + """ Return value is a macOS version or None. """ + return self.get_property("QMAKE_MACOSX_DEPLOYMENT_TARGET") + + def get_build_type(self): + """ + Return value is either debug, release, debug_release, or None. + """ + return self.get_property("BUILD_TYPE") + + def get_src_dir(self): + """ Return path to Qt src dir or None.. """ + return self.get_property("QT_INSTALL_PREFIX/src") + + def get_property(self, prop_name): + if not self._query_dict: + self._get_query_properties() + self._get_other_properties() + if prop_name not in self._query_dict: + return None + return self._query_dict[prop_name] + + def get_mkspecs_variables(self): + return self._mkspecs_dict + + def _get_qmake_output(self, args_list=[]): + assert(self._qmake_command) + cmd = self._qmake_command + args_list + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=False) + output = proc.communicate()[0] + proc.wait() + if proc.returncode != 0: + return "" + if sys.version_info >= (3,): + output = str(output, 'ascii').strip() + else: + output = output.strip() + return output + + def _parse_query_properties(self, process_output): + props = {} + if not process_output: + return props + lines = [s.strip() for s in process_output.splitlines()] + for line in lines: + if line and ':' in line: + key, value = line.split(':', 1) + props[key] = value + return props - def get_headers_path(self): - return self.get_property("QT_INSTALL_HEADERS") + def _get_query_properties(self): + output = self._get_qmake_output(['-query']) + self._query_dict = self._parse_query_properties(output) - def get_docs_path(self): - return self.get_property("QT_INSTALL_DOCS") + def _parse_qt_build_type(self): + key = 'QT_CONFIG' + if key not in self._mkspecs_dict: + return None - def get_qml_path(self): - return self.get_property("QT_INSTALL_QML") + qt_config = self._mkspecs_dict[key] + if 'debug_and_release' in qt_config: + return 'debug_and_release' - def get_macos_deployment_target(self): - """ Return value is a macOS version or None. """ - return self.get_property("QMAKE_MACOSX_DEPLOYMENT_TARGET") + split = qt_config.split(' ') + if 'release' in split and 'debug' in split: + return 'debug_and_release' - def get_build_type(self): - """ - Return value is either debug, release, debug_release, or None. - """ - return self.get_property("BUILD_TYPE") + if 'release' in split: + return 'release' - def get_src_dir(self): - """ Return path to Qt src dir or None.. """ - return self.get_property("QT_INSTALL_PREFIX/src") + if 'debug' in split: + return 'debug' - def get_property(self, prop_name): - if prop_name not in self._query_dict: - return None - return self._query_dict[prop_name] - - def get_properties(self): - return self._query_dict - - def get_mkspecs_variables(self): - return self._mkspecs_dict - - def _get_qmake_output(self, args_list=[]): - cmd = self._qmake_command + args_list - proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=False) - output = proc.communicate()[0] - proc.wait() - if proc.returncode != 0: - return "" - if sys.version_info >= (3,): - output = str(output, 'ascii').strip() - else: - output = output.strip() - return output - - def _parse_query_properties(self, process_output): - props = {} - if not process_output: - return props - lines = [s.strip() for s in process_output.splitlines()] - for line in lines: - if line and ':' in line: - key, value = line.split(':', 1) - props[key] = value - return props - - def _get_query_properties(self): - output = self._get_qmake_output(['-query']) - self._query_dict = self._parse_query_properties(output) - - def _parse_qt_build_type(self): - key = 'QT_CONFIG' - if key not in self._mkspecs_dict: return None - qt_config = self._mkspecs_dict[key] - if 'debug_and_release' in qt_config: - return 'debug_and_release' - - split = qt_config.split(' ') - if 'release' in split and 'debug' in split: - return 'debug_and_release' - - if 'release' in split: - return 'release' - - if 'debug' in split: - return 'debug' - - return None - - def _get_other_properties(self): - # Get the src property separately, because it is not returned by - # qmake unless explicitly specified. - key = 'QT_INSTALL_PREFIX/src' - result = self._get_qmake_output(['-query', key]) - self._query_dict[key] = result - - # Get mkspecs variables and cache them. - self._get_qmake_mkspecs_variables() - - # Get macOS minimum deployment target. - key = 'QMAKE_MACOSX_DEPLOYMENT_TARGET' - if key in self._mkspecs_dict: - self._query_dict[key] = self._mkspecs_dict[key] - - # Figure out how Qt was built: - # debug mode, release mode, or both. - build_type = self._parse_qt_build_type() - if build_type: - self._query_dict['BUILD_TYPE'] = build_type - - def _init_properties(self): - self._get_query_properties() - self._get_other_properties() - - def _get_qmake_mkspecs_variables(self): - # Create empty temporary qmake project file. - temp_file_name = 'qmake_fake_empty_project.txt' - open(temp_file_name, 'a').close() - - # Query qmake for all of its mkspecs variables. - qmake_output = self._get_qmake_output(['-E', temp_file_name]) - lines = [s.strip() for s in qmake_output.splitlines()] - pattern = re.compile(r"^(.+?)=(.+?)$") - for line in lines: - found = pattern.search(line) - if found: - key = found.group(1).strip() - value = found.group(2).strip() - self._mkspecs_dict[key] = value - - # We need to clean up after qmake, which always creates a - # .qmake.stash file after a -E invocation. - qmake_stash_file = os.path.join(os.getcwd(), ".qmake.stash") - if os.path.exists(qmake_stash_file): - os.remove(qmake_stash_file) - - # Also clean up the temporary empty project file. - if os.path.exists(temp_file_name): - os.remove(temp_file_name) - - version = property(get_version) - bins_dir = property(get_bins_path) - libs_dir = property(get_libs_path) - lib_execs_dir = property(get_libs_execs_path) - plugins_dir = property(get_plugins_path) - prefix_dir = property(get_prefix_path) - qmake_command = property(get_qmake_command) - imports_dir = property(get_imports_path) - translations_dir = property(get_translations_path) - headers_dir = property(get_headers_path) - docs_dir = property(get_docs_path) - qml_dir = property(get_qml_path) - macos_min_deployment_target = property(get_macos_deployment_target) - build_type = property(get_build_type) - src_dir = property(get_src_dir) + def _get_other_properties(self): + # Get the src property separately, because it is not returned by + # qmake unless explicitly specified. + key = 'QT_INSTALL_PREFIX/src' + result = self._get_qmake_output(['-query', key]) + self._query_dict[key] = result + + # Get mkspecs variables and cache them. + self._get_qmake_mkspecs_variables() + + # Get macOS minimum deployment target. + key = 'QMAKE_MACOSX_DEPLOYMENT_TARGET' + if key in self._mkspecs_dict: + self._query_dict[key] = self._mkspecs_dict[key] + + # Figure out how Qt was built: + # debug mode, release mode, or both. + build_type = self._parse_qt_build_type() + if build_type: + self._query_dict['BUILD_TYPE'] = build_type + + def _get_qmake_mkspecs_variables(self): + # Create empty temporary qmake project file. + temp_file_name = 'qmake_fake_empty_project.txt' + open(temp_file_name, 'a').close() + + # Query qmake for all of its mkspecs variables. + qmake_output = self._get_qmake_output(['-E', temp_file_name]) + lines = [s.strip() for s in qmake_output.splitlines()] + pattern = re.compile(r"^(.+?)=(.+?)$") + for line in lines: + found = pattern.search(line) + if found: + key = found.group(1).strip() + value = found.group(2).strip() + self._mkspecs_dict[key] = value + + # We need to clean up after qmake, which always creates a + # .qmake.stash file after a -E invocation. + qmake_stash_file = os.path.join(os.getcwd(), ".qmake.stash") + if os.path.exists(qmake_stash_file): + os.remove(qmake_stash_file) + + # Also clean up the temporary empty project file. + if os.path.exists(temp_file_name): + os.remove(temp_file_name) + + version = property(get_version) + bins_dir = property(get_bins_path) + libs_dir = property(get_libs_path) + lib_execs_dir = property(get_libs_execs_path) + plugins_dir = property(get_plugins_path) + prefix_dir = property(get_prefix_path) + qmake_command = property(get_qmake_command) + imports_dir = property(get_imports_path) + translations_dir = property(get_translations_path) + headers_dir = property(get_headers_path) + docs_dir = property(get_docs_path) + qml_dir = property(get_qml_path) + macos_min_deployment_target = property(get_macos_deployment_target) + build_type = property(get_build_type) + src_dir = property(get_src_dir) + + _instance = None # singleton helpers + + def __new__(cls): # __new__ always a classmethod + if not QtInfo._instance: + QtInfo._instance = QtInfo.__QtInfo() + return QtInfo._instance + + def __getattr__(self, name): + return getattr(self._instance, name) + + def __setattr__(self, name): + return setattr(self._instance, name) -- cgit v1.2.3 From d71a4489bcd404bfd3af3ed7938f4cc804e09626 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 6 Oct 2020 12:02:09 +0200 Subject: setup.py: Do not display help multiple times Run only the pyside build when help is requested. Task-number: PYSIDE-807 Change-Id: I0aa5bf2db0a6a7e6e32a66357efd200af70dd653 Reviewed-by: Cristian Maureira-Fredes --- build_scripts/setup_runner.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'build_scripts') diff --git a/build_scripts/setup_runner.py b/build_scripts/setup_runner.py index b5b55fa20..15a0bf380 100644 --- a/build_scripts/setup_runner.py +++ b/build_scripts/setup_runner.py @@ -131,7 +131,11 @@ class SetupRunner(object): .format(config.build_type)) # Build everything: shiboken2, shiboken2-generator and PySide2. - if config.is_top_level_build_all(): + help_requested = '--help' in self.sub_argv or '-h' in self.sub_argv + if help_requested: + self.add_setup_internal_invocation(config.pyside_option_name) + + elif config.is_top_level_build_all(): self.add_setup_internal_invocation(config.shiboken_module_option_name) # Reuse the shiboken build for the generator package instead -- cgit v1.2.3