Skip to content

Commit 03a3e61

Browse files
committed
build: improve the build configuration implementation
- Using Singleton for the class - Adding type hints for the Path variables - Use function for parsing modules instead of duplicating it - Adapting related code in other files as well - Remove historical prints when configuring. Pick-to: 6.8 Change-Id: I9fef2e8d7c2033442f89a6f6ca027b5ae2ac6ab4 Reviewed-by: Friedemann Kleint <[email protected]>
1 parent b513d1e commit 03a3e61

File tree

6 files changed

+62
-82
lines changed

6 files changed

+62
-82
lines changed

build_scripts/config.py

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,22 @@
22
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
33
from __future__ import annotations
44

5+
import os
56
import sys
6-
from .log import log, LogLevel
77
from pathlib import Path
8+
from typing import Any
89

9-
from . import PYSIDE, PYSIDE_MODULE, SHIBOKEN, PYPROJECT_PATH
10-
from .utils import available_pyside_tools
10+
from . import PYPROJECT_PATH, PYSIDE, PYSIDE_MODULE, SHIBOKEN
11+
from .log import LogLevel, log
12+
from .utils import available_pyside_tools, Singleton
1113

1214
try:
1315
import tomllib
1416
except ModuleNotFoundError:
1517
import tomli as tomllib
1618

1719

18-
class Config(object):
20+
class Config(object, metaclass=Singleton):
1921
def __init__(self):
2022
# Constants
2123
self._build_type_all = "all"
@@ -28,19 +30,19 @@ def __init__(self):
2830
# The setup.py invocation type.
2931
# top-level
3032
# internal
31-
self.invocation_type = None
33+
self.invocation_type: str = ""
3234

3335
# The type of the top-level build.
3436
# all - build shiboken6 module, shiboken6-generator and PySide6
3537
# modules
3638
# shiboken6 - build only shiboken6 module
3739
# shiboken6-generator - build only the shiboken6-generator
3840
# pyside6 - build only PySide6 modules
39-
self.build_type = None
41+
self.build_type: str = ""
4042

4143
# The internal build type, used for internal invocations of
4244
# setup.py to build a specific module only.
43-
self.internal_build_type = None
45+
self.internal_build_type: str = ""
4446

4547
# Options that can be given to --build-type and
4648
# --internal-build-type
@@ -51,18 +53,18 @@ def __init__(self):
5153
# Names to be passed to setuptools.setup() name key,
5254
# so not package name, but rather project name as it appears
5355
# in the wheel name and on PyPi.
54-
self.shiboken_module_st_name = SHIBOKEN
55-
self.shiboken_generator_st_name = f"{SHIBOKEN}-generator"
56-
self.pyside_st_name = PYSIDE_MODULE
56+
self.shiboken_module_st_name: str = SHIBOKEN
57+
self.shiboken_generator_st_name: str = f"{SHIBOKEN}-generator"
58+
self.pyside_st_name: str = PYSIDE_MODULE
5759

5860
# Path to CMake toolchain file when intending to cross compile
5961
# the project.
60-
self.cmake_toolchain_file = None
62+
self.cmake_toolchain_file: str | os.PathLike = ""
6163

6264
# Store where host shiboken is built during a cross-build.
63-
self.shiboken_host_query_path = None
65+
self.shiboken_host_query_path: str = ""
6466

65-
self.setup_script_dir = None
67+
self.setup_script_dir: str | os.PathLike = ""
6668

6769
# Getting data from base pyproject.toml file to be consistent
6870

@@ -72,7 +74,7 @@ def __init__(self):
7274
with open(PYPROJECT_PATH, "rb") as f:
7375
_pyproject_data = tomllib.load(f)["project"]
7476

75-
self.setup_kwargs = {}
77+
self.setup_kwargs: dict[str, Any] = {}
7678
self.setup_kwargs['long_description_content_type'] = 'text/markdown'
7779

7880
self.setup_kwargs['keywords'] = _pyproject_data["keywords"]
@@ -87,15 +89,15 @@ def __init__(self):
8789
self.setup_kwargs['classifiers'] = self.classifiers
8890

