summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCristian Maureira-Fredes <[email protected]>2019-09-17 00:11:17 +0200
committerCristian Maureira-Fredes <[email protected]>2019-09-18 12:00:26 +0000
commit91634c3c9b8d4f68f0ebd2ac76a8b5b79e4b4c94 (patch)
treedc1913a6a30f886813901f9584221c1f37fa3c22
parentc1cf305be0f1f529b96a06dc70ce5ee7273006ef (diff)
Improve styling of util/cmake scripts
flake8 was used to evaluate the file, with a couple of exeptions: E501,E266,W503 black was used to reformat the code automatically The changes were: * Added a README that explains how to use pipenv and pip, * Remove unnecessary return statements, * Remove '\' from the end of the lines, * Use f-strings (>= 3.6) since we are requiring Python 3.7, * Commenting unused variables, * Adding assert when Python >= 3.7 is not being used, * Wrapping long lines to 100 (Qt Style), * Re-factoring some lines, * Re-ordering imports, * Naming `except` for sympy (SympifyError, TypeError) Change-Id: Ie05f754e7d8ee4bf427117c58e0eb1b903202933 Reviewed-by: Alexandru Croitor <[email protected]>
-rw-r--r--util/cmake/README.md54
-rwxr-xr-xutil/cmake/cmakeconversionrate.py84
-rwxr-xr-xutil/cmake/configurejson2cmake.py955
-rw-r--r--util/cmake/helper.py795
-rw-r--r--util/cmake/json_parser.py31
-rwxr-xr-xutil/cmake/pro2cmake.py2517
-rwxr-xr-xutil/cmake/pro_conversion_rate.py86
-rw-r--r--util/cmake/requirements.txt4
-rwxr-xr-xutil/cmake/run_pro2cmake.py109
-rw-r--r--util/cmake/special_case_helper.py165
10 files changed, 2752 insertions, 2048 deletions
diff --git a/util/cmake/README.md b/util/cmake/README.md
new file mode 100644
index 00000000000..e1699d52832
--- /dev/null
+++ b/util/cmake/README.md
@@ -0,0 +1,54 @@
+# CMake Utils
+
+This directory holds scripts to help the porting process from `qmake` to `cmake` for Qt6.
+
+# Requirements
+
+* [Python 3.7](https://www.python.org/downloads/),
+* `pipenv` or `pip` to manage the modules.
+
+## Python modules
+
+Since Python has many ways of handling projects, you have a couple of options to
+install the dependencies of the scripts:
+
+### Using `pipenv`
+
+The dependencies are specified on the `Pipfile`, so you just need to run
+`pipenv install` and that will automatically create a virtual environment
+that you can activate with a `pipenv shell`.
+
+### Using `pip`
+
+It's highly recommended to use a [virtualenvironment](https://virtualenv.pypa.io/en/latest/)
+to avoid conflict with other packages that are already installed: `pip install virtualenv`.
+
+* Create an environment: `virtualenv env`,
+* Activate the environment: `source env/bin/activate`
+ (on Windows: `source env\Scripts\activate.bat`)
+* Install the requirements: `pip install -r requirements.txt`
+
+# Contributing to the scripts
+
+You can verify if the styling of a script complaint with PEP8, with a couple of exceptions:
+
+Install [flake8](http://flake8.pycqa.org/en/latest/) (`pip install flake8`) and run it
+on the script you want to test:
+
+```
+flake8 <file>.py --ignore=E501,E266,W503
+```
+
+* `E501`: Line too long (82>79 characters),
+* `E266`: Too many leading '#' for block comment,
+* `W503`: Line break occurred before a binary operator)
+
+You can also modify the file with an automatic formatter,
+like [black](https://black.readthedocs.io/en/stable/) (`pip install black`),
+and execute it:
+
+```
+black -l 100 <file>.py
+```
+
+Using Qt's maximum line length, 100.
diff --git a/util/cmake/cmakeconversionrate.py b/util/cmake/cmakeconversionrate.py
index 3496ed1b91d..b87957df6c4 100755
--- a/util/cmake/cmakeconversionrate.py
+++ b/util/cmake/cmakeconversionrate.py
@@ -32,27 +32,37 @@ from argparse import ArgumentParser
import os
import re
import subprocess
-import sys
import typing
def _parse_commandline():
- parser = ArgumentParser(description='Calculate the conversion rate to cmake.')
- parser.add_argument('--debug', dest='debug', action='store_true',
- help='Turn on debug output')
- parser.add_argument('source_directory', metavar='<Source Directory>', type=str,
- help='The Qt module source directory')
- parser.add_argument('binary_directory', metavar='<CMake build direcotry>', type=str,
- help='The CMake build directory (might be empty)')
+ parser = ArgumentParser(description="Calculate the conversion rate to cmake.")
+ parser.add_argument("--debug", dest="debug", action="store_true", help="Turn on debug output")
+ parser.add_argument(
+ "source_directory",
+ metavar="<Source Directory>",
+ type=str,
+ help="The Qt module source directory",
+ )
+ parser.add_argument(
+ "binary_directory",
+ metavar="<CMake build direcotry>",
+ type=str,
+ help="The CMake build directory (might be empty)",
+ )
return parser.parse_args()
-def calculate_baseline(source_directory: str, *, debug: bool=False) -> int:
+def calculate_baseline(source_directory: str, *, debug: bool = False) -> int:
if debug:
- print('Scanning "{}" for qmake-based tests.'.format(source_directory))
- result = subprocess.run('/usr/bin/git grep -E "^\\s*CONFIG\\s*\\+?=.*\\btestcase\\b" | sort -u | wc -l',
- shell=True, capture_output=True, cwd=source_directory)
+ print(f'Scanning "{source_directory}" for qmake-based tests.')
+ result = subprocess.run(
+ '/usr/bin/git grep -E "^\\s*CONFIG\\s*\\+?=.*\\btestcase\\b" | sort -u | wc -l',
+ shell=True,
+ capture_output=True,
+ cwd=source_directory,
+ )
return int(result.stdout)
@@ -60,41 +70,45 @@ def build(source_directory: str, binary_directory: str, *, debug=False) -> None:
abs_source = os.path.abspath(source_directory)
if not os.path.isdir(binary_directory):
os.makedirs(binary_directory)
- if not os.path.exists(os.path.join(binary_directory, 'CMakeCache.txt')):
+ if not os.path.exists(os.path.join(binary_directory, "CMakeCache.txt")):
if debug:
- print('Running cmake in "{}".'.format(binary_directory))
- result = subprocess.run(['/usr/bin/cmake', '-GNinja', abs_source], cwd=binary_directory)
+ print(f'Running cmake in "{binary_directory}"')
+ result = subprocess.run(["/usr/bin/cmake", "-GNinja", abs_source], cwd=binary_directory)
if debug:
- print('CMake return code: {}.'.format(result.returncode))
+ print(f"CMake return code: {result.returncode}.")
assert result.returncode == 0
if debug:
- print('Running ninja in "{}".'.format(binary_directory))
- result = subprocess.run('/usr/bin/ninja', cwd=binary_directory)
+ print(f'Running ninja in "{binary_directory}".')
+ result = subprocess.run("/usr/bin/ninja", cwd=binary_directory)
if debug:
- print('Ninja return code: {}.'.format(result.returncode))
+ print(f"Ninja return code: {result.returncode}.")
assert result.returncode == 0
def test(binary_directory: str, *, debug=False) -> typing.Tuple[int, int]:
if debug:
- print('Running ctest in "{}".'.format(binary_directory))
- result = subprocess.run('/usr/bin/ctest -j 250 | grep "tests passed, "',
- shell=True, capture_output=True, cwd=binary_directory)
- summary = result.stdout.decode('utf-8').replace('\n', '')
+ print(f'Running ctest in "{binary_directory}".')
+ result = subprocess.run(
+ '/usr/bin/ctest -j 250 | grep "tests passed, "',
+ shell=True,
+ capture_output=True,
+ cwd=binary_directory,
+ )
+ summary = result.stdout.decode("utf-8").replace("\n", "")
if debug:
- print('Test summary: {} ({}).'.format(summary, result.returncode))
+ print(f"Test summary: {summary} ({result.returncode}).")
- matches = re.fullmatch(r'\d+% tests passed, (\d+) tests failed out of (\d+)', summary)
+ matches = re.fullmatch(r"\d+% tests passed, (\d+) tests failed out of (\d+)", summary)
if matches:
if debug:
- print('Matches: failed {}, total {}.'.format(matches.group(1), matches.group(2)))
- return (int(matches.group(2)), int(matches.group(2)) - int(matches.group(1)), )
+ print(f"Matches: failed {matches.group(1)}, total {matches.group(2)}.")
+ return (int(matches.group(2)), int(matches.group(2)) - int(matches.group(1)))
- return (0, 0,)
+ return (0, 0)
def main() -> int:
@@ -102,26 +116,26 @@ def main() -> int:
base_line = calculate_baseline(args.source_directory, debug=args.debug)
if base_line <= 0:
- print('Could not find the qmake baseline in {}.'.format(args.source_directory))
+ print(f"Could not find the qmake baseline in {args.source_directory}.")
return 1
if args.debug:
- print('qmake baseline: {} test binaries.'.format(base_line))
+ print(f"qmake baseline: {base_line} test binaries.")
cmake_total = 0
cmake_success = 0
try:
build(args.source_directory, args.binary_directory, debug=args.debug)
- (cmake_total, cmake_success, ) = test(args.binary_directory, debug=args.debug)
+ (cmake_total, cmake_success) = test(args.binary_directory, debug=args.debug)
finally:
if cmake_total == 0:
- print('\n\n\nCould not calculate the cmake state.')
+ print("\n\n\nCould not calculate the cmake state.")
return 2
else:
- print('\n\n\nCMake test conversion rate: {:.2%}.'.format(cmake_total / base_line))
- print('CMake test success rate : {:.2%}.'.format(cmake_success / base_line))
+ print(f"\n\n\nCMake test conversion rate: {cmake_total/base_line:.2f}.")
+ print(f"CMake test success rate : {cmake_success/base_line:.2f}.")
return 0
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/util/cmake/configurejson2cmake.py b/util/cmake/configurejson2cmake.py
index 31e062580b5..db56f26eda8 100755
--- a/util/cmake/configurejson2cmake.py
+++ b/util/cmake/configurejson2cmake.py
@@ -31,11 +31,16 @@ import json_parser
import posixpath
import re
import sys
-from typing import Set, Union, List, Dict
+from typing import Set
from textwrap import dedent
-from helper import map_qt_library, featureName, map_platform, \
- find_3rd_party_library_mapping, generate_find_package_info
+from helper import (
+ map_qt_library,
+ featureName,
+ map_platform,
+ find_3rd_party_library_mapping,
+ generate_find_package_info,
+)
knownTests = set() # type: Set[str]
@@ -46,114 +51,105 @@ class LibraryMapping:
self.resultVariable = resultVariable
self.appendFoundSuffix = appendFoundSuffix
+
def map_tests(test: str) -> str:
testmap = {
- 'c++11': '$<COMPILE_FEATURES:cxx_std_11>',
- 'c++14': '$<COMPILE_FEATURES:cxx_std_14>',
- 'c++1z': '$<COMPILE_FEATURES:cxx_std_17>',
- 'c99': '$<COMPILE_FEATURES:c_std_99>',
- 'c11': '$<COMPILE_FEATURES:c_std_11>',
-
- 'x86SimdAlways': 'ON', # FIXME: Make this actually do a compile test.
-
- 'aesni': 'TEST_subarch_aes',
- 'avx': 'TEST_subarch_avx',
- 'avx2': 'TEST_subarch_avx2',
- 'avx512f': 'TEST_subarch_avx512f',
- 'avx512cd': 'TEST_subarch_avx512cd',
- 'avx512dq': 'TEST_subarch_avx512dq',
- 'avx512bw': 'TEST_subarch_avx512bw',
- 'avx512er': 'TEST_subarch_avx512er',
- 'avx512pf': 'TEST_subarch_avx512pf',
- 'avx512vl': 'TEST_subarch_avx512vl',
- 'avx512ifma': 'TEST_subarch_avx512ifma',
- 'avx512vbmi': 'TEST_subarch_avx512vbmi',
- 'avx512vbmi2': 'TEST_subarch_avx512vbmi2',
- 'avx512vpopcntdq': 'TEST_subarch_avx512vpopcntdq',
- 'avx5124fmaps': 'TEST_subarch_avx5124fmaps',
- 'avx5124vnniw': 'TEST_subarch_avx5124vnniw',
- 'bmi': 'TEST_subarch_bmi',
- 'bmi2': 'TEST_subarch_bmi2',
- 'cx16': 'TEST_subarch_cx16',
- 'f16c': 'TEST_subarch_f16c',
- 'fma': 'TEST_subarch_fma',
- 'fma4': 'TEST_subarch_fma4',
- 'fsgsbase': 'TEST_subarch_fsgsbase',
- 'gfni': 'TEST_subarch_gfni',
- 'ibt': 'TEST_subarch_ibt',
- 'libclang': 'TEST_libclang',
- 'lwp': 'TEST_subarch_lwp',
- 'lzcnt': 'TEST_subarch_lzcnt',
- 'mmx': 'TEST_subarch_mmx',
- 'movbe': 'TEST_subarch_movbe',
- 'mpx': 'TEST_subarch_mpx',
- 'no-sahf': 'TEST_subarch_no_shaf',
- 'pclmul': 'TEST_subarch_pclmul',
- 'popcnt': 'TEST_subarch_popcnt',
- 'prefetchwt1': 'TEST_subarch_prefetchwt1',
- 'prfchw': 'TEST_subarch_prfchw',
- 'pdpid': 'TEST_subarch_rdpid',
- 'rdpid': 'TEST_subarch_rdpid',
- 'rdseed': 'TEST_subarch_rdseed',
- 'rdrnd': 'TEST_subarch_rdseed', # FIXME: Is this the right thing?
- 'rtm': 'TEST_subarch_rtm',
- 'shani': 'TEST_subarch_sha',
- 'shstk': 'TEST_subarch_shstk',
- 'sse2': 'TEST_subarch_sse2',
- 'sse3': 'TEST_subarch_sse3',
- 'ssse3': 'TEST_subarch_ssse3',
- 'sse4a': 'TEST_subarch_sse4a',
- 'sse4_1': 'TEST_subarch_sse4_1',
- 'sse4_2': 'TEST_subarch_sse4_2',
- 'tbm': 'TEST_subarch_tbm',
- 'xop': 'TEST_subarch_xop',
-
- 'neon': 'TEST_subarch_neon',
- 'iwmmxt': 'TEST_subarch_iwmmxt',
- 'crc32': 'TEST_subarch_crc32',
-
- 'vis': 'TEST_subarch_vis',
- 'vis2': 'TEST_subarch_vis2',
- 'vis3': 'TEST_subarch_vis3',
-
- 'dsp': 'TEST_subarch_dsp',
- 'dspr2': 'TEST_subarch_dspr2',
-
- 'altivec': 'TEST_subarch_altivec',
- 'spe': 'TEST_subarch_spe',
- 'vsx': 'TEST_subarch_vsx',
-
- 'posix-iconv': 'TEST_posix_iconv',
- 'sun-iconv': 'TEST_sun_iconv',
-
- 'openssl11': '(OPENSSL_VERSION VERSION_GREATER_EQUAL "1.1.0")',
-
- 'reduce_exports': 'CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY',
-
- 'libinput_axis_api': 'ON',
+ "c++11": "$<COMPILE_FEATURES:cxx_std_11>",
+ "c++14": "$<COMPILE_FEATURES:cxx_std_14>",
+ "c++1z": "$<COMPILE_FEATURES:cxx_std_17>",
+ "c99": "$<COMPILE_FEATURES:c_std_99>",
+ "c11": "$<COMPILE_FEATURES:c_std_11>",
+ "x86SimdAlways": "ON", # FIXME: Make this actually do a compile test.
+ "aesni": "TEST_subarch_aes",
+ "avx": "TEST_subarch_avx",
+ "avx2": "TEST_subarch_avx2",
+ "avx512f": "TEST_subarch_avx512f",
+ "avx512cd": "TEST_subarch_avx512cd",
+ "avx512dq": "TEST_subarch_avx512dq",
+ "avx512bw": "TEST_subarch_avx512bw",
+ "avx512er": "TEST_subarch_avx512er",
+ "avx512pf": "TEST_subarch_avx512pf",
+ "avx512vl": "TEST_subarch_avx512vl",
+ "avx512ifma": "TEST_subarch_avx512ifma",
+ "avx512vbmi": "TEST_subarch_avx512vbmi",
+ "avx512vbmi2": "TEST_subarch_avx512vbmi2",
+ "avx512vpopcntdq": "TEST_subarch_avx512vpopcntdq",
+ "avx5124fmaps": "TEST_subarch_avx5124fmaps",
+ "avx5124vnniw": "TEST_subarch_avx5124vnniw",
+ "bmi": "TEST_subarch_bmi",
+ "bmi2": "TEST_subarch_bmi2",
+ "cx16": "TEST_subarch_cx16",
+ "f16c": "TEST_subarch_f16c",
+ "fma": "TEST_subarch_fma",
+ "fma4": "TEST_subarch_fma4",
+ "fsgsbase": "TEST_subarch_fsgsbase",
+ "gfni": "TEST_subarch_gfni",
+ "ibt": "TEST_subarch_ibt",
+ "libclang": "TEST_libclang",
+ "lwp": "TEST_subarch_lwp",
+ "lzcnt": "TEST_subarch_lzcnt",
+ "mmx": "TEST_subarch_mmx",
+ "movbe": "TEST_subarch_movbe",
+ "mpx": "TEST_subarch_mpx",
+ "no-sahf": "TEST_subarch_no_shaf",
+ "pclmul": "TEST_subarch_pclmul",
+ "popcnt": "TEST_subarch_popcnt",
+ "prefetchwt1": "TEST_subarch_prefetchwt1",
+ "prfchw": "TEST_subarch_prfchw",
+ "pdpid": "TEST_subarch_rdpid",
+ "rdpid": "TEST_subarch_rdpid",
+ "rdseed": "TEST_subarch_rdseed",
+ "rdrnd": "TEST_subarch_rdseed", # FIXME: Is this the right thing?
+ "rtm": "TEST_subarch_rtm",
+ "shani": "TEST_subarch_sha",
+ "shstk": "TEST_subarch_shstk",
+ "sse2": "TEST_subarch_sse2",
+ "sse3": "TEST_subarch_sse3",
+ "ssse3": "TEST_subarch_ssse3",
+ "sse4a": "TEST_subarch_sse4a",
+ "sse4_1": "TEST_subarch_sse4_1",
+ "sse4_2": "TEST_subarch_sse4_2",
+ "tbm": "TEST_subarch_tbm",
+ "xop": "TEST_subarch_xop",
+ "neon": "TEST_subarch_neon",
+ "iwmmxt": "TEST_subarch_iwmmxt",
+ "crc32": "TEST_subarch_crc32",
+ "vis": "TEST_subarch_vis",
+ "vis2": "TEST_subarch_vis2",
+ "vis3": "TEST_subarch_vis3",
+ "dsp": "TEST_subarch_dsp",
+ "dspr2": "TEST_subarch_dspr2",
+ "altivec": "TEST_subarch_altivec",
+ "spe": "TEST_subarch_spe",
+ "vsx": "TEST_subarch_vsx",
+ "posix-iconv": "TEST_posix_iconv",
+ "sun-iconv": "TEST_sun_iconv",
+ "openssl11": '(OPENSSL_VERSION VERSION_GREATER_EQUAL "1.1.0")',
+ "reduce_exports": "CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY",
+ "libinput_axis_api": "ON",
"xlib": "X11_FOUND",
}
if test in testmap:
return testmap.get(test, None)
if test in knownTests:
- return 'TEST_{}'.format(featureName(test))
+ return "TEST_{}".format(featureName(test))
return None
def cm(ctx, *output):
- txt = ctx['output']
- if txt != '' and not txt.endswith('\n'):
- txt += '\n'
- txt += '\n'.join(output)
+ txt = ctx["output"]
+ if txt != "" and not txt.endswith("\n"):
+ txt += "\n"
+ txt += "\n".join(output)
- ctx['output'] = txt
+ ctx["output"] = txt
return ctx
def readJsonFromDir(dir):
- path = posixpath.join(dir, 'configure.json')
+ path = posixpath.join(dir, "configure.json")
- print('Reading {}...'.format(path))
+ print("Reading {}...".format(path))
assert posixpath.exists(path)
parser = json_parser.QMakeSpecificJSONParser()
@@ -161,12 +157,13 @@ def readJsonFromDir(dir):
def processFiles(ctx, data):
- print(' files:')
- if 'files' in data:
- for (k, v) in data['files'].items():
+ print(" files:")
+ if "files" in data:
+ for (k, v) in data["files"].items():
ctx[k] = v
return ctx
+
def parseLib(ctx, lib, data, cm_fh, cmake_find_packages_set):
newlib = find_3rd_party_library_mapping(lib)
if not newlib:
@@ -177,7 +174,7 @@ def parseLib(ctx, lib, data, cm_fh, cmake_find_packages_set):
print(' **** Skipping library "{}" -- was masked.'.format(lib))
return
- print(' mapped library {} to {}.'.format(lib, newlib.targetName))
+ print(" mapped library {} to {}.".format(lib, newlib.targetName))
# Avoid duplicate find_package calls.
if newlib.targetName in cmake_find_packages_set:
@@ -191,13 +188,15 @@ def parseLib(ctx, lib, data, cm_fh, cmake_find_packages_set):
# Only look through features if a custom emit_if wasn't provided.
if not emit_if:
- for feature in data['features']:
- feature_data = data['features'][feature]
- if 'condition' in feature_data and \
- 'libs.{}'.format(lib) in feature_data['condition'] and \
- 'emitIf' in feature_data and \
- 'config.' in feature_data['emitIf']:
- emit_if = feature_data['emitIf']
+ for feature in data["features"]:
+ feature_data = data["features"][feature]
+ if (
+ "condition" in feature_data
+ and "libs.{}".format(lib) in feature_data["condition"]
+ and "emitIf" in feature_data
+ and "config." in feature_data["emitIf"]
+ ):
+ emit_if = feature_data["emitIf"]
break
if emit_if:
@@ -212,45 +211,46 @@ def lineify(label, value, quote=True):
if value:
if quote:
return ' {} "{}"\n'.format(label, value.replace('"', '\\"'))
- return ' {} {}\n'.format(label, value)
- return ''
+ return " {} {}\n".format(label, value)
+ return ""
+
def map_condition(condition):
# Handle NOT:
if isinstance(condition, list):
- condition = '(' + ') AND ('.join(condition) + ')'
+ condition = "(" + ") AND (".join(condition) + ")"
if isinstance(condition, bool):
if condition:
- return 'ON'
+ return "ON"
else:
- return 'OFF'
+ return "OFF"
assert isinstance(condition, str)
mapped_features = {
- 'gbm': 'gbm_FOUND',
+ "gbm": "gbm_FOUND",
"system-xcb": "ON",
"system-freetype": "ON",
- 'system-pcre2': 'ON',
+ "system-pcre2": "ON",
}
# Turn foo != "bar" into (NOT foo STREQUAL 'bar')
- condition = re.sub(r"(.+)\s*!=\s*('.+')", '(! \\1 == \\2)', condition)
+ condition = re.sub(r"(.+)\s*!=\s*('.+')", "(! \\1 == \\2)", condition)
- condition = condition.replace('!', 'NOT ')
- condition = condition.replace('&&', ' AND ')
- condition = condition.replace('||', ' OR ')
- condition = condition.replace('==', ' STREQUAL ')
+ condition = condition.replace("!", "NOT ")
+ condition = condition.replace("&&", " AND ")
+ condition = condition.replace("||", " OR ")
+ condition = condition.replace("==", " STREQUAL ")
# explicitly handle input.sdk == '':
- condition = re.sub(r"input\.sdk\s*==\s*''", 'NOT INPUT_SDK', condition)
+ condition = re.sub(r"input\.sdk\s*==\s*''", "NOT INPUT_SDK", condition)
last_pos = 0
- mapped_condition = ''
+ mapped_condition = ""
has_failed = False
- for match in re.finditer(r'([a-zA-Z0-9_]+)\.([a-zA-Z0-9_+-]+)', condition):
+ for match in re.finditer(r"([a-zA-Z0-9_]+)\.([a-zA-Z0-9_+-]+)", condition):
substitution = None
- appendFoundSuffix = True
- if match.group(1) == 'libs':
+ # appendFoundSuffix = True
+ if match.group(1) == "libs":
libmapping = find_3rd_party_library_mapping(match.group(2))
if libmapping and libmapping.packageName:
@@ -258,167 +258,164 @@ def map_condition(condition):
if libmapping.resultVariable:
substitution = libmapping.resultVariable
if libmapping.appendFoundSuffix:
- substitution += '_FOUND'
+ substitution += "_FOUND"
- elif match.group(1) == 'features':
+ elif match.group(1) == "features":
feature = match.group(2)
if feature in mapped_features:
substitution = mapped_features.get(feature)
else:
- substitution = 'QT_FEATURE_{}'.format(featureName(match.group(2)))
+ substitution = "QT_FEATURE_{}".format(featureName(match.group(2)))
- elif match.group(1) == 'subarch':
- substitution = 'TEST_arch_{}_subarch_{}'.format("${TEST_architecture_arch}",
- match.group(2))
+ elif match.group(1) == "subarch":
+ substitution = "TEST_arch_{}_subarch_{}".format(
+ "${TEST_architecture_arch}", match.group(2)
+ )
- elif match.group(1) == 'call':
- if match.group(2) == 'crossCompile':
- substitution = 'CMAKE_CROSSCOMPILING'
+ elif match.group(1) == "call":
+ if match.group(2) == "crossCompile":
+ substitution = "CMAKE_CROSSCOMPILING"
- elif match.group(1) == 'tests':
+ elif match.group(1) == "tests":
substitution = map_tests(match.group(2))
- elif match.group(1) == 'input':
- substitution = 'INPUT_{}'.format(featureName(match.group(2)))
+ elif match.group(1) == "input":
+ substitution = "INPUT_{}".format(featureName(match.group(2)))
- elif match.group(1) == 'config':
+ elif match.group(1) == "config":
substitution = map_platform(match.group(2))
- elif match.group(1) == 'module':
- substitution = 'TARGET {}'.format(map_qt_library(match.group(2)))
+ elif match.group(1) == "module":
+ substitution = "TARGET {}".format(map_qt_library(match.group(2)))
- elif match.group(1) == 'arch':
- if match.group(2) == 'i386':
+ elif match.group(1) == "arch":
+ if match.group(2) == "i386":
# FIXME: Does this make sense?
- substitution = '(TEST_architecture_arch STREQUAL i386)'
- elif match.group(2) == 'x86_64':
- substitution = '(TEST_architecture_arch STREQUAL x86_64)'
- elif match.group(2) == 'arm':
+ substitution = "(TEST_architecture_arch STREQUAL i386)"
+ elif match.group(2) == "x86_64":
+ substitution = "(TEST_architecture_arch STREQUAL x86_64)"
+ elif match.group(2) == "arm":
# FIXME: Does this make sense?
- substitution = '(TEST_architecture_arch STREQUAL arm)'
- elif match.group(2) == 'arm64':
+ substitution = "(TEST_architecture_arch STREQUAL arm)"
+ elif match.group(2) == "arm64":
# FIXME: Does this make sense?
- substitution = '(TEST_architecture_arch STREQUAL arm64)'
- elif match.group(2) == 'mips':
+ substitution = "(TEST_architecture_arch STREQUAL arm64)"
+ elif match.group(2) == "mips":
# FIXME: Does this make sense?
- substitution = '(TEST_architecture_arch STREQUAL mips)'
+ substitution = "(TEST_architecture_arch STREQUAL mips)"
if substitution is None:
print(' XXXX Unknown condition "{}".'.format(match.group(0)))
has_failed = True
else:
- mapped_condition += condition[last_pos:match.start(1)] + substitution
+ mapped_condition += condition[last_pos : match.start(1)] + substitution
last_pos = match.end(2)
mapped_condition += condition[last_pos:]
# Space out '(' and ')':
- mapped_condition = mapped_condition.replace('(', ' ( ')
- mapped_condition = mapped_condition.replace(')', ' ) ')
+ mapped_condition = mapped_condition.replace("(", " ( ")
+ mapped_condition = mapped_condition.replace(")", " ) ")
# Prettify:
- condition = re.sub('\\s+', ' ', mapped_condition)
+ condition = re.sub("\\s+", " ", mapped_condition)
condition = condition.strip()
if has_failed:
- condition += ' OR FIXME'
+ condition += " OR FIXME"
return condition
-def parseInput(ctx, input, data, cm_fh):
+def parseInput(ctx, sinput, data, cm_fh):
skip_inputs = {
- "prefix", "hostprefix", "extprefix",
-
- "archdatadir", "bindir", "datadir", "docdir",
- "examplesdir", "external-hostbindir", "headerdir",
- "hostbindir", "hostdatadir", "hostlibdir",
- "importdir", "libdir", "libexecdir",
- "plugindir", "qmldir", "settingsdir",
- "sysconfdir", "testsdir", "translationdir",
-
- "android-arch", "android-ndk", "android-ndk-host",
- "android-ndk-platform", "android-sdk",
- "android-toolchain-version", "android-style-assets",
-
+ "prefix",
+ "hostprefix",
+ "extprefix",
+ "archdatadir",
+ "bindir",
+ "datadir",
+ "docdir",
+ "examplesdir",
+ "external-hostbindir",
+ "headerdir",
+ "hostbindir",
+ "hostdatadir",
+ "hostlibdir",
+ "importdir",
+ "libdir",
+ "libexecdir",
+ "plugindir",
+ "qmldir",
+ "settingsdir",
+ "sysconfdir",
+ "testsdir",
+ "translationdir",
+ "android-arch",
+ "android-ndk",
+ "android-ndk-host",
+ "android-ndk-platform",
+ "android-sdk",
+ "android-toolchain-version",
+ "android-style-assets",
"appstore-compliant",
-
- "avx", "avx2", "avx512", "c++std", "ccache", "commercial",
- "compile-examples", "confirm-license",
+ "avx",
+ "avx2",
+ "avx512",
+ "c++std",
+ "ccache",
+ "commercial",
+ "compile-examples",
+ "confirm-license",
"dbus",
"dbus-runtime",
-
- "debug", "debug-and-release",
-
+ "debug",
+ "debug-and-release",
"developer-build",
-
- "device", "device-option",
-
+ "device",
+ "device-option",
"f16c",
-
- "force-asserts", "force-debug-info", "force-pkg-config",
+ "force-asserts",
+ "force-debug-info",
+ "force-pkg-config",
"framework",
-
"gc-binaries",
-
"gdb-index",
-
"gcc-sysroot",
-
"gcov",
-
"gnumake",
-
"gui",
-
"harfbuzz",
-
"headersclean",
-
"incredibuild-xge",
-
"libudev",
"ltcg",
"make",
"make-tool",
-
"mips_dsp",
"mips_dspr2",
"mp",
-
"nomake",
-
"opensource",
-
- "optimize-debug", "optimize-size", "optimized-qmake", "optimized-tools",
-
+ "optimize-debug",
+ "optimize-size",
+ "optimized-qmake",
+ "optimized-tools",
"pch",
-
"pkg-config",
-
"platform",
-
"plugin-manifests",
"profile",
"qreal",
-
- "reduce-exports", "reduce-relocations",
-
+ "reduce-exports",
+ "reduce-relocations",
"release",
-
"rpath",
-
"sanitize",
-
"sdk",
-
"separate-debug-info",
-
"shared",
-
"silent",
-
"qdbus",
-
"sse2",
"sse3",
"sse4.1",
@@ -436,9 +433,7 @@ def parseInput(ctx, input, data, cm_fh):
"widgets",
"xplatform",
"zlib",
-
"doubleconversion",
-
"eventfd",
"glib",
"icu",
@@ -449,29 +444,31 @@ def parseInput(ctx, input, data, cm_fh):
"pps",
"slog2",
"syslog",
-
"sqlite",
}
- if input in skip_inputs:
- print(' **** Skipping input {}: masked.'.format(input))
+ if sinput in skip_inputs:
+ print(f" **** Skipping input {sinput}: masked.")
return
- type = data
+ dtype = data
if isinstance(data, dict):
- type = data["type"]
+ dtype = data["type"]
- if type == "boolean":
- print(' **** Skipping boolean input {}: masked.'.format(input))
+ if dtype == "boolean":
+ print(f" **** Skipping boolean input {sinput}: masked.")
return
- if type == "enum":
- cm_fh.write("# input {}\n".format(input))
- cm_fh.write('set(INPUT_{} "undefined" CACHE STRING "")\n'.format(featureName(input)))
- cm_fh.write('set_property(CACHE INPUT_{} PROPERTY STRINGS undefined {})\n\n'.format(featureName(input), " ".join(data["values"])))
+ if dtype == "enum":
+ values_line = " ".join(data["values"])
+ cm_fh.write(f"# input {sinput}\n")
+ cm_fh.write(f'set(INPUT_{featureName(sinput)} "undefined" CACHE STRING "")\n')
+ cm_fh.write(
+ f"set_property(CACHE INPUT_{featureName(sinput)} PROPERTY STRINGS undefined {values_line})\n\n"
+ )
return
- print(' XXXX UNHANDLED INPUT TYPE {} in input description'.format(type))
+ print(f" XXXX UNHANDLED INPUT TYPE {dtype} in input description")
return
@@ -490,21 +487,26 @@ def parseInput(ctx, input, data, cm_fh):
# },
def parseTest(ctx, test, data, cm_fh):
skip_tests = {
- 'c++11', 'c++14', 'c++1y', 'c++1z',
- 'c11', 'c99',
- 'gc_binaries',
- 'posix-iconv', "sun-iconv",
- 'precomile_header',
- 'reduce_exports',
- 'separate_debug_info', # FIXME: see if cmake can do this
- 'gc_binaries',
- 'libinput_axis_api',
- 'wayland-scanner',
- 'xlib',
+ "c++11",
+ "c++14",
+ "c++1y",
+ "c++1z",
+ "c11",
+ "c99",
+ "gc_binaries",
+ "posix-iconv",
+ "sun-iconv",
+ "precomile_header",
+ "reduce_exports",
+ "separate_debug_info", # FIXME: see if cmake can do this
+ "gc_binaries",
+ "libinput_axis_api",
+ "wayland-scanner",
+ "xlib",
}
if test in skip_tests:
- print(' **** Skipping features {}: masked.'.format(test))
+ print(f" **** Skipping features {test}: masked.")
return
if data["type"] == "compile":
@@ -513,28 +515,28 @@ def parseTest(ctx, test, data, cm_fh):
details = data["test"]
if isinstance(details, str):
- print(' XXXX UNHANDLED TEST SUB-TYPE {} in test description'.format(details))
+ print(f" XXXX UNHANDLED TEST SUB-TYPE {details} in test description")
return
head = details.get("head", "")
if isinstance(head, list):
head = "\n".join(head)
- sourceCode = head + '\n'
+ sourceCode = head + "\n"
include = details.get("include", "")
if isinstance(include, list):
- include = '#include <' + '>\n#include <'.join(include) + '>'
+ include = "#include <" + ">\n#include <".join(include) + ">"
elif include:
- include = '#include <{}>'.format(include)
+ include = f"#include <{include}>"
- sourceCode += include + '\n'
+ sourceCode += include + "\n"
tail = details.get("tail", "")
if isinstance(tail, list):
tail = "\n".join(tail)
- sourceCode += tail + '\n'
+ sourceCode += tail + "\n"
sourceCode += "int main(int argc, char **argv)\n"
sourceCode += "{\n"
@@ -545,7 +547,7 @@ def parseTest(ctx, test, data, cm_fh):
if isinstance(main, list):
main = "\n".join(main)
- sourceCode += main + '\n'
+ sourceCode += main + "\n"
sourceCode += " /* END TEST: */\n"
sourceCode += " return 0;\n"
@@ -556,8 +558,8 @@ def parseTest(ctx, test, data, cm_fh):
librariesCmakeName = ""
qmakeFixme = ""
- cm_fh.write("# {}\n".format(test))
- if "qmake" in details: # We don't really have many so we can just enumerate them all
+ cm_fh.write(f"# {test}\n")
+ if "qmake" in details: # We don't really have many so we can just enumerate them all
if details["qmake"] == "unix:LIBS += -lpthread":
librariesCmakeName = format(featureName(test)) + "_TEST_LIBRARIES"
cm_fh.write("if (UNIX)\n")
@@ -572,7 +574,7 @@ def parseTest(ctx, test, data, cm_fh):
# do nothing we're always in c++11 mode
pass
else:
- qmakeFixme = "# FIXME: qmake: {}\n".format(details["qmake"])
+ qmakeFixme = f"# FIXME: qmake: {details['qmake']}\n"
if "use" in data:
if data["use"] == "egl xcb_xlib":
@@ -581,12 +583,12 @@ def parseTest(ctx, test, data, cm_fh):
cm_fh.write(" set(" + librariesCmakeName + " EGL::EGL X11::X11 X11::XCB)\n")
cm_fh.write("endif()\n")
else:
- qmakeFixme += "# FIXME: use: {}\n".format(data["use"])
+ qmakeFixme += f"# FIXME: use: {data['use']}\n"
- cm_fh.write("qt_config_compile_test({}\n".format(featureName(test)))
+ cm_fh.write(f"qt_config_compile_test({featureName(test)}\n")
cm_fh.write(lineify("LABEL", data.get("label", "")))
if librariesCmakeName != "":
- cm_fh.write(lineify("LIBRARIES", "${"+librariesCmakeName+"}"))
+ cm_fh.write(lineify("LIBRARIES", "${" + librariesCmakeName + "}"))
cm_fh.write(" CODE\n")
cm_fh.write('"' + sourceCode + '"')
if qmakeFixme != "":
@@ -596,14 +598,18 @@ def parseTest(ctx, test, data, cm_fh):
elif data["type"] == "libclang":
knownTests.add(test)
- cm_fh.write("# {}\n".format(test))
+ cm_fh.write(f"# {test}\n")
lib_clang_lib = find_3rd_party_library_mapping("libclang")
cm_fh.write(generate_find_package_info(lib_clang_lib))
- cm_fh.write(dedent("""
+ cm_fh.write(
+ dedent(
+ """
if(TARGET WrapLibClang::WrapLibClang)
set(TEST_libclang "ON" CACHE BOOL "Required libclang version found." FORCE)
endif()
- """))
+ """
+ )
+ )
cm_fh.write("\n")
elif data["type"] == "x86Simd":
@@ -611,230 +617,238 @@ def parseTest(ctx, test, data, cm_fh):
label = data["label"]
- cm_fh.write("# {}\n".format(test))
- cm_fh.write("qt_config_compile_test_x86simd({} \"{}\")\n".format(test, label))
+ cm_fh.write(f"# {test}\n")
+ cm_fh.write(f'qt_config_compile_test_x86simd({test} "{label}")\n')
cm_fh.write("\n")
-# "features": {
-# "android-style-assets": {
-# "label": "Android Style Assets",
-# "condition": "config.android",
-# "output": [ "privateFeature" ],
-# "comment": "This belongs into gui, but the license check needs it here already."
-# },
+ # "features": {
+ # "android-style-assets": {
+ # "label": "Android Style Assets",
+ # "condition": "config.android",
+ # "output": [ "privateFeature" ],
+ # "comment": "This belongs into gui, but the license check needs it here already."
+ # },
else:
- print(' XXXX UNHANDLED TEST TYPE {} in test description'.format(data["type"]))
+ print(f" XXXX UNHANDLED TEST TYPE {data['type']} in test description")
def parseFeature(ctx, feature, data, cm_fh):
# This is *before* the feature name gets normalized! So keep - and + chars, etc.
feature_mapping = {
- 'alloc_h': None, # handled by alloc target
- 'alloc_malloc_h': None,
- 'alloc_stdlib_h': None,
- 'build_all': None,
- 'c11': None,
- 'c89': None,
- 'c99': None,
- 'ccache': None,
- 'compiler-flags': None,
- 'cross_compile': None,
- 'debug_and_release': None,
- 'debug': None,
- 'dlopen': {
- 'condition': 'UNIX',
- },
- 'doubleconversion': None,
- 'enable_gdb_index': None,
- 'enable_new_dtags': None,
- 'force_debug_info': None,
- 'framework': {
- 'condition': 'APPLE AND BUILD_SHARED_LIBS',
- },
- 'gc_binaries': None,
- 'gcc-sysroot': None,
- 'gcov': None,
- 'gnu-libiconv': {
- 'condition': 'NOT WIN32 AND NOT QNX AND NOT ANDROID AND NOT APPLE AND TEST_posix_iconv AND NOT TEST_iconv_needlib',
- 'enable': 'TEST_posix_iconv AND NOT TEST_iconv_needlib',
- 'disable': 'NOT TEST_posix_iconv OR TEST_iconv_needlib',
+ "alloc_h": None, # handled by alloc target
+ "alloc_malloc_h": None,
+ "alloc_stdlib_h": None,
+ "build_all": None,
+ "c11": None,
+ "c89": None,
+ "c99": None,
+ "ccache": None,
+ "compiler-flags": None,
+ "cross_compile": None,
+ "debug_and_release": None,
+ "debug": None,
+ "dlopen": {"condition": "UNIX"},
+ "doubleconversion": None,
+ "enable_gdb_index": None,
+ "enable_new_dtags": None,
+ "force_debug_info": None,
+ "framework": {"condition": "APPLE AND BUILD_SHARED_LIBS"},
+ "gc_binaries": None,
+ "gcc-sysroot": None,
+ "gcov": None,
+ "gnu-libiconv": {
+ "condition": "NOT WIN32 AND NOT QNX AND NOT ANDROID AND NOT APPLE AND TEST_posix_iconv AND NOT TEST_iconv_needlib",
+ "enable": "TEST_posix_iconv AND NOT TEST_iconv_needlib",
+ "disable": "NOT TEST_posix_iconv OR TEST_iconv_needlib",
},
- 'GNUmake': None,
- 'harfbuzz': {
- 'condition': 'harfbuzz_FOUND'
+ "GNUmake": None,
+ "harfbuzz": {"condition": "harfbuzz_FOUND"},
+ "host-dbus": None,
+ "iconv": {
+ "condition": "NOT QT_FEATURE_icu AND QT_FEATURE_textcodec AND ( TEST_posix_iconv OR TEST_sun_iconv )"
},
- 'host-dbus': None,
- 'iconv': {
- 'condition': 'NOT QT_FEATURE_icu AND QT_FEATURE_textcodec AND ( TEST_posix_iconv OR TEST_sun_iconv )'
- },
- 'incredibuild_xge': None,
- 'jpeg': {
- 'condition': 'QT_FEATURE_imageformatplugin AND JPEG_FOUND'
- },
- 'ltcg': None,
- 'msvc_mp': None,
- 'optimize_debug': None,
- 'optimize_size': None,
+ "incredibuild_xge": None,
+ "jpeg": {"condition": "QT_FEATURE_imageformatplugin AND JPEG_FOUND"},
+ "ltcg": None,
+ "msvc_mp": None,
+ "optimize_debug": None,
+ "optimize_size": None,
# special case to enable implicit feature on WIN32, until ANGLE is ported
- 'opengl-desktop': {
- 'autoDetect': ''
- },
+ "opengl-desktop": {"autoDetect": ""},
# special case to disable implicit feature on WIN32, until ANGLE is ported
- 'opengl-dynamic': {
- 'autoDetect': 'OFF'
+ "opengl-dynamic": {"autoDetect": "OFF"},
+ "opengles2": { # special case to disable implicit feature on WIN32, until ANGLE is ported
+ "condition": "NOT WIN32 AND ( NOT APPLE_WATCHOS AND NOT QT_FEATURE_opengl_desktop AND GLESv2_FOUND )"
},
- 'opengles2': { # special case to disable implicit feature on WIN32, until ANGLE is ported
- 'condition': 'NOT WIN32 AND ( NOT APPLE_WATCHOS AND NOT QT_FEATURE_opengl_desktop AND GLESv2_FOUND )'
+ "pkg-config": None,
+ "posix_fallocate": None, # Only needed for sqlite, which we do not want to build
+ "posix-libiconv": {
+ "condition": "NOT WIN32 AND NOT QNX AND NOT ANDROID AND NOT APPLE AND TEST_posix_iconv AND TEST_iconv_needlib",
+ "enable": "TEST_posix_iconv AND TEST_iconv_needlib",
+ "disable": "NOT TEST_posix_iconv OR NOT TEST_iconv_needlib",
},
- 'pkg-config': None,
- 'posix_fallocate': None, # Only needed for sqlite, which we do not want to build
- 'posix-libiconv': {
- 'condition': 'NOT WIN32 AND NOT QNX AND NOT ANDROID AND NOT APPLE AND TEST_posix_iconv AND TEST_iconv_needlib',
- 'enable': 'TEST_posix_iconv AND TEST_iconv_needlib',
- 'disable': 'NOT TEST_posix_iconv OR NOT TEST_iconv_needlib',
+ "precompile_header": None,
+ "profile": None,
+ "qmakeargs": None,
+ "qpa_default_platform": None, # Not a bool!
+ "reduce_relocations": None,
+ "release": None,
+ "release_tools": None,
+ "rpath_dir": None, # rpath related
+ "rpath": None,
+ "sanitize_address": None, # sanitizer
+ "sanitize_memory": None,
+ "sanitizer": None,
+ "sanitize_thread": None,
+ "sanitize_undefined": None,
+ "separate_debug_info": None,
+ "shared": None,
+ "silent": None,
+ "sql-sqlite": {"condition": "QT_FEATURE_datestring AND SQLite3_FOUND"},
+ "stack-protector-strong": None,
+ "static": None,
+ "static_runtime": None,
+ "stl": None, # Do we really need to test for this in 2018?!
+ "strip": None,
+ "sun-libiconv": {
+ "condition": "NOT WIN32 AND NOT QNX AND NOT ANDROID AND NOT APPLE AND TEST_sun_iconv",
+ "enable": "TEST_sun_iconv",
+ "disable": "NOT TEST_sun_iconv",
},
- 'precompile_header': None,
- 'profile': None,
- 'qmakeargs': None,
- 'qpa_default_platform': None, # Not a bool!
- 'reduce_relocations': None,
- 'release': None,
- 'release_tools': None,
- 'rpath_dir': None, # rpath related
- 'rpath': None,
- 'sanitize_address': None, # sanitizer
- 'sanitize_memory': None,
- 'sanitizer': None,
- 'sanitize_thread': None,
- 'sanitize_undefined': None,
- 'separate_debug_info': None,
- 'shared': None,
- 'silent': None,
- 'sql-sqlite' : {
- 'condition': 'QT_FEATURE_datestring AND SQLite3_FOUND',
- },
- 'stack-protector-strong': None,
- 'static': None,
- 'static_runtime': None,
- 'stl': None, # Do we really need to test for this in 2018?!
- 'strip': None,
- 'sun-libiconv': {
- 'condition': 'NOT WIN32 AND NOT QNX AND NOT ANDROID AND NOT APPLE AND TEST_sun_iconv',
- 'enable': 'TEST_sun_iconv',
- 'disable': 'NOT TEST_sun_iconv',
- },
- 'system-doubleconversion': None, # No system libraries anymore!
- 'system-freetype': None,
- 'system-harfbuzz': None,
- 'system-jpeg': None,
- 'system-pcre2': None,
- 'system-png': None,
- 'system-sqlite': None,
- 'system-xcb': None,
- 'system-zlib': None,
- 'tiff': {
- 'condition': 'QT_FEATURE_imageformatplugin AND TIFF_FOUND'
- },
- 'use_gold_linker': None,
- 'verifyspec': None, # qmake specific...
- 'warnings_are_errors': None, # FIXME: Do we need these?
- 'webp': {
- 'condition': 'QT_FEATURE_imageformatplugin AND WrapWebP_FOUND'
- },
- 'xkbcommon-system': None, # another system library, just named a bit different from the rest
+ "system-doubleconversion": None, # No system libraries anymore!
+ "system-freetype": None,
+ "system-harfbuzz": None,
+ "system-jpeg": None,
+ "system-pcre2": None,
+ "system-png": None,
+ "system-sqlite": None,
+ "system-xcb": None,
+ "system-zlib": None,
+ "tiff": {"condition": "QT_FEATURE_imageformatplugin AND TIFF_FOUND"},
+ "use_gold_linker": None,
+ "verifyspec": None, # qmake specific...
+ "warnings_are_errors": None, # FIXME: Do we need these?
+ "webp": {"condition": "QT_FEATURE_imageformatplugin AND WrapWebP_FOUND"},
+ "xkbcommon-system": None, # another system library, just named a bit different from the rest
}
mapping = feature_mapping.get(feature, {})
if mapping is None:
- print(' **** Skipping features {}: masked.'.format(feature))
+ print(f" **** Skipping features {feature}: masked.")
return
- handled = { 'autoDetect', 'comment', 'condition', 'description', 'disable', 'emitIf', 'enable', 'label', 'output', 'purpose', 'section' }
- label = mapping.get('label', data.get('label', ''))
- purpose = mapping.get('purpose', data.get('purpose', data.get('description', label)))
- autoDetect = map_condition(mapping.get('autoDetect', data.get('autoDetect', '')))
- condition = map_condition(mapping.get('condition', data.get('condition', '')))
- output = mapping.get('output', data.get('output', []))
- comment = mapping.get('comment', data.get('comment', ''))
- section = mapping.get('section', data.get('section', ''))
- enable = map_condition(mapping.get('enable', data.get('enable', '')))
- disable = map_condition(mapping.get('disable', data.get('disable', '')))
- emitIf = map_condition(mapping.get('emitIf', data.get('emitIf', '')))
+ handled = {
+ "autoDetect",
+ "comment",
+ "condition",
+ "description",
+ "disable",
+ "emitIf",
+ "enable",
+ "label",
+ "output",
+ "purpose",
+ "section",
+ }
+ label = mapping.get("label", data.get("label", ""))
+ purpose = mapping.get("purpose", data.get("purpose", data.get("description", label)))
+ autoDetect = map_condition(mapping.get("autoDetect", data.get("autoDetect", "")))
+ condition = map_condition(mapping.get("condition", data.get("condition", "")))
+ output = mapping.get("output", data.get("output", []))
+ comment = mapping.get("comment", data.get("comment", ""))
+ section = mapping.get("section", data.get("section", ""))
+ enable = map_condition(mapping.get("enable", data.get("enable", "")))
+ disable = map_condition(mapping.get("disable", data.get("disable", "")))
+ emitIf = map_condition(mapping.get("emitIf", data.get("emitIf", "")))
for k in [k for k in data.keys() if k not in handled]:
- print(' XXXX UNHANDLED KEY {} in feature description'.format(k))
+ print(f" XXXX UNHANDLED KEY {k} in feature description")
if not output:
# feature that is only used in the conditions of other features
output = ["internalFeature"]
- publicFeature = False # #define QT_FEATURE_featurename in public header
- privateFeature = False # #define QT_FEATURE_featurename in private header
- negativeFeature = False # #define QT_NO_featurename in public header
- internalFeature = False # No custom or QT_FEATURE_ defines
- publicDefine = False # #define MY_CUSTOM_DEFINE in public header
+ publicFeature = False # #define QT_FEATURE_featurename in public header
+ privateFeature = False # #define QT_FEATURE_featurename in private header
+ negativeFeature = False # #define QT_NO_featurename in public header
+ internalFeature = False # No custom or QT_FEATURE_ defines
+ publicDefine = False # #define MY_CUSTOM_DEFINE in public header
for o in output:
outputType = o
outputArgs = {}
if isinstance(o, dict):
- outputType = o['type']
+ outputType = o["type"]
outputArgs = o
- if outputType in ['varAssign', 'varAppend', 'varRemove', 'publicQtConfig', 'privateConfig', 'publicConfig']:
+ if outputType in [
+ "varAssign",
+ "varAppend",
+ "varRemove",
+ "publicQtConfig",
+ "privateConfig",
+ "publicConfig",
+ ]:
continue
- elif outputType == 'define':
+ elif outputType == "define":
publicDefine = True
- elif outputType == 'feature':
+ elif outputType == "feature":
negativeFeature = True
- elif outputType == 'publicFeature':
+ elif outputType == "publicFeature":
publicFeature = True
- elif outputType == 'privateFeature':
+ elif outputType == "privateFeature":
privateFeature = True
- elif outputType == 'internalFeature':
+ elif outputType == "internalFeature":
internalFeature = True
else:
- print(' XXXX UNHANDLED OUTPUT TYPE {} in feature {}.'.format(outputType, feature))
+ print(f" XXXX UNHANDLED OUTPUT TYPE {outputType} in feature {feature}.")
continue
if not any([publicFeature, privateFeature, internalFeature, publicDefine, negativeFeature]):
- print(' **** Skipping feature {}: Not relevant for C++.'.format(feature))
+ print(f" **** Skipping feature {feature}: Not relevant for C++.")
return
cxxFeature = featureName(feature)
- def writeFeature(name, publicFeature=False, privateFeature=False, labelAppend='', superFeature=None, autoDetect=''):
+ def writeFeature(
+ name,
+ publicFeature=False,
+ privateFeature=False,
+ labelAppend="",
+ superFeature=None,
+ autoDetect="",
+ ):
if comment:
- cm_fh.write('# {}\n'.format(comment))
+ cm_fh.write(f"# {comment}\n")
- cm_fh.write('qt_feature("{}"'.format(name))
+ cm_fh.write(f'qt_feature("{name}"')
if publicFeature:
- cm_fh.write(' PUBLIC')
+ cm_fh.write(" PUBLIC")
if privateFeature:
- cm_fh.write(' PRIVATE')
- cm_fh.write('\n')
+ cm_fh.write(" PRIVATE")
+ cm_fh.write("\n")
- cm_fh.write(lineify('SECTION', section))
- cm_fh.write(lineify('LABEL', label + labelAppend))
+ cm_fh.write(lineify("SECTION", section))
+ cm_fh.write(lineify("LABEL", label + labelAppend))
if purpose != label:
- cm_fh.write(lineify('PURPOSE', purpose))
- cm_fh.write(lineify('AUTODETECT', autoDetect, quote=False))
+ cm_fh.write(lineify("PURPOSE", purpose))
+ cm_fh.write(lineify("AUTODETECT", autoDetect, quote=False))
if superFeature:
- feature_condition = "QT_FEATURE_{}".format(superFeature)
+ feature_condition = f"QT_FEATURE_{superFeature}"
else:
feature_condition = condition
- cm_fh.write(lineify('CONDITION', feature_condition, quote=False))
- cm_fh.write(lineify('ENABLE', enable, quote=False))
- cm_fh.write(lineify('DISABLE', disable, quote=False))
- cm_fh.write(lineify('EMIT_IF', emitIf, quote=False))
- cm_fh.write(')\n')
+ cm_fh.write(lineify("CONDITION", feature_condition, quote=False))
+ cm_fh.write(lineify("ENABLE", enable, quote=False))
+ cm_fh.write(lineify("DISABLE", disable, quote=False))
+ cm_fh.write(lineify("EMIT_IF", emitIf, quote=False))
+ cm_fh.write(")\n")
# Write qt_feature() calls before any qt_feature_definition() calls
# Default internal feature case.
featureCalls = {}
- featureCalls[cxxFeature] = {'name': cxxFeature, 'labelAppend': '', 'autoDetect': autoDetect}
+ featureCalls[cxxFeature] = {"name": cxxFeature, "labelAppend": "", "autoDetect": autoDetect}
# Go over all outputs to compute the number of features that have to be declared
for o in output:
@@ -843,26 +857,26 @@ def parseFeature(ctx, feature, data, cm_fh):
# The label append is to provide a unique label for features that have more than one output
# with different names.
- labelAppend = ''
+ labelAppend = ""
if isinstance(o, dict):
- outputType = o['type']
- if 'name' in o:
- name = o['name']
- labelAppend = ': {}'.format(o['name'])
+ outputType = o["type"]
+ if "name" in o:
+ name = o["name"]
+ labelAppend = f": {o['name']}"
- if outputType not in ['feature', 'publicFeature', 'privateFeature']:
+ if outputType not in ["feature", "publicFeature", "privateFeature"]:
continue
if name not in featureCalls:
- featureCalls[name] = {'name': name, 'labelAppend': labelAppend}
+ featureCalls[name] = {"name": name, "labelAppend": labelAppend}
if name != cxxFeature:
- featureCalls[name]['superFeature'] = cxxFeature
+ featureCalls[name]["superFeature"] = cxxFeature
- if outputType in ['feature', 'publicFeature']:
- featureCalls[name]['publicFeature'] = True
- elif outputType == 'privateFeature':
- featureCalls[name]['privateFeature'] = True
+ if outputType in ["feature", "publicFeature"]:
+ featureCalls[name]["publicFeature"] = True
+ elif outputType == "privateFeature":
+ featureCalls[name]["privateFeature"] = True
# Write the qt_feature() calls from the computed feature map
for _, args in featureCalls.items():
@@ -873,77 +887,80 @@ def parseFeature(ctx, feature, data, cm_fh):
outputType = o
outputArgs = {}
if isinstance(o, dict):
- outputType = o['type']
+ outputType = o["type"]
outputArgs = o
# Map negative feature to define:
- if outputType == 'feature':
- outputType = 'define'
- outputArgs = {'name': 'QT_NO_{}'.format(cxxFeature.upper()),
- 'negative': True,
- 'value': 1,
- 'type': 'define'}
-
- if outputType != 'define':
+ if outputType == "feature":
+ outputType = "define"
+ outputArgs = {
+ "name": f"QT_NO_{cxxFeature.upper()}",
+ "negative": True,
+ "value": 1,
+ "type": "define",
+ }
+
+ if outputType != "define":
continue
- if outputArgs.get('name') is None:
- print(' XXXX DEFINE output without name in feature {}.'.format(feature))
+ if outputArgs.get("name") is None:
+ print(f" XXXX DEFINE output without name in feature {feature}.")
continue
- cm_fh.write('qt_feature_definition("{}" "{}"'.format(cxxFeature, outputArgs.get('name')))
- if outputArgs.get('negative', False):
- cm_fh.write(' NEGATE')
- if outputArgs.get('value') is not None:
- cm_fh.write(' VALUE "{}"'.format(outputArgs.get('value')))
- cm_fh.write(')\n')
+ out_name = outputArgs.get("name")
+ cm_fh.write(f'qt_feature_definition("{cxxFeature}" "{out_name}"')
+ if outputArgs.get("negative", False):
+ cm_fh.write(" NEGATE")
+ if outputArgs.get("value") is not None:
+ cm_fh.write(' VALUE "{}"'.format(outputArgs.get("value")))
+ cm_fh.write(")\n")
def processInputs(ctx, data, cm_fh):
- print(' inputs:')
- if 'commandline' not in data:
+ print(" inputs:")
+ if "commandline" not in data:
return
- commandLine = data['commandline']
+ commandLine = data["commandline"]
if "options" not in commandLine:
return
- for input in commandLine['options']:
- parseInput(ctx, input, commandLine['options'][input], cm_fh)
+ for input in commandLine["options"]:
+ parseInput(ctx, input, commandLine["options"][input], cm_fh)
def processTests(ctx, data, cm_fh):
- print(' tests:')
- if 'tests' not in data:
+ print(" tests:")
+ if "tests" not in data:
return
- for test in data['tests']:
- parseTest(ctx, test, data['tests'][test], cm_fh)
+ for test in data["tests"]:
+ parseTest(ctx, test, data["tests"][test], cm_fh)
def processFeatures(ctx, data, cm_fh):
- print(' features:')
- if 'features' not in data:
+ print(" features:")
+ if "features" not in data:
return
- for feature in data['features']:
- parseFeature(ctx, feature, data['features'][feature], cm_fh)
+ for feature in data["features"]:
+ parseFeature(ctx, feature, data["features"][feature], cm_fh)
def processLibraries(ctx, data, cm_fh):
cmake_find_packages_set = set()
- print(' libraries:')
- if 'libraries' not in data:
+ print(" libraries:")
+ if "libraries" not in data:
return
- for lib in data['libraries']:
+ for lib in data["libraries"]:
parseLib(ctx, lib, data, cm_fh, cmake_find_packages_set)
def processSubconfigs(dir, ctx, data):
assert ctx is not None
- if 'subconfigs' in data:
- for subconf in data['subconfigs']:
+ if "subconfigs" in data:
+ for subconf in data["subconfigs"]:
subconfDir = posixpath.join(dir, subconf)
subconfData = readJsonFromDir(subconfDir)
subconfCtx = ctx
@@ -951,11 +968,11 @@ def processSubconfigs(dir, ctx, data):
def processJson(dir, ctx, data):
- ctx['module'] = data.get('module', 'global')
+ ctx["module"] = data.get("module", "global")
ctx = processFiles(ctx, data)
- with open(posixpath.join(dir, "configure.cmake"), 'w') as cm_fh:
+ with open(posixpath.join(dir, "configure.cmake"), "w") as cm_fh:
cm_fh.write("\n\n#### Inputs\n\n")
processInputs(ctx, data, cm_fh)
@@ -972,8 +989,10 @@ def processJson(dir, ctx, data):
processFeatures(ctx, data, cm_fh)
- if ctx.get('module') == 'global':
- cm_fh.write('\nqt_extra_definition("QT_VERSION_STR" "\\\"${PROJECT_VERSION}\\\"" PUBLIC)\n')
+ if ctx.get("module") == "global":
+ cm_fh.write(
+ '\nqt_extra_definition("QT_VERSION_STR" "\\"${PROJECT_VERSION}\\"" PUBLIC)\n'
+ )
cm_fh.write('qt_extra_definition("QT_VERSION_MAJOR" ${PROJECT_VERSION_MAJOR} PUBLIC)\n')
cm_fh.write('qt_extra_definition("QT_VERSION_MINOR" ${PROJECT_VERSION_MINOR} PUBLIC)\n')
cm_fh.write('qt_extra_definition("QT_VERSION_PATCH" ${PROJECT_VERSION_PATCH} PUBLIC)\n')
@@ -984,16 +1003,16 @@ def processJson(dir, ctx, data):
def main():
if len(sys.argv) != 2:
- print("This scripts needs one directory to process!")
- quit(1)
+ print("This scripts needs one directory to process!")
+ quit(1)
- dir = sys.argv[1]
+ directory = sys.argv[1]
- print("Processing: {}.".format(dir))
+ print("Processing: {}.".format(directory))
- data = readJsonFromDir(dir)
- processJson(dir, {}, data)
+ data = readJsonFromDir(directory)
+ processJson(directory, {}, data)
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/util/cmake/helper.py b/util/cmake/helper.py
index 6ad468485c2..ab4f05113bd 100644
--- a/util/cmake/helper.py
+++ b/util/cmake/helper.py
@@ -29,14 +29,19 @@
import re
import typing
+
class LibraryMapping:
- def __init__(self, soName: str,
- packageName: typing.Optional[str],
- targetName: typing.Optional[str], *,
- resultVariable: typing.Optional[str] = None,
- extra: typing.List[str] = [],
- appendFoundSuffix: bool = True,
- emit_if: str = '') -> None:
+ def __init__(
+ self,
+ soName: str,
+ packageName: typing.Optional[str],
+ targetName: typing.Optional[str],
+ *,
+ resultVariable: typing.Optional[str] = None,
+ extra: typing.List[str] = [],
+ appendFoundSuffix: bool = True,
+ emit_if: str = ""
+ ) -> None:
self.soName = soName
self.packageName = packageName
self.resultVariable = resultVariable
@@ -49,232 +54,448 @@ class LibraryMapping:
self.emit_if = emit_if
def is_qt(self) -> bool:
- return self.packageName == 'Qt' \
- or self.packageName == 'Qt5' \
- or self.packageName == 'Qt6'
+ return self.packageName == "Qt" or self.packageName == "Qt5" or self.packageName == "Qt6"
+
_qt_library_map = [
# Qt:
- LibraryMapping('accessibility_support', 'Qt6', 'Qt::AccessibilitySupport', extra = ['COMPONENTS', 'AccessibilitySupport']),
- LibraryMapping('androidextras', 'Qt6', 'Qt::AndroidExtras', extra = ['COMPONENTS', 'AndroidExtras']),
- LibraryMapping('animation', 'Qt6', 'Qt::3DAnimation', extra = ['COMPONENTS', '3DAnimation']),
- LibraryMapping('application-lib', 'Qt6', 'Qt::AppManApplication', extra = ['COMPONENTS', 'AppManApplication']),
- LibraryMapping('bluetooth', 'Qt6', 'Qt::Bluetooth', extra = ['COMPONENTS', 'Bluetooth']),
- LibraryMapping('bootstrap', 'Qt6', 'Qt::Bootstrap', extra = ['COMPONENTS', 'Bootstrap']),
+ LibraryMapping(
+ "accessibility_support",
+ "Qt6",
+ "Qt::AccessibilitySupport",
+ extra=["COMPONENTS", "AccessibilitySupport"],
+ ),
+ LibraryMapping(
+ "androidextras", "Qt6", "Qt::AndroidExtras", extra=["COMPONENTS", "AndroidExtras"]
+ ),
+ LibraryMapping("animation", "Qt6", "Qt::3DAnimation", extra=["COMPONENTS", "3DAnimation"]),
+ LibraryMapping(
+ "application-lib", "Qt6", "Qt::AppManApplication", extra=["COMPONENTS", "AppManApplication"]
+ ),
+ LibraryMapping("bluetooth", "Qt6", "Qt::Bluetooth", extra=["COMPONENTS", "Bluetooth"]),
+ LibraryMapping("bootstrap", "Qt6", "Qt::Bootstrap", extra=["COMPONENTS", "Bootstrap"]),
# bootstrap-dbus: Not needed in Qt6!
- LibraryMapping('client', 'Qt6', 'Qt::WaylandClient', extra = ['COMPONENTS', 'WaylandClient']),
- LibraryMapping('clipboard_support', 'Qt6', 'Qt::ClipboardSupport', extra = ['COMPONENTS', 'ClipboardSupport']),
- LibraryMapping('coap', 'Qt6', 'Qt::Coap', extra = ['COMPONENTS', 'Coap']),
- LibraryMapping('common-lib', 'Qt6', 'Qt::AppManCommon', extra = ['COMPONENTS', 'AppManCommon']),
- LibraryMapping('compositor', 'Qt6', 'Qt::WaylandCompositor', extra = ['COMPONENTS', 'WaylandCompositor']),
- LibraryMapping('concurrent', 'Qt6', 'Qt::Concurrent', extra = ['COMPONENTS', 'Concurrent']),
- LibraryMapping('container', 'Qt6', 'Qt::AxContainer', extra = ['COMPONENTS', 'AxContainer']),
- LibraryMapping('control', 'Qt6', 'Qt::AxServer', extra = ['COMPONENTS', 'AxServer']),
- LibraryMapping('core_headers', 'Qt6', 'Qt::WebEngineCore', extra = ['COMPONENTS', 'WebEngineCore']),
- LibraryMapping('core', 'Qt6', 'Qt::Core', extra = ['COMPONENTS', 'Core']),
- LibraryMapping('coretest', 'Qt6', 'Qt::3DCoreTest', extra = ['COMPONENTS', '3DCoreTest']),
- LibraryMapping('crypto-lib', 'Qt6', 'Qt::AppManCrypto', extra = ['COMPONENTS', 'AppManCrypto']),
- LibraryMapping('dbus', 'Qt6', 'Qt::DBus', extra = ['COMPONENTS', 'DBus']),
- LibraryMapping('designer', 'Qt6', 'Qt::Designer', extra = ['COMPONENTS', 'Designer']),
- LibraryMapping('designercomponents', 'Qt6', 'Qt::DesignerComponents', extra = ['COMPONENTS', 'DesignerComponents']),
- LibraryMapping('devicediscovery', 'Qt6', 'Qt::DeviceDiscoverySupport', extra = ['COMPONENTS', 'DeviceDiscoverySupport']),
- LibraryMapping('devicediscovery_support', 'Qt6', 'Qt::DeviceDiscoverySupport', extra = ['COMPONENTS', 'DeviceDiscoverySupport']),
- LibraryMapping('edid', 'Qt6', 'Qt::EdidSupport', extra = ['COMPONENTS', 'EdidSupport']),
- LibraryMapping('edid_support', 'Qt6', 'Qt::EdidSupport', extra = ['COMPONENTS', 'EdidSupport']),
- LibraryMapping('eglconvenience', 'Qt6', 'Qt::EglSupport', extra = ['COMPONENTS', 'EglSupport']),
- LibraryMapping('eglfsdeviceintegration', 'Qt6', 'Qt::EglFSDeviceIntegration', extra = ['COMPONENTS', 'EglFSDeviceIntegration']),
- LibraryMapping('eglfs_kms_support', 'Qt6', 'Qt::EglFsKmsSupport', extra = ['COMPONENTS', 'EglFsKmsSupport']),
- LibraryMapping('egl_support', 'Qt6', 'Qt::EglSupport', extra = ['COMPONENTS', 'EglSupport']),
+ LibraryMapping("client", "Qt6", "Qt::WaylandClient", extra=["COMPONENTS", "WaylandClient"]),
+ LibraryMapping(
+ "clipboard_support", "Qt6", "Qt::ClipboardSupport", extra=["COMPONENTS", "ClipboardSupport"]
+ ),
+ LibraryMapping("coap", "Qt6", "Qt::Coap", extra=["COMPONENTS", "Coap"]),
+ LibraryMapping("common-lib", "Qt6", "Qt::AppManCommon", extra=["COMPONENTS", "AppManCommon"]),
+ LibraryMapping(
+ "compositor", "Qt6", "Qt::WaylandCompositor", extra=["COMPONENTS", "WaylandCompositor"]
+ ),
+ LibraryMapping("concurrent", "Qt6", "Qt::Concurrent", extra=["COMPONENTS", "Concurrent"]),
+ LibraryMapping("container", "Qt6", "Qt::AxContainer", extra=["COMPONENTS", "AxContainer"]),
+ LibraryMapping("control", "Qt6", "Qt::AxServer", extra=["COMPONENTS", "AxServer"]),
+ LibraryMapping(
+ "core_headers", "Qt6", "Qt::WebEngineCore", extra=["COMPONENTS", "WebEngineCore"]
+ ),
+ LibraryMapping("core", "Qt6", "Qt::Core", extra=["COMPONENTS", "Core"]),
+ LibraryMapping("coretest", "Qt6", "Qt::3DCoreTest", extra=["COMPONENTS", "3DCoreTest"]),
+ LibraryMapping("crypto-lib", "Qt6", "Qt::AppManCrypto", extra=["COMPONENTS", "AppManCrypto"]),
+ LibraryMapping("dbus", "Qt6", "Qt::DBus", extra=["COMPONENTS", "DBus"]),
+ LibraryMapping("designer", "Qt6", "Qt::Designer", extra=["COMPONENTS", "Designer"]),
+ LibraryMapping(
+ "designercomponents",
+ "Qt6",
+ "Qt::DesignerComponents",
+ extra=["COMPONENTS", "DesignerComponents"],
+ ),
+ LibraryMapping(
+ "devicediscovery",
+ "Qt6",
+ "Qt::DeviceDiscoverySupport",
+ extra=["COMPONENTS", "DeviceDiscoverySupport"],
+ ),
+ LibraryMapping(
+ "devicediscovery_support",
+ "Qt6",
+ "Qt::DeviceDiscoverySupport",
+ extra=["COMPONENTS", "DeviceDiscoverySupport"],
+ ),
+ LibraryMapping("edid", "Qt6", "Qt::EdidSupport", extra=["COMPONENTS", "EdidSupport"]),
+ LibraryMapping("edid_support", "Qt6", "Qt::EdidSupport", extra=["COMPONENTS", "EdidSupport"]),
+ LibraryMapping("eglconvenience", "Qt6", "Qt::EglSupport", extra=["COMPONENTS", "EglSupport"]),
+ LibraryMapping(
+ "eglfsdeviceintegration",
+ "Qt6",
+ "Qt::EglFSDeviceIntegration",
+ extra=["COMPONENTS", "EglFSDeviceIntegration"],
+ ),
+ LibraryMapping(
+ "eglfs_kms_support", "Qt6", "Qt::EglFsKmsSupport", extra=["COMPONENTS", "EglFsKmsSupport"]
+ ),
+ LibraryMapping("egl_support", "Qt6", "Qt::EglSupport", extra=["COMPONENTS", "EglSupport"]),
# enginio: Not needed in Qt6!
- LibraryMapping('eventdispatchers', 'Qt6', 'Qt::EventDispatcherSupport', extra = ['COMPONENTS', 'EventDispatcherSupport']),
- LibraryMapping('eventdispatcher_support', 'Qt6', 'Qt::EventDispatcherSupport', extra = ['COMPONENTS', 'EventDispatcherSupport']),
- LibraryMapping('extras', 'Qt6', 'Qt::3DExtras', extra = ['COMPONENTS', '3DExtras']),
- LibraryMapping('fbconvenience', 'Qt6', 'Qt::FbSupport', extra = ['COMPONENTS', 'FbSupport']),
- LibraryMapping('fb_support', 'Qt6', 'Qt::FbSupport', extra = ['COMPONENTS', 'FbSupport']),
- LibraryMapping('fontdatabase_support', 'Qt6', 'Qt::FontDatabaseSupport', extra = ['COMPONENTS', 'FontDatabaseSupport']),
- LibraryMapping('gamepad', 'Qt6', 'Qt::Gamepad', extra = ['COMPONENTS', 'Gamepad']),
- LibraryMapping('global', 'Qt6', 'Qt::Core', extra = ['COMPONENTS', 'Core']), # manually added special case
- LibraryMapping('glx_support', 'Qt6', 'Qt::GlxSupport', extra = ['COMPONENTS', 'GlxSupport']),
- LibraryMapping('graphics_support', 'Qt6', 'Qt::GraphicsSupport', extra = ['COMPONENTS', 'GraphicsSupport']),
- LibraryMapping('gsttools', 'Qt6', 'Qt::MultimediaGstTools', extra = ['COMPONENTS', 'MultimediaGstTools']),
- LibraryMapping('gui', 'Qt6', 'Qt::Gui', extra = ['COMPONENTS', 'Gui']),
- LibraryMapping('help', 'Qt6', 'Qt::Help', extra = ['COMPONENTS', 'Help']),
- LibraryMapping('hunspellinputmethod', 'Qt6', 'Qt::HunspellInputMethod', extra = ['COMPONENTS', 'HunspellInputMethod']),
- LibraryMapping('input', 'Qt6', 'Qt::InputSupport', extra = ['COMPONENTS', 'InputSupport']),
- LibraryMapping('input_support', 'Qt6', 'Qt::InputSupport', extra = ['COMPONENTS', 'InputSupport']),
- LibraryMapping('installer-lib', 'Qt6', 'Qt::AppManInstaller', extra = ['COMPONENTS', 'AppManInstaller']),
- LibraryMapping('knx', 'Qt6', 'Qt::Knx', extra = ['COMPONENTS', 'Knx']),
- LibraryMapping('kmsconvenience', 'Qt6', 'Qt::KmsSupport', extra = ['COMPONENTS', 'KmsSupport']),
- LibraryMapping('kms_support', 'Qt6', 'Qt::KmsSupport', extra = ['COMPONENTS', 'KmsSupport']),
- LibraryMapping('launcher-lib', 'Qt6', 'Qt::AppManLauncher', extra = ['COMPONENTS', 'AppManLauncher']),
- LibraryMapping('lib', 'Qt6', 'Qt::Designer', extra = ['COMPONENTS', 'Designer']),
- LibraryMapping('linuxaccessibility_support', 'Qt6', 'Qt::LinuxAccessibilitySupport', extra = ['COMPONENTS', 'LinuxAccessibilitySupport']),
- LibraryMapping('location', 'Qt6', 'Qt::Location', extra = ['COMPONENTS', 'Location']),
- LibraryMapping('logic', 'Qt6', 'Qt::3DLogic', extra = ['COMPONENTS', '3DLogic']),
- LibraryMapping('macextras', 'Qt6', 'Qt::MacExtras', extra = ['COMPONENTS', 'MacExtras']),
- LibraryMapping('main-lib', 'Qt6', 'Qt::AppManMain', extra = ['COMPONENTS', 'AppManMain']),
- LibraryMapping('manager-lib', 'Qt6', 'Qt::AppManManager', extra = ['COMPONENTS', 'AppManManager']),
- LibraryMapping('monitor-lib', 'Qt6', 'Qt::AppManMonitor', extra = ['COMPONENTS', 'AppManMonitor']),
- LibraryMapping('mqtt', 'Qt6', 'Qt::Mqtt', extra = ['COMPONENTS', 'Mqtt']),
- LibraryMapping('multimedia', 'Qt6', 'Qt::Multimedia', extra = ['COMPONENTS', 'Multimedia']),
- LibraryMapping('multimediawidgets', 'Qt6', 'Qt::MultimediaWidgets', extra = ['COMPONENTS', 'MultimediaWidgets']),
- LibraryMapping('network', 'Qt6', 'Qt::Network', extra = ['COMPONENTS', 'Network']),
- LibraryMapping('networkauth', 'Qt6', 'Qt::NetworkAuth', extra = ['COMPONENTS', 'NetworkAuth']),
- LibraryMapping('nfc', 'Qt6', 'Qt::Nfc', extra = ['COMPONENTS', 'Nfc']),
- LibraryMapping('oauth', 'Qt6', 'Qt::NetworkAuth', extra = ['COMPONENTS', 'NetworkAuth']),
- LibraryMapping('openglextensions', 'Qt6', 'Qt::OpenGLExtensions', extra = ['COMPONENTS', 'OpenGLExtensions']),
- LibraryMapping('opengl', 'Qt6', 'Qt::OpenGL', extra = ['COMPONENTS', 'OpenGL']),
- LibraryMapping('package-lib', 'Qt6', 'Qt::AppManPackage', extra = ['COMPONENTS', 'AppManPackage']),
- LibraryMapping('packetprotocol', 'Qt6', 'Qt::PacketProtocol', extra = ['COMPONENTS', 'PacketProtocol']),
- LibraryMapping('particles', 'Qt6', 'Qt::QuickParticles', extra = ['COMPONENTS', 'QuickParticles']),
- LibraryMapping('platformcompositor', 'Qt6', 'Qt::PlatformCompositorSupport', extra = ['COMPONENTS', 'PlatformCompositorSupport']),
- LibraryMapping('platformcompositor_support', 'Qt6', 'Qt::PlatformCompositorSupport', extra = ['COMPONENTS', 'PlatformCompositorSupport']),
- LibraryMapping('plugin-interfaces', 'Qt6', 'Qt::AppManPluginInterfaces', extra = ['COMPONENTS', 'AppManPluginInterfaces']),
- LibraryMapping('positioning', 'Qt6', 'Qt::Positioning', extra = ['COMPONENTS', 'Positioning']),
- LibraryMapping('positioningquick', 'Qt6', 'Qt::PositioningQuick', extra = ['COMPONENTS', 'PositioningQuick']),
- LibraryMapping('printsupport', 'Qt6', 'Qt::PrintSupport', extra = ['COMPONENTS', 'PrintSupport']),
- LibraryMapping('purchasing', 'Qt6', 'Qt::Purchasing', extra = ['COMPONENTS', 'Purchasing']),
- LibraryMapping('qmldebug', 'Qt6', 'Qt::QmlDebug', extra = ['COMPONENTS', 'QmlDebug']),
- LibraryMapping('qmldevtools', 'Qt6', 'Qt::QmlDevTools', extra = ['COMPONENTS', 'QmlDevTools']),
- LibraryMapping('qml', 'Qt6', 'Qt::Qml', extra = ['COMPONENTS', 'Qml']),
- LibraryMapping('qmlmodels', 'Qt6', 'Qt::QmlModels', extra = ['COMPONENTS', 'QmlModels']),
- LibraryMapping('qmltest', 'Qt6', 'Qt::QuickTest', extra = ['COMPONENTS', 'QuickTest']),
- LibraryMapping('qtmultimediaquicktools', 'Qt6', 'Qt::MultimediaQuick', extra = ['COMPONENTS', 'MultimediaQuick']),
- LibraryMapping('quick3danimation', 'Qt6', 'Qt::3DQuickAnimation', extra = ['COMPONENTS', '3DQuickAnimation']),
- LibraryMapping('quick3dextras', 'Qt6', 'Qt::3DQuickExtras', extra = ['COMPONENTS', '3DQuickExtras']),
- LibraryMapping('quick3dinput', 'Qt6', 'Qt::3DQuickInput', extra = ['COMPONENTS', '3DQuickInput']),
- LibraryMapping('quick3d', 'Qt6', 'Qt::3DQuick', extra = ['COMPONENTS', '3DQuick']),
- LibraryMapping('quick3drender', 'Qt6', 'Qt::3DQuickRender', extra = ['COMPONENTS', '3DQuickRender']),
- LibraryMapping('quick3dscene2d', 'Qt6', 'Qt::3DQuickScene2D', extra = ['COMPONENTS', '3DQuickScene2D']),
- LibraryMapping('quickcontrols2', 'Qt6', 'Qt::QuickControls2', extra = ['COMPONENTS', 'QuickControls2']),
- LibraryMapping('quick', 'Qt6', 'Qt::Quick', extra = ['COMPONENTS', 'Quick']),
- LibraryMapping('quickshapes', 'Qt6', 'Qt::QuickShapes', extra = ['COMPONENTS', 'QuickShapes']),
- LibraryMapping('quicktemplates2', 'Qt6', 'Qt::QuickTemplates2', extra = ['COMPONENTS', 'QuickTemplates2']),
- LibraryMapping('quickwidgets', 'Qt6', 'Qt::QuickWidgets', extra = ['COMPONENTS', 'QuickWidgets']),
- LibraryMapping('render', 'Qt6', 'Qt::3DRender', extra = ['COMPONENTS', '3DRender']),
- LibraryMapping('script', 'Qt6', 'Qt::Script', extra = ['COMPONENTS', 'Script']),
- LibraryMapping('scripttools', 'Qt6', 'Qt::ScriptTools', extra = ['COMPONENTS', 'ScriptTools']),
- LibraryMapping('sensors', 'Qt6', 'Qt::Sensors', extra = ['COMPONENTS', 'Sensors']),
- LibraryMapping('serialport', 'Qt6', 'Qt::SerialPort', extra = ['COMPONENTS', 'SerialPort']),
- LibraryMapping('serialbus', 'Qt6', 'Qt::SerialBus', extra = ['COMPONENTS', 'SerialBus']),
- LibraryMapping('services', 'Qt6', 'Qt::ServiceSupport', extra = ['COMPONENTS', 'ServiceSupport']),
- LibraryMapping('service_support', 'Qt6', 'Qt::ServiceSupport', extra = ['COMPONENTS', 'ServiceSupport']),
- LibraryMapping('sql', 'Qt6', 'Qt::Sql', extra = ['COMPONENTS', 'Sql']),
- LibraryMapping('svg', 'Qt6', 'Qt::Svg', extra = ['COMPONENTS', 'Svg']),
- LibraryMapping('testlib', 'Qt6', 'Qt::Test', extra = ['COMPONENTS', 'Test']),
- LibraryMapping('texttospeech', 'Qt6', 'Qt::TextToSpeech', extra = ['COMPONENTS', 'TextToSpeech']),
- LibraryMapping('theme_support', 'Qt6', 'Qt::ThemeSupport', extra = ['COMPONENTS', 'ThemeSupport']),
- LibraryMapping('tts', 'Qt6', 'Qt::TextToSpeech', extra = ['COMPONENTS', 'TextToSpeech']),
- LibraryMapping('uiplugin', 'Qt6', 'Qt::UiPlugin', extra = ['COMPONENTS', 'UiPlugin']),
- LibraryMapping('uitools', 'Qt6', 'Qt::UiTools', extra = ['COMPONENTS', 'UiTools']),
- LibraryMapping('virtualkeyboard', 'Qt6', 'Qt::VirtualKeyboard', extra = ['COMPONENTS', 'VirtualKeyboard']),
- LibraryMapping('vulkan_support', 'Qt6', 'Qt::VulkanSupport', extra = ['COMPONENTS', 'VulkanSupport']),
- LibraryMapping('waylandclient', 'Qt6', 'Qt::WaylandClient', extra = ['COMPONENTS', 'WaylandClient']),
- LibraryMapping('webchannel', 'Qt6', 'Qt::WebChannel', extra = ['COMPONENTS', 'WebChannel']),
- LibraryMapping('webengine', 'Qt6', 'Qt::WebEngine', extra = ['COMPONENTS', 'WebEngine']),
- LibraryMapping('webenginewidgets', 'Qt6', 'Qt::WebEngineWidgets', extra = ['COMPONENTS', 'WebEngineWidgets']),
- LibraryMapping('websockets', 'Qt6', 'Qt::WebSockets', extra = ['COMPONENTS', 'WebSockets']),
- LibraryMapping('webview', 'Qt6', 'Qt::WebView', extra = ['COMPONENTS', 'WebView']),
- LibraryMapping('widgets', 'Qt6', 'Qt::Widgets', extra = ['COMPONENTS', 'Widgets']),
- LibraryMapping('window-lib', 'Qt6', 'Qt::AppManWindow', extra = ['COMPONENTS', 'AppManWindow']),
- LibraryMapping('windowsuiautomation_support', 'Qt6', 'Qt::WindowsUIAutomationSupport', extra = ['COMPONENTS', 'WindowsUIAutomationSupport']),
- LibraryMapping('winextras', 'Qt6', 'Qt::WinExtras', extra = ['COMPONENTS', 'WinExtras']),
- LibraryMapping('x11extras', 'Qt6', 'Qt::X11Extras', extra = ['COMPONENTS', 'X11Extras']),
- LibraryMapping('xcb_qpa_lib', 'Qt6', 'Qt::XcbQpa', extra = ['COMPONENTS', 'XcbQpa']),
- LibraryMapping('xkbcommon_support', 'Qt6', 'Qt::XkbCommonSupport', extra = ['COMPONENTS', 'XkbCommonSupport']),
- LibraryMapping('xmlpatterns', 'Qt6', 'Qt::XmlPatterns', extra = ['COMPONENTS', 'XmlPatterns']),
- LibraryMapping('xml', 'Qt6', 'Qt::Xml', extra = ['COMPONENTS', 'Xml']),
- LibraryMapping('qmlworkerscript', 'Qt6', 'Qt::QmlWorkerScript', extra = ['COMPONENTS', 'QmlWorkerScript']),
- LibraryMapping('quickparticles', 'Qt6', 'Qt::QuickParticles', extra = ['COMPONENTS', 'QuickParticles'])
+ LibraryMapping(
+ "eventdispatchers",
+ "Qt6",
+ "Qt::EventDispatcherSupport",
+ extra=["COMPONENTS", "EventDispatcherSupport"],
+ ),
+ LibraryMapping(
+ "eventdispatcher_support",
+ "Qt6",
+ "Qt::EventDispatcherSupport",
+ extra=["COMPONENTS", "EventDispatcherSupport"],
+ ),
+ LibraryMapping("extras", "Qt6", "Qt::3DExtras", extra=["COMPONENTS", "3DExtras"]),
+ LibraryMapping("fbconvenience", "Qt6", "Qt::FbSupport", extra=["COMPONENTS", "FbSupport"]),
+ LibraryMapping("fb_support", "Qt6", "Qt::FbSupport", extra=["COMPONENTS", "FbSupport"]),
+ LibraryMapping(
+ "fontdatabase_support",
+ "Qt6",
+ "Qt::FontDatabaseSupport",
+ extra=["COMPONENTS", "FontDatabaseSupport"],
+ ),
+ LibraryMapping("gamepad", "Qt6", "Qt::Gamepad", extra=["COMPONENTS", "Gamepad"]),
+ LibraryMapping(
+ "global", "Qt6", "Qt::Core", extra=["COMPONENTS", "Core"]
+ ), # manually added special case
+ LibraryMapping("glx_support", "Qt6", "Qt::GlxSupport", extra=["COMPONENTS", "GlxSupport"]),
+ LibraryMapping(
+ "graphics_support", "Qt6", "Qt::GraphicsSupport", extra=["COMPONENTS", "GraphicsSupport"]
+ ),
+ LibraryMapping(
+ "gsttools", "Qt6", "Qt::MultimediaGstTools", extra=["COMPONENTS", "MultimediaGstTools"]
+ ),
+ LibraryMapping("gui", "Qt6", "Qt::Gui", extra=["COMPONENTS", "Gui"]),
+ LibraryMapping("help", "Qt6", "Qt::Help", extra=["COMPONENTS", "Help"]),
+ LibraryMapping(
+ "hunspellinputmethod",
+ "Qt6",
+ "Qt::HunspellInputMethod",
+ extra=["COMPONENTS", "HunspellInputMethod"],
+ ),
+ LibraryMapping("input", "Qt6", "Qt::InputSupport", extra=["COMPONENTS", "InputSupport"]),
+ LibraryMapping(
+ "input_support", "Qt6", "Qt::InputSupport", extra=["COMPONENTS", "InputSupport"]
+ ),
+ LibraryMapping(
+ "installer-lib", "Qt6", "Qt::AppManInstaller", extra=["COMPONENTS", "AppManInstaller"]
+ ),
+ LibraryMapping("knx", "Qt6", "Qt::Knx", extra=["COMPONENTS", "Knx"]),
+ LibraryMapping("kmsconvenience", "Qt6", "Qt::KmsSupport", extra=["COMPONENTS", "KmsSupport"]),
+ LibraryMapping("kms_support", "Qt6", "Qt::KmsSupport", extra=["COMPONENTS", "KmsSupport"]),
+ LibraryMapping(
+ "launcher-lib", "Qt6", "Qt::AppManLauncher", extra=["COMPONENTS", "AppManLauncher"]
+ ),
+ LibraryMapping("lib", "Qt6", "Qt::Designer", extra=["COMPONENTS", "Designer"]),
+ LibraryMapping(
+ "linuxaccessibility_support",
+ "Qt6",
+ "Qt::LinuxAccessibilitySupport",
+ extra=["COMPONENTS", "LinuxAccessibilitySupport"],
+ ),
+ LibraryMapping("location", "Qt6", "Qt::Location", extra=["COMPONENTS", "Location"]),
+ LibraryMapping("logic", "Qt6", "Qt::3DLogic", extra=["COMPONENTS", "3DLogic"]),
+ LibraryMapping("macextras", "Qt6", "Qt::MacExtras", extra=["COMPONENTS", "MacExtras"]),
+ LibraryMapping("main-lib", "Qt6", "Qt::AppManMain", extra=["COMPONENTS", "AppManMain"]),
+ LibraryMapping(
+ "manager-lib", "Qt6", "Qt::AppManManager", extra=["COMPONENTS", "AppManManager"]
+ ),
+ LibraryMapping(
+ "monitor-lib", "Qt6", "Qt::AppManMonitor", extra=["COMPONENTS", "AppManMonitor"]
+ ),
+ LibraryMapping("mqtt", "Qt6", "Qt::Mqtt", extra=["COMPONENTS", "Mqtt"]),
+ LibraryMapping("multimedia", "Qt6", "Qt::Multimedia", extra=["COMPONENTS", "Multimedia"]),
+ LibraryMapping(
+ "multimediawidgets",
+ "Qt6",
+ "Qt::MultimediaWidgets",
+ extra=["COMPONENTS", "MultimediaWidgets"],
+ ),
+ LibraryMapping("network", "Qt6", "Qt::Network", extra=["COMPONENTS", "Network"]),
+ LibraryMapping("networkauth", "Qt6", "Qt::NetworkAuth", extra=["COMPONENTS", "NetworkAuth"]),
+ LibraryMapping("nfc", "Qt6", "Qt::Nfc", extra=["COMPONENTS", "Nfc"]),
+ LibraryMapping("oauth", "Qt6", "Qt::NetworkAuth", extra=["COMPONENTS", "NetworkAuth"]),
+ LibraryMapping(
+ "openglextensions", "Qt6", "Qt::OpenGLExtensions", extra=["COMPONENTS", "OpenGLExtensions"]
+ ),
+ LibraryMapping("opengl", "Qt6", "Qt::OpenGL", extra=["COMPONENTS", "OpenGL"]),
+ LibraryMapping(
+ "package-lib", "Qt6", "Qt::AppManPackage", extra=["COMPONENTS", "AppManPackage"]
+ ),
+ LibraryMapping(
+ "packetprotocol", "Qt6", "Qt::PacketProtocol", extra=["COMPONENTS", "PacketProtocol"]
+ ),
+ LibraryMapping(
+ "particles", "Qt6", "Qt::QuickParticles", extra=["COMPONENTS", "QuickParticles"]
+ ),
+ LibraryMapping(
+ "platformcompositor",
+ "Qt6",
+ "Qt::PlatformCompositorSupport",
+ extra=["COMPONENTS", "PlatformCompositorSupport"],
+ ),
+ LibraryMapping(
+ "platformcompositor_support",
+ "Qt6",
+ "Qt::PlatformCompositorSupport",
+ extra=["COMPONENTS", "PlatformCompositorSupport"],
+ ),
+ LibraryMapping(
+ "plugin-interfaces",
+ "Qt6",
+ "Qt::AppManPluginInterfaces",
+ extra=["COMPONENTS", "AppManPluginInterfaces"],
+ ),
+ LibraryMapping("positioning", "Qt6", "Qt::Positioning", extra=["COMPONENTS", "Positioning"]),
+ LibraryMapping(
+ "positioningquick", "Qt6", "Qt::PositioningQuick", extra=["COMPONENTS", "PositioningQuick"]
+ ),
+ LibraryMapping("printsupport", "Qt6", "Qt::PrintSupport", extra=["COMPONENTS", "PrintSupport"]),
+ LibraryMapping("purchasing", "Qt6", "Qt::Purchasing", extra=["COMPONENTS", "Purchasing"]),
+ LibraryMapping("qmldebug", "Qt6", "Qt::QmlDebug", extra=["COMPONENTS", "QmlDebug"]),
+ LibraryMapping("qmldevtools", "Qt6", "Qt::QmlDevTools", extra=["COMPONENTS", "QmlDevTools"]),
+ LibraryMapping("qml", "Qt6", "Qt::Qml", extra=["COMPONENTS", "Qml"]),
+ LibraryMapping("qmlmodels", "Qt6", "Qt::QmlModels", extra=["COMPONENTS", "QmlModels"]),
+ LibraryMapping("qmltest", "Qt6", "Qt::QuickTest", extra=["COMPONENTS", "QuickTest"]),
+ LibraryMapping(
+ "qtmultimediaquicktools",
+ "Qt6",
+ "Qt::MultimediaQuick",
+ extra=["COMPONENTS", "MultimediaQuick"],
+ ),
+ LibraryMapping(
+ "quick3danimation", "Qt6", "Qt::3DQuickAnimation", extra=["COMPONENTS", "3DQuickAnimation"]
+ ),
+ LibraryMapping(
+ "quick3dextras", "Qt6", "Qt::3DQuickExtras", extra=["COMPONENTS", "3DQuickExtras"]
+ ),
+ LibraryMapping("quick3dinput", "Qt6", "Qt::3DQuickInput", extra=["COMPONENTS", "3DQuickInput"]),
+ LibraryMapping("quick3d", "Qt6", "Qt::3DQuick", extra=["COMPONENTS", "3DQuick"]),
+ LibraryMapping(
+ "quick3drender", "Qt6", "Qt::3DQuickRender", extra=["COMPONENTS", "3DQuickRender"]
+ ),
+ LibraryMapping(
+ "quick3dscene2d", "Qt6", "Qt::3DQuickScene2D", extra=["COMPONENTS", "3DQuickScene2D"]
+ ),
+ LibraryMapping(
+ "quickcontrols2", "Qt6", "Qt::QuickControls2", extra=["COMPONENTS", "QuickControls2"]
+ ),
+ LibraryMapping("quick", "Qt6", "Qt::Quick", extra=["COMPONENTS", "Quick"]),
+ LibraryMapping("quickshapes", "Qt6", "Qt::QuickShapes", extra=["COMPONENTS", "QuickShapes"]),
+ LibraryMapping(
+ "quicktemplates2", "Qt6", "Qt::QuickTemplates2", extra=["COMPONENTS", "QuickTemplates2"]
+ ),
+ LibraryMapping("quickwidgets", "Qt6", "Qt::QuickWidgets", extra=["COMPONENTS", "QuickWidgets"]),
+ LibraryMapping("render", "Qt6", "Qt::3DRender", extra=["COMPONENTS", "3DRender"]),
+ LibraryMapping("script", "Qt6", "Qt::Script", extra=["COMPONENTS", "Script"]),
+ LibraryMapping("scripttools", "Qt6", "Qt::ScriptTools", extra=["COMPONENTS", "ScriptTools"]),
+ LibraryMapping("sensors", "Qt6", "Qt::Sensors", extra=["COMPONENTS", "Sensors"]),
+ LibraryMapping("serialport", "Qt6", "Qt::SerialPort", extra=["COMPONENTS", "SerialPort"]),
+ LibraryMapping("serialbus", "Qt6", "Qt::SerialBus", extra=["COMPONENTS", "SerialBus"]),
+ LibraryMapping("services", "Qt6", "Qt::ServiceSupport", extra=["COMPONENTS", "ServiceSupport"]),
+ LibraryMapping(
+ "service_support", "Qt6", "Qt::ServiceSupport", extra=["COMPONENTS", "ServiceSupport"]
+ ),
+ LibraryMapping("sql", "Qt6", "Qt::Sql", extra=["COMPONENTS", "Sql"]),
+ LibraryMapping("svg", "Qt6", "Qt::Svg", extra=["COMPONENTS", "Svg"]),
+ LibraryMapping("testlib", "Qt6", "Qt::Test", extra=["COMPONENTS", "Test"]),
+ LibraryMapping("texttospeech", "Qt6", "Qt::TextToSpeech", extra=["COMPONENTS", "TextToSpeech"]),
+ LibraryMapping(
+ "theme_support", "Qt6", "Qt::ThemeSupport", extra=["COMPONENTS", "ThemeSupport"]
+ ),
+ LibraryMapping("tts", "Qt6", "Qt::TextToSpeech", extra=["COMPONENTS", "TextToSpeech"]),
+ LibraryMapping("uiplugin", "Qt6", "Qt::UiPlugin", extra=["COMPONENTS", "UiPlugin"]),
+ LibraryMapping("uitools", "Qt6", "Qt::UiTools", extra=["COMPONENTS", "UiTools"]),
+ LibraryMapping(
+ "virtualkeyboard", "Qt6", "Qt::VirtualKeyboard", extra=["COMPONENTS", "VirtualKeyboard"]
+ ),
+ LibraryMapping(
+ "vulkan_support", "Qt6", "Qt::VulkanSupport", extra=["COMPONENTS", "VulkanSupport"]
+ ),
+ LibraryMapping(
+ "waylandclient", "Qt6", "Qt::WaylandClient", extra=["COMPONENTS", "WaylandClient"]
+ ),
+ LibraryMapping("webchannel", "Qt6", "Qt::WebChannel", extra=["COMPONENTS", "WebChannel"]),
+ LibraryMapping("webengine", "Qt6", "Qt::WebEngine", extra=["COMPONENTS", "WebEngine"]),
+ LibraryMapping(
+ "webenginewidgets", "Qt6", "Qt::WebEngineWidgets", extra=["COMPONENTS", "WebEngineWidgets"]
+ ),
+ LibraryMapping("websockets", "Qt6", "Qt::WebSockets", extra=["COMPONENTS", "WebSockets"]),
+ LibraryMapping("webview", "Qt6", "Qt::WebView", extra=["COMPONENTS", "WebView"]),
+ LibraryMapping("widgets", "Qt6", "Qt::Widgets", extra=["COMPONENTS", "Widgets"]),
+ LibraryMapping("window-lib", "Qt6", "Qt::AppManWindow", extra=["COMPONENTS", "AppManWindow"]),
+ LibraryMapping(
+ "windowsuiautomation_support",
+ "Qt6",
+ "Qt::WindowsUIAutomationSupport",
+ extra=["COMPONENTS", "WindowsUIAutomationSupport"],
+ ),
+ LibraryMapping("winextras", "Qt6", "Qt::WinExtras", extra=["COMPONENTS", "WinExtras"]),
+ LibraryMapping("x11extras", "Qt6", "Qt::X11Extras", extra=["COMPONENTS", "X11Extras"]),
+ LibraryMapping("xcb_qpa_lib", "Qt6", "Qt::XcbQpa", extra=["COMPONENTS", "XcbQpa"]),
+ LibraryMapping(
+ "xkbcommon_support", "Qt6", "Qt::XkbCommonSupport", extra=["COMPONENTS", "XkbCommonSupport"]
+ ),
+ LibraryMapping("xmlpatterns", "Qt6", "Qt::XmlPatterns", extra=["COMPONENTS", "XmlPatterns"]),
+ LibraryMapping("xml", "Qt6", "Qt::Xml", extra=["COMPONENTS", "Xml"]),
+ LibraryMapping(
+ "qmlworkerscript", "Qt6", "Qt::QmlWorkerScript", extra=["COMPONENTS", "QmlWorkerScript"]
+ ),
+ LibraryMapping(
+ "quickparticles", "Qt6", "Qt::QuickParticles", extra=["COMPONENTS", "QuickParticles"]
+ )
# qtzlib: No longer supported.
]
# Note that the library map is adjusted dynamically further down.
_library_map = [
# 3rd party:
- LibraryMapping('atspi', 'ATSPI2', 'PkgConfig::ATSPI2'),
- LibraryMapping('corewlan', None, None),
- LibraryMapping('cups', 'Cups', 'Cups::Cups'),
- LibraryMapping('db2', 'DB2', 'DB2::DB2'),
- LibraryMapping('dbus', 'WrapDBus1', 'dbus-1', resultVariable="DBus1"),
- LibraryMapping('doubleconversion', None, None),
- LibraryMapping('drm', 'Libdrm', 'Libdrm::Libdrm'),
- LibraryMapping('egl', 'EGL', 'EGL::EGL'),
- LibraryMapping('flite', 'Flite', 'Flite::Flite'),
- LibraryMapping('flite_alsa', 'ALSA', 'ALSA::ALSA'),
- LibraryMapping('fontconfig', 'Fontconfig', 'Fontconfig::Fontconfig', resultVariable="FONTCONFIG"),
- LibraryMapping('freetype', 'WrapFreetype', 'WrapFreetype::WrapFreetype', extra=['REQUIRED']),
- LibraryMapping('gbm', 'gbm', 'gbm::gbm'),
- LibraryMapping('glib', 'GLIB2', 'GLIB2::GLIB2'),
- LibraryMapping('gnu_iconv', None, None),
- LibraryMapping('gtk3', 'GTK3', 'PkgConfig::GTK3'),
- LibraryMapping('harfbuzz', 'harfbuzz', 'harfbuzz::harfbuzz'),
- LibraryMapping('host_dbus', None, None),
- LibraryMapping('icu', 'ICU', 'ICU::i18n ICU::uc ICU::data', extra=['COMPONENTS', 'i18n', 'uc', 'data']),
- LibraryMapping('journald', 'Libsystemd', 'PkgConfig::Libsystemd'),
- LibraryMapping('jpeg', 'JPEG', 'JPEG::JPEG'), # see also libjpeg
- LibraryMapping('libatomic', 'Atomic', 'Atomic'),
- LibraryMapping('libclang', 'WrapLibClang', 'WrapLibClang::WrapLibClang'),
- LibraryMapping('libdl', None, '${CMAKE_DL_LIBS}'),
- LibraryMapping('libinput', 'Libinput', 'Libinput::Libinput'),
- LibraryMapping('libjpeg', 'JPEG', 'JPEG::JPEG'), # see also jpeg
- LibraryMapping('libpng', 'PNG', 'PNG::PNG'),
- LibraryMapping('libproxy', 'Libproxy', 'PkgConfig::Libproxy'),
- LibraryMapping('librt', 'WrapRt','WrapRt'),
- LibraryMapping('libudev', 'Libudev', 'PkgConfig::Libudev'),
- LibraryMapping('lttng-ust', 'LTTngUST', 'LTTng::UST', resultVariable='LTTNGUST'),
- LibraryMapping('mtdev', 'Mtdev', 'PkgConfig::Mtdev'),
- LibraryMapping('mysql', 'MySQL', 'MySQL::MySQL'),
- LibraryMapping('odbc', 'ODBC', 'ODBC::ODBC'),
- LibraryMapping('opengl_es2', 'GLESv2', 'GLESv2::GLESv2'),
- LibraryMapping('opengl', 'OpenGL', 'OpenGL::GL', resultVariable='OpenGL_OpenGL'),
- LibraryMapping('openssl_headers', 'OpenSSL', 'OpenSSL::SSL_nolink', resultVariable='OPENSSL_INCLUDE_DIR', appendFoundSuffix=False),
- LibraryMapping('openssl', 'OpenSSL', 'OpenSSL::SSL'),
- LibraryMapping('oci', 'Oracle', 'Oracle::OCI'),
- LibraryMapping('pcre2', 'WrapPCRE2', 'WrapPCRE2::WrapPCRE2', extra = ['REQUIRED']),
- LibraryMapping('posix_iconv', None, None),
- LibraryMapping('pps', 'PPS', 'PPS::PPS'),
- LibraryMapping('psql', 'PostgreSQL', 'PostgreSQL::PostgreSQL'),
- LibraryMapping('slog2', 'Slog2', 'Slog2::Slog2'),
- LibraryMapping('speechd', 'SpeechDispatcher', 'SpeechDispatcher::SpeechDispatcher'),
- LibraryMapping('sqlite2', None, None), # No more sqlite2 support in Qt6!
- LibraryMapping('sqlite3', 'SQLite3', 'SQLite::SQLite3'),
- LibraryMapping('sun_iconv', None, None),
- LibraryMapping('tslib', 'Tslib', 'PkgConfig::Tslib'),
- LibraryMapping('udev', 'Libudev', 'PkgConfig::Libudev'),
- LibraryMapping('udev', 'Libudev', 'PkgConfig::Libudev'), # see also libudev!
- LibraryMapping('vulkan', 'Vulkan', 'Vulkan::Vulkan'),
- LibraryMapping('wayland-server', 'Wayland', 'Wayland::Server'),
- LibraryMapping('wayland-client', 'Wayland', 'Wayland::Client'),
- LibraryMapping('wayland-cursor', 'Wayland', 'Wayland::Cursor'),
- LibraryMapping('wayland-egl', 'Wayland', 'Wayland::Egl'),
- LibraryMapping('x11sm', 'X11', '${X11_SM_LIB} ${X11_ICE_LIB}', resultVariable="X11_SM"),
- LibraryMapping('xcb', 'XCB', 'XCB::XCB', extra = ['1.9'], resultVariable='TARGET XCB::XCB', appendFoundSuffix=False),
- LibraryMapping('xcb_glx', 'XCB', 'XCB::GLX', extra = ['COMPONENTS', 'GLX'], resultVariable='XCB_GLX'),
- LibraryMapping('xcb_icccm', 'XCB', 'XCB::ICCCM', extra = ['COMPONENTS', 'ICCCM'], resultVariable='XCB_ICCCM'),
- LibraryMapping('xcb_image', 'XCB', 'XCB::IMAGE', extra = ['COMPONENTS', 'IMAGE'], resultVariable='XCB_IMAGE'),
- LibraryMapping('xcb_keysyms', 'XCB', 'XCB::KEYSYMS', extra = ['COMPONENTS', 'KEYSYMS'], resultVariable='XCB_KEYSYMS'),
- LibraryMapping('xcb_randr', 'XCB', 'XCB::RANDR', extra = ['COMPONENTS', 'RANDR'], resultVariable='XCB_RANDR'),
- LibraryMapping('xcb_render', 'XCB', 'XCB::RENDER', extra = ['COMPONENTS', 'RENDER'], resultVariable='XCB_RENDER'),
- LibraryMapping('xcb_renderutil', 'XCB', 'XCB::RENDERUTIL', extra = ['COMPONENTS', 'RENDERUTIL'], resultVariable='XCB_RENDERUTIL'),
- LibraryMapping('xcb_shape', 'XCB', 'XCB::SHAPE', extra = ['COMPONENTS', 'SHAPE'], resultVariable='XCB_SHAPE'),
- LibraryMapping('xcb_shm', 'XCB', 'XCB::SHM', extra = ['COMPONENTS', 'SHM'], resultVariable='XCB_SHM'),
- LibraryMapping('xcb_sync', 'XCB', 'XCB::SYNC', extra = ['COMPONENTS', 'SYNC'], resultVariable='XCB_SYNC'),
- LibraryMapping('xcb_xfixes', 'XCB', 'XCB::XFIXES', extra = ['COMPONENTS', 'XFIXES'], resultVariable='XCB_XFIXES'),
- LibraryMapping('xcb_xinerama', 'XCB', 'XCB::XINERAMA', extra = ['COMPONENTS', 'XINERAMA'], resultVariable='XCB_XINERAMA'),
- LibraryMapping('xcb_xinput', 'XCB', 'XCB::XINPUT', extra = ['COMPONENTS', 'XINPUT'], resultVariable='XCB_XINPUT'),
- LibraryMapping('xcb_xkb', 'XCB', 'XCB::XKB', extra = ['COMPONENTS', 'XKB'], resultVariable='XCB_XKB'),
- LibraryMapping('xcb_xlib', 'X11_XCB', 'X11::XCB'),
- LibraryMapping('xkbcommon_evdev', 'XKB', 'XKB::XKB', extra = ['0.4.1']), # see also xkbcommon
- LibraryMapping('xkbcommon_x11', 'XKB', 'XKB::XKB', extra = ['0.4.1']), # see also xkbcommon
- LibraryMapping('xkbcommon', 'XKB', 'XKB::XKB', extra = ['0.4.1']),
- LibraryMapping('xlib', 'X11', 'X11::XCB'), # FIXME: Is this correct?
- LibraryMapping('xrender', 'XRender', 'PkgConfig::XRender'),
- LibraryMapping('zlib', 'ZLIB', 'ZLIB::ZLIB', extra=['REQUIRED']),
- LibraryMapping('zstd', 'ZSTD', 'ZSTD::ZSTD'),
- LibraryMapping('tiff', 'TIFF', 'TIFF::TIFF'),
- LibraryMapping('webp', 'WrapWebP', 'WrapWebP::WrapWebP'),
- LibraryMapping('jasper', 'WrapJasper', 'WrapJasper::WrapJasper'),
+ LibraryMapping("atspi", "ATSPI2", "PkgConfig::ATSPI2"),
+ LibraryMapping("corewlan", None, None),
+ LibraryMapping("cups", "Cups", "Cups::Cups"),
+ LibraryMapping("db2", "DB2", "DB2::DB2"),
+ LibraryMapping("dbus", "WrapDBus1", "dbus-1", resultVariable="DBus1"),
+ LibraryMapping("doubleconversion", None, None),
+ LibraryMapping("drm", "Libdrm", "Libdrm::Libdrm"),
+ LibraryMapping("egl", "EGL", "EGL::EGL"),
+ LibraryMapping("flite", "Flite", "Flite::Flite"),
+ LibraryMapping("flite_alsa", "ALSA", "ALSA::ALSA"),
+ LibraryMapping(
+ "fontconfig", "Fontconfig", "Fontconfig::Fontconfig", resultVariable="FONTCONFIG"
+ ),
+ LibraryMapping("freetype", "WrapFreetype", "WrapFreetype::WrapFreetype", extra=["REQUIRED"]),
+ LibraryMapping("gbm", "gbm", "gbm::gbm"),
+ LibraryMapping("glib", "GLIB2", "GLIB2::GLIB2"),
+ LibraryMapping("gnu_iconv", None, None),
+ LibraryMapping("gtk3", "GTK3", "PkgConfig::GTK3"),
+ LibraryMapping("harfbuzz", "harfbuzz", "harfbuzz::harfbuzz"),
+ LibraryMapping("host_dbus", None, None),
+ LibraryMapping(
+ "icu", "ICU", "ICU::i18n ICU::uc ICU::data", extra=["COMPONENTS", "i18n", "uc", "data"]
+ ),
+ LibraryMapping("journald", "Libsystemd", "PkgConfig::Libsystemd"),
+ LibraryMapping("jpeg", "JPEG", "JPEG::JPEG"), # see also libjpeg
+ LibraryMapping("libatomic", "Atomic", "Atomic"),
+ LibraryMapping("libclang", "WrapLibClang", "WrapLibClang::WrapLibClang"),
+ LibraryMapping("libdl", None, "${CMAKE_DL_LIBS}"),
+ LibraryMapping("libinput", "Libinput", "Libinput::Libinput"),
+ LibraryMapping("libjpeg", "JPEG", "JPEG::JPEG"), # see also jpeg
+ LibraryMapping("libpng", "PNG", "PNG::PNG"),
+ LibraryMapping("libproxy", "Libproxy", "PkgConfig::Libproxy"),
+ LibraryMapping("librt", "WrapRt", "WrapRt"),
+ LibraryMapping("libudev", "Libudev", "PkgConfig::Libudev"),
+ LibraryMapping("lttng-ust", "LTTngUST", "LTTng::UST", resultVariable="LTTNGUST"),
+ LibraryMapping("mtdev", "Mtdev", "PkgConfig::Mtdev"),
+ LibraryMapping("mysql", "MySQL", "MySQL::MySQL"),
+ LibraryMapping("odbc", "ODBC", "ODBC::ODBC"),
+ LibraryMapping("opengl_es2", "GLESv2", "GLESv2::GLESv2"),
+ LibraryMapping("opengl", "OpenGL", "OpenGL::GL", resultVariable="OpenGL_OpenGL"),
+ LibraryMapping(
+ "openssl_headers",
+ "OpenSSL",
+ "OpenSSL::SSL_nolink",
+ resultVariable="OPENSSL_INCLUDE_DIR",
+ appendFoundSuffix=False,
+ ),
+ LibraryMapping("openssl", "OpenSSL", "OpenSSL::SSL"),
+ LibraryMapping("oci", "Oracle", "Oracle::OCI"),
+ LibraryMapping("pcre2", "WrapPCRE2", "WrapPCRE2::WrapPCRE2", extra=["REQUIRED"]),
+ LibraryMapping("posix_iconv", None, None),
+ LibraryMapping("pps", "PPS", "PPS::PPS"),
+ LibraryMapping("psql", "PostgreSQL", "PostgreSQL::PostgreSQL"),
+ LibraryMapping("slog2", "Slog2", "Slog2::Slog2"),
+ LibraryMapping("speechd", "SpeechDispatcher", "SpeechDispatcher::SpeechDispatcher"),
+ LibraryMapping("sqlite2", None, None), # No more sqlite2 support in Qt6!
+ LibraryMapping("sqlite3", "SQLite3", "SQLite::SQLite3"),
+ LibraryMapping("sun_iconv", None, None),
+ LibraryMapping("tslib", "Tslib", "PkgConfig::Tslib"),
+ LibraryMapping("udev", "Libudev", "PkgConfig::Libudev"),
+ LibraryMapping("udev", "Libudev", "PkgConfig::Libudev"), # see also libudev!
+ LibraryMapping("vulkan", "Vulkan", "Vulkan::Vulkan"),
+ LibraryMapping("wayland-server", "Wayland", "Wayland::Server"),
+ LibraryMapping("wayland-client", "Wayland", "Wayland::Client"),
+ LibraryMapping("wayland-cursor", "Wayland", "Wayland::Cursor"),
+ LibraryMapping("wayland-egl", "Wayland", "Wayland::Egl"),
+ LibraryMapping("x11sm", "X11", "${X11_SM_LIB} ${X11_ICE_LIB}", resultVariable="X11_SM"),
+ LibraryMapping(
+ "xcb",
+ "XCB",
+ "XCB::XCB",
+ extra=["1.9"],
+ resultVariable="TARGET XCB::XCB",
+ appendFoundSuffix=False,
+ ),
+ LibraryMapping(
+ "xcb_glx", "XCB", "XCB::GLX", extra=["COMPONENTS", "GLX"], resultVariable="XCB_GLX"
+ ),
+ LibraryMapping(
+ "xcb_icccm", "XCB", "XCB::ICCCM", extra=["COMPONENTS", "ICCCM"], resultVariable="XCB_ICCCM"
+ ),
+ LibraryMapping(
+ "xcb_image", "XCB", "XCB::IMAGE", extra=["COMPONENTS", "IMAGE"], resultVariable="XCB_IMAGE"
+ ),
+ LibraryMapping(
+ "xcb_keysyms",
+ "XCB",
+ "XCB::KEYSYMS",
+ extra=["COMPONENTS", "KEYSYMS"],
+ resultVariable="XCB_KEYSYMS",
+ ),
+ LibraryMapping(
+ "xcb_randr", "XCB", "XCB::RANDR", extra=["COMPONENTS", "RANDR"], resultVariable="XCB_RANDR"
+ ),
+ LibraryMapping(
+ "xcb_render",
+ "XCB",
+ "XCB::RENDER",
+ extra=["COMPONENTS", "RENDER"],
+ resultVariable="XCB_RENDER",
+ ),
+ LibraryMapping(
+ "xcb_renderutil",
+ "XCB",
+ "XCB::RENDERUTIL",
+ extra=["COMPONENTS", "RENDERUTIL"],
+ resultVariable="XCB_RENDERUTIL",
+ ),
+ LibraryMapping(
+ "xcb_shape", "XCB", "XCB::SHAPE", extra=["COMPONENTS", "SHAPE"], resultVariable="XCB_SHAPE"
+ ),
+ LibraryMapping(
+ "xcb_shm", "XCB", "XCB::SHM", extra=["COMPONENTS", "SHM"], resultVariable="XCB_SHM"
+ ),
+ LibraryMapping(
+ "xcb_sync", "XCB", "XCB::SYNC", extra=["COMPONENTS", "SYNC"], resultVariable="XCB_SYNC"
+ ),
+ LibraryMapping(
+ "xcb_xfixes",
+ "XCB",
+ "XCB::XFIXES",
+ extra=["COMPONENTS", "XFIXES"],
+ resultVariable="XCB_XFIXES",
+ ),
+ LibraryMapping(
+ "xcb_xinerama",
+ "XCB",
+ "XCB::XINERAMA",
+ extra=["COMPONENTS", "XINERAMA"],
+ resultVariable="XCB_XINERAMA",
+ ),
+ LibraryMapping(
+ "xcb_xinput",
+ "XCB",
+ "XCB::XINPUT",
+ extra=["COMPONENTS", "XINPUT"],
+ resultVariable="XCB_XINPUT",
+ ),
+ LibraryMapping(
+ "xcb_xkb", "XCB", "XCB::XKB", extra=["COMPONENTS", "XKB"], resultVariable="XCB_XKB"
+ ),
+ LibraryMapping("xcb_xlib", "X11_XCB", "X11::XCB"),
+ LibraryMapping("xkbcommon_evdev", "XKB", "XKB::XKB", extra=["0.4.1"]), # see also xkbcommon
+ LibraryMapping("xkbcommon_x11", "XKB", "XKB::XKB", extra=["0.4.1"]), # see also xkbcommon
+ LibraryMapping("xkbcommon", "XKB", "XKB::XKB", extra=["0.4.1"]),
+ LibraryMapping("xlib", "X11", "X11::XCB"), # FIXME: Is this correct?
+ LibraryMapping("xrender", "XRender", "PkgConfig::XRender"),
+ LibraryMapping("zlib", "ZLIB", "ZLIB::ZLIB", extra=["REQUIRED"]),
+ LibraryMapping("zstd", "ZSTD", "ZSTD::ZSTD"),
+ LibraryMapping("tiff", "TIFF", "TIFF::TIFF"),
+ LibraryMapping("webp", "WrapWebP", "WrapWebP::WrapWebP"),
+ LibraryMapping("jasper", "WrapJasper", "WrapJasper::WrapJasper"),
]
@@ -283,10 +504,10 @@ def _adjust_library_map():
# We don't want to get pages of package not found messages on
# Windows and macOS, and this also improves configure time on
# those platforms.
- linux_package_prefixes = ['xcb', 'x11', 'xkb', 'xrender', 'xlib', 'wayland']
+ linux_package_prefixes = ["xcb", "x11", "xkb", "xrender", "xlib", "wayland"]
for i, _ in enumerate(_library_map):
if any([_library_map[i].soName.startswith(p) for p in linux_package_prefixes]):
- _library_map[i].emit_if = 'config.linux'
+ _library_map[i].emit_if = "config.linux"
_adjust_library_map()
@@ -308,7 +529,7 @@ def find_qt_library_mapping(soName: str) -> typing.Optional[LibraryMapping]:
def find_library_info_for_target(targetName: str) -> typing.Optional[LibraryMapping]:
qt_target = targetName
- if targetName.endswith('Private'):
+ if targetName.endswith("Private"):
qt_target = qt_target[:-7]
for i in _qt_library_map:
@@ -323,61 +544,61 @@ def find_library_info_for_target(targetName: str) -> typing.Optional[LibraryMapp
def featureName(input: str) -> str:
- replacement_char = '_'
- if input.startswith('c++'):
- replacement_char = 'x'
- return re.sub(r'[^a-zA-Z0-9_]', replacement_char, input)
+ replacement_char = "_"
+ if input.startswith("c++"):
+ replacement_char = "x"
+ return re.sub(r"[^a-zA-Z0-9_]", replacement_char, input)
def map_qt_library(lib: str) -> str:
private = False
- if lib.endswith('-private'):
+ if lib.endswith("-private"):
private = True
lib = lib[:-8]
mapped = find_qt_library_mapping(lib)
qt_name = lib
if mapped:
- assert mapped.targetName # Qt libs must have a target name set
+ assert mapped.targetName # Qt libs must have a target name set
qt_name = mapped.targetName
if private:
- qt_name += 'Private'
+ qt_name += "Private"
return qt_name
platform_mapping = {
- 'win32': 'WIN32',
- 'win': 'WIN32',
- 'unix': 'UNIX',
- 'darwin': 'APPLE',
- 'linux': 'LINUX',
- 'integrity': 'INTEGRITY',
- 'qnx': 'QNX',
- 'vxworks': 'VXWORKS',
- 'hpux': 'HPUX',
- 'nacl': 'NACL',
- 'android': 'ANDROID',
- 'android-embedded': 'ANDROID_EMBEDDED',
- 'uikit': 'APPLE_UIKIT',
- 'tvos': 'APPLE_TVOS',
- 'watchos': 'APPLE_WATCHOS',
- 'winrt': 'WINRT',
- 'wasm': 'WASM',
- 'msvc': 'MSVC',
- 'clang': 'CLANG',
- 'gcc': 'GCC',
- 'icc': 'ICC',
- 'intel_icc': 'ICC',
- 'osx': 'APPLE_OSX',
- 'ios': 'APPLE_IOS',
- 'freebsd': 'FREEBSD',
- 'openbsd': 'OPENBSD',
- 'netbsd': 'NETBSD',
- 'haiku': 'HAIKU',
- 'netbsd': 'NETBSD',
- 'mac': 'APPLE',
- 'macx': 'APPLE_OSX',
- 'macos': 'APPLE_OSX',
- 'macx-icc': '(APPLE_OSX AND ICC)',
+ "win32": "WIN32",
+ "win": "WIN32",
+ "unix": "UNIX",
+ "darwin": "APPLE",
+ "linux": "LINUX",
+ "integrity": "INTEGRITY",
+ "qnx": "QNX",
+ "vxworks": "VXWORKS",
+ "hpux": "HPUX",
+ "nacl": "NACL",
+ "android": "ANDROID",
+ "android-embedded": "ANDROID_EMBEDDED",
+ "uikit": "APPLE_UIKIT",
+ "tvos": "APPLE_TVOS",
+ "watchos": "APPLE_WATCHOS",
+ "winrt": "WINRT",
+ "wasm": "WASM",
+ "msvc": "MSVC",
+ "clang": "CLANG",
+ "gcc": "GCC",
+ "icc": "ICC",
+ "intel_icc": "ICC",
+ "osx": "APPLE_OSX",
+ "ios": "APPLE_IOS",
+ "freebsd": "FREEBSD",
+ "openbsd": "OPENBSD",
+ "netbsd": "NETBSD",
+ "haiku": "HAIKU",
+ "netbsd": "NETBSD",
+ "mac": "APPLE",
+ "macx": "APPLE_OSX",
+ "macos": "APPLE_OSX",
+ "macx-icc": "(APPLE_OSX AND ICC)",
}
@@ -387,7 +608,7 @@ def map_platform(platform: str) -> str:
def is_known_3rd_party_library(lib: str) -> bool:
- if lib.endswith('/nolink') or lib.endswith('_nolink'):
+ if lib.endswith("/nolink") or lib.endswith("_nolink"):
lib = lib[:-7]
mapping = find_3rd_party_library_mapping(lib)
@@ -395,20 +616,19 @@ def is_known_3rd_party_library(lib: str) -> bool:
def map_3rd_party_library(lib: str) -> str:
- libpostfix = ''
- if lib.endswith('/nolink'):
+ libpostfix = ""
+ if lib.endswith("/nolink"):
lib = lib[:-7]
- libpostfix = '_nolink'
+ libpostfix = "_nolink"
mapping = find_3rd_party_library_mapping(lib)
if not mapping or not mapping.targetName:
return lib
return mapping.targetName + libpostfix
-def generate_find_package_info(lib: LibraryMapping,
- use_qt_find_package: bool=True, *,
- indent: int = 0,
- emit_if: str = '') -> str:
+def generate_find_package_info(
+ lib: LibraryMapping, use_qt_find_package: bool = True, *, indent: int = 0, emit_if: str = ""
+) -> str:
isRequired = False
extra = lib.extra.copy()
@@ -418,40 +638,41 @@ def generate_find_package_info(lib: LibraryMapping,
extra.remove("REQUIRED")
cmake_target_name = lib.targetName
- assert(cmake_target_name);
+ assert cmake_target_name
# _nolink or not does not matter at this point:
- if cmake_target_name.endswith('_nolink') or cmake_target_name.endswith('/nolink'):
+ if cmake_target_name.endswith("_nolink") or cmake_target_name.endswith("/nolink"):
cmake_target_name = cmake_target_name[:-7]
if cmake_target_name and use_qt_find_package:
- extra += ['PROVIDED_TARGETS', cmake_target_name]
+ extra += ["PROVIDED_TARGETS", cmake_target_name]
- result = ''
- one_ind = ' '
+ result = ""
+ one_ind = " "
ind = one_ind * indent
if use_qt_find_package:
if extra:
- result = '{}qt_find_package({} {})\n'.format(ind, lib.packageName, ' '.join(extra))
+ result = "{}qt_find_package({} {})\n".format(ind, lib.packageName, " ".join(extra))
else:
- result = '{}qt_find_package({})\n'.format(ind, lib.packageName)
+ result = "{}qt_find_package({})\n".format(ind, lib.packageName)
if isRequired:
- result += '{}set_package_properties({} PROPERTIES TYPE REQUIRED)\n'.format(ind, lib.packageName)
+ result += "{}set_package_properties({} PROPERTIES TYPE REQUIRED)\n".format(
+ ind, lib.packageName
+ )
else:
if extra:
- result = '{}find_package({} {})\n'.format(ind, lib.packageName, ' '.join(extra))
+ result = "{}find_package({} {})\n".format(ind, lib.packageName, " ".join(extra))
else:
- result = '{}find_package({})\n'.format(ind, lib.packageName)
+ result = "{}find_package({})\n".format(ind, lib.packageName)
# If a package should be found only in certain conditions, wrap
# the find_package call within that condition.
if emit_if:
- result = "if(({emit_if}) OR QT_FIND_ALL_PACKAGES_ALWAYS)\n" \
- "{ind}{result}endif()\n".format(emit_if=emit_if,
- result=result,
- ind=one_ind)
+ result = "if(({emit_if}) OR QT_FIND_ALL_PACKAGES_ALWAYS)\n" "{ind}{result}endif()\n".format(
+ emit_if=emit_if, result=result, ind=one_ind
+ )
return result
diff --git a/util/cmake/json_parser.py b/util/cmake/json_parser.py
index 6ead008f081..36e8cee37ff 100644
--- a/util/cmake/json_parser.py
+++ b/util/cmake/json_parser.py
@@ -31,6 +31,7 @@ import pyparsing as pp
import json
import re
from helper import _set_up_py_parsing_nicer_debug_output
+
_set_up_py_parsing_nicer_debug_output(pp)
@@ -41,7 +42,7 @@ class QMakeSpecificJSONParser:
def create_py_parsing_grammar(self):
# Keep around all whitespace.
- pp.ParserElement.setDefaultWhitespaceChars('')
+ pp.ParserElement.setDefaultWhitespaceChars("")
def add_element(name: str, value: pp.ParserElement):
nonlocal self
@@ -57,44 +58,44 @@ class QMakeSpecificJSONParser:
# skip to the next quote, and repeat that until the end of the
# file.
- EOF = add_element('EOF', pp.StringEnd())
- SkipToQuote = add_element('SkipToQuote', pp.SkipTo('"'))
- SkipToEOF = add_element('SkipToEOF', pp.SkipTo(EOF))
+ EOF = add_element("EOF", pp.StringEnd())
+ SkipToQuote = add_element("SkipToQuote", pp.SkipTo('"'))
+ SkipToEOF = add_element("SkipToEOF", pp.SkipTo(EOF))
def remove_newlines_and_whitespace_in_quoted_string(tokens):
first_string = tokens[0]
- replaced_string = re.sub(r'\n[ ]*', ' ', first_string)
+ replaced_string = re.sub(r"\n[ ]*", " ", first_string)
return replaced_string
- QuotedString = add_element('QuotedString', pp.QuotedString(quoteChar='"',
- multiline=True,
- unquoteResults=False))
+ QuotedString = add_element(
+ "QuotedString", pp.QuotedString(quoteChar='"', multiline=True, unquoteResults=False)
+ )
QuotedString.setParseAction(remove_newlines_and_whitespace_in_quoted_string)
- QuotedTerm = add_element('QuotedTerm', pp.Optional(SkipToQuote) + QuotedString)
- Grammar = add_element('Grammar', pp.OneOrMore(QuotedTerm) + SkipToEOF)
+ QuotedTerm = add_element("QuotedTerm", pp.Optional(SkipToQuote) + QuotedString)
+ Grammar = add_element("Grammar", pp.OneOrMore(QuotedTerm) + SkipToEOF)
return Grammar
def parse_file_using_py_parsing(self, file: str):
- print('Pre processing "{}" using py parsing to remove incorrect newlines.'.format(file))
+ print(f'Pre processing "{file}" using py parsing to remove incorrect newlines.')
try:
- with open(file, 'r') as file_fd:
+ with open(file, "r") as file_fd:
contents = file_fd.read()
parser_result = self.grammar.parseString(contents, parseAll=True)
token_list = parser_result.asList()
- joined_string = ''.join(token_list)
+ joined_string = "".join(token_list)
return joined_string
except pp.ParseException as pe:
print(pe.line)
- print(' '*(pe.col-1) + '^')
+ print(" " * (pe.col - 1) + "^")
print(pe)
raise pe
def parse(self, file: str):
pre_processed_string = self.parse_file_using_py_parsing(file)
- print('Parsing "{}" using json.loads().'.format(file))
+ print(f'Parsing "{file}" using json.loads().')
json_parsed = json.loads(pre_processed_string)
return json_parsed
diff --git a/util/cmake/pro2cmake.py b/util/cmake/pro2cmake.py
index 28eb70454e5..7363ace586d 100755
--- a/util/cmake/pro2cmake.py
+++ b/util/cmake/pro2cmake.py
@@ -30,16 +30,12 @@
from __future__ import annotations
-from argparse import ArgumentParser
-from textwrap import dedent
import copy
-import xml.etree.ElementTree as ET
-from itertools import chain
import os.path
import posixpath
+import sys
import re
import io
-import typing
import glob
import collections
@@ -48,119 +44,164 @@ try:
except AttributeError:
collectionsAbc = collections
-from sympy.logic import (simplify_logic, And, Or, Not,)
import pyparsing as pp
-from helper import _set_up_py_parsing_nicer_debug_output
-_set_up_py_parsing_nicer_debug_output(pp)
-
-from helper import map_qt_library, map_3rd_party_library, is_known_3rd_party_library, \
- featureName, map_platform, find_library_info_for_target, generate_find_package_info, \
- LibraryMapping
+import xml.etree.ElementTree as ET
+from argparse import ArgumentParser
+from textwrap import dedent
+from itertools import chain
from shutil import copyfile
+from sympy.logic import simplify_logic, And, Or, Not
+from sympy.core.sympify import SympifyError
+from typing import List, Optional, Dict, Set, IO, Union, Mapping, Any, Callable, FrozenSet, Tuple
from special_case_helper import SpecialCaseHandler
+from helper import (
+ map_qt_library,
+ map_3rd_party_library,
+ is_known_3rd_party_library,
+ featureName,
+ map_platform,
+ find_library_info_for_target,
+ generate_find_package_info,
+ LibraryMapping,
+)
+from helper import _set_up_py_parsing_nicer_debug_output
+
+_set_up_py_parsing_nicer_debug_output(pp)
cmake_version_string = "3.15.0"
+
def _parse_commandline():
- parser = ArgumentParser(description='Generate CMakeLists.txt files from .'
- 'pro files.',
- epilog='Requirements: pip install sympy pyparsing')
- parser.add_argument('--debug', dest='debug', action='store_true',
- help='Turn on all debug output')
- parser.add_argument('--debug-parser', dest='debug_parser',
- action='store_true',
- help='Print debug output from qmake parser.')
- parser.add_argument('--debug-parse-result', dest='debug_parse_result',
- action='store_true',
- help='Dump the qmake parser result.')
- parser.add_argument('--debug-parse-dictionary',
- dest='debug_parse_dictionary', action='store_true',
- help='Dump the qmake parser result as dictionary.')
- parser.add_argument('--debug-pro-structure', dest='debug_pro_structure',
- action='store_true',
- help='Dump the structure of the qmake .pro-file.')
- parser.add_argument('--debug-full-pro-structure',
- dest='debug_full_pro_structure', action='store_true',
- help='Dump the full structure of the qmake .pro-file '
- '(with includes).')
- parser.add_argument('--debug-special-case-preservation',
- dest='debug_special_case_preservation', action='store_true',
- help='Show all git commands and file copies.')
-
- parser.add_argument('--is-example', action='store_true',
- dest="is_example",
- help='Treat the input .pro file as an example.')
- parser.add_argument('-s', '--skip-special-case-preservation',
- dest='skip_special_case_preservation', action='store_true',
- help='Skips behavior to reapply '
- 'special case modifications (requires git in PATH)')
- parser.add_argument('-k', '--keep-temporary-files',
- dest='keep_temporary_files', action='store_true',
- help='Don\'t automatically remove CMakeLists.gen.txt and other '
- 'intermediate files.')
-
- parser.add_argument('files', metavar='<.pro/.pri file>', type=str,
- nargs='+', help='The .pro/.pri file to process')
+ parser = ArgumentParser(
+ description="Generate CMakeLists.txt files from ." "pro files.",
+ epilog="Requirements: pip install sympy pyparsing",
+ )
+ parser.add_argument(
+ "--debug", dest="debug", action="store_true", help="Turn on all debug output"
+ )
+ parser.add_argument(
+ "--debug-parser",
+ dest="debug_parser",
+ action="store_true",
+ help="Print debug output from qmake parser.",
+ )
+ parser.add_argument(
+ "--debug-parse-result",
+ dest="debug_parse_result",
+ action="store_true",
+ help="Dump the qmake parser result.",
+ )
+ parser.add_argument(
+ "--debug-parse-dictionary",
+ dest="debug_parse_dictionary",
+ action="store_true",
+ help="Dump the qmake parser result as dictionary.",
+ )
+ parser.add_argument(
+ "--debug-pro-structure",
+ dest="debug_pro_structure",
+ action="store_true",
+ help="Dump the structure of the qmake .pro-file.",
+ )
+ parser.add_argument(
+ "--debug-full-pro-structure",
+ dest="debug_full_pro_structure",
+ action="store_true",
+ help="Dump the full structure of the qmake .pro-file " "(with includes).",
+ )
+ parser.add_argument(
+ "--debug-special-case-preservation",
+ dest="debug_special_case_preservation",
+ action="store_true",
+ help="Show all git commands and file copies.",
+ )
+
+ parser.add_argument(
+ "--is-example",
+ action="store_true",
+ dest="is_example",
+ help="Treat the input .pro file as an example.",
+ )
+ parser.add_argument(
+ "-s",
+ "--skip-special-case-preservation",
+ dest="skip_special_case_preservation",
+ action="store_true",
+ help="Skips behavior to reapply " "special case modifications (requires git in PATH)",
+ )
+ parser.add_argument(
+ "-k",
+ "--keep-temporary-files",
+ dest="keep_temporary_files",
+ action="store_true",
+ help="Don't automatically remove CMakeLists.gen.txt and other " "intermediate files.",
+ )
+
+ parser.add_argument(
+ "files",
+ metavar="<.pro/.pri file>",
+ type=str,
+ nargs="+",
+ help="The .pro/.pri file to process",
+ )
return parser.parse_args()
-def is_top_level_repo_project(project_file_path: str = '') -> bool:
+def is_top_level_repo_project(project_file_path: str = "") -> bool:
qmake_conf_path = find_qmake_conf(project_file_path)
qmake_conf_dir_path = os.path.dirname(qmake_conf_path)
project_dir_path = os.path.dirname(project_file_path)
- if qmake_conf_dir_path == project_dir_path:
- return True
- return False
+ return qmake_conf_dir_path == project_dir_path
-def is_top_level_repo_tests_project(project_file_path: str = '') -> bool:
+def is_top_level_repo_tests_project(project_file_path: str = "") -> bool:
qmake_conf_path = find_qmake_conf(project_file_path)
qmake_conf_dir_path = os.path.dirname(qmake_conf_path)
project_dir_path = os.path.dirname(project_file_path)
project_dir_name = os.path.basename(project_dir_path)
maybe_same_level_dir_path = os.path.join(project_dir_path, "..")
normalized_maybe_same_level_dir_path = os.path.normpath(maybe_same_level_dir_path)
- if qmake_conf_dir_path == normalized_maybe_same_level_dir_path and project_dir_name == 'tests':
- return True
- return False
+ return (
+ qmake_conf_dir_path == normalized_maybe_same_level_dir_path and project_dir_name == "tests"
+ )
-def is_top_level_repo_examples_project(project_file_path: str = '') -> bool:
+def is_top_level_repo_examples_project(project_file_path: str = "") -> bool:
qmake_conf_path = find_qmake_conf(project_file_path)
qmake_conf_dir_path = os.path.dirname(qmake_conf_path)
project_dir_path = os.path.dirname(project_file_path)
project_dir_name = os.path.basename(project_dir_path)
maybe_same_level_dir_path = os.path.join(project_dir_path, "..")
normalized_maybe_same_level_dir_path = os.path.normpath(maybe_same_level_dir_path)
- if qmake_conf_dir_path == normalized_maybe_same_level_dir_path \
- and project_dir_name == 'examples':
- return True
- return False
+ return (
+ qmake_conf_dir_path == normalized_maybe_same_level_dir_path
+ and project_dir_name == "examples"
+ )
-def is_example_project(project_file_path: str = '') -> bool:
+def is_example_project(project_file_path: str = "") -> bool:
qmake_conf_path = find_qmake_conf(project_file_path)
qmake_conf_dir_path = os.path.dirname(qmake_conf_path)
project_relative_path = os.path.relpath(project_file_path, qmake_conf_dir_path)
# If the project file is found in a subdir called 'examples'
# relative to the repo source dir, then it must be an example.
- if project_relative_path.startswith('examples'):
- return True
- return False
+ return project_relative_path.startswith("examples")
-def find_qmake_conf(project_file_path: str = '') -> typing.Optional[str]:
+def find_qmake_conf(project_file_path: str = "") -> Optional[str]:
if not os.path.isabs(project_file_path):
- print('Warning: could not find .qmake.conf file, given path is not an absolute path: {}'
- .format(project_file_path))
+ print(
+ f"Warning: could not find .qmake.conf file, given path is not an "
+ f"absolute path: {project_file_path}"
+ )
return None
cwd = os.path.dirname(project_file_path)
- file_name = '.qmake.conf'
+ file_name = ".qmake.conf"
while os.path.isdir(cwd):
maybe_file = posixpath.join(cwd, file_name)
@@ -172,13 +213,20 @@ def find_qmake_conf(project_file_path: str = '') -> typing.Optional[str]:
return None
-def process_qrc_file(target: str, filepath: str, base_dir: str = '', project_file_path: str = '', skip_qtquick_compiler: bool = False,
- retain_qtquick_compiler: bool = False, is_example: bool = False) -> str:
- assert(target)
+def process_qrc_file(
+ target: str,
+ filepath: str,
+ base_dir: str = "",
+ project_file_path: str = "",
+ skip_qtquick_compiler: bool = False,
+ retain_qtquick_compiler: bool = False,
+ is_example: bool = False,
+) -> str:
+ assert target
# Hack to handle QT_SOURCE_TREE. Assume currently that it's the same
# as the qtbase source path.
- qt_source_tree_literal = '${QT_SOURCE_TREE}'
+ qt_source_tree_literal = "${QT_SOURCE_TREE}"
if qt_source_tree_literal in filepath:
qmake_conf = find_qmake_conf(project_file_path)
@@ -186,43 +234,44 @@ def process_qrc_file(target: str, filepath: str, base_dir: str = '', project_fil
qt_source_tree = os.path.dirname(qmake_conf)
filepath = filepath.replace(qt_source_tree_literal, qt_source_tree)
else:
- print('Warning, could not determine QT_SOURCE_TREE location while trying to find: {}'
- .format(filepath))
-
+ print(
+ f"Warning, could not determine QT_SOURCE_TREE location while trying "
+ f"to find: {filepath}"
+ )
resource_name = os.path.splitext(os.path.basename(filepath))[0]
dir_name = os.path.dirname(filepath)
- base_dir = posixpath.join('' if base_dir == '.' else base_dir, dir_name)
+ base_dir = posixpath.join("" if base_dir == "." else base_dir, dir_name)
# Small not very thorough check to see if this a shared qrc resource
# pattern is mostly used by the tests.
- is_parent_path = dir_name.startswith('..')
+ is_parent_path = dir_name.startswith("..")
if not os.path.isfile(filepath):
- raise RuntimeError('Invalid file path given to process_qrc_file: {}'.format(filepath))
+ raise RuntimeError(f"Invalid file path given to process_qrc_file: {filepath}")
tree = ET.parse(filepath)
root = tree.getroot()
- assert(root.tag == 'RCC')
+ assert root.tag == "RCC"
- output = ''
+ output = ""
resource_count = 0
for resource in root:
- assert(resource.tag == 'qresource')
- lang = resource.get('lang', '')
- prefix = resource.get('prefix', '/')
- if not prefix.startswith('/'):
- prefix = '/' + prefix
+ assert resource.tag == "qresource"
+ lang = resource.get("lang", "")
+ prefix = resource.get("prefix", "/")
+ if not prefix.startswith("/"):
+ prefix = "/" + prefix
- full_resource_name = resource_name + (str(resource_count) if resource_count > 0 else '')
+ full_resource_name = resource_name + (str(resource_count) if resource_count > 0 else "")
- files: typing.Dict[str, str] = {}
+ files: Dict[str, str] = {}
for file in resource:
path = file.text
assert path
# Get alias:
- alias = file.get('alias', '')
+ alias = file.get("alias", "")
# In cases where examples use shared resources, we set the alias
# too the same name of the file, or the applications won't be
# be able to locate the resource
@@ -230,58 +279,87 @@ def process_qrc_file(target: str, filepath: str, base_dir: str = '', project_fil
alias = path
files[path] = alias
- output += write_add_qt_resource_call(target, full_resource_name, prefix, base_dir, lang, files, skip_qtquick_compiler, retain_qtquick_compiler, is_example)
+ output += write_add_qt_resource_call(
+ target,
+ full_resource_name,
+ prefix,
+ base_dir,
+ lang,
+ files,
+ skip_qtquick_compiler,
+ retain_qtquick_compiler,
+ is_example,
+ )
resource_count += 1
return output
-def write_add_qt_resource_call(target: str, resource_name: str, prefix: typing.Optional[str], base_dir: typing.Optional[str],
- lang: typing.Optional[str], files: typing.Dict[str, str], skip_qtquick_compiler: bool, retain_qtquick_compiler: bool, is_example :bool) -> str:
- output = ''
+def write_add_qt_resource_call(
+ target: str,
+ resource_name: str,
+ prefix: Optional[str],
+ base_dir: Optional[str],
+ lang: Optional[str],
+ files: Dict[str, str],
+ skip_qtquick_compiler: bool,
+ retain_qtquick_compiler: bool,
+ is_example: bool,
+) -> str:
+ output = ""
sorted_files = sorted(files.keys())
- assert(sorted_files)
+ assert sorted_files
for source in sorted_files:
alias = files[source]
if alias:
full_source = posixpath.join(base_dir, source)
- output += 'set_source_files_properties("{}"\n' \
- ' PROPERTIES QT_RESOURCE_ALIAS "{}"\n)\n'.format(full_source, alias)
+ output += (
+ f'set_source_files_properties("{full_source}"\n'
+ f' PROPERTIES QT_RESOURCE_ALIAS "{alias}"\n)\n'
+ )
# Quote file paths in case there are spaces.
sorted_files_backup = sorted_files
sorted_files = []
for source in sorted_files_backup:
- if source.startswith('${'):
+ if source.startswith("${"):
sorted_files.append(source)
else:
- sorted_files.append('"{}"'.format(source))
+ sorted_files.append(f'"{source}"')
- file_list = '\n '.join(sorted_files)
- output += 'set({}_resource_files\n {}\n)\n\n'.format(resource_name, file_list)
- file_list = "${{{}_resource_files}}".format(resource_name)
+ file_list = "\n ".join(sorted_files)
+ output += f"set({resource_name}_resource_files\n {file_list}\n)\n\n"
+ file_list = f"${{{resource_name}_resource_files}}"
if skip_qtquick_compiler:
- output += 'set_source_files_properties(${{{}_resource_files}} PROPERTIES QT_SKIP_QUICKCOMPILER 1)\n\n'.format(resource_name)
+ output += (
+ f"set_source_files_properties(${{{resource_name}_resource_files}}"
+ " PROPERTIES QT_SKIP_QUICKCOMPILER 1)\n\n"
+ )
if retain_qtquick_compiler:
- output += 'set_source_files_properties(${{{}_resource_files}} PROPERTIES QT_RETAIN_QUICKCOMPILER 1)\n\n'.format(resource_name)
+ output += (
+ f"set_source_files_properties(${{{resource_name}_resource_files}}"
+ "PROPERTIES QT_RETAIN_QUICKCOMPILER 1)\n\n"
+ )
- params = ''
+ params = ""
if lang:
- params += ' LANG\n "{}"\n'.format(lang)
- params += ' PREFIX\n "{}"\n'.format(prefix)
+ params += f'{spaces(1)}LANG\n{spaces(2)}"{lang}"\n'
+ params += f'{spaces(1)}PREFIX\n{spaces(2)}"{prefix}"\n'
if base_dir:
- params += ' BASE\n "{}"\n'.format(base_dir)
- add_resource_command = ''
+ params += f'{spaces(1)}BASE\n{spaces(2)}"{base_dir}"\n'
+ add_resource_command = ""
if is_example:
- add_resource_command = 'QT6_ADD_RESOURCES'
+ add_resource_command = "QT6_ADD_RESOURCES"
else:
- add_resource_command = 'add_qt_resource'
- output += '{}({} "{}"\n{} FILES\n {}\n)\n'.format(add_resource_command,
- target, resource_name, params, file_list)
+ add_resource_command = "add_qt_resource"
+ output += (
+ f'{add_resource_command}({target} "{resource_name}"\n{params}{spaces(1)}FILES\n'
+ f"{spaces(2)}{file_list}\n)\n"
+ )
return output
@@ -291,8 +369,8 @@ def fixup_linecontinuation(contents: str) -> str:
# a newline character with an arbitrary amount of whitespace
# between the backslash and the newline.
# This greatly simplifies the qmake parsing grammar.
- contents = re.sub(r'([^\t ])\\[ \t]*\n', '\\1 ', contents)
- contents = re.sub(r'\\[ \t]*\n', '', contents)
+ contents = re.sub(r"([^\t ])\\[ \t]*\n", "\\1 ", contents)
+ contents = re.sub(r"\\[ \t]*\n", "", contents)
return contents
@@ -313,24 +391,24 @@ def fixup_comments(contents: str) -> str:
# care of it as well, as if the commented line didn't exist in the
# first place.
- contents = re.sub(r'\n#[^\n]*?\n', '\n', contents, re.DOTALL)
+ contents = re.sub(r"\n#[^\n]*?\n", "\n", contents, re.DOTALL)
return contents
def spaces(indent: int) -> str:
- return ' ' * indent
+ return " " * indent
def trim_leading_dot(file: str) -> str:
- while file.startswith('./'):
+ while file.startswith("./"):
file = file[2:]
return file
def map_to_file(f: str, scope: Scope, *, is_include: bool = False) -> str:
- assert('$$' not in f)
+ assert "$$" not in f
- if f.startswith('${'): # Some cmake variable is prepended
+ if f.startswith("${"): # Some cmake variable is prepended
return f
base_dir = scope.currentdir if is_include else scope.basedir
@@ -339,11 +417,11 @@ def map_to_file(f: str, scope: Scope, *, is_include: bool = False) -> str:
return trim_leading_dot(f)
-def handle_vpath(source: str, base_dir: str, vpath: typing.List[str]) -> str:
- assert('$$' not in source)
+def handle_vpath(source: str, base_dir: str, vpath: List[str]) -> str:
+ assert "$$" not in source
if not source:
- return ''
+ return ""
if not vpath:
return source
@@ -351,7 +429,7 @@ def handle_vpath(source: str, base_dir: str, vpath: typing.List[str]) -> str:
if os.path.exists(os.path.join(base_dir, source)):
return source
- variable_pattern = re.compile(r'\$\{[A-Za-z0-9_]+\}')
+ variable_pattern = re.compile(r"\$\{[A-Za-z0-9_]+\}")
match = re.match(variable_pattern, source)
if match:
# a complex, variable based path, skipping validation
@@ -363,8 +441,8 @@ def handle_vpath(source: str, base_dir: str, vpath: typing.List[str]) -> str:
if os.path.exists(fullpath):
return trim_leading_dot(posixpath.relpath(fullpath, base_dir))
- print(' XXXX: Source {}: Not found.'.format(source))
- return '{}-NOTFOUND'.format(source)
+ print(f" XXXX: Source {source}: Not found.")
+ return f"{source}-NOTFOUND"
def flatten_list(l):
@@ -379,74 +457,91 @@ def flatten_list(l):
def handle_function_value(group: pp.ParseResults):
function_name = group[0]
function_args = group[1]
- if function_name == 'qtLibraryTarget':
+ if function_name == "qtLibraryTarget":
if len(function_args) > 1:
- raise RuntimeError('Don\'t know what to with more than one function argument for $$qtLibraryTarget().')
+ raise RuntimeError(
+ "Don't know what to with more than one function argument "
+ "for $$qtLibraryTarget()."
+ )
return str(function_args[0])
- if function_name == 'quote':
+ if function_name == "quote":
# Do nothing, just return a string result
return str(group)
- if function_name == 'files':
+ if function_name == "files":
if len(function_args) > 1:
- raise RuntimeError('Don\'t know what to with more than one function argument for $$files().')
+ raise RuntimeError(
+ "Don't know what to with more than one function argument for $$files()."
+ )
return str(function_args[0])
if isinstance(function_args, pp.ParseResults):
function_args = list(flatten_list(function_args.asList()))
# Return the whole expression as a string.
- if function_name in ['join', 'files', 'cmakeRelativePath', 'shell_quote', 'shadowed', 'cmakeTargetPath',
- 'shell_path', 'cmakeProcessLibs', 'cmakeTargetPaths',
- 'cmakePortablePaths', 'escape_expand', 'member']:
- return 'join({})'.format(''.join(function_args))
-
+ if function_name in [
+ "join",
+ "files",
+ "cmakeRelativePath",
+ "shell_quote",
+ "shadowed",
+ "cmakeTargetPath",
+ "shell_path",
+ "cmakeProcessLibs",
+ "cmakeTargetPaths",
+ "cmakePortablePaths",
+ "escape_expand",
+ "member",
+ ]:
+ return f"join({''.join(function_args)})"
- raise RuntimeError('No logic to handle function "{}", please add one in handle_function_value().'.format(function_name))
class Operation:
- def __init__(self, value: typing.Union[typing.List[str], str]):
+ def __init__(self, value: Union[List[str], str]):
if isinstance(value, list):
self._value = value
else:
- self._value = [str(value), ]
+ self._value = [str(value)]
- def process(self, key: str, input: typing.List[str],
- transformer: typing.Callable[[typing.List[str]], typing.List[str]]) -> typing.List[str]:
- assert(False)
+ def process(
+ self, key: str, input: List[str], transformer: Callable[[List[str]], List[str]]
+ ) -> List[str]:
+ assert False
def __repr__(self):
- assert(False)
+ assert False
def _dump(self):
if not self._value:
- return '<NOTHING>'
+ return "<NOTHING>"
if not isinstance(self._value, list):
- return '<NOT A LIST>'
+ return "<NOT A LIST>"
result = []
for i in self._value:
if not i:
- result.append('<NONE>')
+ result.append("<NONE>")
else:
result.append(str(i))
return '"' + '", "'.join(result) + '"'
class AddOperation(Operation):
- def process(self, key: str, input: typing.List[str],
- transformer: typing.Callable[[typing.List[str]], typing.List[str]]) -> typing.List[str]:
+ def process(
+ self, key: str, input: List[str], transformer: Callable[[List[str]], List[str]]
+ ) -> List[str]:
return input + transformer(self._value)
def __repr__(self):
- return '+({})'.format(self._dump())
+ return f"+({self._dump()})"
class UniqueAddOperation(Operation):
- def process(self, key: str, input: typing.List[str],
- transformer: typing.Callable[[typing.List[str]], typing.List[str]]) -> typing.List[str]:
+ def process(
+ self, key: str, input: List[str], transformer: Callable[[List[str]], List[str]]
+ ) -> List[str]:
result = input
for v in transformer(self._value):
if v not in result:
@@ -454,15 +549,16 @@ class UniqueAddOperation(Operation):
return result
def __repr__(self):
- return '*({})'.format(self._dump())
+ return f"*({self._dump()})"
class SetOperation(Operation):
- def process(self, key: str, input: typing.List[str],
- transformer: typing.Callable[[typing.List[str]], typing.List[str]]) -> typing.List[str]:
- values = [] # typing.List[str]
+ def process(
+ self, key: str, input: List[str], transformer: Callable[[List[str]], List[str]]
+ ) -> List[str]:
+ values = [] # List[str]
for v in self._value:
- if v != '$${}'.format(key):
+ if v != f"$${key}":
values.append(v)
else:
values += input
@@ -473,66 +569,70 @@ class SetOperation(Operation):
return values
def __repr__(self):
- return '=({})'.format(self._dump())
+ return f"=({self._dump()})"
class RemoveOperation(Operation):
def __init__(self, value):
super().__init__(value)
- def process(self, key: str, input: typing.List[str],
- transformer: typing.Callable[[typing.List[str]], typing.List[str]]) -> typing.List[str]:
+ def process(
+ self, key: str, input: List[str], transformer: Callable[[List[str]], List[str]]
+ ) -> List[str]:
input_set = set(input)
value_set = set(self._value)
- result = []
+ result: List[str] = []
# Add everything that is not going to get removed:
for v in input:
if v not in value_set:
- result += [v,]
+ result += [v]
# Add everything else with removal marker:
for v in transformer(self._value):
if v not in input_set:
- result += ['-{}'.format(v), ]
+ result += [f"-{v}"]
return result
def __repr__(self):
- return '-({})'.format(self._dump())
+ return f"-({self._dump()})"
class Scope(object):
SCOPE_ID: int = 1
- def __init__(self, *,
- parent_scope: typing.Optional[Scope],
- file: typing.Optional[str] = None, condition: str = '',
- base_dir: str = '',
- operations: typing.Union[
- typing.Mapping[str, typing.List[Operation]], None] = None) -> None:
+ def __init__(
+ self,
+ *,
+ parent_scope: Optional[Scope],
+ file: Optional[str] = None,
+ condition: str = "",
+ base_dir: str = "",
+ operations: Union[Mapping[str, List[Operation]], None] = None,
+ ) -> None:
if operations is None:
operations = {
- 'QT_SOURCE_TREE': [SetOperation(['${QT_SOURCE_TREE}'])],
- 'QT_BUILD_TREE': [SetOperation(['${PROJECT_BUILD_DIR}'])],
+ "QT_SOURCE_TREE": [SetOperation(["${QT_SOURCE_TREE}"])],
+ "QT_BUILD_TREE": [SetOperation(["${PROJECT_BUILD_DIR}"])],
}
self._operations = copy.deepcopy(operations)
if parent_scope:
parent_scope._add_child(self)
else:
- self._parent = None # type: typing.Optional[Scope]
+ self._parent = None # type: Optional[Scope]
# Only add the "QT = core gui" Set operation once, on the
# very top-level .pro scope, aka it's basedir is empty.
if not base_dir:
- self._operations['QT'] = [SetOperation(['core', 'gui'])]
+ self._operations["QT"] = [SetOperation(["core", "gui"])]
self._basedir = base_dir
if file:
self._currentdir = os.path.dirname(file)
if not self._currentdir:
- self._currentdir = '.'
+ self._currentdir = "."
if not self._basedir:
self._basedir = self._currentdir
@@ -541,30 +641,31 @@ class Scope(object):
self._file = file
self._file_absolute_path = os.path.abspath(file)
self._condition = map_condition(condition)
- self._children = [] # type: typing.List[Scope]
- self._included_children = [] # type: typing.List[Scope]
- self._visited_keys = set() # type: typing.Set[str]
- self._total_condition = None # type: typing.Optional[str]
+ self._children = [] # type: List[Scope]
+ self._included_children = [] # type: List[Scope]
+ self._visited_keys = set() # type: Set[str]
+ self._total_condition = None # type: Optional[str]
def __repr__(self):
- return '{}:{}:{}:{}:{}'.format(self._scope_id,
- self._basedir, self._currentdir,
- self._file, self._condition or '<TRUE>')
+ return (
+ f"{self._scope_id}:{self._basedir}:{self._currentdir}:{self._file}:"
+ f"{self._condition or '<TRUE>'}"
+ )
def reset_visited_keys(self):
self._visited_keys = set()
- def merge(self, other: 'Scope') -> None:
+ def merge(self, other: "Scope") -> None:
assert self != other
self._included_children.append(other)
@property
def scope_debug(self) -> bool:
- merge = self.get_string('PRO2CMAKE_SCOPE_DEBUG').lower()
- return merge == '1' or merge == 'on' or merge == 'yes' or merge == 'true'
+ merge = self.get_string("PRO2CMAKE_SCOPE_DEBUG").lower()
+ return merge == "1" or merge == "on" or merge == "yes" or merge == "true"
@property
- def parent(self) -> typing.Optional[Scope]:
+ def parent(self) -> Optional[Scope]:
return self._parent
@property
@@ -576,7 +677,7 @@ class Scope(object):
return self._currentdir
def can_merge_condition(self):
- if self._condition == 'else':
+ if self._condition == "else":
return False
if self._operations:
return False
@@ -584,167 +685,162 @@ class Scope(object):
child_count = len(self._children)
if child_count == 0 or child_count > 2:
return False
- assert child_count != 1 or self._children[0]._condition != 'else'
- return child_count == 1 or self._children[1]._condition == 'else'
+ assert child_count != 1 or self._children[0]._condition != "else"
+ return child_count == 1 or self._children[1]._condition == "else"
def settle_condition(self):
- new_children: typing.List[Scope] = []
+ new_children: List[Scope] = []
for c in self._children:
c.settle_condition()
if c.can_merge_condition():
child = c._children[0]
- child._condition = '({}) AND ({})'.format(c._condition, child._condition)
+ child._condition = "({c._condition}) AND ({child._condition})"
new_children += c._children
else:
new_children.append(c)
self._children = new_children
@staticmethod
- def FromDict(parent_scope: typing.Optional['Scope'],
- file: str, statements, cond: str = '', base_dir: str = '') -> Scope:
+ def FromDict(
+ parent_scope: Optional["Scope"], file: str, statements, cond: str = "", base_dir: str = ""
+ ) -> Scope:
scope = Scope(parent_scope=parent_scope, file=file, condition=cond, base_dir=base_dir)
for statement in statements:
if isinstance(statement, list): # Handle skipped parts...
assert not statement
continue
- operation = statement.get('operation', None)
+ operation = statement.get("operation", None)
if operation:
- key = statement.get('key', '')
- value = statement.get('value', [])
- assert key != ''
+ key = statement.get("key", "")
+ value = statement.get("value", [])
+ assert key != ""
- if operation == '=':
+ if operation == "=":
scope._append_operation(key, SetOperation(value))
- elif operation == '-=':
+ elif operation == "-=":
scope._append_operation(key, RemoveOperation(value))
- elif operation == '+=':
+ elif operation == "+=":
scope._append_operation(key, AddOperation(value))
- elif operation == '*=':
+ elif operation == "*=":
scope._append_operation(key, UniqueAddOperation(value))
else:
- print('Unexpected operation "{}" in scope "{}".'
- .format(operation, scope))
- assert(False)
+ print(f'Unexpected operation "{operation}" in scope "{scope}".')
+ assert False
continue
- condition = statement.get('condition', None)
+ condition = statement.get("condition", None)
if condition:
- Scope.FromDict(scope, file,
- statement.get('statements'), condition,
- scope.basedir)
+ Scope.FromDict(scope, file, statement.get("statements"), condition, scope.basedir)
- else_statements = statement.get('else_statements')
+ else_statements = statement.get("else_statements")
if else_statements:
- Scope.FromDict(scope, file, else_statements,
- 'else', scope.basedir)
+ Scope.FromDict(scope, file, else_statements, "else", scope.basedir)
continue
- loaded = statement.get('loaded')
+ loaded = statement.get("loaded")
if loaded:
- scope._append_operation('_LOADED', UniqueAddOperation(loaded))
+ scope._append_operation("_LOADED", UniqueAddOperation(loaded))
continue
- option = statement.get('option', None)
+ option = statement.get("option", None)
if option:
- scope._append_operation('_OPTION', UniqueAddOperation(option))
+ scope._append_operation("_OPTION", UniqueAddOperation(option))
continue
- included = statement.get('included', None)
+ included = statement.get("included", None)
if included:
- scope._append_operation('_INCLUDED',
- UniqueAddOperation(included))
+ scope._append_operation("_INCLUDED", UniqueAddOperation(included))
continue
scope.settle_condition()
if scope.scope_debug:
- print('..... [SCOPE_DEBUG]: Created scope {}:'.format(scope))
+ print(f"..... [SCOPE_DEBUG]: Created scope {scope}:")
scope.dump(indent=1)
- print('..... [SCOPE_DEBUG]: <<END OF SCOPE>>')
+ print("..... [SCOPE_DEBUG]: <<END OF SCOPE>>")
return scope
def _append_operation(self, key: str, op: Operation) -> None:
if key in self._operations:
self._operations[key].append(op)
else:
- self._operations[key] = [op, ]
+ self._operations[key] = [op]
@property
def file(self) -> str:
- return self._file or ''
+ return self._file or ""
@property
def file_absolute_path(self) -> str:
- return self._file_absolute_path or ''
+ return self._file_absolute_path or ""
@property
def generated_cmake_lists_path(self) -> str:
assert self.basedir
- return os.path.join(self.basedir, 'CMakeLists.gen.txt')
+ return os.path.join(self.basedir, "CMakeLists.gen.txt")
@property
def original_cmake_lists_path(self) -> str:
assert self.basedir
- return os.path.join(self.basedir, 'CMakeLists.txt')
+ return os.path.join(self.basedir, "CMakeLists.txt")
@property
def condition(self) -> str:
return self._condition
@property
- def total_condition(self) -> typing.Optional[str]:
+ def total_condition(self) -> Optional[str]:
return self._total_condition
@total_condition.setter
def total_condition(self, condition: str) -> None:
self._total_condition = condition
- def _add_child(self, scope: 'Scope') -> None:
+ def _add_child(self, scope: "Scope") -> None:
scope._parent = self
self._children.append(scope)
@property
- def children(self) -> typing.List['Scope']:
+ def children(self) -> List["Scope"]:
result = list(self._children)
for include_scope in self._included_children:
result += include_scope.children
return result
def dump(self, *, indent: int = 0) -> None:
- ind = ' ' * indent
- print('{}Scope "{}":'.format(ind, self))
+ ind = spaces(indent)
+ print(f'{ind}Scope "{self}":')
if self.total_condition:
- print('{} Total condition = {}'.format(ind, self.total_condition))
- print('{} Keys:'.format(ind))
+ print(f"{ind} Total condition = {self.total_condition}")
+ print(f"{ind} Keys:")
keys = self._operations.keys()
if not keys:
- print('{} -- NONE --'.format(ind))
+ print(f"{ind} -- NONE --")
else:
for k in sorted(keys):
- print('{} {} = "{}"'
- .format(ind, k, self._operations.get(k, [])))
- print('{} Children:'.format(ind))
+ print(f'{ind} {k} = "{self._operations.get(k, [])}"')
+ print(f"{ind} Children:")
if not self._children:
- print('{} -- NONE --'.format(ind))
+ print(f"{ind} -- NONE --")
else:
for c in self._children:
c.dump(indent=indent + 1)
- print('{} Includes:'.format(ind))
+ print(f"{ind} Includes:")
if not self._included_children:
- print('{} -- NONE --'.format(ind))
+ print(f"{ind} -- NONE --")
else:
for c in self._included_children:
c.dump(indent=indent + 1)
- def dump_structure(self, *, type: str = 'ROOT', indent: int = 0) -> None:
- print('{}{}: {}'.format(spaces(indent), type, self))
+ def dump_structure(self, *, type: str = "ROOT", indent: int = 0) -> None:
+ print(f"{spaces(indent)}{type}: {self}")
for i in self._included_children:
- i.dump_structure(type='INCL', indent=indent + 1)
+ i.dump_structure(type="INCL", indent=indent + 1)
for i in self._children:
- i.dump_structure(type='CHLD', indent=indent + 1)
+ i.dump_structure(type="CHLD", indent=indent + 1)
@property
def keys(self):
@@ -754,10 +850,14 @@ class Scope(object):
def visited_keys(self):
return self._visited_keys
- def _evalOps(self, key: str,
- transformer: typing.Optional[typing.Callable[[Scope, typing.List[str]], typing.List[str]]],
- result: typing.List[str], *, inherit: bool = False) \
- -> typing.List[str]:
+ def _evalOps(
+ self,
+ key: str,
+ transformer: Optional[Callable[[Scope, List[str]], List[str]]],
+ result: List[str],
+ *,
+ inherit: bool = False,
+ ) -> List[str]:
self._visited_keys.add(key)
# Inherrit values from above:
@@ -765,9 +865,14 @@ class Scope(object):
result = self._parent._evalOps(key, transformer, result)
if transformer:
- op_transformer = lambda files: transformer(self, files)
+
+ def op_transformer(files):
+ return transformer(self, files)
+
else:
- op_transformer = lambda files: files
+
+ def op_transformer(files):
+ return files
for op in self._operations.get(key, []):
result = op.process(key, result, op_transformer)
@@ -777,68 +882,83 @@ class Scope(object):
return result
- def get(self, key: str, *, ignore_includes: bool = False, inherit: bool = False) -> typing.List[str]:
+ def get(self, key: str, *, ignore_includes: bool = False, inherit: bool = False) -> List[str]:
is_same_path = self.currentdir == self.basedir
+ if not is_same_path:
+ relative_path = os.path.relpath(self.currentdir, self.basedir)
- if key == '_PRO_FILE_PWD_':
- return ['${CMAKE_CURRENT_SOURCE_DIR}']
- if key == 'PWD':
+ if key == "_PRO_FILE_PWD_":
+ return ["${CMAKE_CURRENT_SOURCE_DIR}"]
+ if key == "PWD":
if is_same_path:
- return ['${CMAKE_CURRENT_SOURCE_DIR}']
+ return ["${CMAKE_CURRENT_SOURCE_DIR}"]
else:
- return ['${CMAKE_CURRENT_SOURCE_DIR}/' + os.path.relpath(self.currentdir, self.basedir),]
- if key == 'OUT_PWD':
+ return [f"${{CMAKE_CURRENT_SOURCE_DIR}}/{relative_path}"]
+ if key == "OUT_PWD":
if is_same_path:
- return ['${CMAKE_CURRENT_BINARY_DIR}']
+ return ["${CMAKE_CURRENT_BINARY_DIR}"]
else:
- return ['${CMAKE_CURRENT_BINARY_DIR}/' + os.path.relpath(self.currentdir, self.basedir),]
+ return [f"${{CMAKE_CURRENT_BINARY_DIR}}/{relative_path}"]
return self._evalOps(key, None, [], inherit=inherit)
- def get_string(self, key: str, default: str = '', inherit : bool = False) -> str:
- v = self.get(key, inherit = inherit)
+ def get_string(self, key: str, default: str = "", inherit: bool = False) -> str:
+ v = self.get(key, inherit=inherit)
if len(v) == 0:
return default
assert len(v) == 1
return v[0]
- def _map_files(self, files: typing.List[str], *,
- use_vpath: bool = True, is_include: bool = False) -> typing.List[str]:
+ def _map_files(
+ self, files: List[str], *, use_vpath: bool = True, is_include: bool = False
+ ) -> List[str]:
- expanded_files = [] # type: typing.List[str]
+ expanded_files = [] # type: List[str]
for f in files:
r = self._expand_value(f)
expanded_files += r
- mapped_files = list(map(lambda f: map_to_file(f, self, is_include=is_include), expanded_files))
+ mapped_files = list(
+ map(lambda f: map_to_file(f, self, is_include=is_include), expanded_files)
+ )
if use_vpath:
- result = list(map(lambda f: handle_vpath(f, self.basedir, self.get('VPATH', inherit=True)), mapped_files))
+ result = list(
+ map(
+ lambda f: handle_vpath(f, self.basedir, self.get("VPATH", inherit=True)),
+ mapped_files,
+ )
+ )
else:
result = mapped_files
# strip ${CMAKE_CURRENT_SOURCE_DIR}:
- result = list(map(lambda f: f[28:] if f.startswith('${CMAKE_CURRENT_SOURCE_DIR}/') else f, result))
+ result = list(
+ map(lambda f: f[28:] if f.startswith("${CMAKE_CURRENT_SOURCE_DIR}/") else f, result)
+ )
# strip leading ./:
result = list(map(lambda f: trim_leading_dot(f), result))
return result
- def get_files(self, key: str, *, use_vpath: bool = False,
- is_include: bool = False) -> typing.List[str]:
- transformer = lambda scope, files: scope._map_files(files, use_vpath=use_vpath, is_include=is_include)
+ def get_files(
+ self, key: str, *, use_vpath: bool = False, is_include: bool = False
+ ) -> List[str]:
+ def transformer(scope, files):
+ return scope._map_files(files, use_vpath=use_vpath, is_include=is_include)
+
return list(self._evalOps(key, transformer, []))
- def _expand_value(self, value: str) -> typing.List[str]:
+ def _expand_value(self, value: str) -> List[str]:
result = value
- pattern = re.compile(r'\$\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?')
+ pattern = re.compile(r"\$\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?")
match = re.search(pattern, result)
while match:
old_result = result
if match.group(0) == value:
- get_result = self.get(match.group(1), inherit = True)
+ get_result = self.get(match.group(1), inherit=True)
if len(get_result) == 1:
result = get_result[0]
else:
@@ -849,21 +969,19 @@ class Scope(object):
result_list += self._expand_value(entry_value)
return result_list
else:
- replacement = self.get(match.group(1), inherit = True)
- replacement_str = replacement[0] if replacement else ''
- result = result[:match.start()] \
- + replacement_str \
- + result[match.end():]
+ replacement = self.get(match.group(1), inherit=True)
+ replacement_str = replacement[0] if replacement else ""
+ result = result[: match.start()] + replacement_str + result[match.end() :]
if result == old_result:
- return [result,] # Do not go into infinite loop
+ return [result] # Do not go into infinite loop
match = re.search(pattern, result)
- return [result,]
+ return [result]
- def expand(self, key: str) -> typing.List[str]:
+ def expand(self, key: str) -> List[str]:
value = self.get(key)
- result: typing.List[str] = []
+ result: List[str] = []
assert isinstance(value, list)
for v in value:
result += self._expand_value(v)
@@ -876,20 +994,19 @@ class Scope(object):
@property
def TEMPLATE(self) -> str:
- return self.get_string('TEMPLATE', 'app')
+ return self.get_string("TEMPLATE", "app")
def _rawTemplate(self) -> str:
- return self.get_string('TEMPLATE')
+ return self.get_string("TEMPLATE")
@property
def TARGET(self) -> str:
- target = self.expandString('TARGET') \
- or os.path.splitext(os.path.basename(self.file))[0]
- return re.sub('\.\./', '', target)
+ target = self.expandString("TARGET") or os.path.splitext(os.path.basename(self.file))[0]
+ return re.sub(r"\.\./", "", target)
@property
- def _INCLUDED(self) -> typing.List[str]:
- return self.get('_INCLUDED')
+ def _INCLUDED(self) -> List[str]:
+ return self.get("_INCLUDED")
class QmakeParser:
@@ -899,7 +1016,7 @@ class QmakeParser:
def _generate_grammar(self):
# Define grammar:
- pp.ParserElement.setDefaultWhitespaceChars(' \t')
+ pp.ParserElement.setDefaultWhitespaceChars(" \t")
def add_element(name: str, value: pp.ParserElement):
nonlocal self
@@ -908,66 +1025,81 @@ class QmakeParser:
value.setDebug()
return value
- EOL = add_element('EOL', pp.Suppress(pp.LineEnd()))
- Else = add_element('Else', pp.Keyword('else'))
- Identifier = add_element('Identifier', pp.Word(pp.alphas + '_',
- bodyChars=pp.alphanums+'_-./'))
- BracedValue = add_element('BracedValue',
- pp.nestedExpr(
- ignoreExpr=pp.quotedString |
- pp.QuotedString(quoteChar='$(',
- endQuoteChar=')',
- escQuote='\\',
- unquoteResults=False)
- ).setParseAction(lambda s, l, t: ['(', *t[0], ')']))
-
- Substitution \
- = add_element('Substitution',
- pp.Combine(pp.Literal('$')
- + (((pp.Literal('$') + Identifier
- + pp.Optional(pp.nestedExpr()))
- | (pp.Literal('(') + Identifier + pp.Literal(')'))
- | (pp.Literal('{') + Identifier + pp.Literal('}'))
- | (pp.Literal('$') + pp.Literal('{')
- + Identifier + pp.Optional(pp.nestedExpr())
- + pp.Literal('}'))
- | (pp.Literal('$') + pp.Literal('[') + Identifier
- + pp.Literal(']'))
- ))))
- LiteralValuePart = add_element('LiteralValuePart',
- pp.Word(pp.printables, excludeChars='$#{}()'))
- SubstitutionValue \
- = add_element('SubstitutionValue',
- pp.Combine(pp.OneOrMore(Substitution
- | LiteralValuePart
- | pp.Literal('$'))))
- FunctionValue \
- = add_element('FunctionValue',
- pp.Group(pp.Suppress(pp.Literal('$') + pp.Literal('$'))
+ EOL = add_element("EOL", pp.Suppress(pp.LineEnd()))
+ Else = add_element("Else", pp.Keyword("else"))
+ Identifier = add_element(
+ "Identifier", pp.Word(f"{pp.alphas}_", bodyChars=pp.alphanums + "_-./")
+ )
+ BracedValue = add_element(
+ "BracedValue",
+ pp.nestedExpr(
+ ignoreExpr=pp.quotedString
+ | pp.QuotedString(
+ quoteChar="$(", endQuoteChar=")", escQuote="\\", unquoteResults=False
+ )
+ ).setParseAction(lambda s, l, t: ["(", *t[0], ")"]),
+ )
+
+ Substitution = add_element(
+ "Substitution",
+ pp.Combine(
+ pp.Literal("$")
+ + (
+ (
+ (pp.Literal("$") + Identifier + pp.Optional(pp.nestedExpr()))
+ | (pp.Literal("(") + Identifier + pp.Literal(")"))
+ | (pp.Literal("{") + Identifier + pp.Literal("}"))
+ | (
+ pp.Literal("$")
+ + pp.Literal("{")
+ Identifier
- + pp.nestedExpr() #.setParseAction(lambda s, l, t: ['(', *t[0], ')'])
- ).setParseAction(lambda s, l, t: handle_function_value(*t)))
- Value \
- = add_element('Value',
- pp.NotAny(Else | pp.Literal('}') | EOL) \
- + (pp.QuotedString(quoteChar='"', escChar='\\')
- | FunctionValue
- | SubstitutionValue
- | BracedValue))
-
- Values = add_element('Values', pp.ZeroOrMore(Value)('value'))
-
- Op = add_element('OP',
- pp.Literal('=') | pp.Literal('-=') | pp.Literal('+=') \
- | pp.Literal('*='))
-
- Key = add_element('Key', Identifier)
-
- Operation = add_element('Operation', Key('key') + Op('operation') + Values('value'))
- CallArgs = add_element('CallArgs', pp.nestedExpr())
+ + pp.Optional(pp.nestedExpr())
+ + pp.Literal("}")
+ )
+ | (pp.Literal("$") + pp.Literal("[") + Identifier + pp.Literal("]"))
+ )
+ )
+ ),
+ )
+ LiteralValuePart = add_element(
+ "LiteralValuePart", pp.Word(pp.printables, excludeChars="$#{}()")
+ )
+ SubstitutionValue = add_element(
+ "SubstitutionValue",
+ pp.Combine(pp.OneOrMore(Substitution | LiteralValuePart | pp.Literal("$"))),
+ )
+ FunctionValue = add_element(
+ "FunctionValue",
+ pp.Group(
+ pp.Suppress(pp.Literal("$") + pp.Literal("$"))
+ + Identifier
+ + pp.nestedExpr() # .setParseAction(lambda s, l, t: ['(', *t[0], ')'])
+ ).setParseAction(lambda s, l, t: handle_function_value(*t)),
+ )
+ Value = add_element(
+ "Value",
+ pp.NotAny(Else | pp.Literal("}") | EOL)
+ + (
+ pp.QuotedString(quoteChar='"', escChar="\\")
+ | FunctionValue
+ | SubstitutionValue
+ | BracedValue
+ ),
+ )
+
+ Values = add_element("Values", pp.ZeroOrMore(Value)("value"))
+
+ Op = add_element(
+ "OP", pp.Literal("=") | pp.Literal("-=") | pp.Literal("+=") | pp.Literal("*=")
+ )
+
+ Key = add_element("Key", Identifier)
+
+ Operation = add_element("Operation", Key("key") + Op("operation") + Values("value"))
+ CallArgs = add_element("CallArgs", pp.nestedExpr())
def parse_call_args(results):
- out = ''
+ out = ""
for item in chain(*results):
if isinstance(item, str):
out += item
@@ -977,111 +1109,144 @@ class QmakeParser:
CallArgs.setParseAction(parse_call_args)
- Load = add_element('Load', pp.Keyword('load') + CallArgs('loaded'))
- Include = add_element('Include', pp.Keyword('include') + CallArgs('included'))
- Option = add_element('Option', pp.Keyword('option') + CallArgs('option'))
+ Load = add_element("Load", pp.Keyword("load") + CallArgs("loaded"))
+ Include = add_element("Include", pp.Keyword("include") + CallArgs("included"))
+ Option = add_element("Option", pp.Keyword("option") + CallArgs("option"))
# ignore the whole thing...
DefineTestDefinition = add_element(
- 'DefineTestDefinition',
- pp.Suppress(pp.Keyword('defineTest') + CallArgs
- + pp.nestedExpr(opener='{', closer='}', ignoreExpr=pp.LineEnd())))
+ "DefineTestDefinition",
+ pp.Suppress(
+ pp.Keyword("defineTest")
+ + CallArgs
+ + pp.nestedExpr(opener="{", closer="}", ignoreExpr=pp.LineEnd())
+ ),
+ )
# ignore the whole thing...
ForLoop = add_element(
- 'ForLoop',
- pp.Suppress(pp.Keyword('for') + CallArgs
- + pp.nestedExpr(opener='{', closer='}', ignoreExpr=pp.LineEnd())))
+ "ForLoop",
+ pp.Suppress(
+ pp.Keyword("for")
+ + CallArgs
+ + pp.nestedExpr(opener="{", closer="}", ignoreExpr=pp.LineEnd())
+ ),
+ )
# ignore the whole thing...
ForLoopSingleLine = add_element(
- 'ForLoopSingleLine',
- pp.Suppress(pp.Keyword('for') + CallArgs + pp.Literal(':') + pp.SkipTo(EOL)))
+ "ForLoopSingleLine",
+ pp.Suppress(pp.Keyword("for") + CallArgs + pp.Literal(":") + pp.SkipTo(EOL)),
+ )
# ignore the whole thing...
- FunctionCall = add_element('FunctionCall', pp.Suppress(Identifier + pp.nestedExpr()))
-
- Scope = add_element('Scope', pp.Forward())
-
- Statement = add_element('Statement',
- pp.Group(Load | Include | Option | ForLoop | ForLoopSingleLine
- | DefineTestDefinition | FunctionCall | Operation))
- StatementLine = add_element('StatementLine', Statement + (EOL | pp.FollowedBy('}')))
- StatementGroup = add_element('StatementGroup',
- pp.ZeroOrMore(StatementLine | Scope | pp.Suppress(EOL)))
-
- Block = add_element('Block',
- pp.Suppress('{') + pp.Optional(EOL)
- + StatementGroup + pp.Optional(EOL)
- + pp.Suppress('}') + pp.Optional(EOL))
-
- ConditionEnd = add_element('ConditionEnd',
- pp.FollowedBy((pp.Optional(pp.White())
- + (pp.Literal(':')
- | pp.Literal('{')
- | pp.Literal('|')))))
-
- ConditionPart1 = add_element('ConditionPart1',
- (pp.Optional('!') + Identifier + pp.Optional(BracedValue)))
- ConditionPart2 = add_element('ConditionPart2', pp.CharsNotIn('#{}|:=\\\n'))
+ FunctionCall = add_element("FunctionCall", pp.Suppress(Identifier + pp.nestedExpr()))
+
+ Scope = add_element("Scope", pp.Forward())
+
+ Statement = add_element(
+ "Statement",
+ pp.Group(
+ Load
+ | Include
+ | Option
+ | ForLoop
+ | ForLoopSingleLine
+ | DefineTestDefinition
+ | FunctionCall
+ | Operation
+ ),
+ )
+ StatementLine = add_element("StatementLine", Statement + (EOL | pp.FollowedBy("}")))
+ StatementGroup = add_element(
+ "StatementGroup", pp.ZeroOrMore(StatementLine | Scope | pp.Suppress(EOL))
+ )
+
+ Block = add_element(
+ "Block",
+ pp.Suppress("{")
+ + pp.Optional(EOL)
+ + StatementGroup
+ + pp.Optional(EOL)
+ + pp.Suppress("}")
+ + pp.Optional(EOL),
+ )
+
+ ConditionEnd = add_element(
+ "ConditionEnd",
+ pp.FollowedBy(
+ (pp.Optional(pp.White()) + (pp.Literal(":") | pp.Literal("{") | pp.Literal("|")))
+ ),
+ )
+
+ ConditionPart1 = add_element(
+ "ConditionPart1", (pp.Optional("!") + Identifier + pp.Optional(BracedValue))
+ )
+ ConditionPart2 = add_element("ConditionPart2", pp.CharsNotIn("#{}|:=\\\n"))
ConditionPart = add_element(
- 'ConditionPart',
- (ConditionPart1 ^ ConditionPart2) + ConditionEnd)
+ "ConditionPart", (ConditionPart1 ^ ConditionPart2) + ConditionEnd
+ )
- ConditionOp = add_element('ConditionOp', pp.Literal('|') ^ pp.Literal(':'))
- ConditionWhiteSpace = add_element('ConditionWhiteSpace',
- pp.Suppress(pp.Optional(pp.White(' '))))
+ ConditionOp = add_element("ConditionOp", pp.Literal("|") ^ pp.Literal(":"))
+ ConditionWhiteSpace = add_element(
+ "ConditionWhiteSpace", pp.Suppress(pp.Optional(pp.White(" ")))
+ )
- ConditionRepeated = add_element('ConditionRepeated',
- pp.ZeroOrMore(ConditionOp
- + ConditionWhiteSpace + ConditionPart))
+ ConditionRepeated = add_element(
+ "ConditionRepeated", pp.ZeroOrMore(ConditionOp + ConditionWhiteSpace + ConditionPart)
+ )
- Condition = add_element('Condition', pp.Combine(ConditionPart + ConditionRepeated))
- Condition.setParseAction(lambda x: ' '.join(x).strip().replace(':', ' && ').strip(' && '))
+ Condition = add_element("Condition", pp.Combine(ConditionPart + ConditionRepeated))
+ Condition.setParseAction(lambda x: " ".join(x).strip().replace(":", " && ").strip(" && "))
# Weird thing like write_file(a)|error() where error() is the alternative condition
# which happens to be a function call. In this case there is no scope, but our code expects
# a scope with a list of statements, so create a fake empty statement.
ConditionEndingInFunctionCall = add_element(
- 'ConditionEndingInFunctionCall', pp.Suppress(ConditionOp) + FunctionCall
- + pp.Empty().setParseAction(lambda x: [[]])
- .setResultsName('statements'))
-
- SingleLineScope = add_element('SingleLineScope',
- pp.Suppress(pp.Literal(':'))
- + pp.Group(Block | (Statement + EOL))('statements'))
- MultiLineScope = add_element('MultiLineScope', Block('statements'))
-
- SingleLineElse = add_element('SingleLineElse',
- pp.Suppress(pp.Literal(':'))
- + (Scope | Block | (Statement + pp.Optional(EOL))))
- MultiLineElse = add_element('MultiLineElse', Block)
- ElseBranch = add_element('ElseBranch', pp.Suppress(Else) + (SingleLineElse | MultiLineElse))
+ "ConditionEndingInFunctionCall",
+ pp.Suppress(ConditionOp)
+ + FunctionCall
+ + pp.Empty().setParseAction(lambda x: [[]]).setResultsName("statements"),
+ )
+
+ SingleLineScope = add_element(
+ "SingleLineScope",
+ pp.Suppress(pp.Literal(":")) + pp.Group(Block | (Statement + EOL))("statements"),
+ )
+ MultiLineScope = add_element("MultiLineScope", Block("statements"))
+
+ SingleLineElse = add_element(
+ "SingleLineElse",
+ pp.Suppress(pp.Literal(":")) + (Scope | Block | (Statement + pp.Optional(EOL))),
+ )
+ MultiLineElse = add_element("MultiLineElse", Block)
+ ElseBranch = add_element("ElseBranch", pp.Suppress(Else) + (SingleLineElse | MultiLineElse))
# Scope is already add_element'ed in the forward declaration above.
- Scope <<= \
- pp.Group(Condition('condition')
- + (SingleLineScope | MultiLineScope | ConditionEndingInFunctionCall)
- + pp.Optional(ElseBranch)('else_statements'))
+ Scope <<= pp.Group(
+ Condition("condition")
+ + (SingleLineScope | MultiLineScope | ConditionEndingInFunctionCall)
+ + pp.Optional(ElseBranch)("else_statements")
+ )
- Grammar = StatementGroup('statements')
+ Grammar = StatementGroup("statements")
Grammar.ignore(pp.pythonStyleComment())
return Grammar
def parseFile(self, file: str):
- print('Parsing \"{}\"...'.format(file))
+ print(f'Parsing "{file}"...')
try:
- with open(file, 'r') as file_fd:
+ with open(file, "r") as file_fd:
contents = file_fd.read()
- old_contents = contents
+ # old_contents = contents
contents = fixup_comments(contents)
contents = fixup_linecontinuation(contents)
result = self._Grammar.parseString(contents, parseAll=True)
except pp.ParseException as pe:
print(pe.line)
- print(' '*(pe.col-1) + '^')
+ print(f"{' ' * (pe.col-1)}^")
print(pe)
raise pe
return result
@@ -1094,30 +1259,32 @@ def parseProFile(file: str, *, debug=False):
def map_condition(condition: str) -> str:
# Some hardcoded cases that are too bothersome to generalize.
- condition = re.sub(r'qtConfig\(opengl\(es1\|es2\)\?\)',
- r'QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT_FEATURE_opengles3',
- condition)
- condition = re.sub(r'qtConfig\(opengl\.\*\)', r'QT_FEATURE_opengl', condition)
- condition = re.sub(r'^win\*$', r'win', condition)
- condition = re.sub(r'^no-png$', r'NOT QT_FEATURE_png', condition)
- condition = re.sub(r'contains\(CONFIG, static\)', r'NOT QT_BUILD_SHARED_LIBS', condition)
- condition = re.sub(r'contains\(QT_CONFIG,\w*shared\)', r'QT_BUILD_SHARED_LIBS', condition)
+ condition = re.sub(
+ r"qtConfig\(opengl\(es1\|es2\)\?\)",
+ r"QT_FEATURE_opengl OR QT_FEATURE_opengles2 OR QT_FEATURE_opengles3",
+ condition,
+ )
+ condition = re.sub(r"qtConfig\(opengl\.\*\)", r"QT_FEATURE_opengl", condition)
+ condition = re.sub(r"^win\*$", r"win", condition)
+ condition = re.sub(r"^no-png$", r"NOT QT_FEATURE_png", condition)
+ condition = re.sub(r"contains\(CONFIG, static\)", r"NOT QT_BUILD_SHARED_LIBS", condition)
+ condition = re.sub(r"contains\(QT_CONFIG,\w*shared\)", r"QT_BUILD_SHARED_LIBS", condition)
def gcc_version_handler(match_obj: re.Match):
operator = match_obj.group(1)
version_type = match_obj.group(2)
- if operator == 'equals':
- operator = 'STREQUAL'
- elif operator == 'greaterThan':
- operator = 'STRGREATER'
- elif operator == 'lessThan':
- operator = 'STRLESS'
+ if operator == "equals":
+ operator = "STREQUAL"
+ elif operator == "greaterThan":
+ operator = "STRGREATER"
+ elif operator == "lessThan":
+ operator = "STRLESS"
version = match_obj.group(3)
- return '(QT_COMPILER_VERSION_{} {} {})'.format(version_type, operator, version)
+ return f"(QT_COMPILER_VERSION_{version_type} {operator} {version})"
# TODO: Possibly fix for other compilers.
- pattern = r'(equals|greaterThan|lessThan)\(QT_GCC_([A-Z]+)_VERSION,[ ]*([0-9]+)\)'
+ pattern = r"(equals|greaterThan|lessThan)\(QT_GCC_([A-Z]+)_VERSION,[ ]*([0-9]+)\)"
condition = re.sub(pattern, gcc_version_handler, condition)
# TODO: the current if(...) replacement makes the parentheses
@@ -1125,108 +1292,104 @@ def map_condition(condition: str) -> str:
# Need to fix this either with pypi regex recursive regexps,
# using pyparsing, or some other proper means of handling
# balanced parentheses.
- condition = re.sub(r'\bif\s*\((.*?)\)', r'\1', condition)
-
- condition = re.sub(r'\bisEmpty\s*\((.*?)\)', r'\1_ISEMPTY', condition)
- condition = re.sub(r'\bcontains\s*\((.*?),\s*"?(.*?)"?\)',
- r'\1___contains___\2', condition)
- condition = re.sub(r'\bequals\s*\((.*?),\s*"?(.*?)"?\)',
- r'\1___equals___\2', condition)
- condition = re.sub(r'\bisEqual\s*\((.*?),\s*"?(.*?)"?\)',
- r'\1___equals___\2', condition)
- condition = re.sub(r'\s*==\s*', '___STREQUAL___', condition)
- condition = re.sub(r'\bexists\s*\((.*?)\)', r'EXISTS \1', condition)
-
- pattern = r'CONFIG\((debug|release),debug\|release\)'
+ condition = re.sub(r"\bif\s*\((.*?)\)", r"\1", condition)
+
+ condition = re.sub(r"\bisEmpty\s*\((.*?)\)", r"\1_ISEMPTY", condition)
+ condition = re.sub(r'\bcontains\s*\((.*?),\s*"?(.*?)"?\)', r"\1___contains___\2", condition)
+ condition = re.sub(r'\bequals\s*\((.*?),\s*"?(.*?)"?\)', r"\1___equals___\2", condition)
+ condition = re.sub(r'\bisEqual\s*\((.*?),\s*"?(.*?)"?\)', r"\1___equals___\2", condition)
+ condition = re.sub(r"\s*==\s*", "___STREQUAL___", condition)
+ condition = re.sub(r"\bexists\s*\((.*?)\)", r"EXISTS \1", condition)
+
+ pattern = r"CONFIG\((debug|release),debug\|release\)"
match_result = re.match(pattern, condition)
if match_result:
build_type = match_result.group(1)
- if build_type == 'debug':
- build_type = 'Debug'
- elif build_type == 'release':
- build_type = 'Release'
- condition = re.sub(pattern, '(CMAKE_BUILD_TYPE STREQUAL {})'.format(build_type), condition)
+ if build_type == "debug":
+ build_type = "Debug"
+ elif build_type == "release":
+ build_type = "Release"
+ condition = re.sub(pattern, f"(CMAKE_BUILD_TYPE STREQUAL {build_type})", condition)
- condition = condition.replace('*', '_x_')
- condition = condition.replace('.$$', '__ss_')
- condition = condition.replace('$$', '_ss_')
+ condition = condition.replace("*", "_x_")
+ condition = condition.replace(".$$", "__ss_")
+ condition = condition.replace("$$", "_ss_")
- condition = condition.replace('!', 'NOT ')
- condition = condition.replace('&&', ' AND ')
- condition = condition.replace('|', ' OR ')
+ condition = condition.replace("!", "NOT ")
+ condition = condition.replace("&&", " AND ")
+ condition = condition.replace("|", " OR ")
- cmake_condition = ''
+ cmake_condition = ""
for part in condition.split():
# some features contain e.g. linux, that should not be
# turned upper case
- feature = re.match(r"(qtConfig|qtHaveModule)\(([a-zA-Z0-9_-]+)\)",
- part)
+ feature = re.match(r"(qtConfig|qtHaveModule)\(([a-zA-Z0-9_-]+)\)", part)
if feature:
- if (feature.group(1) == "qtHaveModule"):
- part = 'TARGET {}'.format(map_qt_library(feature.group(2)))
+ if feature.group(1) == "qtHaveModule":
+ part = f"TARGET {map_qt_library(feature.group(2))}"
else:
feature_name = featureName(feature.group(2))
- if feature_name.startswith('system_') and is_known_3rd_party_library(feature_name[7:]):
- part = 'ON'
- elif feature == 'dlopen':
- part = 'ON'
+ if feature_name.startswith("system_") and is_known_3rd_party_library(
+ feature_name[7:]
+ ):
+ part = "ON"
+ elif feature == "dlopen":
+ part = "ON"
else:
- part = 'QT_FEATURE_' + feature_name
+ part = "QT_FEATURE_" + feature_name
else:
part = map_platform(part)
- part = part.replace('true', 'ON')
- part = part.replace('false', 'OFF')
- cmake_condition += ' ' + part
+ part = part.replace("true", "ON")
+ part = part.replace("false", "OFF")
+ cmake_condition += " " + part
return cmake_condition.strip()
-def handle_subdir(scope: Scope,
- cm_fh: typing.IO[str],
- *,
- indent: int = 0,
- is_example: bool = False) -> None:
+def handle_subdir(
+ scope: Scope, cm_fh: IO[str], *, indent: int = 0, is_example: bool = False
+) -> None:
# Global nested dictionary that will contain sub_dir assignments and their conditions.
# Declared as a global in order not to pollute the nested function signatures with giant
# type hints.
- sub_dirs: typing.Dict[str, typing.Dict[str, typing.Set[typing.FrozenSet[str]]]] = {}
+ sub_dirs: Dict[str, Dict[str, Set[FrozenSet[str]]]] = {}
# Collects assignment conditions into global sub_dirs dict.
- def collect_subdir_info(sub_dir_assignment: str,
- *,
- current_conditions: typing.FrozenSet[str] = None):
- subtraction = sub_dir_assignment.startswith('-')
+ def collect_subdir_info(sub_dir_assignment: str, *, current_conditions: FrozenSet[str] = None):
+ subtraction = sub_dir_assignment.startswith("-")
if subtraction:
subdir_name = sub_dir_assignment[1:]
else:
subdir_name = sub_dir_assignment
if subdir_name not in sub_dirs:
sub_dirs[subdir_name] = {}
- additions = sub_dirs[subdir_name].get('additions', set())
- subtractions = sub_dirs[subdir_name].get('subtractions', set())
+ additions = sub_dirs[subdir_name].get("additions", set())
+ subtractions = sub_dirs[subdir_name].get("subtractions", set())
if current_conditions:
if subtraction:
subtractions.add(current_conditions)
else:
additions.add(current_conditions)
if additions:
- sub_dirs[subdir_name]['additions'] = additions
+ sub_dirs[subdir_name]["additions"] = additions
if subtractions:
- sub_dirs[subdir_name]['subtractions'] = subtractions
+ sub_dirs[subdir_name]["subtractions"] = subtractions
# Recursive helper that collects subdir info for given scope,
# and the children of the given scope.
- def handle_subdir_helper(scope: Scope,
- cm_fh: typing.IO[str],
- *,
- indent: int = 0,
- current_conditions: typing.FrozenSet[str] = None,
- is_example: bool = False):
- for sd in scope.get_files('SUBDIRS'):
+ def handle_subdir_helper(
+ scope: Scope,
+ cm_fh: IO[str],
+ *,
+ indent: int = 0,
+ current_conditions: FrozenSet[str] = None,
+ is_example: bool = False,
+ ):
+ for sd in scope.get_files("SUBDIRS"):
# Collect info about conditions and SUBDIR assignments in the
# current scope.
- if os.path.isdir(sd) or sd.startswith('-'):
+ if os.path.isdir(sd) or sd.startswith("-"):
collect_subdir_info(sd, current_conditions=current_conditions)
# For the file case, directly write into the file handle.
elif os.path.isfile(sd):
@@ -1239,15 +1402,14 @@ def handle_subdir(scope: Scope,
collect_subdir_info(dirname, current_conditions=current_conditions)
else:
subdir_result = parseProFile(sd, debug=False)
- subdir_scope \
- = Scope.FromDict(scope, sd,
- subdir_result.asDict().get('statements'),
- '', scope.basedir)
+ subdir_scope = Scope.FromDict(
+ scope, sd, subdir_result.asDict().get("statements"), "", scope.basedir
+ )
do_include(subdir_scope)
cmakeify_scope(subdir_scope, cm_fh, indent=indent, is_example=is_example)
else:
- print(' XXXX: SUBDIR {} in {}: Not found.'.format(sd, scope))
+ print(f" XXXX: SUBDIR {sd} in {scope}: Not found.")
# Collect info about conditions and SUBDIR assignments in child
# scopes, aka recursively call the same function, but with an
@@ -1255,12 +1417,14 @@ def handle_subdir(scope: Scope,
for c in scope.children:
# Use total_condition for 'else' conditions, otherwise just use the regular value to
# simplify the logic.
- child_condition = c.total_condition if c.condition == 'else' else c.condition
- handle_subdir_helper(c, cm_fh,
- indent=indent + 1,
- is_example=is_example,
- current_conditions=frozenset((*current_conditions,
- child_condition)))
+ child_condition = c.total_condition if c.condition == "else" else c.condition
+ handle_subdir_helper(
+ c,
+ cm_fh,
+ indent=indent + 1,
+ is_example=is_example,
+ current_conditions=frozenset((*current_conditions, child_condition)),
+ )
def group_and_print_sub_dirs(indent: int = 0):
# Simplify conditions, and group
@@ -1270,40 +1434,42 @@ def handle_subdir(scope: Scope,
# Wraps each element in the given interable with parentheses,
# to make sure boolean simplification happens correctly.
def wrap_in_parenthesis(iterable):
- return ['({})'.format(c) for c in iterable]
+ return [f"({c})" for c in iterable]
def join_all_conditions(set_of_alternatives):
# Elements within one frozen set represent one single
# alternative whose pieces are ANDed together.
# This is repeated for each alternative that would
# enable a subdir, and are thus ORed together.
- final_str = ''
+ final_str = ""
if set_of_alternatives:
- wrapped_set_of_alternatives = [wrap_in_parenthesis(alternative)
- for alternative in set_of_alternatives]
- alternatives = ['({})'.format(" AND ".join(alternative))
- for alternative in wrapped_set_of_alternatives]
- final_str = ' OR '.join(sorted(alternatives))
+ wrapped_set_of_alternatives = [
+ wrap_in_parenthesis(alternative) for alternative in set_of_alternatives
+ ]
+ alternatives = [
+ f'({" AND ".join(alternative)})' for alternative in wrapped_set_of_alternatives
+ ]
+ final_str = " OR ".join(sorted(alternatives))
return final_str
for subdir_name in sub_dirs:
- additions = sub_dirs[subdir_name].get('additions', set())
- subtractions = sub_dirs[subdir_name].get('subtractions', set())
+ additions = sub_dirs[subdir_name].get("additions", set())
+ subtractions = sub_dirs[subdir_name].get("subtractions", set())
# An empty condition key represents the group of sub dirs
# that should be added unconditionally.
- condition_key = ''
+ condition_key = ""
if additions or subtractions:
addition_str = join_all_conditions(additions)
if addition_str:
- addition_str = '({})'.format(addition_str)
+ addition_str = f"({addition_str})"
subtraction_str = join_all_conditions(subtractions)
if subtraction_str:
- subtraction_str = 'NOT ({})'.format(subtraction_str)
+ subtraction_str = f"NOT ({subtraction_str})"
condition_str = addition_str
if condition_str and subtraction_str:
- condition_str += ' AND '
+ condition_str += " AND "
condition_str += subtraction_str
condition_simplified = simplify_condition(condition_str)
condition_key = condition_simplified
@@ -1313,18 +1479,18 @@ def handle_subdir(scope: Scope,
grouped_sub_dirs[condition_key] = sub_dir_list_by_key
# Print the groups.
- ind = ' ' * indent
+ ind = spaces(1)
for condition_key in grouped_sub_dirs:
cond_ind = ind
if condition_key:
- cm_fh.write(f'{ind}if({condition_key})\n')
+ cm_fh.write(f"{ind}if({condition_key})\n")
cond_ind += " "
sub_dir_list_by_key = grouped_sub_dirs.get(condition_key, [])
for subdir_name in sub_dir_list_by_key:
- cm_fh.write(f'{cond_ind}add_subdirectory({subdir_name})\n')
+ cm_fh.write(f"{cond_ind}add_subdirectory({subdir_name})\n")
if condition_key:
- cm_fh.write(f'{ind}endif()\n')
+ cm_fh.write(f"{ind}endif()\n")
# A set of conditions which will be ANDed together. The set is recreated with more conditions
# as the scope deepens.
@@ -1335,22 +1501,21 @@ def handle_subdir(scope: Scope,
recursive_evaluate_scope(scope)
# Do the work.
- handle_subdir_helper(scope, cm_fh,
- indent=indent,
- current_conditions=current_conditions,
- is_example=is_example)
+ handle_subdir_helper(
+ scope, cm_fh, indent=indent, current_conditions=current_conditions, is_example=is_example
+ )
group_and_print_sub_dirs(indent=indent)
-def sort_sources(sources: typing.List[str]) -> typing.List[str]:
- to_sort = {} # type: typing.Dict[str, typing.List[str]]
+def sort_sources(sources: List[str]) -> List[str]:
+ to_sort = {} # type: Dict[str, List[str]]
for s in sources:
if s is None:
continue
dir = os.path.dirname(s)
base = os.path.splitext(os.path.basename(s))[0]
- if base.endswith('_p'):
+ if base.endswith("_p"):
base = base[:-2]
sort_name = posixpath.join(dir, base)
@@ -1361,245 +1526,280 @@ def sort_sources(sources: typing.List[str]) -> typing.List[str]:
lines = []
for k in sorted(to_sort.keys()):
- lines.append(' '.join(sorted(to_sort[k])))
+ lines.append(" ".join(sorted(to_sort[k])))
return lines
-def _map_libraries_to_cmake(libraries: typing.List[str],
- known_libraries: typing.Set[str]) -> typing.List[str]:
- result = [] # type: typing.List[str]
+def _map_libraries_to_cmake(libraries: List[str], known_libraries: Set[str]) -> List[str]:
+ result = [] # type: List[str]
is_framework = False
- for l in libraries:
- if l == '-framework':
+ for lib in libraries:
+ if lib == "-framework":
is_framework = True
continue
if is_framework:
- l = '${FW%s}' % l
- if l.startswith('-l'):
- l = l[2:]
+ lib = f"${{FW{lib}}}"
+ if lib.startswith("-l"):
+ lib = lib[2:]
- if l.startswith('-'):
- l = '# Remove: {}'.format(l[1:])
+ if lib.startswith("-"):
+ lib = f"# Remove: {lib[1:]}"
else:
- l = map_3rd_party_library(l)
+ lib = map_3rd_party_library(lib)
- if not l or l in result or l in known_libraries:
+ if not lib or lib in result or lib in known_libraries:
continue
- result.append(l)
+ result.append(lib)
is_framework = False
return result
-def extract_cmake_libraries(scope: Scope, *, known_libraries: typing.Set[str]=set()) \
- -> typing.Tuple[typing.List[str], typing.List[str]]:
- public_dependencies = [] # type: typing.List[str]
- private_dependencies = [] # type: typing.List[str]
+def extract_cmake_libraries(
+ scope: Scope, *, known_libraries: Set[str] = set()
+) -> Tuple[List[str], List[str]]:
+ public_dependencies = [] # type: List[str]
+ private_dependencies = [] # type: List[str]
- for key in ['QMAKE_USE', 'LIBS',]:
+ for key in ["QMAKE_USE", "LIBS"]:
public_dependencies += scope.expand(key)
- for key in ['QMAKE_USE_PRIVATE', 'QMAKE_USE_FOR_PRIVATE', 'LIBS_PRIVATE',]:
+ for key in ["QMAKE_USE_PRIVATE", "QMAKE_USE_FOR_PRIVATE", "LIBS_PRIVATE"]:
private_dependencies += scope.expand(key)
- for key in ['QT_FOR_PRIVATE','QT_PRIVATE']:
+ for key in ["QT_FOR_PRIVATE", "QT_PRIVATE"]:
private_dependencies += [map_qt_library(q) for q in scope.expand(key)]
- for key in ['QT',]:
+ for key in ["QT"]:
# Qt public libs: These may include FooPrivate in which case we get
# a private dependency on FooPrivate as well as a public dependency on Foo
for lib in scope.expand(key):
mapped_lib = map_qt_library(lib)
- if mapped_lib.endswith('Private'):
+ if mapped_lib.endswith("Private"):
private_dependencies.append(mapped_lib)
public_dependencies.append(mapped_lib[:-7])
else:
public_dependencies.append(mapped_lib)
- return (_map_libraries_to_cmake(public_dependencies, known_libraries),
- _map_libraries_to_cmake(private_dependencies, known_libraries))
-
+ return (
+ _map_libraries_to_cmake(public_dependencies, known_libraries),
+ _map_libraries_to_cmake(private_dependencies, known_libraries),
+ )
-def write_header(cm_fh: typing.IO[str], name: str,
- typename: str, *, indent: int = 0):
- cm_fh.write('{}###########################################'
- '##########################\n'.format(spaces(indent)))
- cm_fh.write('{}## {} {}:\n'.format(spaces(indent), name, typename))
- cm_fh.write('{}###########################################'
- '##########################\n\n'.format(spaces(indent)))
-
-def write_scope_header(cm_fh: typing.IO[str], *, indent: int = 0):
- cm_fh.write('\n{}## Scopes:\n'.format(spaces(indent)))
- cm_fh.write('{}###########################################'
- '##########################\n'.format(spaces(indent)))
+def write_header(cm_fh: IO[str], name: str, typename: str, *, indent: int = 0):
+ ind = spaces(indent)
+ comment_line = "#" * 69
+ cm_fh.write(f"{ind}{comment_line}\n")
+ cm_fh.write(f"{ind}## {name} {typename}:\n")
+ cm_fh.write(f"{ind}{comment_line}\n\n")
-def write_list(cm_fh: typing.IO[str], entries: typing.List[str],
- cmake_parameter: str,
- indent: int = 0, *,
- header: str = '', footer: str = ''):
+def write_scope_header(cm_fh: IO[str], *, indent: int = 0):
+ ind = spaces(indent)
+ comment_line = "#" * 69
+ cm_fh.write(f"\n{ind}## Scopes:\n")
+ cm_fh.write(f"{ind}{comment_line}\n")
+
+
+def write_list(
+ cm_fh: IO[str],
+ entries: List[str],
+ cmake_parameter: str,
+ indent: int = 0,
+ *,
+ header: str = "",
+ footer: str = "",
+):
if not entries:
return
ind = spaces(indent)
- extra_indent = ''
+ extra_indent = ""
if header:
- cm_fh.write('{}{}'.format(ind, header))
- extra_indent += ' '
+ cm_fh.write(f"{ind}{header}")
+ extra_indent += " "
if cmake_parameter:
- cm_fh.write('{}{}{}\n'.format(ind, extra_indent, cmake_parameter))
- extra_indent += ' '
+ cm_fh.write(f"{ind}{extra_indent}{cmake_parameter}\n")
+ extra_indent += " "
for s in sort_sources(entries):
- cm_fh.write('{}{}{}\n'.format(ind, extra_indent, s))
+ cm_fh.write(f"{ind}{extra_indent}{s}\n")
if footer:
- cm_fh.write('{}{}\n'.format(ind, footer))
-
-
-def write_source_file_list(cm_fh: typing.IO[str], scope, cmake_parameter: str,
- keys: typing.List[str], indent: int = 0, *,
- header: str = '', footer: str = ''):
+ cm_fh.write(f"{ind}{footer}\n")
+
+
+def write_source_file_list(
+ cm_fh: IO[str],
+ scope,
+ cmake_parameter: str,
+ keys: List[str],
+ indent: int = 0,
+ *,
+ header: str = "",
+ footer: str = "",
+):
# collect sources
- sources: typing.List[str] = []
+ sources: List[str] = []
for key in keys:
sources += scope.get_files(key, use_vpath=True)
write_list(cm_fh, sources, cmake_parameter, indent, header=header, footer=footer)
-def write_all_source_file_lists(cm_fh: typing.IO[str], scope: Scope, header: str, *,
- indent: int = 0, footer: str = '',
- extra_keys: typing.Optional[typing.List[str]] = None):
+def write_all_source_file_lists(
+ cm_fh: IO[str],
+ scope: Scope,
+ header: str,
+ *,
+ indent: int = 0,
+ footer: str = "",
+ extra_keys: Optional[List[str]] = None,
+):
if extra_keys is None:
extra_keys = []
- write_source_file_list(cm_fh, scope, header,
- ['SOURCES', 'HEADERS', 'OBJECTIVE_SOURCES', 'NO_PCH_SOURCES', 'FORMS'] + extra_keys,
- indent, footer=footer)
-
-
-def write_defines(cm_fh: typing.IO[str], scope: Scope, cmake_parameter: str, *,
- indent: int = 0, footer: str = ''):
- defines = scope.expand('DEFINES')
- defines += [d[2:] for d in scope.expand('QMAKE_CXXFLAGS') if d.startswith('-D')]
- defines = [d.replace('=\\\\\\"$$PWD/\\\\\\"',
- '="${CMAKE_CURRENT_SOURCE_DIR}/"') for d in defines]
-
- if 'qml_debug' in scope.get('CONFIG'):
- defines.append('QT_QML_DEBUG')
+ write_source_file_list(
+ cm_fh,
+ scope,
+ header,
+ ["SOURCES", "HEADERS", "OBJECTIVE_SOURCES", "NO_PCH_SOURCES", "FORMS"] + extra_keys,
+ indent,
+ footer=footer,
+ )
+
+
+def write_defines(
+ cm_fh: IO[str], scope: Scope, cmake_parameter: str, *, indent: int = 0, footer: str = ""
+):
+ defines = scope.expand("DEFINES")
+ defines += [d[2:] for d in scope.expand("QMAKE_CXXFLAGS") if d.startswith("-D")]
+ defines = [
+ d.replace('=\\\\\\"$$PWD/\\\\\\"', '="${CMAKE_CURRENT_SOURCE_DIR}/"') for d in defines
+ ]
+
+ if "qml_debug" in scope.get("CONFIG"):
+ defines.append("QT_QML_DEBUG")
write_list(cm_fh, defines, cmake_parameter, indent, footer=footer)
-def write_include_paths(cm_fh: typing.IO[str], scope: Scope, cmake_parameter: str, *,
- indent: int = 0, footer: str = ''):
- includes = [i.rstrip('/') or ('/') for i in scope.get_files('INCLUDEPATH')]
+def write_include_paths(
+ cm_fh: IO[str], scope: Scope, cmake_parameter: str, *, indent: int = 0, footer: str = ""
+):
+ includes = [i.rstrip("/") or ("/") for i in scope.get_files("INCLUDEPATH")]
write_list(cm_fh, includes, cmake_parameter, indent, footer=footer)
-def write_compile_options(cm_fh: typing.IO[str], scope: Scope, cmake_parameter: str, *,
- indent: int = 0, footer: str = ''):
- compile_options = [d for d in scope.expand('QMAKE_CXXFLAGS') if not d.startswith('-D')]
+def write_compile_options(
+ cm_fh: IO[str], scope: Scope, cmake_parameter: str, *, indent: int = 0, footer: str = ""
+):
+ compile_options = [d for d in scope.expand("QMAKE_CXXFLAGS") if not d.startswith("-D")]
write_list(cm_fh, compile_options, cmake_parameter, indent, footer=footer)
-def write_library_section(cm_fh: typing.IO[str], scope: Scope, *,
- indent: int = 0, known_libraries: typing.Set[str]=set()):
- (public_dependencies, private_dependencies) \
- = extract_cmake_libraries(scope, known_libraries=known_libraries)
+def write_library_section(
+ cm_fh: IO[str], scope: Scope, *, indent: int = 0, known_libraries: Set[str] = set()
+):
+ public_dependencies, private_dependencies = extract_cmake_libraries(
+ scope, known_libraries=known_libraries
+ )
- write_list(cm_fh, private_dependencies, 'LIBRARIES', indent + 1)
- write_list(cm_fh, public_dependencies, 'PUBLIC_LIBRARIES', indent + 1)
+ write_list(cm_fh, private_dependencies, "LIBRARIES", indent + 1)
+ write_list(cm_fh, public_dependencies, "PUBLIC_LIBRARIES", indent + 1)
-def write_autogen_section(cm_fh: typing.IO[str], scope: Scope, *,
- indent: int = 0):
- forms = scope.get_files('FORMS')
+def write_autogen_section(cm_fh: IO[str], scope: Scope, *, indent: int = 0):
+ forms = scope.get_files("FORMS")
if forms:
- write_list(cm_fh, ['uic'], 'ENABLE_AUTOGEN_TOOLS', indent)
+ write_list(cm_fh, ["uic"], "ENABLE_AUTOGEN_TOOLS", indent)
-def write_sources_section(cm_fh: typing.IO[str], scope: Scope, *,
- indent: int = 0, known_libraries=set()):
+def write_sources_section(cm_fh: IO[str], scope: Scope, *, indent: int = 0, known_libraries=set()):
ind = spaces(indent)
# mark RESOURCES as visited:
- scope.get('RESOURCES')
+ scope.get("RESOURCES")
- write_all_source_file_lists(cm_fh, scope, 'SOURCES', indent=indent + 1)
+ write_all_source_file_lists(cm_fh, scope, "SOURCES", indent=indent + 1)
- write_source_file_list(cm_fh, scope, 'DBUS_ADAPTOR_SOURCES', ['DBUS_ADAPTORS',], indent + 1)
- dbus_adaptor_flags = scope.expand('QDBUSXML2CPP_ADAPTOR_HEADER_FLAGS')
+ write_source_file_list(cm_fh, scope, "DBUS_ADAPTOR_SOURCES", ["DBUS_ADAPTORS"], indent + 1)
+ dbus_adaptor_flags = scope.expand("QDBUSXML2CPP_ADAPTOR_HEADER_FLAGS")
if dbus_adaptor_flags:
- cm_fh.write('{} DBUS_ADAPTOR_FLAGS\n'.format(ind))
- cm_fh.write('{} "{}"\n'.format(ind, '" "'.join(dbus_adaptor_flags)))
+ dbus_adaptor_flags_line = '" "'.join(dbus_adaptor_flags)
+ cm_fh.write(f"{ind} DBUS_ADAPTOR_FLAGS\n")
+ cm_fh.write(f'{ind} "{dbus_adaptor_flags_line}"\n')
- write_source_file_list(cm_fh, scope, 'DBUS_INTERFACE_SOURCES', ['DBUS_INTERFACES',], indent + 1)
- dbus_interface_flags = scope.expand('QDBUSXML2CPP_INTERFACE_HEADER_FLAGS')
+ write_source_file_list(cm_fh, scope, "DBUS_INTERFACE_SOURCES", ["DBUS_INTERFACES"], indent + 1)
+ dbus_interface_flags = scope.expand("QDBUSXML2CPP_INTERFACE_HEADER_FLAGS")
if dbus_interface_flags:
- cm_fh.write('{} DBUS_INTERFACE_FLAGS\n'.format(ind))
- cm_fh.write('{} "{}"\n'.format(ind, '" "'.join(dbus_interface_flags)))
+ dbus_interface_flags_line = '" "'.join(dbus_interface_flags)
+ cm_fh.write(f"{ind} DBUS_INTERFACE_FLAGS\n")
+ cm_fh.write(f'{ind} "{dbus_interface_flags_line}"\n')
- write_defines(cm_fh, scope, 'DEFINES', indent=indent + 1)
+ write_defines(cm_fh, scope, "DEFINES", indent=indent + 1)
- write_include_paths(cm_fh, scope, 'INCLUDE_DIRECTORIES', indent=indent + 1)
+ write_include_paths(cm_fh, scope, "INCLUDE_DIRECTORIES", indent=indent + 1)
write_library_section(cm_fh, scope, indent=indent, known_libraries=known_libraries)
- write_compile_options(cm_fh, scope, 'COMPILE_OPTIONS', indent=indent + 1)
+ write_compile_options(cm_fh, scope, "COMPILE_OPTIONS", indent=indent + 1)
write_autogen_section(cm_fh, scope, indent=indent + 1)
- link_options = scope.get('QMAKE_LFLAGS')
+ link_options = scope.get("QMAKE_LFLAGS")
if link_options:
- cm_fh.write('{} LINK_OPTIONS\n'.format(ind))
+ cm_fh.write(f"{ind} LINK_OPTIONS\n")
for lo in link_options:
- cm_fh.write('{} "{}"\n'.format(ind, lo))
+ cm_fh.write(f'{ind} "{lo}"\n')
- moc_options = scope.get('QMAKE_MOC_OPTIONS')
+ moc_options = scope.get("QMAKE_MOC_OPTIONS")
if moc_options:
- cm_fh.write('{} MOC_OPTIONS\n'.format(ind))
+ cm_fh.write(f"{ind} MOC_OPTIONS\n")
for mo in moc_options:
- cm_fh.write('{} "{}"\n'.format(ind, mo))
+ cm_fh.write(f'{ind} "{mo}"\n')
- precompiled_header = scope.get('PRECOMPILED_HEADER')
+ precompiled_header = scope.get("PRECOMPILED_HEADER")
if precompiled_header:
- cm_fh.write('{} PRECOMPILED_HEADER\n'.format(ind))
+ cm_fh.write(f"{ind} PRECOMPILED_HEADER\n")
for header in precompiled_header:
- cm_fh.write('{} "{}"\n'.format(ind, header))
+ cm_fh.write(f'{ind} "{header}"\n')
- no_pch_sources = scope.get('NO_PCH_SOURCES')
+ no_pch_sources = scope.get("NO_PCH_SOURCES")
if no_pch_sources:
- cm_fh.write('{} NO_PCH_SOURCES\n'.format(ind))
+ cm_fh.write(f"{ind} NO_PCH_SOURCES\n")
for source in no_pch_sources:
- cm_fh.write('{} "{}"\n'.format(ind, source))
+ cm_fh.write(f'{ind} "{source}"\n')
def is_simple_condition(condition: str) -> bool:
- return ' ' not in condition \
- or (condition.startswith('NOT ') and ' ' not in condition[4:])
+ return " " not in condition or (condition.startswith("NOT ") and " " not in condition[4:])
def write_ignored_keys(scope: Scope, indent: str) -> str:
- result = ''
+ result = ""
ignored_keys = scope.keys - scope.visited_keys
for k in sorted(ignored_keys):
- if k == '_INCLUDED' or k == 'TARGET' or k == 'QMAKE_DOCS' or k == 'QT_SOURCE_TREE' \
- or k == 'QT_BUILD_TREE' or k == 'TRACEPOINT_PROVIDER':
+ if k in {
+ "_INCLUDED",
+ "TARGET",
+ "QMAKE_DOCS",
+ "QT_SOURCE_TREE",
+ "QT_BUILD_TREE",
+ "TRACEPOINT_PROVIDER",
+ }:
# All these keys are actually reported already
continue
values = scope.get(k)
- value_string = '<EMPTY>' if not values \
- else '"' + '" "'.join(scope.get(k)) + '"'
- result += '{}# {} = {}\n'.format(indent, k, value_string)
+ value_string = "<EMPTY>" if not values else '"' + '" "'.join(scope.get(k)) + '"'
+ result += f"{indent}# {k} = {value_string}\n"
if result:
- result = '\n#### Keys ignored in scope {}:\n{}'.format(scope, result)
+ result = f"\n#### Keys ignored in scope {scope}:\n{result}"
return result
@@ -1620,8 +1820,7 @@ def _iterate_expr_tree(expr, op, matches):
def _simplify_expressions(expr, op, matches, replacement):
for arg in expr.args:
- expr = expr.subs(arg, _simplify_expressions(arg, op, matches,
- replacement))
+ expr = expr.subs(arg, _simplify_expressions(arg, op, matches, replacement))
if expr.func == op:
(to_match, keepers) = tuple(_iterate_expr_tree(expr, op, matches))
@@ -1644,18 +1843,15 @@ def _simplify_expressions(expr, op, matches, replacement):
def _simplify_flavors_in_condition(base: str, flavors, expr):
- ''' Simplify conditions based on the knownledge of which flavors
- belong to which OS. '''
+ """ Simplify conditions based on the knownledge of which flavors
+ belong to which OS. """
base_expr = simplify_logic(base)
- false_expr = simplify_logic('false')
+ false_expr = simplify_logic("false")
for flavor in flavors:
flavor_expr = simplify_logic(flavor)
- expr = _simplify_expressions(expr, And, (base_expr, flavor_expr,),
- flavor_expr)
- expr = _simplify_expressions(expr, Or, (base_expr, flavor_expr),
- base_expr)
- expr = _simplify_expressions(expr, And, (Not(base_expr), flavor_expr,),
- false_expr)
+ expr = _simplify_expressions(expr, And, (base_expr, flavor_expr), flavor_expr)
+ expr = _simplify_expressions(expr, Or, (base_expr, flavor_expr), base_expr)
+ expr = _simplify_expressions(expr, And, (Not(base_expr), flavor_expr), false_expr)
return expr
@@ -1670,50 +1866,59 @@ def _simplify_os_families(expr, family_members, other_family_members):
expr = _simplify_expressions(expr, And, (f_expr, Not(o_expr)), f_expr)
expr = _simplify_expressions(expr, And, (Not(f_expr), o_expr), o_expr)
- expr = _simplify_expressions(expr, And, (f_expr, o_expr), simplify_logic('false'))
+ expr = _simplify_expressions(expr, And, (f_expr, o_expr), simplify_logic("false"))
return expr
def _recursive_simplify(expr):
- ''' Simplify the expression as much as possible based on
- domain knowledge. '''
+ """ Simplify the expression as much as possible based on
+ domain knowledge. """
input_expr = expr
# Simplify even further, based on domain knowledge:
- windowses = ('WIN32', 'WINRT')
- apples = ('APPLE_OSX', 'APPLE_UIKIT', 'APPLE_IOS',
- 'APPLE_TVOS', 'APPLE_WATCHOS',)
- bsds = ('FREEBSD', 'OPENBSD', 'NETBSD',)
- androids = ('ANDROID', 'ANDROID_EMBEDDED')
- unixes = ('APPLE', *apples, 'BSD', *bsds, 'LINUX',
- *androids, 'HAIKU',
- 'INTEGRITY', 'VXWORKS', 'QNX', 'WASM')
-
- unix_expr = simplify_logic('UNIX')
- win_expr = simplify_logic('WIN32')
- false_expr = simplify_logic('false')
- true_expr = simplify_logic('true')
+ # windowses = ('WIN32', 'WINRT')
+ apples = ("APPLE_OSX", "APPLE_UIKIT", "APPLE_IOS", "APPLE_TVOS", "APPLE_WATCHOS")
+ bsds = ("FREEBSD", "OPENBSD", "NETBSD")
+ androids = ("ANDROID", "ANDROID_EMBEDDED")
+ unixes = (
+ "APPLE",
+ *apples,
+ "BSD",
+ *bsds,
+ "LINUX",
+ *androids,
+ "HAIKU",
+ "INTEGRITY",
+ "VXWORKS",
+ "QNX",
+ "WASM",
+ )
+
+ unix_expr = simplify_logic("UNIX")
+ win_expr = simplify_logic("WIN32")
+ false_expr = simplify_logic("false")
+ true_expr = simplify_logic("true")
expr = expr.subs(Not(unix_expr), win_expr) # NOT UNIX -> WIN32
expr = expr.subs(Not(win_expr), unix_expr) # NOT WIN32 -> UNIX
# UNIX [OR foo ]OR WIN32 -> ON [OR foo]
- expr = _simplify_expressions(expr, Or, (unix_expr, win_expr,), true_expr)
+ expr = _simplify_expressions(expr, Or, (unix_expr, win_expr), true_expr)
# UNIX [AND foo ]AND WIN32 -> OFF [AND foo]
- expr = _simplify_expressions(expr, And, (unix_expr, win_expr,), false_expr)
+ expr = _simplify_expressions(expr, And, (unix_expr, win_expr), false_expr)
- expr = _simplify_flavors_in_condition('WIN32', ('WINRT',), expr)
- expr = _simplify_flavors_in_condition('APPLE', apples, expr)
- expr = _simplify_flavors_in_condition('BSD', bsds, expr)
- expr = _simplify_flavors_in_condition('UNIX', unixes, expr)
- expr = _simplify_flavors_in_condition('ANDROID', ('ANDROID_EMBEDDED',), expr)
+ expr = _simplify_flavors_in_condition("WIN32", ("WINRT",), expr)
+ expr = _simplify_flavors_in_condition("APPLE", apples, expr)
+ expr = _simplify_flavors_in_condition("BSD", bsds, expr)
+ expr = _simplify_flavors_in_condition("UNIX", unixes, expr)
+ expr = _simplify_flavors_in_condition("ANDROID", ("ANDROID_EMBEDDED",), expr)
# Simplify families of OSes against other families:
- expr = _simplify_os_families(expr, ('WIN32', 'WINRT'), unixes)
+ expr = _simplify_os_families(expr, ("WIN32", "WINRT"), unixes)
expr = _simplify_os_families(expr, androids, unixes)
- expr = _simplify_os_families(expr, ('BSD', *bsds), unixes)
+ expr = _simplify_os_families(expr, ("BSD", *bsds), unixes)
- for family in ('HAIKU', 'QNX', 'INTEGRITY', 'LINUX', 'VXWORKS'):
+ for family in ("HAIKU", "QNX", "INTEGRITY", "LINUX", "VXWORKS"):
expr = _simplify_os_families(expr, (family,), unixes)
# Now simplify further:
@@ -1730,21 +1935,21 @@ def simplify_condition(condition: str) -> str:
input_condition = condition.strip()
# Map to sympy syntax:
- condition = ' ' + input_condition + ' '
- condition = condition.replace('(', ' ( ')
- condition = condition.replace(')', ' ) ')
+ condition = " " + input_condition + " "
+ condition = condition.replace("(", " ( ")
+ condition = condition.replace(")", " ) ")
- tmp = ''
+ tmp = ""
while tmp != condition:
tmp = condition
- condition = condition.replace(' NOT ', ' ~ ')
- condition = condition.replace(' AND ', ' & ')
- condition = condition.replace(' OR ', ' | ')
- condition = condition.replace(' ON ', ' true ')
- condition = condition.replace(' OFF ', ' false ')
+ condition = condition.replace(" NOT ", " ~ ")
+ condition = condition.replace(" AND ", " & ")
+ condition = condition.replace(" OR ", " | ")
+ condition = condition.replace(" ON ", " true ")
+ condition = condition.replace(" OFF ", " false ")
# Replace dashes with a token
- condition = condition.replace('-', '_dash_')
+ condition = condition.replace("-", "_dash_")
# SymPy chokes on expressions that contain two tokens one next to
# the other delimited by a space, which are not an operation.
@@ -1756,12 +1961,12 @@ def simplify_condition(condition: str) -> str:
# token symbols.
# Support both target names without double colons, and with double
# colons.
- pattern = re.compile(r'(TARGET [a-zA-Z]+(?:::[a-zA-Z]+)?)')
+ pattern = re.compile(r"(TARGET [a-zA-Z]+(?:::[a-zA-Z]+)?)")
target_symbol_mapping = {}
all_target_conditions = re.findall(pattern, condition)
for target_condition in all_target_conditions:
# Replace spaces and colons with underscores.
- target_condition_symbol_name = re.sub('[ :]', '_', target_condition)
+ target_condition_symbol_name = re.sub("[ :]", "_", target_condition)
target_symbol_mapping[target_condition_symbol_name] = target_condition
condition = re.sub(target_condition, target_condition_symbol_name, condition)
@@ -1775,101 +1980,131 @@ def simplify_condition(condition: str) -> str:
condition = re.sub(symbol_name, target_symbol_mapping[symbol_name], condition)
# Map back to CMake syntax:
- condition = condition.replace('~', 'NOT ')
- condition = condition.replace('&', 'AND')
- condition = condition.replace('|', 'OR')
- condition = condition.replace('True', 'ON')
- condition = condition.replace('False', 'OFF')
- condition = condition.replace('_dash_', '-')
- except:
+ condition = condition.replace("~", "NOT ")
+ condition = condition.replace("&", "AND")
+ condition = condition.replace("|", "OR")
+ condition = condition.replace("True", "ON")
+ condition = condition.replace("False", "OFF")
+ condition = condition.replace("_dash_", "-")
+ except (SympifyError, TypeError):
# sympy did not like our input, so leave this condition alone:
condition = input_condition
- return condition or 'ON'
+ return condition or "ON"
-def recursive_evaluate_scope(scope: Scope, parent_condition: str = '',
- previous_condition: str = '') -> str:
+def recursive_evaluate_scope(
+ scope: Scope, parent_condition: str = "", previous_condition: str = ""
+) -> str:
current_condition = scope.condition
total_condition = current_condition
- if total_condition == 'else':
- assert previous_condition, \
- "Else branch without previous condition in: %s" % scope.file
- total_condition = 'NOT ({})'.format(previous_condition)
+ if total_condition == "else":
+ assert previous_condition, f"Else branch without previous condition in: {scope.file}"
+ total_condition = f"NOT ({previous_condition})"
if parent_condition:
if not total_condition:
total_condition = parent_condition
else:
- total_condition = '({}) AND ({})'.format(parent_condition,
- total_condition)
+ total_condition = f"({parent_condition}) AND ({total_condition})"
scope.total_condition = simplify_condition(total_condition)
- prev_condition = ''
+ prev_condition = ""
for c in scope.children:
- prev_condition = recursive_evaluate_scope(c, total_condition,
- prev_condition)
+ prev_condition = recursive_evaluate_scope(c, total_condition, prev_condition)
return current_condition
-def map_to_cmake_condition(condition: typing.Optional[str]) -> str:
+def map_to_cmake_condition(condition: str = "") -> str:
condition = condition.replace("QTDIR_build", "QT_BUILDING_QT")
- condition = re.sub(r'\bQT_ARCH___equals___([a-zA-Z_0-9]*)',
- r'(TEST_architecture_arch STREQUAL "\1")', condition or '')
- condition = re.sub(r'\bQT_ARCH___contains___([a-zA-Z_0-9]*)',
- r'(TEST_architecture_arch STREQUAL "\1")', condition or '')
+ condition = re.sub(
+ r"\bQT_ARCH___equals___([a-zA-Z_0-9]*)",
+ r'(TEST_architecture_arch STREQUAL "\1")',
+ condition or "",
+ )
+ condition = re.sub(
+ r"\bQT_ARCH___contains___([a-zA-Z_0-9]*)",
+ r'(TEST_architecture_arch STREQUAL "\1")',
+ condition or "",
+ )
return condition
resource_file_expansion_counter = 0
-def write_resources(cm_fh: typing.IO[str], target: str, scope: Scope, indent: int = 0, is_example = False):
- vpath = scope.expand('VPATH')
+
+
+def write_resources(cm_fh: IO[str], target: str, scope: Scope, indent: int = 0, is_example=False):
+ # vpath = scope.expand('VPATH')
# Handle QRC files by turning them into add_qt_resource:
- resources = scope.get_files('RESOURCES')
- qtquickcompiler_skipped = scope.get_files('QTQUICK_COMPILER_SKIPPED_RESOURCES')
- qtquickcompiler_retained = scope.get_files('QTQUICK_COMPILER_RETAINED_RESOURCES')
- qrc_output = ''
+ resources = scope.get_files("RESOURCES")
+ qtquickcompiler_skipped = scope.get_files("QTQUICK_COMPILER_SKIPPED_RESOURCES")
+ qtquickcompiler_retained = scope.get_files("QTQUICK_COMPILER_RETAINED_RESOURCES")
+ qrc_output = ""
if resources:
- standalone_files: typing.List[str] = []
+ standalone_files: List[str] = []
for r in resources:
skip_qtquick_compiler = r in qtquickcompiler_skipped
retain_qtquick_compiler = r in qtquickcompiler_retained
- if r.endswith('.qrc'):
- qrc_output += process_qrc_file(target, r, scope.basedir, scope.file_absolute_path,
- skip_qtquick_compiler, retain_qtquick_compiler, is_example)
+ if r.endswith(".qrc"):
+ qrc_output += process_qrc_file(
+ target,
+ r,
+ scope.basedir,
+ scope.file_absolute_path,
+ skip_qtquick_compiler,
+ retain_qtquick_compiler,
+ is_example,
+ )
else:
- immediate_files = {f:"" for f in scope.get_files(r + ".files")}
+ immediate_files = {f: "" for f in scope.get_files(f"{r}.files")}
if immediate_files:
immediate_prefix = scope.get(r + ".prefix")
if immediate_prefix:
immediate_prefix = immediate_prefix[0]
else:
immediate_prefix = "/"
- immediate_base = scope.get(r + ".base")
+ immediate_base = scope.get(f"{r}.base")
immediate_lang = None
- immediate_name = "qmake_" + r
- qrc_output += write_add_qt_resource_call(target, immediate_name, immediate_prefix, immediate_base, immediate_lang,
- immediate_files, skip_qtquick_compiler, retain_qtquick_compiler, is_example)
+ immediate_name = f"qmake_{r}"
+ qrc_output += write_add_qt_resource_call(
+ target,
+ immediate_name,
+ immediate_prefix,
+ immediate_base,
+ immediate_lang,
+ immediate_files,
+ skip_qtquick_compiler,
+ retain_qtquick_compiler,
+ is_example,
+ )
else:
- if '*' in r:
+ if "*" in r:
global resource_file_expansion_counter
- r = r.replace('"','')
- qrc_output += '\nfile(GLOB resource_glob_{} RELATIVE "${{CMAKE_CURRENT_SOURCE_DIR}}" "{}")\n'.format(resource_file_expansion_counter, r)
- qrc_output +='foreach(file IN LISTS resource_glob_{})\n'.format(resource_file_expansion_counter)
- qrc_output += ' set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/${file}" PROPERTIES QT_RESOURCE_ALIAS "${file}")\n'
- qrc_output +='endforeach()\n'
- standalone_files.append('${{resource_glob_{}}}'.format(resource_file_expansion_counter))
+ r = r.replace('"', "")
+
+ qrc_output += dedent(
+ f"""
+ file(GLOB resource_glob_{resource_file_expansion_counter} RELATIVE "${{CMAKE_CURRENT_SOURCE_DIR}}" "{r}")
+ foreach(file IN LISTS resource_glob_{resource_file_expansion_counter})
+ set_source_files_properties("${{CMAKE_CURRENT_SOURCE_DIR}}/${{file}}" PROPERTIES QT_RESOURCE_ALIAS "${{file}}")
+ endforeach()
+ """
+ )
+
+ standalone_files.append(
+ f"${{resource_glob_{resource_file_expansion_counter}}}"
+ )
resource_file_expansion_counter += 1
else:
# stadalone source file properties need to be set as they
# are parsed.
if skip_qtquick_compiler:
- qrc_output += 'set_source_files_properties("{}" PROPERTIES QT_SKIP_QUICKCOMPILER 1)\n\n'.format(r)
+ qrc_output += 'set_source_files_properties(f"{r}" PROPERTIES QT_SKIP_QUICKCOMPILER 1)\n\n'
if retain_qtquick_compiler:
- qrc_output += 'set_source_files_properties("{}" PROPERTIES QT_RETAIN_QUICKCOMPILER 1)\n\n'.format(r)
+ qrc_output += 'set_source_files_properties(f"{r}" PROPERTIES QT_RETAIN_QUICKCOMPILER 1)\n\n'
standalone_files.append(r)
if standalone_files:
@@ -1877,54 +2112,62 @@ def write_resources(cm_fh: typing.IO[str], target: str, scope: Scope, indent: in
prefix = "/"
base = None
lang = None
- files = {f:"" for f in standalone_files}
+ files = {f: "" for f in standalone_files}
skip_qtquick_compiler = False
- qrc_output += write_add_qt_resource_call(target, name, prefix, base, lang, files,
- skip_qtquick_compiler = False, retain_qtquick_compiler = False,
- is_example = is_example)
-
+ qrc_output += write_add_qt_resource_call(
+ target,
+ name,
+ prefix,
+ base,
+ lang,
+ files,
+ skip_qtquick_compiler=False,
+ retain_qtquick_compiler=False,
+ is_example=is_example,
+ )
if qrc_output:
- cm_fh.write('\n# Resources:\n')
- for line in qrc_output.split('\n'):
- cm_fh.write(' ' * indent + line + '\n')
+ cm_fh.write("\n# Resources:\n")
+ for line in qrc_output.split("\n"):
+ cm_fh.write(f"{' ' * indent}{line}\n")
-def write_extend_target(cm_fh: typing.IO[str], target: str,
- scope: Scope, indent: int = 0):
+def write_extend_target(cm_fh: IO[str], target: str, scope: Scope, indent: int = 0):
ind = spaces(indent)
extend_qt_io_string = io.StringIO()
write_sources_section(extend_qt_io_string, scope)
extend_qt_string = extend_qt_io_string.getvalue()
- extend_scope = '\n{}extend_target({} CONDITION {}\n' \
- '{}{})\n'.format(ind, target,
- map_to_cmake_condition(scope.total_condition),
- extend_qt_string, ind)
+ extend_scope = (
+ f"\n{ind}extend_target({target} CONDITION"
+ f" {map_to_cmake_condition(scope.total_condition)}\n"
+ f"{extend_qt_string}{ind})\n"
+ )
if not extend_qt_string:
- extend_scope = '' # Nothing to report, so don't!
+ extend_scope = "" # Nothing to report, so don't!
cm_fh.write(extend_scope)
write_resources(cm_fh, target, scope, indent)
-def flatten_scopes(scope: Scope) -> typing.List[Scope]:
- result = [scope] # type: typing.List[Scope]
+
+def flatten_scopes(scope: Scope) -> List[Scope]:
+ result = [scope] # type: List[Scope]
for c in scope.children:
result += flatten_scopes(c)
return result
-def merge_scopes(scopes: typing.List[Scope]) -> typing.List[Scope]:
- result = [] # type: typing.List[Scope]
+def merge_scopes(scopes: List[Scope]) -> List[Scope]:
+ result = [] # type: List[Scope]
# Merge scopes with their parents:
- known_scopes = {} # type: typing.Mapping[str, Scope]
+ known_scopes = {} # type: Mapping[str, Scope]
for scope in scopes:
total_condition = scope.total_condition
assert total_condition
- if total_condition == 'OFF':
+ if total_condition == "OFF":
# ignore this scope entirely!
pass
elif total_condition in known_scopes:
@@ -1937,30 +2180,57 @@ def merge_scopes(scopes: typing.List[Scope]) -> typing.List[Scope]:
return result
-def write_simd_part(cm_fh: typing.IO[str], target: str, scope: Scope, indent: int = 0):
- simd_options = [ 'sse2', 'sse3', 'ssse3', 'sse4_1', 'sse4_2', 'aesni', 'shani', 'avx', 'avx2',
- 'avx512f', 'avx512cd', 'avx512er', 'avx512pf', 'avx512dq', 'avx512bw',
- 'avx512vl', 'avx512ifma', 'avx512vbmi', 'f16c', 'rdrnd', 'neon', 'mips_dsp',
- 'mips_dspr2',
- 'arch_haswell', 'avx512common', 'avx512core'];
+def write_simd_part(cm_fh: IO[str], target: str, scope: Scope, indent: int = 0):
+ simd_options = [
+ "sse2",
+ "sse3",
+ "ssse3",
+ "sse4_1",
+ "sse4_2",
+ "aesni",
+ "shani",
+ "avx",
+ "avx2",
+ "avx512f",
+ "avx512cd",
+ "avx512er",
+ "avx512pf",
+ "avx512dq",
+ "avx512bw",
+ "avx512vl",
+ "avx512ifma",
+ "avx512vbmi",
+ "f16c",
+ "rdrnd",
+ "neon",
+ "mips_dsp",
+ "mips_dspr2",
+ "arch_haswell",
+ "avx512common",
+ "avx512core",
+ ]
for simd in simd_options:
- SIMD = simd.upper();
- write_source_file_list(cm_fh, scope, 'SOURCES',
- ['{}_HEADERS'.format(SIMD),
- '{}_SOURCES'.format(SIMD),
- '{}_C_SOURCES'.format(SIMD),
- '{}_ASM'.format(SIMD)],
- indent,
- header = 'add_qt_simd_part({} SIMD {}\n'.format(target, simd),
- footer = ')\n\n')
-
-def write_android_part(cm_fh: typing.IO[str], target: str, scope:Scope, indent: int = 0):
- keys = [ 'ANDROID_BUNDLED_JAR_DEPENDENCIES'
- , 'ANDROID_LIB_DEPENDENCIES'
- , 'ANDROID_JAR_DEPENDENCIES'
- , 'ANDROID_LIB_DEPENDENCY_REPLACEMENTS'
- , 'ANDROID_BUNDLED_FILES'
- , 'ANDROID_PERMISSIONS' ]
+ SIMD = simd.upper()
+ write_source_file_list(
+ cm_fh,
+ scope,
+ "SOURCES",
+ [f"{SIMD}_HEADERS", f"{SIMD}_SOURCES", f"{SIMD}_C_SOURCES", f"{SIMD}_ASM"],
+ indent,
+ header=f"add_qt_simd_part({target} SIMD {simd}\n",
+ footer=")\n\n",
+ )
+
+
+def write_android_part(cm_fh: IO[str], target: str, scope: Scope, indent: int = 0):
+ keys = [
+ "ANDROID_BUNDLED_JAR_DEPENDENCIES",
+ "ANDROID_LIB_DEPENDENCIES",
+ "ANDROID_JAR_DEPENDENCIES",
+ "ANDROID_LIB_DEPENDENCY_REPLACEMENTS",
+ "ANDROID_BUNDLED_FILES",
+ "ANDROID_PERMISSIONS",
+ ]
has_no_values = True
for key in keys:
@@ -1968,40 +2238,48 @@ def write_android_part(cm_fh: typing.IO[str], target: str, scope:Scope, indent:
if len(value) != 0:
if has_no_values:
if scope.condition:
- cm_fh.write('\n{}if(ANDROID AND ({}))\n'.format(spaces(indent), scope.condition))
+ cm_fh.write(f"\n{spaces(indent)}if(ANDROID AND ({scope.condition}))\n")
else:
- cm_fh.write('\n{}if(ANDROID)\n'.format(spaces(indent)))
+ cm_fh.write(f"\n{spaces(indent)}if(ANDROID)\n")
indent += 1
has_no_values = False
- cm_fh.write('{}set_property(TARGET {} APPEND PROPERTY QT_{}\n'.format(spaces(indent), target, key))
- write_list(cm_fh, value, '', indent + 1)
- cm_fh.write('{})\n'.format(spaces(indent)))
+ cm_fh.write(f"{spaces(indent)}set_property(TARGET {target} APPEND PROPERTY QT_{key}\n")
+ write_list(cm_fh, value, "", indent + 1)
+ cm_fh.write(f"{spaces(indent)})\n")
indent -= 1
if not has_no_values:
- cm_fh.write('{}endif()\n'.format(spaces(indent)))
-
-def write_main_part(cm_fh: typing.IO[str], name: str, typename: str,
- cmake_function: str, scope: Scope, *,
- extra_lines: typing.List[str] = [],
- indent: int = 0, extra_keys: typing.List[str],
- **kwargs: typing.Any):
+ cm_fh.write(f"{spaces(indent)}endif()\n")
+
+
+def write_main_part(
+ cm_fh: IO[str],
+ name: str,
+ typename: str,
+ cmake_function: str,
+ scope: Scope,
+ *,
+ extra_lines: List[str] = [],
+ indent: int = 0,
+ extra_keys: List[str],
+ **kwargs: Any,
+):
# Evaluate total condition of all scopes:
recursive_evaluate_scope(scope)
- is_qml_plugin = any('qml_plugin' == s for s in scope.get('_LOADED'))
+ is_qml_plugin = any("qml_plugin" == s for s in scope.get("_LOADED"))
- if 'exceptions' in scope.get('CONFIG'):
- extra_lines.append('EXCEPTIONS')
+ if "exceptions" in scope.get("CONFIG"):
+ extra_lines.append("EXCEPTIONS")
# Get a flat list of all scopes but the main one:
scopes = flatten_scopes(scope)
- total_scopes = len(scopes)
+ # total_scopes = len(scopes)
# Merge scopes based on their conditions:
scopes = merge_scopes(scopes)
assert len(scopes)
- assert scopes[0].total_condition == 'ON'
+ assert scopes[0].total_condition == "ON"
scopes[0].reset_visited_keys()
for k in extra_keys:
@@ -2012,44 +2290,44 @@ def write_main_part(cm_fh: typing.IO[str], name: str, typename: str,
# collect all testdata and insert globbing commands
has_test_data = False
- if typename == 'Test':
- test_data = scope.expand('TESTDATA')
+ if typename == "Test":
+ test_data = scope.expand("TESTDATA")
if test_data:
has_test_data = True
- cm_fh.write('# Collect test data\n')
+ cm_fh.write("# Collect test data\n")
for data in test_data:
- if '*' in data:
- cm_fh.write(dedent("""
- {indent}file(GLOB_RECURSE test_data_glob
- {indent1}RELATIVE ${{CMAKE_CURRENT_SOURCE_DIR}}
- {indent1}"{}")
- """).format(
- data,
- indent=spaces(indent),
- indent1=spaces(indent + 1)
- ))
- cm_fh.write('{}list(APPEND test_data ${{test_data_glob}})\n'.format(spaces(indent)))
+ if "*" in data:
+ cm_fh.write(
+ dedent(
+ """
+ {spaces(indent)}file(GLOB_RECURSE test_data_glob
+ {spaces(indent+1)}RELATIVE ${{CMAKE_CURRENT_SOURCE_DIR}}
+ {spaces(indent+1)}"{}")
+ """
+ )
+ )
+ cm_fh.write(f"{spaces(indent)}list(APPEND test_data ${{test_data_glob}})\n")
else:
- cm_fh.write('{}list(APPEND test_data "{}")\n'.format(spaces(indent), data))
- cm_fh.write('\n')
+ cm_fh.write(f'{spaces(indent)}list(APPEND test_data "{data}")\n')
+ cm_fh.write("\n")
# Check for DESTDIR override
- destdir = scope.get_string('DESTDIR')
+ destdir = scope.get_string("DESTDIR")
if destdir:
- if destdir.startswith('./') or destdir.startswith('../'):
- destdir = '${CMAKE_CURRENT_BINARY_DIR}/' + destdir
- extra_lines.append('OUTPUT_DIRECTORY "{}"'.format(destdir))
+ if destdir.startswith("./") or destdir.startswith("../"):
+ destdir = "${CMAKE_CURRENT_BINARY_DIR}/" + destdir
+ extra_lines.append(f'OUTPUT_DIRECTORY "{destdir}"')
- cm_fh.write('{}{}({}\n'.format(spaces(indent), cmake_function, name))
+ cm_fh.write(f"{spaces(indent)}{cmake_function}({name}\n")
for extra_line in extra_lines:
- cm_fh.write('{} {}\n'.format(spaces(indent), extra_line))
+ cm_fh.write(f"{spaces(indent)} {extra_line}\n")
write_sources_section(cm_fh, scopes[0], indent=indent, **kwargs)
if has_test_data:
- cm_fh.write('{} TESTDATA ${{test_data}}\n'.format(spaces(indent)))
+ cm_fh.write(f"{spaces(indent)} TESTDATA ${{test_data}}\n")
# Footer:
- cm_fh.write('{})\n'.format(spaces(indent)))
+ cm_fh.write(f"{spaces(indent)})\n")
write_resources(cm_fh, name, scope, indent)
@@ -2064,7 +2342,6 @@ def write_main_part(cm_fh: typing.IO[str], name: str, typename: str,
if ignored_keys_report:
cm_fh.write(ignored_keys_report)
-
# Scopes:
if len(scopes) == 1:
return
@@ -2079,121 +2356,151 @@ def write_main_part(cm_fh: typing.IO[str], name: str, typename: str,
if ignored_keys_report:
cm_fh.write(ignored_keys_report)
-def write_module(cm_fh: typing.IO[str], scope: Scope, *,
- indent: int = 0) -> str:
+
+def write_module(cm_fh: IO[str], scope: Scope, *, indent: int = 0) -> str:
module_name = scope.TARGET
- if not module_name.startswith('Qt'):
- print('XXXXXX Module name {} does not start with Qt!'.format(module_name))
+ if not module_name.startswith("Qt"):
+ print(f"XXXXXX Module name {module_name} does not start with Qt!")
extra = []
# A module should be static when 'static' is in CONFIG
# or when option(host_build) is used, as described in qt_module.prf.
- is_static = 'static' in scope.get('CONFIG') or 'host_build' in scope.get('_OPTION')
+ is_static = "static" in scope.get("CONFIG") or "host_build" in scope.get("_OPTION")
if is_static:
- extra.append('STATIC')
- if 'internal_module' in scope.get('CONFIG'):
- extra.append('INTERNAL_MODULE')
- if 'no_module_headers' in scope.get('CONFIG'):
- extra.append('NO_MODULE_HEADERS')
- if 'minimal_syncqt' in scope.get('CONFIG'):
- extra.append('NO_SYNC_QT')
- if 'no_private_module' in scope.get('CONFIG'):
- extra.append('NO_PRIVATE_MODULE')
- if 'header_module' in scope.get('CONFIG'):
- extra.append('HEADER_MODULE')
+ extra.append("STATIC")
+ if "internal_module" in scope.get("CONFIG"):
+ extra.append("INTERNAL_MODULE")
+ if "no_module_headers" in scope.get("CONFIG"):
+ extra.append("NO_MODULE_HEADERS")
+ if "minimal_syncqt" in scope.get("CONFIG"):
+ extra.append("NO_SYNC_QT")
+ if "no_private_module" in scope.get("CONFIG"):
+ extra.append("NO_PRIVATE_MODULE")
+ if "header_module" in scope.get("CONFIG"):
+ extra.append("HEADER_MODULE")
module_config = scope.get("MODULE_CONFIG")
if len(module_config):
- extra.append('QMAKE_MODULE_CONFIG {}'.format(" ".join(module_config)))
+ extra.append(f'QMAKE_MODULE_CONFIG {" ".join(module_config)}')
- module_plugin_types = scope.get_files('MODULE_PLUGIN_TYPES')
+ module_plugin_types = scope.get_files("MODULE_PLUGIN_TYPES")
if module_plugin_types:
- extra.append('PLUGIN_TYPES {}'.format(" ".join(module_plugin_types)))
+ extra.append(f"PLUGIN_TYPES {' '.join(module_plugin_types)}")
target_name = module_name[2:]
- write_main_part(cm_fh, target_name, 'Module', 'add_qt_module', scope,
- extra_lines=extra, indent=indent,
- known_libraries={}, extra_keys=[])
-
- if 'qt_tracepoints' in scope.get('CONFIG'):
- tracepoints = scope.get_files('TRACEPOINT_PROVIDER')
- cm_fh.write('\n\n{}qt_create_tracepoints({} {})\n'
- .format(spaces(indent), module_name[2:], ' '.join(tracepoints)))
+ write_main_part(
+ cm_fh,
+ target_name,
+ "Module",
+ "add_qt_module",
+ scope,
+ extra_lines=extra,
+ indent=indent,
+ known_libraries={},
+ extra_keys=[],
+ )
+
+ if "qt_tracepoints" in scope.get("CONFIG"):
+ tracepoints = scope.get_files("TRACEPOINT_PROVIDER")
+ cm_fh.write(
+ f"\n\n{spaces(indent)}qt_create_tracepoints({module_name[2:]} {' '.join(tracepoints)})\n"
+ )
return target_name
-def write_tool(cm_fh: typing.IO[str], scope: Scope, *,
- indent: int = 0) -> str:
+def write_tool(cm_fh: IO[str], scope: Scope, *, indent: int = 0) -> str:
tool_name = scope.TARGET
- extra = ['BOOTSTRAP'] if 'force_bootstrap' in scope.get('CONFIG') else []
+ extra = ["BOOTSTRAP"] if "force_bootstrap" in scope.get("CONFIG") else []
- write_main_part(cm_fh, tool_name, 'Tool', 'add_qt_tool', scope,
- indent=indent, known_libraries={'Qt::Core', },
- extra_lines=extra, extra_keys=['CONFIG'])
+ write_main_part(
+ cm_fh,
+ tool_name,
+ "Tool",
+ "add_qt_tool",
+ scope,
+ indent=indent,
+ known_libraries={"Qt::Core"},
+ extra_lines=extra,
+ extra_keys=["CONFIG"],
+ )
return tool_name
-def write_test(cm_fh: typing.IO[str], scope: Scope,
- gui: bool = False, *, indent: int = 0) -> str:
+def write_test(cm_fh: IO[str], scope: Scope, gui: bool = False, *, indent: int = 0) -> str:
test_name = scope.TARGET
assert test_name
- extra = ['GUI',] if gui else []
- libraries={'Qt::Core', 'Qt::Test'}
+ extra = ["GUI"] if gui else []
+ libraries = {"Qt::Core", "Qt::Test"}
- if 'qmltestcase' in scope.get('CONFIG'):
- libraries.add('Qt::QmlTest')
- extra.append('QMLTEST')
- importpath = scope.expand('IMPORTPATH')
+ if "qmltestcase" in scope.get("CONFIG"):
+ libraries.add("Qt::QmlTest")
+ extra.append("QMLTEST")
+ importpath = scope.expand("IMPORTPATH")
if importpath:
- extra.append('QML_IMPORTPATH')
+ extra.append("QML_IMPORTPATH")
for path in importpath:
- extra.append(' "{}"'.format(path))
-
- write_main_part(cm_fh, test_name, 'Test', 'add_qt_test', scope,
- indent=indent, known_libraries=libraries,
- extra_lines=extra, extra_keys=[])
+ extra.append(f' "{path}"')
+
+ write_main_part(
+ cm_fh,
+ test_name,
+ "Test",
+ "add_qt_test",
+ scope,
+ indent=indent,
+ known_libraries=libraries,
+ extra_lines=extra,
+ extra_keys=[],
+ )
return test_name
-def write_binary(cm_fh: typing.IO[str], scope: Scope,
- gui: bool = False, *, indent: int = 0) -> None:
+def write_binary(cm_fh: IO[str], scope: Scope, gui: bool = False, *, indent: int = 0) -> None:
binary_name = scope.TARGET
assert binary_name
- is_qt_test_helper = 'qt_test_helper' in scope.get('_LOADED')
+ is_qt_test_helper = "qt_test_helper" in scope.get("_LOADED")
- extra = ['GUI'] if gui and not is_qt_test_helper else []
- cmake_function_call = 'add_qt_executable'
+ extra = ["GUI"] if gui and not is_qt_test_helper else []
+ cmake_function_call = "add_qt_executable"
if is_qt_test_helper:
- binary_name += '_helper'
- cmake_function_call = 'add_qt_test_helper'
+ binary_name += "_helper"
+ cmake_function_call = "add_qt_test_helper"
- target_path = scope.get_string('target.path')
+ target_path = scope.get_string("target.path")
if target_path:
- target_path = target_path.replace('$$[QT_INSTALL_EXAMPLES]', '${INSTALL_EXAMPLESDIR}')
- extra.append('OUTPUT_DIRECTORY "{}"'.format(target_path))
- if 'target' in scope.get('INSTALLS'):
- extra.append('INSTALL_DIRECTORY "{}"'.format(target_path))
-
- write_main_part(cm_fh, binary_name, 'Binary', cmake_function_call, scope,
- extra_lines=extra, indent=indent,
- known_libraries={'Qt::Core', }, extra_keys=['target.path', 'INSTALLS'])
+ target_path = target_path.replace("$$[QT_INSTALL_EXAMPLES]", "${INSTALL_EXAMPLESDIR}")
+ extra.append(f'OUTPUT_DIRECTORY "{target_path}"')
+ if "target" in scope.get("INSTALLS"):
+ extra.append(f'INSTALL_DIRECTORY "{target_path}"')
+
+ write_main_part(
+ cm_fh,
+ binary_name,
+ "Binary",
+ cmake_function_call,
+ scope,
+ extra_lines=extra,
+ indent=indent,
+ known_libraries={"Qt::Core"},
+ extra_keys=["target.path", "INSTALLS"],
+ )
return binary_name
-def write_find_package_section(cm_fh: typing.IO[str],
- public_libs: typing.List[str],
- private_libs: typing.List[str], *, indent: int=0):
- packages = [] # type: typing.List[LibraryMapping]
+def write_find_package_section(
+ cm_fh: IO[str], public_libs: List[str], private_libs: List[str], *, indent: int = 0
+):
+ packages = [] # type: List[LibraryMapping]
all_libs = public_libs + private_libs
for l in all_libs:
@@ -2201,55 +2508,73 @@ def write_find_package_section(cm_fh: typing.IO[str],
if info and info not in packages:
packages.append(info)
- ind = spaces(indent)
+ # ind = spaces(indent)
for p in packages:
cm_fh.write(generate_find_package_info(p, use_qt_find_package=False, indent=indent))
if packages:
- cm_fh.write('\n')
+ cm_fh.write("\n")
-def write_example(cm_fh: typing.IO[str], scope: Scope,
- gui: bool = False, *, indent: int = 0) -> str:
+def write_example(cm_fh: IO[str], scope: Scope, gui: bool = False, *, indent: int = 0) -> str:
binary_name = scope.TARGET
assert binary_name
- cm_fh.write('cmake_minimum_required(VERSION 3.14)\n' +
- 'project({} LANGUAGES CXX)\n\n'.format(binary_name) +
- 'set(CMAKE_INCLUDE_CURRENT_DIR ON)\n\n' +
- 'set(CMAKE_AUTOMOC ON)\n' +
- 'set(CMAKE_AUTORCC ON)\n' +
- 'set(CMAKE_AUTOUIC ON)\n\n' +
- 'set(INSTALL_EXAMPLEDIR "examples")\n\n')
+ cm_fh.write(
+ "cmake_minimum_required(VERSION 3.14)\n"
+ f"project({binary_name} LANGUAGES CXX)\n\n"
+ "set(CMAKE_INCLUDE_CURRENT_DIR ON)\n\n"
+ "set(CMAKE_AUTOMOC ON)\n"
+ "set(CMAKE_AUTORCC ON)\n"
+ "set(CMAKE_AUTOUIC ON)\n\n"
+ 'set(INSTALL_EXAMPLEDIR "examples")\n\n'
+ )
(public_libs, private_libs) = extract_cmake_libraries(scope)
write_find_package_section(cm_fh, public_libs, private_libs, indent=indent)
- add_executable = 'add_{}executable({}'.format("qt_gui_" if gui else "", binary_name);
+ add_executable = f'add_{"qt_gui_" if gui else ""}executable({binary_name}'
write_all_source_file_lists(cm_fh, scope, add_executable, indent=0)
- cm_fh.write(')\n')
-
- write_include_paths(cm_fh, scope, 'target_include_directories({} PUBLIC'.format(binary_name),
- indent=0, footer=')')
- write_defines(cm_fh, scope, 'target_compile_definitions({} PUBLIC'.format(binary_name),
- indent=0, footer=')')
- write_list(cm_fh, private_libs, '', indent=indent,
- header='target_link_libraries({} PRIVATE\n'.format(binary_name), footer=')')
- write_list(cm_fh, public_libs, '', indent=indent,
- header='target_link_libraries({} PUBLIC\n'.format(binary_name), footer=')')
- write_compile_options(cm_fh, scope, 'target_compile_options({}'.format(binary_name),
- indent=0, footer=')')
-
- write_resources(cm_fh, binary_name, scope, indent = indent, is_example = True)
-
- cm_fh.write('\ninstall(TARGETS {}\n'.format(binary_name) +
- ' RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"\n' +
- ' BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"\n' +
- ' LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"\n' +
- ')\n')
+ cm_fh.write(")\n")
+
+ write_include_paths(
+ cm_fh, scope, f"target_include_directories({binary_name} PUBLIC", indent=0, footer=")"
+ )
+ write_defines(
+ cm_fh, scope, f"target_compile_definitions({binary_name} PUBLIC", indent=0, footer=")"
+ )
+ write_list(
+ cm_fh,
+ private_libs,
+ "",
+ indent=indent,
+ header=f"target_link_libraries({binary_name} PRIVATE\n",
+ footer=")",
+ )
+ write_list(
+ cm_fh,
+ public_libs,
+ "",
+ indent=indent,
+ header=f"target_link_libraries({binary_name} PUBLIC\n",
+ footer=")",
+ )
+ write_compile_options(
+ cm_fh, scope, f"target_compile_options({binary_name}", indent=0, footer=")"
+ )
+
+ write_resources(cm_fh, binary_name, scope, indent=indent, is_example=True)
+
+ cm_fh.write(
+ f"\ninstall(TARGETS {binary_name}\n"
+ ' RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"\n'
+ ' BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"\n'
+ ' LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"\n'
+ ")\n"
+ )
return binary_name
@@ -2260,123 +2585,130 @@ def write_plugin(cm_fh, scope, *, indent: int = 0) -> str:
extra = []
- plugin_type = scope.get_string('PLUGIN_TYPE')
- is_qml_plugin = any('qml_plugin' == s for s in scope.get('_LOADED'))
- plugin_function_name = 'add_qt_plugin'
+ plugin_type = scope.get_string("PLUGIN_TYPE")
+ is_qml_plugin = any("qml_plugin" == s for s in scope.get("_LOADED"))
+ plugin_function_name = "add_qt_plugin"
if plugin_type:
- extra.append('TYPE {}'.format(plugin_type))
+ extra.append(f"TYPE {plugin_type}")
elif is_qml_plugin:
- plugin_function_name = 'add_qml_module'
+ plugin_function_name = "add_qml_module"
write_qml_plugin(cm_fh, plugin_name, scope, indent=indent, extra_lines=extra)
- plugin_class_name = scope.get_string('PLUGIN_CLASS_NAME')
+ plugin_class_name = scope.get_string("PLUGIN_CLASS_NAME")
if plugin_class_name:
- extra.append('CLASS_NAME {}'.format(plugin_class_name))
-
- write_main_part(cm_fh, plugin_name, 'Plugin', plugin_function_name, scope,
- indent=indent, extra_lines=extra, known_libraries={}, extra_keys=[])
+ extra.append(f"CLASS_NAME {plugin_class_name}")
+
+ write_main_part(
+ cm_fh,
+ plugin_name,
+ "Plugin",
+ plugin_function_name,
+ scope,
+ indent=indent,
+ extra_lines=extra,
+ known_libraries={},
+ extra_keys=[],
+ )
return plugin_name
-def write_qml_plugin(cm_fh: typing.IO[str],
- target: str,
- scope: Scope, *,
- extra_lines: typing.List[str] = [],
- indent: int = 0,
- **kwargs: typing.Any):
+def write_qml_plugin(
+ cm_fh: IO[str],
+ target: str,
+ scope: Scope,
+ *,
+ extra_lines: List[str] = [],
+ indent: int = 0,
+ **kwargs: Any,
+):
# Collect other args if available
indent += 2
- scope_config = scope.get('CONFIG')
- is_embedding_qml_files = False
+ # scope_config = scope.get('CONFIG')
+ # is_embedding_qml_files = False
-
- sources = scope.get_files('SOURCES')
+ sources = scope.get_files("SOURCES")
if len(sources) != 0:
- extra_lines.append('CPP_PLUGIN')
+ extra_lines.append("CPP_PLUGIN")
- target_path = scope.get_string('TARGETPATH')
+ target_path = scope.get_string("TARGETPATH")
if target_path:
- uri = target_path.replace('/','.')
- import_name = scope.get_string('IMPORT_NAME')
+ uri = target_path.replace("/", ".")
+ import_name = scope.get_string("IMPORT_NAME")
# Catch special cases such as foo.QtQuick.2.bar, which when converted
# into a target path via cmake will result in foo/QtQuick/2/bar, which is
# not what we want. So we supply the target path override.
- target_path_from_uri = uri.replace('.', '/')
+ target_path_from_uri = uri.replace(".", "/")
if target_path != target_path_from_uri:
- extra_lines.append('TARGET_PATH "{}"'.format(target_path))
+ extra_lines.append(f'TARGET_PATH "{target_path}"')
if import_name:
- extra_lines.append('URI "{}"'.format(import_name))
+ extra_lines.append(f'URI "{import_name}"')
else:
- uri = re.sub('\\.\\d+', '', uri)
- extra_lines.append('URI "{}"'.format(uri))
+ uri = re.sub("\\.\\d+", "", uri)
+ extra_lines.append(f'URI "{uri}"')
- import_version = scope.get_string('IMPORT_VERSION')
+ import_version = scope.get_string("IMPORT_VERSION")
if import_version:
- import_version = import_version.replace("$$QT_MINOR_VERSION","${CMAKE_PROJECT_VERSION_MINOR}")
- extra_lines.append('VERSION "{}"'.format(import_version))
+ import_version = import_version.replace(
+ "$$QT_MINOR_VERSION", "${CMAKE_PROJECT_VERSION_MINOR}"
+ )
+ extra_lines.append(f'VERSION "{import_version}"')
- plugindump_dep = scope.get_string('QML_PLUGINDUMP_DEPENDENCIES')
+ plugindump_dep = scope.get_string("QML_PLUGINDUMP_DEPENDENCIES")
if plugindump_dep:
- extra_lines.append('QML_PLUGINDUMP_DEPENDENCIES "{}"'.format(plugindump_dep))
+ extra_lines.append(f'QML_PLUGINDUMP_DEPENDENCIES "{plugindump_dep}"')
-def write_qml_plugin_qml_files(cm_fh: typing.IO[str],
- target: str,
- scope: Scope,
- indent: int = 0):
+def write_qml_plugin_qml_files(cm_fh: IO[str], target: str, scope: Scope, indent: int = 0):
- qml_files = scope.get_files('QML_FILES', use_vpath=True)
+ qml_files = scope.get_files("QML_FILES", use_vpath=True)
if qml_files:
# Quote file paths in case there are spaces.
- qml_files = ['"{}"'.format(f) for f in qml_files]
-
- cm_fh.write('\n{}set(qml_files\n{}{}\n)\n'.format(
- spaces(indent),
- spaces(indent + 1),
- '\n{}'.format(spaces(indent + 1)).join(qml_files)))
-
- target_path = scope.get_string('TARGETPATH', inherit=True)
- target_path_mangled = target_path.replace('/', '_')
- target_path_mangled = target_path_mangled.replace('.', '_')
- resource_name = 'qmake_' + target_path_mangled
- cm_fh.write('\n{}add_qt_resource({} {}\n{}FILES\n{}${{qml_files}}\n)\n'.format(
- spaces(indent),
- target,
- resource_name,
- spaces(indent + 1),
- spaces(indent + 2)))
-
- cm_fh.write('\nqt_install_qml_files({}\n FILES ${{qml_files}}\n)\n\n'.format(
- target))
-
-
-def handle_app_or_lib(scope: Scope, cm_fh: typing.IO[str], *,
- indent: int = 0, is_example: bool=False) -> None:
- assert scope.TEMPLATE in ('app', 'lib')
-
- config = scope.get('CONFIG')
- is_lib = scope.TEMPLATE == 'lib'
- is_qml_plugin = any('qml_plugin' == s for s in scope.get('_LOADED'))
- is_plugin = any('qt_plugin' == s for s in scope.get('_LOADED')) or is_qml_plugin or 'plugin' in config
+ qml_files = [f'"{f}"' for f in qml_files]
+
+ qml_files_line = "\n{spaces(indent+1)}".join(qml_files)
+ cm_fh.write(f"\n{spaces(indent)}set(qml_files\n{spaces(indent+1)}{qml_files_line}\n)\n")
+
+ target_path = scope.get_string("TARGETPATH", inherit=True)
+ target_path_mangled = target_path.replace("/", "_")
+ target_path_mangled = target_path_mangled.replace(".", "_")
+ resource_name = "qmake_" + target_path_mangled
+ cm_fh.write(
+ f"\n{spaces(indent)}add_qt_resource({target} {resource_name}\n"
+ f"{spaces(indent+1)}FILES\n{spaces(indent+2)}${{qml_files}}\n)\n"
+ )
+
+ cm_fh.write(f"\nqt_install_qml_files({target}\n FILES ${{qml_files}}\n)\n\n")
+
+
+def handle_app_or_lib(
+ scope: Scope, cm_fh: IO[str], *, indent: int = 0, is_example: bool = False
+) -> None:
+ assert scope.TEMPLATE in ("app", "lib")
+
+ config = scope.get("CONFIG")
+ is_lib = scope.TEMPLATE == "lib"
+ is_qml_plugin = any("qml_plugin" == s for s in scope.get("_LOADED"))
+ is_plugin = (
+ any("qt_plugin" == s for s in scope.get("_LOADED")) or is_qml_plugin or "plugin" in config
+ )
target = ""
if is_plugin:
assert not is_example
target = write_plugin(cm_fh, scope, indent=indent)
- elif is_lib or 'qt_module' in scope.get('_LOADED'):
+ elif is_lib or "qt_module" in scope.get("_LOADED"):
assert not is_example
target = write_module(cm_fh, scope, indent=indent)
- elif 'qt_tool' in scope.get('_LOADED'):
+ elif "qt_tool" in scope.get("_LOADED"):
assert not is_example
target = write_tool(cm_fh, scope, indent=indent)
else:
- gui = all(val not in config for val in ['console', 'cmdline']) \
- and 'testlib' not in scope.expand('QT')
- if 'testcase' in config \
- or 'testlib' in config \
- or 'qmltestcase' in config:
+ gui = all(
+ val not in config for val in ["console", "cmdline"]
+ ) and "testlib" not in scope.expand("QT")
+ if "testcase" in config or "testlib" in config or "qmltestcase" in config:
assert not is_example
target = write_test(cm_fh, scope, gui, indent=indent)
else:
@@ -2385,15 +2717,13 @@ def handle_app_or_lib(scope: Scope, cm_fh: typing.IO[str], *,
else:
target = write_binary(cm_fh, scope, gui, indent=indent)
- ind = spaces(indent)
- write_source_file_list(cm_fh, scope, '',
- ['QMAKE_DOCS',],
- indent,
- header = f"add_qt_docs({target},\n",
- footer = ')\n')
+ # ind = spaces(indent)
+ write_source_file_list(
+ cm_fh, scope, "", ["QMAKE_DOCS"], indent, header=f"add_qt_docs({target},\n", footer=")\n"
+ )
-def handle_top_level_repo_project(scope: Scope, cm_fh: typing.IO[str]):
+def handle_top_level_repo_project(scope: Scope, cm_fh: IO[str]):
# qtdeclarative
project_file_name = os.path.splitext(os.path.basename(scope.file_absolute_path))[0]
@@ -2406,7 +2736,7 @@ def handle_top_level_repo_project(scope: Scope, cm_fh: typing.IO[str]):
# Found a mapping, adjust name.
if qt_lib != file_name_without_qt_prefix:
# QtDeclarative
- qt_lib = re.sub(r':', r'', qt_lib)
+ qt_lib = re.sub(r":", r"", qt_lib)
# Declarative
qt_lib_no_prefix = qt_lib[2:]
@@ -2414,36 +2744,39 @@ def handle_top_level_repo_project(scope: Scope, cm_fh: typing.IO[str]):
qt_lib += "_FIXME"
qt_lib_no_prefix = qt_lib
- content = """cmake_minimum_required(VERSION {})
+ content = dedent(
+ f"""\
+ cmake_minimum_required(VERSION {cmake_version_string})
-project({}
- VERSION 6.0.0
- DESCRIPTION "Qt {} Libraries"
- HOMEPAGE_URL "https://qt.io/"
- LANGUAGES CXX C
-)
+ project({qt_lib}
+ VERSION 6.0.0
+ DESCRIPTION "Qt {qt_lib_no_prefix} Libraries"
+ HOMEPAGE_URL "https://qt.io/"
+ LANGUAGES CXX C
+ )
-find_package(Qt6 ${{PROJECT_VERSION}} CONFIG REQUIRED COMPONENTS BuildInternals Core SET_ME_TO_SOMETHING_USEFUL)
-find_package(Qt6 ${{PROJECT_VERSION}} CONFIG OPTIONAL_COMPONENTS SET_ME_TO_SOMETHING_USEFUL)
-qt_build_repo()
-""".format(cmake_version_string, qt_lib, qt_lib_no_prefix)
+ find_package(Qt6 ${{PROJECT_VERSION}} CONFIG REQUIRED COMPONENTS BuildInternals Core SET_ME_TO_SOMETHING_USEFUL)
+ find_package(Qt6 ${{PROJECT_VERSION}} CONFIG OPTIONAL_COMPONENTS SET_ME_TO_SOMETHING_USEFUL)
+ qt_build_repo()
+ """
+ )
- cm_fh.write('{}'.format(content))
+ cm_fh.write(f"{content}")
-def find_top_level_repo_project_file(project_file_path: str = '') -> typing.Optional[str]:
+def find_top_level_repo_project_file(project_file_path: str = "") -> Optional[str]:
qmake_conf_path = find_qmake_conf(project_file_path)
qmake_dir = os.path.dirname(qmake_conf_path)
# Hope to a programming god that there's only one .pro file at the
# top level directory of repository.
- glob_result = glob.glob(os.path.join(qmake_dir, '*.pro'))
+ glob_result = glob.glob(os.path.join(qmake_dir, "*.pro"))
if len(glob_result) > 0:
return glob_result[0]
return None
-def handle_top_level_repo_tests_project(scope: Scope, cm_fh: typing.IO[str]):
+def handle_top_level_repo_tests_project(scope: Scope, cm_fh: IO[str]):
top_level_project_path = find_top_level_repo_project_file(scope.file_absolute_path)
if top_level_project_path:
# qtdeclarative
@@ -2458,28 +2791,30 @@ def handle_top_level_repo_tests_project(scope: Scope, cm_fh: typing.IO[str]):
# Found a mapping, adjust name.
if qt_lib != file_name_without_qt:
# QtDeclarative
- qt_lib = re.sub(r':', r'', qt_lib) + "Tests"
+ qt_lib = re.sub(r":", r"", qt_lib) + "Tests"
else:
qt_lib += "Tests_FIXME"
else:
qt_lib = "Tests_FIXME"
- content = """if(NOT TARGET Qt::Test)
- cmake_minimum_required(VERSION {})
- project({} VERSION 6.0.0 LANGUAGES C CXX)
- find_package(Qt6 ${{PROJECT_VERSION}} REQUIRED COMPONENTS BuildInternals Core SET_ME_TO_SOMETHING_USEFUL)
- find_package(Qt6 ${{PROJECT_VERSION}} OPTIONAL_COMPONENTS SET_ME_TO_SOMETHING_USEFUL)
- qt_set_up_standalone_tests_build()
-endif()
+ content = dedent(
+ f"""\
+ if(NOT TARGET Qt::Test)
+ cmake_minimum_required(VERSION {cmake_version_string})
+ project({qt_lib} VERSION 6.0.0 LANGUAGES C CXX)
+ find_package(Qt6 ${{PROJECT_VERSION}} REQUIRED COMPONENTS BuildInternals Core SET_ME_TO_SOMETHING_USEFUL)
+ find_package(Qt6 ${{PROJECT_VERSION}} OPTIONAL_COMPONENTS SET_ME_TO_SOMETHING_USEFUL)
+ qt_set_up_standalone_tests_build()
+ endif()
+ qt_build_tests()"""
+ )
-qt_build_tests()
-""".format(cmake_version_string, qt_lib)
+ cm_fh.write(f"{content}")
- cm_fh.write('{}'.format(content))
-
-def cmakeify_scope(scope: Scope, cm_fh: typing.IO[str], *,
- indent: int = 0, is_example: bool=False) -> None:
+def cmakeify_scope(
+ scope: Scope, cm_fh: IO[str], *, indent: int = 0, is_example: bool = False
+) -> None:
template = scope.TEMPLATE
temp_buffer = io.StringIO()
@@ -2490,13 +2825,12 @@ def cmakeify_scope(scope: Scope, cm_fh: typing.IO[str], *,
# Same for top-level tests.
elif is_top_level_repo_tests_project(scope.file_absolute_path):
handle_top_level_repo_tests_project(scope, temp_buffer)
- elif template == 'subdirs':
+ elif template == "subdirs":
handle_subdir(scope, temp_buffer, indent=indent, is_example=is_example)
- elif template in ('app', 'lib'):
+ elif template in ("app", "lib"):
handle_app_or_lib(scope, temp_buffer, indent=indent, is_example=is_example)
else:
- print(' XXXX: {}: Template type {} not yet supported.'
- .format(scope.file, template))
+ print(f" XXXX: {scope.file}: Template type {template} not yet supported.")
buffer_value = temp_buffer.getvalue()
@@ -2504,21 +2838,23 @@ def cmakeify_scope(scope: Scope, cm_fh: typing.IO[str], *,
# Wrap top level examples project with some commands which
# are necessary to build examples as part of the overall
# build.
- buffer_value = """qt_examples_build_begin()
+ buffer_value = dedent(
+ """\
+ qt_examples_build_begin()
-{}
-qt_examples_build_end()
-""".format(buffer_value)
+ {buffer_value}
+ qt_examples_build_end()
+ """
+ )
cm_fh.write(buffer_value)
-def generate_new_cmakelists(scope: Scope, *, is_example: bool=False) -> None:
- print('Generating CMakeLists.gen.txt')
- with open(scope.generated_cmake_lists_path, 'w') as cm_fh:
+def generate_new_cmakelists(scope: Scope, *, is_example: bool = False) -> None:
+ print("Generating CMakeLists.gen.txt")
+ with open(scope.generated_cmake_lists_path, "w") as cm_fh:
assert scope.file
- cm_fh.write('# Generated from {}.\n\n'
- .format(os.path.basename(scope.file)))
+ cm_fh.write(f"# Generated from {os.path.basename(scope.file)}.\n\n")
is_example_heuristic = is_example_project(scope.file_absolute_path)
final_is_example_decision = is_example or is_example_heuristic
@@ -2529,18 +2865,17 @@ def do_include(scope: Scope, *, debug: bool = False) -> None:
for c in scope.children:
do_include(c)
- for include_file in scope.get_files('_INCLUDED', is_include=True):
+ for include_file in scope.get_files("_INCLUDED", is_include=True):
if not include_file:
continue
if not os.path.isfile(include_file):
- print(' XXXX: Failed to include {}.'.format(include_file))
+ print(f" XXXX: Failed to include {include_file}.")
continue
include_result = parseProFile(include_file, debug=debug)
- include_scope \
- = Scope.FromDict(None, include_file,
- include_result.asDict().get('statements'),
- '', scope.basedir) # This scope will be merged into scope!
+ include_scope = Scope.FromDict(
+ None, include_file, include_result.asDict().get("statements"), "", scope.basedir
+ ) # This scope will be merged into scope!
do_include(include_scope)
@@ -2548,31 +2883,33 @@ def do_include(scope: Scope, *, debug: bool = False) -> None:
def copy_generated_file_to_final_location(scope: Scope, keep_temporary_files=False) -> None:
- print('Copying {} to {}'.format(scope.generated_cmake_lists_path,
- scope.original_cmake_lists_path))
+ print(f"Copying {scope.generated_cmake_lists_path} to {scope.original_cmake_lists_path}")
copyfile(scope.generated_cmake_lists_path, scope.original_cmake_lists_path)
if not keep_temporary_files:
os.remove(scope.generated_cmake_lists_path)
-def should_convert_project(project_file_path: str = '') -> bool:
+def should_convert_project(project_file_path: str = "") -> bool:
qmake_conf_path = find_qmake_conf(project_file_path)
qmake_conf_dir_path = os.path.dirname(qmake_conf_path)
project_relative_path = os.path.relpath(project_file_path, qmake_conf_dir_path)
# Skip cmake auto tests, they should not be converted.
- if project_relative_path.startswith('tests/auto/cmake'):
+ if project_relative_path.startswith("tests/auto/cmake"):
return False
# Skip qmake testdata projects.
- if project_relative_path.startswith('tests/auto/tools/qmake/testdata'):
+ if project_relative_path.startswith("tests/auto/tools/qmake/testdata"):
return False
return True
def main() -> None:
+ # Be sure of proper Python version
+ assert sys.version_info >= (3, 7)
+
args = _parse_commandline()
debug_parsing = args.debug_parser or args.debug
@@ -2587,53 +2924,57 @@ def main() -> None:
project_file_absolute_path = os.path.abspath(file_relative_path)
if not should_convert_project(project_file_absolute_path):
- print('Skipping conversion of project: "{}"'.format(project_file_absolute_path))
+ print(f'Skipping conversion of project: "{project_file_absolute_path}"')
continue
parseresult = parseProFile(file_relative_path, debug=debug_parsing)
if args.debug_parse_result or args.debug:
- print('\n\n#### Parser result:')
+ print("\n\n#### Parser result:")
print(parseresult)
- print('\n#### End of parser result.\n')
+ print("\n#### End of parser result.\n")
if args.debug_parse_dictionary or args.debug:
- print('\n\n####Parser result dictionary:')
+ print("\n\n####Parser result dictionary:")
print(parseresult.asDict())
- print('\n#### End of parser result dictionary.\n')
+ print("\n#### End of parser result dictionary.\n")
- file_scope = Scope.FromDict(None, file_relative_path,
- parseresult.asDict().get('statements'))
+ file_scope = Scope.FromDict(
+ None, file_relative_path, parseresult.asDict().get("statements")
+ )
if args.debug_pro_structure or args.debug:
- print('\n\n#### .pro/.pri file structure:')
+ print("\n\n#### .pro/.pri file structure:")
file_scope.dump()
- print('\n#### End of .pro/.pri file structure.\n')
+ print("\n#### End of .pro/.pri file structure.\n")
do_include(file_scope, debug=debug_parsing)
if args.debug_full_pro_structure or args.debug:
- print('\n\n#### Full .pro/.pri file structure:')
+ print("\n\n#### Full .pro/.pri file structure:")
file_scope.dump()
- print('\n#### End of full .pro/.pri file structure.\n')
+ print("\n#### End of full .pro/.pri file structure.\n")
generate_new_cmakelists(file_scope, is_example=args.is_example)
copy_generated_file = True
if not args.skip_special_case_preservation:
debug_special_case = args.debug_special_case_preservation or args.debug
- handler = SpecialCaseHandler(file_scope.original_cmake_lists_path,
- file_scope.generated_cmake_lists_path,
- file_scope.basedir,
- keep_temporary_files=args.keep_temporary_files,
- debug=debug_special_case)
+ handler = SpecialCaseHandler(
+ file_scope.original_cmake_lists_path,
+ file_scope.generated_cmake_lists_path,
+ file_scope.basedir,
+ keep_temporary_files=args.keep_temporary_files,
+ debug=debug_special_case,
+ )
copy_generated_file = handler.handle_special_cases()
if copy_generated_file:
- copy_generated_file_to_final_location(file_scope,
- keep_temporary_files=args.keep_temporary_files)
+ copy_generated_file_to_final_location(
+ file_scope, keep_temporary_files=args.keep_temporary_files
+ )
os.chdir(backup_current_dir)
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/util/cmake/pro_conversion_rate.py b/util/cmake/pro_conversion_rate.py
index 740e834ca5e..c2807434a68 100755
--- a/util/cmake/pro_conversion_rate.py
+++ b/util/cmake/pro_conversion_rate.py
@@ -47,9 +47,10 @@ from timeit import default_timer
def _parse_commandline():
- parser = ArgumentParser(description='Find pro files for which there are no CMakeLists.txt.')
- parser.add_argument('source_directory', metavar='<src dir>', type=str,
- help='The source directory')
+ parser = ArgumentParser(description="Find pro files for which there are no CMakeLists.txt.")
+ parser.add_argument(
+ "source_directory", metavar="<src dir>", type=str, help="The source directory"
+ )
return parser.parse_args()
@@ -68,6 +69,7 @@ class Blacklist:
try:
# If package is available, use Aho-Corasick algorithm,
from ahocorapy.keywordtree import KeywordTree
+
self.tree = KeywordTree(case_insensitive=True)
for p in self.path_parts:
@@ -117,45 +119,58 @@ def check_for_cmake_project(pro_path: str) -> bool:
return os.path.exists(cmake_project_path)
-def compute_stats(src_path: str, pros_with_missing_project: typing.List[str],
- total_pros: int, existing_pros: int, missing_pros: int) -> dict:
+def compute_stats(
+ src_path: str,
+ pros_with_missing_project: typing.List[str],
+ total_pros: int,
+ existing_pros: int,
+ missing_pros: int,
+) -> dict:
stats = {}
- stats['total projects'] = {'label': 'Total pro files found',
- 'value': total_pros}
- stats['existing projects'] = {'label': 'Existing CMakeLists.txt files found',
- 'value': existing_pros}
- stats['missing projects'] = {'label': 'Missing CMakeLists.txt files found',
- 'value': missing_pros}
- stats['missing examples'] = {'label': 'Missing examples', 'value': 0}
- stats['missing tests'] = {'label': 'Missing tests', 'value': 0}
- stats['missing src'] = {'label': 'Missing src/**/**', 'value': 0}
- stats['missing plugins'] = {'label': 'Missing plugins', 'value': 0}
+ stats["total projects"] = {"label": "Total pro files found", "value": total_pros}
+ stats["existing projects"] = {
+ "label": "Existing CMakeLists.txt files found",
+ "value": existing_pros,
+ }
+ stats["missing projects"] = {
+ "label": "Missing CMakeLists.txt files found",
+ "value": missing_pros,
+ }
+ stats["missing examples"] = {"label": "Missing examples", "value": 0}
+ stats["missing tests"] = {"label": "Missing tests", "value": 0}
+ stats["missing src"] = {"label": "Missing src/**/**", "value": 0}
+ stats["missing plugins"] = {"label": "Missing plugins", "value": 0}
for p in pros_with_missing_project:
rel_path = os.path.relpath(p, src_path)
if rel_path.startswith("examples"):
- stats['missing examples']['value'] += 1
+ stats["missing examples"]["value"] += 1
elif rel_path.startswith("tests"):
- stats['missing tests']['value'] += 1
+ stats["missing tests"]["value"] += 1
elif rel_path.startswith(os.path.join("src", "plugins")):
- stats['missing plugins']['value'] += 1
+ stats["missing plugins"]["value"] += 1
elif rel_path.startswith("src"):
- stats['missing src']['value'] += 1
+ stats["missing src"]["value"] += 1
for stat in stats:
- if stats[stat]['value'] > 0:
- stats[stat]['percentage'] = round(stats[stat]['value'] * 100 / total_pros, 2)
+ if stats[stat]["value"] > 0:
+ stats[stat]["percentage"] = round(stats[stat]["value"] * 100 / total_pros, 2)
return stats
-def print_stats(src_path: str, pros_with_missing_project: typing.List[str], stats: dict,
- scan_time: float, script_time: float):
+def print_stats(
+ src_path: str,
+ pros_with_missing_project: typing.List[str],
+ stats: dict,
+ scan_time: float,
+ script_time: float,
+):
- if stats['total projects']['value'] == 0:
+ if stats["total projects"]["value"] == 0:
print("No .pro files found. Did you specify a correct source path?")
return
- if stats['total projects']['value'] == stats['existing projects']['value']:
+ if stats["total projects"]["value"] == stats["existing projects"]["value"]:
print("All projects were converted.")
else:
print("Missing CMakeLists.txt files for the following projects: \n")
@@ -167,10 +182,12 @@ def print_stats(src_path: str, pros_with_missing_project: typing.List[str], stat
print("\nStatistics: \n")
for stat in stats:
- if stats[stat]['value'] > 0:
- print("{:<40}: {} ({}%)".format(stats[stat]['label'],
- stats[stat]['value'],
- stats[stat]['percentage']))
+ if stats[stat]["value"] > 0:
+ print(
+ "{:<40}: {} ({}%)".format(
+ stats[stat]["label"], stats[stat]["value"], stats[stat]["percentage"]
+ )
+ )
print("\n{:<40}: {:.10f} seconds".format("Scan time", scan_time))
print("{:<40}: {:.10f} seconds".format("Total script time", script_time))
@@ -184,9 +201,7 @@ def main():
extension = ".pro"
blacklist_names = ["config.tests", "doc", "3rdparty", "angle"]
- blacklist_path_parts = [
- os.path.join("util", "cmake")
- ]
+ blacklist_path_parts = [os.path.join("util", "cmake")]
script_start_time = default_timer()
blacklist = Blacklist(blacklist_names, blacklist_path_parts)
@@ -206,13 +221,14 @@ def main():
missing_pros = len(pros_with_missing_project)
existing_pros = total_pros - missing_pros
- stats = compute_stats(src_path, pros_with_missing_project, total_pros, existing_pros,
- missing_pros)
+ stats = compute_stats(
+ src_path, pros_with_missing_project, total_pros, existing_pros, missing_pros
+ )
script_end_time = default_timer()
script_time = script_end_time - script_start_time
print_stats(src_path, pros_with_missing_project, stats, scan_time, script_time)
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/util/cmake/requirements.txt b/util/cmake/requirements.txt
new file mode 100644
index 00000000000..3a5d19a0448
--- /dev/null
+++ b/util/cmake/requirements.txt
@@ -0,0 +1,4 @@
+pytest; python_version >= '3.7'
+mypy; python_version >= '3.7'
+pyparsing; python_version >= '3.7'
+sympy; python_version >= '3.7'
diff --git a/util/cmake/run_pro2cmake.py b/util/cmake/run_pro2cmake.py
index 0d4cff2d67c..5d5f50cc2a8 100755
--- a/util/cmake/run_pro2cmake.py
+++ b/util/cmake/run_pro2cmake.py
@@ -38,56 +38,70 @@ from argparse import ArgumentParser
def parse_command_line():
- parser = ArgumentParser(description='Run pro2cmake on all .pro files recursively in given path.')
- parser.add_argument('--only-existing', dest='only_existing', action='store_true',
- help='Run pro2cmake only on .pro files that already have a CMakeLists.txt.')
- parser.add_argument('--only-qtbase-main-modules', dest='only_qtbase_main_modules', action='store_true',
- help='Run pro2cmake only on the main modules in qtbase.')
- parser.add_argument('--is-example', dest='is_example', action='store_true',
- help='Run pro2cmake with --is-example flag.')
- parser.add_argument('path', metavar='<path>', type=str,
- help='The path where to look for .pro files.')
+ parser = ArgumentParser(
+ description="Run pro2cmake on all .pro files recursively in given path."
+ )
+ parser.add_argument(
+ "--only-existing",
+ dest="only_existing",
+ action="store_true",
+ help="Run pro2cmake only on .pro files that already have a CMakeLists.txt.",
+ )
+ parser.add_argument(
+ "--only-qtbase-main-modules",
+ dest="only_qtbase_main_modules",
+ action="store_true",
+ help="Run pro2cmake only on the main modules in qtbase.",
+ )
+ parser.add_argument(
+ "--is-example",
+ dest="is_example",
+ action="store_true",
+ help="Run pro2cmake with --is-example flag.",
+ )
+ parser.add_argument(
+ "path", metavar="<path>", type=str, help="The path where to look for .pro files."
+ )
return parser.parse_args()
def find_all_pro_files(base_path: str, args: argparse.Namespace):
-
def sorter(pro_file: str) -> str:
""" Sorter that tries to prioritize main pro files in a directory. """
- pro_file_without_suffix = pro_file.rsplit('/', 1)[-1][:-4]
+ pro_file_without_suffix = pro_file.rsplit("/", 1)[-1][:-4]
dir_name = os.path.dirname(pro_file)
- if dir_name.endswith('/' + pro_file_without_suffix):
+ if dir_name.endswith("/" + pro_file_without_suffix):
return dir_name
return dir_name + "/__" + pro_file
all_files = []
previous_dir_name: str = None
- print('Finding .pro files.')
- glob_result = glob.glob(os.path.join(base_path, '**/*.pro'), recursive=True)
+ print("Finding .pro files.")
+ glob_result = glob.glob(os.path.join(base_path, "**/*.pro"), recursive=True)
def cmake_lists_exists_filter(path):
path_dir_name = os.path.dirname(path)
- if os.path.exists(os.path.join(path_dir_name, 'CMakeLists.txt')):
+ if os.path.exists(os.path.join(path_dir_name, "CMakeLists.txt")):
return True
return False
def qtbase_main_modules_filter(path):
main_modules = [
- 'corelib',
- 'network',
- 'gui',
- 'widgets',
- 'testlib',
- 'printsupport',
- 'opengl',
- 'sql',
- 'dbus',
- 'concurrent',
- 'xml',
+ "corelib",
+ "network",
+ "gui",
+ "widgets",
+ "testlib",
+ "printsupport",
+ "opengl",
+ "sql",
+ "dbus",
+ "concurrent",
+ "xml",
]
- path_suffixes = ['src/{}/{}.pro'.format(m, m, '.pro') for m in main_modules]
+ path_suffixes = ["src/{m}/{m}.pro" for m in main_modules]
for path_suffix in path_suffixes:
if path.endswith(path_suffix):
@@ -102,7 +116,7 @@ def find_all_pro_files(base_path: str, args: argparse.Namespace):
filter_func = qtbase_main_modules_filter
if filter_func:
- print('Filtering.')
+ print("Filtering.")
filter_result = [p for p in filter_result if filter_func(p)]
for pro_file in sorted(filter_result, key=sorter):
@@ -118,14 +132,14 @@ def find_all_pro_files(base_path: str, args: argparse.Namespace):
def run(all_files: typing.List[str], pro2cmake: str, args: argparse.Namespace) -> typing.List[str]:
failed_files = []
files_count = len(all_files)
- workers = (os.cpu_count() or 1)
+ workers = os.cpu_count() or 1
if args.only_qtbase_main_modules:
# qtbase main modules take longer than usual to process.
workers = 2
with concurrent.futures.ThreadPoolExecutor(max_workers=workers, initargs=(10,)) as pool:
- print('Firing up thread pool executor.')
+ print("Firing up thread pool executor.")
def _process_a_file(data: typing.Tuple[str, int, int]) -> typing.Tuple[int, str, str]:
filename, index, total = data
@@ -134,18 +148,21 @@ def run(all_files: typing.List[str], pro2cmake: str, args: argparse.Namespace) -
pro2cmake_args.append(sys.executable)
pro2cmake_args.append(pro2cmake)
if args.is_example:
- pro2cmake_args.append('--is-example')
+ pro2cmake_args.append("--is-example")
pro2cmake_args.append(os.path.basename(filename))
- result = subprocess.run(pro2cmake_args,
- cwd=os.path.dirname(filename),
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- stdout = 'Converted[{}/{}]: {}\n'.format(index, total, filename)
+ result = subprocess.run(
+ pro2cmake_args,
+ cwd=os.path.dirname(filename),
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ )
+ stdout = f"Converted[{index}/{total}]: {filename}\n"
return result.returncode, filename, stdout + result.stdout.decode()
- for return_code, filename, stdout in pool.map(_process_a_file,
- zip(all_files,
- range(1, files_count + 1),
- (files_count for _ in all_files))):
+ for return_code, filename, stdout in pool.map(
+ _process_a_file,
+ zip(all_files, range(1, files_count + 1), (files_count for _ in all_files)),
+ ):
if return_code:
failed_files.append(filename)
print(stdout)
@@ -157,21 +174,23 @@ def main() -> None:
args = parse_command_line()
script_path = os.path.dirname(os.path.abspath(__file__))
- pro2cmake = os.path.join(script_path, 'pro2cmake.py')
+ pro2cmake = os.path.join(script_path, "pro2cmake.py")
base_path = args.path
all_files = find_all_pro_files(base_path, args)
files_count = len(all_files)
failed_files = run(all_files, pro2cmake, args)
if len(all_files) == 0:
- print('No files found.')
+ print("No files found.")
if failed_files:
- print('The following files were not successfully '
- 'converted ({} of {}):'.format(len(failed_files), files_count))
+ print(
+ f"The following files were not successfully "
+ f"converted ({len(failed_files)} of {files_count}):"
+ )
for f in failed_files:
- print(' "{}"'.format(f))
+ print(f' "{f}"')
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/util/cmake/special_case_helper.py b/util/cmake/special_case_helper.py
index b9cb93dce0f..60443aeb612 100644
--- a/util/cmake/special_case_helper.py
+++ b/util/cmake/special_case_helper.py
@@ -93,31 +93,34 @@ import stat
from shutil import copyfile
from shutil import rmtree
+from textwrap import dedent
def remove_special_cases(original: str) -> str:
# Remove content between the following markers
# '# special case begin' and '# special case end'.
# This also remove the markers.
- replaced = re.sub(r'\n[^#\n]*?#[^\n]*?special case begin.*?#[^\n]*special case end[^\n]*?\n',
- '\n',
- original,
- 0,
- re.DOTALL)
+ replaced = re.sub(
+ r"\n[^#\n]*?#[^\n]*?special case begin.*?#[^\n]*special case end[^\n]*?\n",
+ "\n",
+ original,
+ 0,
+ re.DOTALL,
+ )
# Remove individual lines that have the "# special case" marker.
- replaced = re.sub(r'\n.*#.*special case[^\n]*\n', '\n', replaced)
+ replaced = re.sub(r"\n.*#.*special case[^\n]*\n", "\n", replaced)
return replaced
def read_content_from_file(file_path: str) -> str:
- with open(file_path, 'r') as file_fd:
+ with open(file_path, "r") as file_fd:
content = file_fd.read()
return content
def write_content_to_file(file_path: str, content: str) -> None:
- with open(file_path, 'w') as file_fd:
+ with open(file_path, "w") as file_fd:
file_fd.write(content)
@@ -126,23 +129,23 @@ def resolve_simple_git_conflicts(file_path: str, debug=False) -> None:
# If the conflict represents the addition of a new content hunk,
# keep the content and remove the conflict markers.
if debug:
- print('Resolving simple conflicts automatically.')
- replaced = re.sub(r'\n<<<<<<< HEAD\n=======(.+?)>>>>>>> master\n', r'\1', content, 0, re.DOTALL)
+ print("Resolving simple conflicts automatically.")
+ replaced = re.sub(r"\n<<<<<<< HEAD\n=======(.+?)>>>>>>> master\n", r"\1", content, 0, re.DOTALL)
write_content_to_file(file_path, replaced)
def copyfile_log(src: str, dst: str, debug=False):
if debug:
- print('Copying {} to {}.'.format(src, dst))
+ print(f"Copying {src} to {dst}.")
copyfile(src, dst)
def check_if_git_in_path() -> bool:
- is_win = os.name == 'nt'
- for path in os.environ['PATH'].split(os.pathsep):
- git_path = os.path.join(path, 'git')
+ is_win = os.name == "nt"
+ for path in os.environ["PATH"].split(os.pathsep):
+ git_path = os.path.join(path, "git")
if is_win:
- git_path += '.exe'
+ git_path += ".exe"
if os.path.isfile(git_path) and os.access(git_path, os.X_OK):
return True
return False
@@ -150,31 +153,38 @@ def check_if_git_in_path() -> bool:
def run_process_quiet(args_string: str, debug=False) -> bool:
if debug:
- print('Running command: "{}\"'.format(args_string))
+ print(f'Running command: "{args_string}"')
args_list = args_string.split()
try:
subprocess.run(args_list, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
# git merge with conflicts returns with exit code 1, but that's not
# an error for us.
- if 'git merge' not in args_string:
- print('Error while running: "{}"\n{}'.format(args_string, e.stdout))
+ if "git merge" not in args_string:
+ print(
+ dedent(
+ f"""\
+ Error while running: "{args_string}"
+ {e.stdout}"""
+ )
+ )
return False
return True
def does_file_have_conflict_markers(file_path: str, debug=False) -> bool:
if debug:
- print('Checking if {} has no leftover conflict markers.'.format(file_path))
+ print(f"Checking if {file_path} has no leftover conflict markers.")
content_actual = read_content_from_file(file_path)
- if '<<<<<<< HEAD' in content_actual:
- print('Conflict markers found in {}. '
- 'Please remove or solve them first.'.format(file_path))
+ if "<<<<<<< HEAD" in content_actual:
+ print(f"Conflict markers found in {file_path}. " "Please remove or solve them first.")
return True
return False
-def create_file_with_no_special_cases(original_file_path: str, no_special_cases_file_path: str, debug=False):
+def create_file_with_no_special_cases(
+ original_file_path: str, no_special_cases_file_path: str, debug=False
+):
"""
Reads content of original CMakeLists.txt, removes all content
between "# special case" markers or lines, saves the result into a
@@ -182,35 +192,36 @@ def create_file_with_no_special_cases(original_file_path: str, no_special_cases_
"""
content_actual = read_content_from_file(original_file_path)
if debug:
- print('Removing special case blocks from {}.'.format(original_file_path))
+ print(f"Removing special case blocks from {original_file_path}.")
content_no_special_cases = remove_special_cases(content_actual)
if debug:
- print('Saving original contents of {} '
- 'with removed special case blocks to {}'.format(original_file_path,
- no_special_cases_file_path))
+ print(
+ f"Saving original contents of {original_file_path} "
+ f"with removed special case blocks to {no_special_cases_file_path}"
+ )
write_content_to_file(no_special_cases_file_path, content_no_special_cases)
-def rm_tree_on_error_handler(func: typing.Callable[..., None],
- path: str, exception_info: tuple):
+def rm_tree_on_error_handler(func: typing.Callable[..., None], path: str, exception_info: tuple):
# If the path is read only, try to make it writable, and try
# to remove the path again.
if not os.access(path, os.W_OK):
os.chmod(path, stat.S_IWRITE)
func(path)
else:
- print('Error while trying to remove path: {}. Exception: {}'.format(path, exception_info))
+ print(f"Error while trying to remove path: {path}. Exception: {exception_info}")
class SpecialCaseHandler(object):
-
- def __init__(self,
- original_file_path: str,
- generated_file_path: str,
- base_dir: str,
- keep_temporary_files=False,
- debug=False) -> None:
+ def __init__(
+ self,
+ original_file_path: str,
+ generated_file_path: str,
+ base_dir: str,
+ keep_temporary_files=False,
+ debug=False,
+ ) -> None:
self.base_dir = base_dir
self.original_file_path = original_file_path
self.generated_file_path = generated_file_path
@@ -220,29 +231,28 @@ class SpecialCaseHandler(object):
@property
def prev_file_path(self) -> str:
- return os.path.join(self.base_dir, '.prev_CMakeLists.txt')
+ return os.path.join(self.base_dir, ".prev_CMakeLists.txt")
@property
def post_merge_file_path(self) -> str:
- return os.path.join(self.base_dir, 'CMakeLists-post-merge.txt')
+ return os.path.join(self.base_dir, "CMakeLists-post-merge.txt")
@property
def no_special_file_path(self) -> str:
- return os.path.join(self.base_dir, 'CMakeLists.no-special.txt')
+ return os.path.join(self.base_dir, "CMakeLists.no-special.txt")
def apply_git_merge_magic(self, no_special_cases_file_path: str) -> None:
# Create new folder for temporary repo, and ch dir into it.
- repo = os.path.join(self.base_dir, 'tmp_repo')
+ repo = os.path.join(self.base_dir, "tmp_repo")
repo_absolute_path = os.path.abspath(repo)
- txt = 'CMakeLists.txt'
+ txt = "CMakeLists.txt"
try:
os.mkdir(repo)
current_dir = os.getcwd()
os.chdir(repo)
except Exception as e:
- print('Failed to create temporary directory for temporary git repo. Exception: {}'
- .format(e))
+ print(f"Failed to create temporary directory for temporary git repo. Exception: {e}")
raise e
generated_file_path = os.path.join("..", self.generated_file_path)
@@ -252,34 +262,34 @@ class SpecialCaseHandler(object):
try:
# Create new repo with the "clean" CMakeLists.txt file.
- run_process_quiet('git init .', debug=self.debug)
- run_process_quiet('git config user.name fake', debug=self.debug)
- run_process_quiet('git config user.email fake@fake', debug=self.debug)
+ run_process_quiet("git init .", debug=self.debug)
+ run_process_quiet("git config user.name fake", debug=self.debug)
+ run_process_quiet("git config user.email fake@fake", debug=self.debug)
copyfile_log(no_special_cases_file_path, txt, debug=self.debug)
- run_process_quiet('git add {}'.format(txt), debug=self.debug)
- run_process_quiet('git commit -m no_special', debug=self.debug)
- run_process_quiet('git checkout -b no_special', debug=self.debug)
+ run_process_quiet(f"git add {txt}", debug=self.debug)
+ run_process_quiet("git commit -m no_special", debug=self.debug)
+ run_process_quiet("git checkout -b no_special", debug=self.debug)
# Copy the original "modified" file (with the special cases)
# and make a new commit.
- run_process_quiet('git checkout -b original', debug=self.debug)
+ run_process_quiet("git checkout -b original", debug=self.debug)
copyfile_log(original_file_path, txt, debug=self.debug)
- run_process_quiet('git add {}'.format(txt), debug=self.debug)
- run_process_quiet('git commit -m original', debug=self.debug)
+ run_process_quiet(f"git add {txt}", debug=self.debug)
+ run_process_quiet("git commit -m original", debug=self.debug)
# Checkout the commit with "clean" file again, and create a
# new branch.
- run_process_quiet('git checkout no_special', debug=self.debug)
- run_process_quiet('git checkout -b newly_generated', debug=self.debug)
+ run_process_quiet("git checkout no_special", debug=self.debug)
+ run_process_quiet("git checkout -b newly_generated", debug=self.debug)
# Copy the new "modified" file and make a commit.
copyfile_log(generated_file_path, txt, debug=self.debug)
- run_process_quiet('git add {}'.format(txt), debug=self.debug)
- run_process_quiet('git commit -m newly_generated', debug=self.debug)
+ run_process_quiet(f"git add {txt}", debug=self.debug)
+ run_process_quiet("git commit -m newly_generated", debug=self.debug)
# Merge the "old" branch with modifications into the "new"
# branch with the newly generated file.
- run_process_quiet('git merge original', debug=self.debug)
+ run_process_quiet("git merge original", debug=self.debug)
# Resolve some simple conflicts (just remove the markers)
# for cases that don't need intervention.
@@ -288,7 +298,7 @@ class SpecialCaseHandler(object):
# Copy the resulting file from the merge.
copyfile_log(txt, post_merge_file_path)
except Exception as e:
- print('Git merge conflict resolution process failed. Exception: {}'.format(e))
+ print(f"Git merge conflict resolution process failed. Exception: {e}")
raise e
finally:
os.chdir(current_dir)
@@ -298,7 +308,7 @@ class SpecialCaseHandler(object):
if not self.keep_temporary_files:
rmtree(repo_absolute_path, onerror=rm_tree_on_error_handler)
except Exception as e:
- print('Error removing temporary repo. Exception: {}'.format(e))
+ print(f"Error removing temporary repo. Exception: {e}")
def save_next_clean_file(self):
files_are_equivalent = filecmp.cmp(self.generated_file_path, self.post_merge_file_path)
@@ -316,20 +326,18 @@ class SpecialCaseHandler(object):
failed_once = False
i = 0
while not success and i < 20:
- success = run_process_quiet("git add {}".format(self.prev_file_path),
- debug=self.debug)
+ success = run_process_quiet(f"git add {self.prev_file_path}", debug=self.debug)
if not success:
failed_once = True
i += 1
time.sleep(0.1)
if failed_once and not success:
- print('Retrying git add, the index.lock was probably acquired.')
+ print("Retrying git add, the index.lock was probably acquired.")
if failed_once and success:
- print('git add succeeded.')
+ print("git add succeeded.")
elif failed_once and not success:
- print('git add failed. Make sure to git add {} yourself.'.format(
- self.prev_file_path))
+ print(f"git add failed. Make sure to git add {self.prev_file_path} yourself.")
def handle_special_cases_helper(self) -> bool:
"""
@@ -348,15 +356,18 @@ class SpecialCaseHandler(object):
return False
if self.use_heuristic:
- create_file_with_no_special_cases(self.original_file_path,
- self.no_special_file_path)
+ create_file_with_no_special_cases(
+ self.original_file_path, self.no_special_file_path
+ )
no_special_cases_file_path = self.no_special_file_path
else:
no_special_cases_file_path = self.prev_file_path
if self.debug:
- print('Using git to reapply special case modifications to newly generated {} '
- 'file'.format(self.generated_file_path))
+ print(
+ f"Using git to reapply special case modifications to newly "
+ f"generated {self.generated_file_path} file"
+ )
self.apply_git_merge_magic(no_special_cases_file_path)
self.save_next_clean_file()
@@ -365,11 +376,13 @@ class SpecialCaseHandler(object):
if not self.keep_temporary_files:
os.remove(self.post_merge_file_path)
- print('Special case reapplication using git is complete. '
- 'Make sure to fix remaining conflict markers.')
+ print(
+ "Special case reapplication using git is complete. "
+ "Make sure to fix remaining conflict markers."
+ )
except Exception as e:
- print('Error occurred while trying to reapply special case modifications: {}'.format(e))
+ print(f"Error occurred while trying to reapply special case modifications: {e}")
return False
finally:
if not self.keep_temporary_files and self.use_heuristic:
@@ -386,8 +399,10 @@ class SpecialCaseHandler(object):
keep_special_cases = original_file_exists and git_available
if not git_available:
- print('You need to have git in PATH in order to reapply the special '
- 'case modifications.')
+ print(
+ "You need to have git in PATH in order to reapply the special "
+ "case modifications."
+ )
copy_generated_file = True