8991
def init_config(self,
90-
build_type=None,
91-
internal_build_type=None,
92+
build_type="",
93+
internal_build_type="",
9294
cmd_class_dict=None,
9395
package_version=None,
9496
ext_modules=None,
95-
setup_script_dir=None,
96-
cmake_toolchain_file=None,
97+
setup_script_dir: str | os.PathLike = "",
98+
cmake_toolchain_file: str | os.PathLike = "",
9799
log_level=LogLevel.INFO,
98-
qt_install_path: Path = None):
100+
qt_install_dir: str | os.PathLike = ""):
99101
"""
100102
Sets up the global singleton config which is used in many parts
101103
of the setup process.
@@ -182,8 +184,8 @@ def init_config(self,
182184
self.setup_kwargs['install_requires'] = [
183185
f"{self.shiboken_module_st_name}=={package_version}"
184186
]
185-
if qt_install_path:
186-
_pyside_tools = available_pyside_tools(qt_tools_path=qt_install_path)
187+
if qt_install_dir:
188+
_pyside_tools = available_pyside_tools(qt_tools_path=Path(qt_install_dir))
187189

188190
# replacing pyside6-android_deploy by pyside6-android-deploy for consistency
189191
# Also, the tool should not exist in any other platform than Linux and macOS
@@ -209,31 +211,23 @@ def get_long_description(self):
209211
elif self.is_internal_pyside_build():
210212
readme_filename = f'README.{PYSIDE}.md'
211213

212-
content = ''
213-
changes = ''
214-
try:
215-
with open(self.setup_script_dir / readme_filename) as f:
216-
readme = f.read()
217-
except Exception as e:
218-
log.error(f"Couldn't read contents of {readme_filename}. {e}")
219-
raise
214+
with open(Path(self.setup_script_dir) / readme_filename) as f:
215+
readme = f.read()
220216

221217
# Don't include CHANGES.rst for now, because we have not decided
222218
# how to handle change files yet.
223219
include_changes = False
224220
if include_changes:
225221
try:
226-
with open(self.setup_script_dir / changes_filename) as f:
222+
changes = ''
223+
with open(Path(self.setup_script_dir) / changes_filename) as f:
227224
changes = f.read()
228225
except Exception as e:
229226
log.error(f"Couldn't read contents of {changes_filename}. {e}")
230227
raise
231-
content += readme
232-
233-
if changes:
234-
content += f"\n\n{changes}"
228+
return f"{readme}\n\n{changes}"
235229

236-
return content
230+
return readme
237231

238232
def package_name(self):
239233
"""

build_scripts/main.py

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from packaging.version import parse as parse_version
1414
from pathlib import Path
1515
from shutil import copytree, rmtree
16-
from textwrap import dedent
1716

1817
# PYSIDE-1760: Pre-load setuptools modules early to avoid racing conditions.
1918
# may be touched (should be avoided anyway, btw.)
@@ -40,7 +39,7 @@
4039
from .qtinfo import QtInfo
4140
from .utils import (copydir, copyfile, detect_clang,
4241
get_numpy_location, get_python_dict,
43-
linux_fix_rpaths_for_library, macos_fix_rpaths_for_library,
42+
linux_fix_rpaths_for_library, macos_fix_rpaths_for_library, parse_modules,
4443
platform_cmake_options, remove_tree, run_process,
4544
run_process_output, update_env_path, which)
4645
from . import PYSIDE, PYSIDE_MODULE, SHIBOKEN
@@ -490,27 +489,13 @@ def log_pre_build_info(self):
490489
log.info(f"Make generator: {self.make_generator}")
491490
log.info(f"Make jobs: {OPTION['JOBS']}")
492491
log.info("-" * 3)
493-
log.info(f"setup.py directory: {self.script_dir}")
494-
log.info(f"Build scripts directory: {build_scripts_dir}")
495-
log.info(f"Sources directory: {self.sources_dir}")
496-
log.info(dedent(f"""
497-
Building {config.package_name()} will create and touch directories
498-
in the following order:
499-
make build directory ->
500-
make install directory ->
501-
setuptools build directory ->
502-
setuptools install directory
503-
(usually path-installed-python/lib/python*/site-packages/*)
504-
"""))
492+
log.info(f"setup.py directory: {self.script_dir}")
493+
log.info(f"Build scripts directory: {build_scripts_dir}")
494+
log.info(f"Sources directory: {self.sources_dir}")
505495
log.info(f"make build directory: {self.build_dir}")
506496
log.info(f"make install directory: {self.install_dir}")
507497
log.info(f"setuptools build directory: {self.st_build_dir}")
508498
log.info(f"setuptools install directory: {setuptools_install_prefix}")
509-
log.info(dedent(f"""
510-
make-installed site-packages directory: {self.site_packages_dir}
511-
(only relevant for copying files from 'make install directory'
512-
to 'setuptools build directory'
513-
"""))
514499
log.info("-" * 3)
515500
log.info(f"Python executable: {self.py_executable}")
516501
log.info(f"Python includes: {self.py_include_dir}")
@@ -662,24 +647,11 @@ def build_extension(self, extension):
662647
f"Path given: {config_dir}")
663648

664649
if OPTION["MODULE_SUBSET"]:
665-
module_sub_set = ''
666-
for m in OPTION["MODULE_SUBSET"].split(','):
667-
if m.startswith('Qt'):
668-
m = m[2:]
669-
if module_sub_set:
670-
module_sub_set += ';'
671-
module_sub_set += m
672-
cmake_cmd.append(f"-DMODULES={module_sub_set}")
650+
cmake_cmd.append(f"-DMODULES={parse_modules(OPTION['MODULE_SUBSET'])}")
673651

674652
if OPTION["SKIP_MODULES"]:
675-
skip_modules = ''
676-
for m in OPTION["SKIP_MODULES"].split(','):
677-
if m.startswith('Qt'):
678-
m = m[2:]
679-
if skip_modules:
680-
skip_modules += ';'
681-
skip_modules += m
682-
cmake_cmd.append(f"-DSKIP_MODULES={skip_modules}")
653+
cmake_cmd.append(f"-DSKIP_MODULES={parse_modules(OPTION['SKIP_MODULES'])}")
654+
683655
# Add source location for generating documentation
684656
cmake_src_dir = OPTION["QT_SRC"] if OPTION["QT_SRC"] else qt_src_dir
685657
if cmake_src_dir:
@@ -715,17 +687,20 @@ def build_extension(self, extension):
715687
if OPTION['NO_OVERRIDE_OPTIMIZATION_FLAGS']:
716688
cmake_cmd.append("-DQFP_NO_OVERRIDE_OPTIMIZATION_FLAGS=1")
717689

718-
if OPTION["LIMITED_API"] == "yes":
719-
cmake_cmd.append("-DFORCE_LIMITED_API=yes")
720-
elif OPTION["LIMITED_API"] == "no":
721-
cmake_cmd.append("-DFORCE_LIMITED_API=no")
722-
elif not OPTION["LIMITED_API"]:
690+
if not OPTION["LIMITED_API"]:
723691
if sys.platform == 'win32' and self.debug:
724692
cmake_cmd.append("-DFORCE_LIMITED_API=no")
725693
else:
726-
raise SetupError("option limited-api must be 'yes' or 'no' "
727-
"(default yes if applicable, i.e. Python "
728-
"version >= 3.9 and release build if on Windows)")
694+
if OPTION["LIMITED_API"].lower() in ("yes", "y", "1", "true"):
695+
cmake_cmd.append("-DFORCE_LIMITED_API=yes")
696+
elif OPTION["LIMITED_API"].lower() in ("no", "n", "0", "false"):
697+
cmake_cmd.append("-DFORCE_LIMITED_API=no")
698+
else:
699+
raise SetupError(
700+
"Option '--limited-api' must be 'yes' or 'no'."
701+
f"Default is yes if Python version >= {get_allowed_python_versions()[0]} "
702+
"and Release build on Windows"
703+
)
729704

730705
if OPTION["DISABLE_PYI"]:
731706
cmake_cmd.append("-DDISABLE_PYI=yes")

build_scripts/options.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ def __init__(self):
307307
self.shiboken_target_path = None
308308
self.python_target_path = None
309309
self.is_cross_compile = False
310-
self.cmake_toolchain_file = None
310+
self.cmake_toolchain_file: str = ""
311311
self.make_spec = None
312312
self.macos_arch = None
313313
self.macos_sysroot = None
@@ -379,7 +379,7 @@ def _do_finalize(self):
379379
# because we DON'T want those to be found when cross compiling.
380380
# Currently when cross compiling, qt-target-path MUST be used.
381381
using_cmake_toolchain_file = False
382-
cmake_toolchain_file = None
382+
cmake_toolchain_file: str = ""
383383
if OPTION["CMAKE_TOOLCHAIN_FILE"]:
384384
self.is_cross_compile = True
385385
using_cmake_toolchain_file = True

build_scripts/qtinfo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self):
3232
self._force_qmake = False
3333
self._use_cmake = False
3434
self._qt_target_path = None
35-
self._cmake_toolchain_file = None
35+
self._cmake_toolchain_file: str = ""
3636
# Dict to cache qmake values.
3737
self._query_dict = {}
3838

build_scripts/setup_runner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ def run_setup(self):
188188
setup_script_dir=self.setup_script_dir,
189189
cmake_toolchain_file=OPTION["CMAKE_TOOLCHAIN_FILE"],
190190
log_level=OPTION["LOG_LEVEL"],
191-
qt_install_path=qt_install_path)
191+
qt_install_dir=qt_install_path)
192192

193193
# Enable logging for both the top-level invocation of setup.py
194194
# as well as for child invocations. We we now use

build_scripts/utils.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,3 +1125,14 @@ def copy_qt_metatypes(destination_qt_dir, _vars):
11251125

11261126
def in_coin():
11271127
return os.environ.get('COIN_LAUNCH_PARAMETERS', None) is not None
1128+
1129+
1130+
def parse_modules(modules: str) -> str:
1131+
module_sub_set = ""
1132+
for m in modules.split(','):
1133+
if m.startswith('Qt'):
1134+
m = m[2:]
1135+
if module_sub_set:
1136+
module_sub_set += ';'
1137+
module_sub_set += m
1138+
return module_sub_set

0 commit comments

Comments
 (0)