summaryrefslogtreecommitdiffstats
path: root/util/cmake
diff options
context:
space:
mode:
Diffstat (limited to 'util/cmake')
-rw-r--r--util/cmake/README.md15
-rwxr-xr-xutil/cmake/cmakeconversionrate.py31
-rwxr-xr-x[-rw-r--r--]util/cmake/condition_simplifier.py40
-rwxr-xr-x[-rw-r--r--]util/cmake/condition_simplifier_cache.py35
-rwxr-xr-xutil/cmake/configurejson2cmake.py62
-rwxr-xr-xutil/cmake/generate_module_map.sh29
-rw-r--r--util/cmake/helper.py532
-rw-r--r--util/cmake/json_parser.py29
-rwxr-xr-xutil/cmake/pro2cmake.py1070
-rwxr-xr-xutil/cmake/pro_conversion_rate.py33
-rwxr-xr-x[-rw-r--r--]util/cmake/qmake_parser.py82
-rwxr-xr-xutil/cmake/run_pro2cmake.py31
-rw-r--r--util/cmake/special_case_helper.py29
-rw-r--r--util/cmake/tests/data/condition_operator_precedence.pro11
-rw-r--r--util/cmake/tests/data/conversion/optional_qt_modules.pro4
-rw-r--r--util/cmake/tests/data/conversion/qt_version_check.pro8
-rw-r--r--util/cmake/tests/data/conversion/required_qt_modules.pro3
-rw-r--r--util/cmake/tests/data/standardpaths.pro2
-rwxr-xr-xutil/cmake/tests/test_conversion.py66
-rwxr-xr-xutil/cmake/tests/test_lc_fixup.py29
-rwxr-xr-xutil/cmake/tests/test_logic_mapping.py32
-rwxr-xr-xutil/cmake/tests/test_operations.py29
-rwxr-xr-xutil/cmake/tests/test_parsing.py47
-rwxr-xr-xutil/cmake/tests/test_scope_handling.py44
24 files changed, 1195 insertions, 1098 deletions
diff --git a/util/cmake/README.md b/util/cmake/README.md
index f8a6e9f540..0d80fbcdce 100644
--- a/util/cmake/README.md
+++ b/util/cmake/README.md
@@ -2,6 +2,9 @@
This directory holds scripts to help the porting process from `qmake` to `cmake` for Qt6.
+If you're looking to port your own Qt-based project from `qmake` to `cmake`, please use
+[qmake2cmake](https://wiki.qt.io/Qmake2cmake).
+
# Requirements
* [Python 3.7](https://www.python.org/downloads/),
@@ -39,22 +42,16 @@ python3.7 -m pip install -r requirements.txt
You can verify if the styling of a script is compliant 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:
+on all python source files:
```
-flake8 <file>.py --ignore=E501,E266,W503
+make flake8
```
-* `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
+make format
```
-
-Using Qt's maximum line length, 100.
diff --git a/util/cmake/cmakeconversionrate.py b/util/cmake/cmakeconversionrate.py
index b87957df6c..012ef1ee2d 100755
--- a/util/cmake/cmakeconversionrate.py
+++ b/util/cmake/cmakeconversionrate.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
from argparse import ArgumentParser
@@ -46,7 +21,7 @@ def _parse_commandline():
)
parser.add_argument(
"binary_directory",
- metavar="<CMake build direcotry>",
+ metavar="<CMake build directory>",
type=str,
help="The CMake build directory (might be empty)",
)
diff --git a/util/cmake/condition_simplifier.py b/util/cmake/condition_simplifier.py
index e6588a7cc7..a540ee0519 100644..100755
--- a/util/cmake/condition_simplifier.py
+++ b/util/cmake/condition_simplifier.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2021 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import re
@@ -72,8 +47,8 @@ def _simplify_expressions(expr, op, matches, replacement):
def _simplify_flavors_in_condition(base: str, flavors, expr):
- """ Simplify conditions based on the knowledge of which flavors
- belong to which OS. """
+ """Simplify conditions based on the knowledge of which flavors
+ belong to which OS."""
base_expr = simplify_logic(base)
false_expr = simplify_logic("false")
for flavor in flavors:
@@ -100,15 +75,15 @@ def _simplify_os_families(expr, family_members, other_family_members):
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 = ("MACOS", "UIKIT", "IOS", "TVOS", "WATCHOS")
bsds = ("FREEBSD", "OPENBSD", "NETBSD")
- androids = ("ANDROID", "ANDROID_EMBEDDED")
+ androids = ("ANDROID",)
unixes = (
"APPLE",
*apples,
@@ -140,7 +115,6 @@ def _recursive_simplify(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)
diff --git a/util/cmake/condition_simplifier_cache.py b/util/cmake/condition_simplifier_cache.py
index 58cd5b88c5..5995c5bb81 100644..100755
--- a/util/cmake/condition_simplifier_cache.py
+++ b/util/cmake/condition_simplifier_cache.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import atexit
@@ -105,11 +80,7 @@ def open_file_safe(file_path: str, mode: str = "r+"):
try:
import portalocker # type: ignore
- file_open_func = portalocker.Lock
- file_open_args = [file_path]
- file_open_kwargs = {"mode": mode, "flags": portalocker.LOCK_EX}
- file_handle = file_open_func(*file_open_args, **file_open_kwargs)
- return file_handle
+ return portalocker.Lock(file_path, mode=mode, flags=portalocker.LOCK_EX)
except ImportError:
print(
"The conversion script is missing a required package: portalocker. Please run "
diff --git a/util/cmake/configurejson2cmake.py b/util/cmake/configurejson2cmake.py
index b5e148f63c..50a40f6112 100755
--- a/util/cmake/configurejson2cmake.py
+++ b/util/cmake/configurejson2cmake.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import json_parser
import posixpath
@@ -611,7 +586,7 @@ def write_compile_test(
head = detail.get("head")
if isinstance(head, list):
head = "\n".join(head)
- return head + '\n' if head else ''
+ return head + "\n" if head else ""
head = ""
if inherit_details:
@@ -646,7 +621,7 @@ def write_compile_test(
tail = detail.get("tail")
if isinstance(tail, list):
tail = "\n".join(tail)
- return tail + '\n' if tail else ''
+ return tail + "\n" if tail else ""
tail = ""
if inherit_details:
@@ -655,8 +630,8 @@ def write_compile_test(
sourceCode += tail
- if sourceCode: # blank line before main
- sourceCode += '\n'
+ if sourceCode: # blank line before main
+ sourceCode += "\n"
sourceCode += "int main(void)\n"
sourceCode += "{\n"
sourceCode += " /* BEGIN TEST: */\n"
@@ -665,7 +640,7 @@ def write_compile_test(
main = detail.get("main")
if isinstance(main, list):
main = "\n".join(main)
- return main + '\n' if main else ''
+ return main + "\n" if main else ""
main = ""
if inherit_details:
@@ -934,7 +909,7 @@ endif()""",
"condition": "__qt_ltcg_detected",
},
"msvc_mp": None,
- "simulator_and_device": {"condition": "UIKIT AND NOT QT_UIKIT_SDK"},
+ "simulator_and_device": {"condition": "UIKIT AND NOT QT_APPLE_SDK"},
"pkg-config": {"condition": "PKG_CONFIG_FOUND"},
"precompile_header": {"condition": "BUILD_WITH_PCH"},
"profile": None,
@@ -943,7 +918,11 @@ endif()""",
"qreal": {
"condition": 'DEFINED QT_COORD_TYPE AND NOT QT_COORD_TYPE STREQUAL "double"',
"output": [
- {"type": "define", "name": "QT_COORD_TYPE", "value": "${QT_COORD_TYPE}",},
+ {
+ "type": "define",
+ "name": "QT_COORD_TYPE",
+ "value": "${QT_COORD_TYPE}",
+ },
{
"type": "define",
"name": "QT_COORD_TYPE_STRING",
@@ -951,7 +930,9 @@ endif()""",
},
],
},
- "reduce_exports": {"condition": "NOT MSVC",},
+ "reduce_exports": {
+ "condition": "NOT MSVC",
+ },
"release": None,
"release_tools": None,
"rpath": {
@@ -1407,11 +1388,6 @@ def parseCommandLinePrefixes(ctx, data, cm_fh):
cm_fh.write(f"qt_commandline_prefix({key} {data[key]})\n")
-def parseCommandLineAssignments(ctx, data, cm_fh):
- for key in data:
- cm_fh.write(f"qt_commandline_assignment({key} {data[key]})\n")
-
-
def processCommandLine(ctx, data, cm_fh):
print(" commandline:")
@@ -1433,8 +1409,7 @@ def processCommandLine(ctx, data, cm_fh):
print(" prefix:")
parseCommandLinePrefixes(ctx, commandLine["prefix"], cm_fh)
if "assignments" in commandLine:
- print(" assignments:")
- parseCommandLineAssignments(ctx, commandLine["assignments"], cm_fh)
+ print(" assignments are ignored")
def processInputs(ctx, data, cm_fh):
@@ -1524,6 +1499,7 @@ class special_cased_file:
self.sc_handler.handle_special_cases()
os.replace(self.gen_file_path, self.file_path)
+
def processJson(path, ctx, data, skip_special_case_preservation=False):
ctx["project_dir"] = path
ctx["module"] = data.get("module", "global")
@@ -1571,7 +1547,7 @@ def main():
quit(1)
directory = sys.argv[1]
- skip_special_case_preservation = '-s' in sys.argv[2:]
+ skip_special_case_preservation = "-s" in sys.argv[2:]
print(f"Processing: {directory}.")
diff --git a/util/cmake/generate_module_map.sh b/util/cmake/generate_module_map.sh
index 1ca0bfc43c..8cca1c0aa3 100755
--- a/util/cmake/generate_module_map.sh
+++ b/util/cmake/generate_module_map.sh
@@ -1,31 +1,6 @@
#!/usr/bin/bash
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
pro_files=$(find . -name \*.pro)
diff --git a/util/cmake/helper.py b/util/cmake/helper.py
index e0f4309a4f..3e9f4d73b2 100644
--- a/util/cmake/helper.py
+++ b/util/cmake/helper.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2021 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import re
import typing
@@ -39,6 +14,7 @@ class LibraryMapping:
*,
resultVariable: typing.Optional[str] = None,
extra: typing.List[str] = [],
+ components: typing.Optional[typing.List[str]] = None,
appendFoundSuffix: bool = True,
emit_if: str = "",
is_bundled_with_qt: bool = False,
@@ -52,6 +28,7 @@ class LibraryMapping:
self.appendFoundSuffix = appendFoundSuffix
# Allows passing addiitonal arguments to the generated find_package call.
self.extra = extra
+ self.components = components
self.targetName = targetName
# True if qt bundles the library sources as part of Qt.
@@ -77,327 +54,309 @@ class LibraryMapping:
_qt_library_map = [
# Qt:
- LibraryMapping(
- "androidextras", "Qt6", "Qt::AndroidExtras", extra=["COMPONENTS", "AndroidExtras"]
- ),
- LibraryMapping("3danimation", "Qt6", "Qt::3DAnimation", extra=["COMPONENTS", "3DAnimation"]),
- LibraryMapping("3dcore", "Qt6", "Qt::3DCore", extra=["COMPONENTS", "3DCore"]),
- LibraryMapping("3dcoretest", "Qt6", "Qt::3DCoreTest", extra=["COMPONENTS", "3DCoreTest"]),
- LibraryMapping("3dextras", "Qt6", "Qt::3DExtras", extra=["COMPONENTS", "3DExtras"]),
- LibraryMapping("3dinput", "Qt6", "Qt::3DInput", extra=["COMPONENTS", "3DInput"]),
- LibraryMapping("3dlogic", "Qt6", "Qt::3DLogic", extra=["COMPONENTS", "3DLogic"]),
- LibraryMapping("3dquick", "Qt6", "Qt::3DQuick", extra=["COMPONENTS", "3DQuick"]),
- LibraryMapping(
- "3dquickextras", "Qt6", "Qt::3DQuickExtras", extra=["COMPONENTS", "3DQuickExtras"]
- ),
- LibraryMapping("3dquickinput", "Qt6", "Qt::3DQuickInput", extra=["COMPONENTS", "3DQuickInput"]),
- LibraryMapping(
- "3dquickrender", "Qt6", "Qt::3DQuickRender", extra=["COMPONENTS", "3DQuickRender"]
- ),
- LibraryMapping("3drender", "Qt6", "Qt::3DRender", extra=["COMPONENTS", "3DRender"]),
- LibraryMapping(
- "application-lib", "Qt6", "Qt::AppManApplication", extra=["COMPONENTS", "AppManApplication"]
- ),
- LibraryMapping("axbase", "Qt6", "Qt::AxBase", extra=["COMPONENTS", "AxBase"]),
- LibraryMapping("axcontainer", "Qt6", "Qt::AxContainer", extra=["COMPONENTS", "AxContainer"]),
- LibraryMapping("axserver", "Qt6", "Qt::AxServer", extra=["COMPONENTS", "AxServer"]),
- LibraryMapping("bluetooth", "Qt6", "Qt::Bluetooth", extra=["COMPONENTS", "Bluetooth"]),
- LibraryMapping("bootstrap", "Qt6", "Qt::Bootstrap", extra=["COMPONENTS", "Bootstrap"]),
+ LibraryMapping("androidextras", "Qt6", "Qt::AndroidExtras", components=["AndroidExtras"]),
+ LibraryMapping("3danimation", "Qt6", "Qt::3DAnimation", components=["3DAnimation"]),
+ LibraryMapping("3dcore", "Qt6", "Qt::3DCore", components=["3DCore"]),
+ LibraryMapping("3dcoretest", "Qt6", "Qt::3DCoreTest", components=["3DCoreTest"]),
+ LibraryMapping("3dextras", "Qt6", "Qt::3DExtras", components=["3DExtras"]),
+ LibraryMapping("3dinput", "Qt6", "Qt::3DInput", components=["3DInput"]),
+ LibraryMapping("3dlogic", "Qt6", "Qt::3DLogic", components=["3DLogic"]),
+ LibraryMapping("3dquick", "Qt6", "Qt::3DQuick", components=["3DQuick"]),
+ LibraryMapping("3dquickextras", "Qt6", "Qt::3DQuickExtras", components=["3DQuickExtras"]),
+ LibraryMapping("3dquickinput", "Qt6", "Qt::3DQuickInput", components=["3DQuickInput"]),
+ LibraryMapping("3dquickrender", "Qt6", "Qt::3DQuickRender", components=["3DQuickRender"]),
+ LibraryMapping("3drender", "Qt6", "Qt::3DRender", components=["3DRender"]),
+ LibraryMapping(
+ "application-lib", "Qt6", "Qt::AppManApplication", components=["AppManApplication"]
+ ),
+ LibraryMapping("axbase", "Qt6", "Qt::AxBasePrivate", components=["AxBasePrivate"]),
+ LibraryMapping("axcontainer", "Qt6", "Qt::AxContainer", components=["AxContainer"]),
+ LibraryMapping("axserver", "Qt6", "Qt::AxServer", components=["AxServer"]),
+ LibraryMapping("bluetooth", "Qt6", "Qt::Bluetooth", components=["Bluetooth"]),
+ LibraryMapping("bootstrap", "Qt6", "Qt::Bootstrap", components=["Bootstrap"]),
# bootstrap-dbus: Not needed in Qt6!
- LibraryMapping("client", "Qt6", "Qt::WaylandClient", extra=["COMPONENTS", "WaylandClient"]),
- 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("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("client", "Qt6", "Qt::WaylandClient", components=["WaylandClient"]),
+ LibraryMapping("coap", "Qt6", "Qt::Coap", components=["Coap"]),
+ LibraryMapping("common-lib", "Qt6", "Qt::AppManCommon", components=["AppManCommon"]),
+ LibraryMapping("compositor", "Qt6", "Qt::WaylandCompositor", components=["WaylandCompositor"]),
+ LibraryMapping("concurrent", "Qt6", "Qt::Concurrent", components=["Concurrent"]),
+ LibraryMapping("container", "Qt6", "Qt::AxContainer", components=["AxContainer"]),
+ LibraryMapping("control", "Qt6", "Qt::AxServer", components=["AxServer"]),
+ LibraryMapping("core_headers", "Qt6", "Qt::WebEngineCore", components=["WebEngineCore"]),
+ LibraryMapping("core", "Qt6", "Qt::Core", components=["Core"]),
+ LibraryMapping("crypto-lib", "Qt6", "Qt::AppManCrypto", components=["AppManCrypto"]),
+ LibraryMapping("dbus", "Qt6", "Qt::DBus", components=["DBus"]),
+ LibraryMapping("designer", "Qt6", "Qt::Designer", components=["Designer"]),
LibraryMapping(
"designercomponents",
"Qt6",
- "Qt::DesignerComponents",
- extra=["COMPONENTS", "DesignerComponents"],
+ "Qt::DesignerComponentsPrivate",
+ components=["DesignerComponentsPrivate"],
),
LibraryMapping(
"devicediscovery",
"Qt6",
- "Qt::DeviceDiscoverySupport",
- extra=["COMPONENTS", "DeviceDiscoverySupport"],
+ "Qt::DeviceDiscoverySupportPrivate",
+ components=["DeviceDiscoverySupportPrivate"],
),
LibraryMapping(
"devicediscovery_support",
"Qt6",
- "Qt::DeviceDiscoverySupport",
- extra=["COMPONENTS", "DeviceDiscoverySupport"],
+ "Qt::DeviceDiscoverySupportPrivate",
+ components=["DeviceDiscoverySupportPrivate"],
),
- 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("edid", "Qt6", "Qt::EdidSupport", components=["EdidSupport"]),
+ LibraryMapping("edid_support", "Qt6", "Qt::EdidSupport", components=["EdidSupport"]),
+ LibraryMapping("eglconvenience", "Qt6", "Qt::EglSupport", components=["EglSupport"]),
LibraryMapping(
"eglfsdeviceintegration",
"Qt6",
- "Qt::EglFSDeviceIntegration",
- extra=["COMPONENTS", "EglFSDeviceIntegration"],
+ "Qt::EglFSDeviceIntegrationPrivate",
+ components=["EglFSDeviceIntegrationPrivate"],
),
LibraryMapping(
- "eglfs_kms_support", "Qt6", "Qt::EglFsKmsSupport", extra=["COMPONENTS", "EglFsKmsSupport"]
+ "eglfs_kms_support",
+ "Qt6",
+ "Qt::EglFsKmsSupportPrivate",
+ components=["EglFsKmsSupportPrivate"],
),
LibraryMapping(
"eglfs_kms_gbm_support",
"Qt6",
- "Qt::EglFsKmsGbmSupport",
- extra=["COMPONENTS", "EglFsKmsGbmSupport"],
+ "Qt::EglFsKmsGbmSupportPrivate",
+ components=["EglFsKmsGbmSupportPrivate"],
),
- LibraryMapping("egl_support", "Qt6", "Qt::EglSupport", extra=["COMPONENTS", "EglSupport"]),
+ LibraryMapping("egl_support", "Qt6", "Qt::EglSupport", components=["EglSupport"]),
# enginio: Not needed in Qt6!
LibraryMapping(
"eventdispatchers",
"Qt6",
"Qt::EventDispatcherSupport",
- extra=["COMPONENTS", "EventDispatcherSupport"],
+ components=["EventDispatcherSupport"],
),
LibraryMapping(
"eventdispatcher_support",
"Qt6",
"Qt::EventDispatcherSupport",
- extra=["COMPONENTS", "EventDispatcherSupport"],
+ components=["EventDispatcherSupport"],
),
- LibraryMapping("fbconvenience", "Qt6", "Qt::FbSupport", extra=["COMPONENTS", "FbSupport"]),
- LibraryMapping("fb_support", "Qt6", "Qt::FbSupport", extra=["COMPONENTS", "FbSupport"]),
+ LibraryMapping("fbconvenience", "Qt6", "Qt::FbSupportPrivate", components=["FbSupportPrivate"]),
+ LibraryMapping("fb_support", "Qt6", "Qt::FbSupportPrivate", components=["FbSupportPrivate"]),
LibraryMapping(
"fontdatabase_support",
"Qt6",
"Qt::FontDatabaseSupport",
- extra=["COMPONENTS", "FontDatabaseSupport"],
+ 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(
- "gsttools", "Qt6", "Qt::MultimediaGstTools", extra=["COMPONENTS", "MultimediaGstTools"]
- ),
- LibraryMapping("gui", "Qt6", "Qt::Gui", extra=["COMPONENTS", "Gui"]),
- LibraryMapping("help", "Qt6", "Qt::Help", extra=["COMPONENTS", "Help"]),
+ LibraryMapping("gamepad", "Qt6", "Qt::Gamepad", components=["Gamepad"]),
+ LibraryMapping("geniviextras", "Qt6", "Qt::GeniviExtras", components=["GeniviExtras"]),
+ LibraryMapping("global", "Qt6", "Qt::Core", components=["Core"]), # manually added special case
+ LibraryMapping("glx_support", "Qt6", "Qt::GlxSupport", components=["GlxSupport"]),
+ LibraryMapping("gsttools", "Qt6", "Qt::MultimediaGstTools", components=["MultimediaGstTools"]),
+ LibraryMapping("gui", "Qt6", "Qt::Gui", components=["Gui"]),
+ LibraryMapping("help", "Qt6", "Qt::Help", 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"]
+ "Qt::HunspellInputMethodPrivate",
+ components=["HunspellInputMethodPrivate"],
),
+ LibraryMapping("input", "Qt6", "Qt::InputSupportPrivate", components=["InputSupportPrivate"]),
LibraryMapping(
- "installer-lib", "Qt6", "Qt::AppManInstaller", extra=["COMPONENTS", "AppManInstaller"]
+ "input_support",
+ "Qt6",
+ "Qt::InputSupportPrivate",
+ components=["InputSupportPrivate"],
),
- 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("installer-lib", "Qt6", "Qt::AppManInstaller", components=["AppManInstaller"]),
+ LibraryMapping("ivi", "Qt6", "Qt::Ivi", components=["Ivi"]),
+ LibraryMapping("ivicore", "Qt6", "Qt::IviCore", components=["IviCore"]),
+ LibraryMapping("ivimedia", "Qt6", "Qt::IviMedia", components=["IviMedia"]),
+ LibraryMapping("knx", "Qt6", "Qt::Knx", components=["Knx"]),
LibraryMapping(
- "launcher-lib", "Qt6", "Qt::AppManLauncher", extra=["COMPONENTS", "AppManLauncher"]
+ "kmsconvenience", "Qt6", "Qt::KmsSupportPrivate", components=["KmsSupportPrivate"]
),
- LibraryMapping("lib", "Qt6", "Qt::Designer", extra=["COMPONENTS", "Designer"]),
+ LibraryMapping("kms_support", "Qt6", "Qt::KmsSupportPrivate", components=["KmsSupportPrivate"]),
+ LibraryMapping("launcher-lib", "Qt6", "Qt::AppManLauncher", components=["AppManLauncher"]),
+ LibraryMapping("lib", "Qt6", "Qt::Designer", components=["Designer"]),
LibraryMapping(
"linuxaccessibility_support",
"Qt6",
"Qt::LinuxAccessibilitySupport",
- extra=["COMPONENTS", "LinuxAccessibilitySupport"],
- ),
- LibraryMapping("location", "Qt6", "Qt::Location", extra=["COMPONENTS", "Location"]),
- 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"]
+ components=["LinuxAccessibilitySupport"],
),
- LibraryMapping("mqtt", "Qt6", "Qt::Mqtt", extra=["COMPONENTS", "Mqtt"]),
- LibraryMapping("multimedia", "Qt6", "Qt::Multimedia", extra=["COMPONENTS", "Multimedia"]),
+ LibraryMapping("location", "Qt6", "Qt::Location", components=["Location"]),
+ LibraryMapping("macextras", "Qt6", "Qt::MacExtras", components=["MacExtras"]),
+ LibraryMapping("main-lib", "Qt6", "Qt::AppManMain", components=["AppManMain"]),
+ LibraryMapping("manager-lib", "Qt6", "Qt::AppManManager", components=["AppManManager"]),
+ LibraryMapping("monitor-lib", "Qt6", "Qt::AppManMonitor", components=["AppManMonitor"]),
+ LibraryMapping("mqtt", "Qt6", "Qt::Mqtt", components=["Mqtt"]),
+ LibraryMapping("multimedia", "Qt6", "Qt::Multimedia", 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("opcua", "Qt6", "Qt::OpcUa", extra=["COMPONENTS", "OpcUa"]),
- LibraryMapping(
- "opcua_private", "Qt6", "Qt::OpcUaPrivate", extra=["COMPONENTS", "OpcUaPrivate"]
- ),
- LibraryMapping("opengl", "Qt6", "Qt::OpenGL", extra=["COMPONENTS", "OpenGL"]),
- LibraryMapping(
- "openglwidgets", "Qt6", "Qt::OpenGLWidgets", extra=["COMPONENTS", "OpenGLWidgets"]
+ components=["MultimediaWidgets"],
+ ),
+ LibraryMapping("network", "Qt6", "Qt::Network", components=["Network"]),
+ LibraryMapping("networkauth", "Qt6", "Qt::NetworkAuth", components=["NetworkAuth"]),
+ LibraryMapping("nfc", "Qt6", "Qt::Nfc", components=["Nfc"]),
+ LibraryMapping("oauth", "Qt6", "Qt::NetworkAuth", components=["NetworkAuth"]),
+ LibraryMapping("opcua", "Qt6", "Qt::OpcUa", components=["OpcUa"]),
+ LibraryMapping("opcua_private", "Qt6", "Qt::OpcUaPrivate", components=["OpcUaPrivate"]),
+ LibraryMapping("opengl", "Qt6", "Qt::OpenGL", components=["OpenGL"]),
+ LibraryMapping("openglwidgets", "Qt6", "Qt::OpenGLWidgets", components=["OpenGLWidgets"]),
+ LibraryMapping("package-lib", "Qt6", "Qt::AppManPackage", components=["AppManPackage"]),
+ LibraryMapping(
+ "packetprotocol",
+ "Qt6",
+ "Qt::PacketProtocolPrivate",
+ components=["PacketProtocolPrivate"],
),
LibraryMapping(
- "package-lib", "Qt6", "Qt::AppManPackage", extra=["COMPONENTS", "AppManPackage"]
+ "particles",
+ "Qt6",
+ "Qt::QuickParticlesPrivate",
+ components=["QuickParticlesPrivate"],
),
LibraryMapping(
- "packetprotocol", "Qt6", "Qt::PacketProtocol", extra=["COMPONENTS", "PacketProtocol"]
+ "plugin-interfaces",
+ "Qt6",
+ "Qt::AppManPluginInterfaces",
+ components=["AppManPluginInterfaces"],
),
+ LibraryMapping("positioning", "Qt6", "Qt::Positioning", components=["Positioning"]),
LibraryMapping(
- "particles", "Qt6", "Qt::QuickParticles", extra=["COMPONENTS", "QuickParticles"]
+ "positioningquick", "Qt6", "Qt::PositioningQuick", components=["PositioningQuick"]
),
+ LibraryMapping("printsupport", "Qt6", "Qt::PrintSupport", components=["PrintSupport"]),
+ LibraryMapping("purchasing", "Qt6", "Qt::Purchasing", components=["Purchasing"]),
+ LibraryMapping("qmldebug", "Qt6", "Qt::QmlDebugPrivate", components=["QmlDebugPrivate"]),
LibraryMapping(
- "plugin-interfaces",
- "Qt6",
- "Qt::AppManPluginInterfaces",
- extra=["COMPONENTS", "AppManPluginInterfaces"],
+ "qmldevtools", "Qt6", "Qt::QmlDevToolsPrivate", components=["QmlDevToolsPrivate"]
),
- LibraryMapping("positioning", "Qt6", "Qt::Positioning", extra=["COMPONENTS", "Positioning"]),
LibraryMapping(
- "positioningquick", "Qt6", "Qt::PositioningQuick", extra=["COMPONENTS", "PositioningQuick"]
+ "qmlcompiler", "Qt6", "Qt::QmlCompilerPrivate", components=["QmlCompilerPrivate"]
),
- 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("qmlcompiler", "Qt6", "Qt::QmlCompiler", extra=["COMPONENTS", "QmlCompiler"]),
- LibraryMapping("qml", "Qt6", "Qt::Qml", extra=["COMPONENTS", "Qml"]),
- LibraryMapping("qmldom", "Qt6", "Qt::QmlDom", extra=["COMPONENTS", "QmlDom"]),
- LibraryMapping("qmlmodels", "Qt6", "Qt::QmlModels", extra=["COMPONENTS", "QmlModels"]),
- LibraryMapping("qmltest", "Qt6", "Qt::QuickTest", extra=["COMPONENTS", "QuickTest"]),
+ LibraryMapping("qml", "Qt6", "Qt::Qml", components=["Qml"]),
+ LibraryMapping("qmldom", "Qt6", "Qt::QmlDomPrivate", components=["QmlDomPrivate"]),
+ LibraryMapping("qmlmodels", "Qt6", "Qt::QmlModels", components=["QmlModels"]),
+ LibraryMapping("qmltest", "Qt6", "Qt::QuickTest", components=["QuickTest"]),
LibraryMapping(
"qtmultimediaquicktools",
"Qt6",
- "Qt::MultimediaQuick",
- extra=["COMPONENTS", "MultimediaQuick"],
+ "Qt::MultimediaQuickPrivate",
+ components=["MultimediaQuickPrivate"],
),
LibraryMapping(
"quick3dassetimport",
"Qt6",
"Qt::Quick3DAssetImport",
- extra=["COMPONENTS", "Quick3DAssetImport"],
- ),
- LibraryMapping("core5compat", "Qt6", "Qt::Core5Compat", extra=["COMPONENTS", "Core5Compat"]),
- LibraryMapping("quick3d", "Qt6", "Qt::Quick3D", extra=["COMPONENTS", "Quick3D"]),
- LibraryMapping(
- "quick3drender", "Qt6", "Qt::Quick3DRender", extra=["COMPONENTS", "Quick3DRender"]
+ components=["Quick3DAssetImport"],
),
+ LibraryMapping("core5compat", "Qt6", "Qt::Core5Compat", components=["Core5Compat"]),
+ LibraryMapping("quick3d", "Qt6", "Qt::Quick3D", components=["Quick3D"]),
+ LibraryMapping("quick3drender", "Qt6", "Qt::Quick3DRender", components=["Quick3DRender"]),
LibraryMapping(
"quick3druntimerender",
"Qt6",
"Qt::Quick3DRuntimeRender",
- extra=["COMPONENTS", "Quick3DRuntimeRender"],
- ),
- LibraryMapping("quick3dutils", "Qt6", "Qt::Quick3DUtils", extra=["COMPONENTS", "Quick3DUtils"]),
- LibraryMapping(
- "quickcontrols2", "Qt6", "Qt::QuickControls2", extra=["COMPONENTS", "QuickControls2"]
+ components=["Quick3DRuntimeRender"],
),
+ LibraryMapping("quick3dutils", "Qt6", "Qt::Quick3DUtils", components=["Quick3DUtils"]),
+ LibraryMapping("quickcontrols2", "Qt6", "Qt::QuickControls2", components=["QuickControls2"]),
LibraryMapping(
"quickcontrols2impl",
"Qt6",
"Qt::QuickControls2Impl",
- extra=["COMPONENTS", "QuickControls2Impl"],
- ),
- 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(
- "remoteobjects", "Qt6", "Qt::RemoteObjects", extra=["COMPONENTS", "RemoteObjects"]
- ),
- LibraryMapping("script", "Qt6", "Qt::Script", extra=["COMPONENTS", "Script"]),
- LibraryMapping("scripttools", "Qt6", "Qt::ScriptTools", extra=["COMPONENTS", "ScriptTools"]),
- LibraryMapping("scxml", "Qt6", "Qt::Scxml", extra=["COMPONENTS", "Scxml"]),
- 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("shadertools", "Qt6", "Qt::ShaderTools", extra=["COMPONENTS", "ShaderTools"]),
- LibraryMapping("statemachine", "Qt6", "Qt::StateMachine", extra=["COMPONENTS", "StateMachine"]),
- LibraryMapping("sql", "Qt6", "Qt::Sql", extra=["COMPONENTS", "Sql"]),
- LibraryMapping("svg", "Qt6", "Qt::Svg", extra=["COMPONENTS", "Svg"]),
- LibraryMapping("svgwidgets", "Qt6", "Qt::SvgWidgets", extra=["COMPONENTS", "SvgWidgets"]),
- LibraryMapping("charts", "Qt6", "Qt::Charts", extra=["COMPONENTS", "Charts"]),
- 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(
- "waylandclient", "Qt6", "Qt::WaylandClient", extra=["COMPONENTS", "WaylandClient"]
- ),
+ components=["QuickControls2Impl"],
+ ),
+ LibraryMapping("quick", "Qt6", "Qt::Quick", components=["Quick"]),
+ LibraryMapping(
+ "quickshapes", "Qt6", "Qt::QuickShapesPrivate", components=["QuickShapesPrivate"]
+ ),
+ LibraryMapping("quicktemplates2", "Qt6", "Qt::QuickTemplates2", components=["QuickTemplates2"]),
+ LibraryMapping("quickwidgets", "Qt6", "Qt::QuickWidgets", components=["QuickWidgets"]),
+ LibraryMapping("remoteobjects", "Qt6", "Qt::RemoteObjects", components=["RemoteObjects"]),
+ LibraryMapping("script", "Qt6", "Qt::Script", components=["Script"]),
+ LibraryMapping("scripttools", "Qt6", "Qt::ScriptTools", components=["ScriptTools"]),
+ LibraryMapping("scxml", "Qt6", "Qt::Scxml", components=["Scxml"]),
+ LibraryMapping("sensors", "Qt6", "Qt::Sensors", components=["Sensors"]),
+ LibraryMapping("serialport", "Qt6", "Qt::SerialPort", components=["SerialPort"]),
+ LibraryMapping("serialbus", "Qt6", "Qt::SerialBus", components=["SerialBus"]),
+ LibraryMapping("services", "Qt6", "Qt::ServiceSupport", components=["ServiceSupport"]),
+ LibraryMapping("service_support", "Qt6", "Qt::ServiceSupport", components=["ServiceSupport"]),
+ LibraryMapping("shadertools", "Qt6", "Qt::ShaderTools", components=["ShaderTools"]),
+ LibraryMapping("statemachine", "Qt6", "Qt::StateMachine", components=["StateMachine"]),
+ LibraryMapping("sql", "Qt6", "Qt::Sql", components=["Sql"]),
+ LibraryMapping("svg", "Qt6", "Qt::Svg", components=["Svg"]),
+ LibraryMapping("svgwidgets", "Qt6", "Qt::SvgWidgets", components=["SvgWidgets"]),
+ LibraryMapping("charts", "Qt6", "Qt::Charts", components=["Charts"]),
+ LibraryMapping("testlib", "Qt6", "Qt::Test", components=["Test"]),
+ LibraryMapping("texttospeech", "Qt6", "Qt::TextToSpeech", components=["TextToSpeech"]),
+ LibraryMapping("theme_support", "Qt6", "Qt::ThemeSupport", components=["ThemeSupport"]),
+ LibraryMapping("tts", "Qt6", "Qt::TextToSpeech", components=["TextToSpeech"]),
+ LibraryMapping("uiplugin", "Qt6", "Qt::UiPlugin", components=["UiPlugin"]),
+ LibraryMapping("uitools", "Qt6", "Qt::UiTools", components=["UiTools"]),
+ LibraryMapping("virtualkeyboard", "Qt6", "Qt::VirtualKeyboard", components=["VirtualKeyboard"]),
+ LibraryMapping("waylandclient", "Qt6", "Qt::WaylandClient", components=["WaylandClient"]),
LibraryMapping(
"waylandcompositor",
"Qt6",
"Qt::WaylandCompositor",
- extra=["COMPONENTS", "WaylandCompositor"],
+ components=["WaylandCompositor"],
),
- LibraryMapping("webchannel", "Qt6", "Qt::WebChannel", extra=["COMPONENTS", "WebChannel"]),
- LibraryMapping("webengine", "Qt6", "Qt::WebEngine", extra=["COMPONENTS", "WebEngine"]),
+ LibraryMapping("webchannel", "Qt6", "Qt::WebChannel", components=["WebChannel"]),
+ LibraryMapping("webengine", "Qt6", "Qt::WebEngine", components=["WebEngine"]),
LibraryMapping(
- "webenginewidgets", "Qt6", "Qt::WebEngineWidgets", extra=["COMPONENTS", "WebEngineWidgets"]
+ "webenginewidgets", "Qt6", "Qt::WebEngineWidgets", 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("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("websockets", "Qt6", "Qt::WebSockets", components=["WebSockets"]),
+ LibraryMapping("webview", "Qt6", "Qt::WebView", components=["WebView"]),
+ LibraryMapping("widgets", "Qt6", "Qt::Widgets", components=["Widgets"]),
+ LibraryMapping("window-lib", "Qt6", "Qt::AppManWindow", components=["AppManWindow"]),
+ LibraryMapping("winextras", "Qt6", "Qt::WinExtras", components=["WinExtras"]),
+ LibraryMapping("x11extras", "Qt6", "Qt::X11Extras", components=["X11Extras"]),
+ LibraryMapping("xcb_qpa_lib", "Qt6", "Qt::XcbQpaPrivate", components=["XcbQpaPrivate"]),
LibraryMapping(
- "xkbcommon_support", "Qt6", "Qt::XkbCommonSupport", extra=["COMPONENTS", "XkbCommonSupport"]
+ "xkbcommon_support", "Qt6", "Qt::XkbCommonSupport", components=["XkbCommonSupport"]
),
- LibraryMapping("xmlpatterns", "Qt6", "Qt::XmlPatterns", extra=["COMPONENTS", "XmlPatterns"]),
- LibraryMapping("xml", "Qt6", "Qt::Xml", extra=["COMPONENTS", "Xml"]),
+ LibraryMapping("xmlpatterns", "Qt6", "Qt::XmlPatterns", components=["XmlPatterns"]),
+ LibraryMapping("xml", "Qt6", "Qt::Xml", components=["Xml"]),
+ LibraryMapping("qmlworkerscript", "Qt6", "Qt::QmlWorkerScript", components=["QmlWorkerScript"]),
LibraryMapping(
- "qmlworkerscript", "Qt6", "Qt::QmlWorkerScript", extra=["COMPONENTS", "QmlWorkerScript"]
- ),
- LibraryMapping(
- "quickparticles", "Qt6", "Qt::QuickParticles", extra=["COMPONENTS", "QuickParticles"]
+ "quickparticles",
+ "Qt6",
+ "Qt::QuickParticlesPrivate",
+ components=["QuickParticlesPrivate"],
),
LibraryMapping(
"linuxofono_support",
"Qt6",
"Qt::LinuxOfonoSupport",
- extra=["COMPONENTS", "LinuxOfonoSupport"],
+ components=["LinuxOfonoSupport"],
),
LibraryMapping(
"linuxofono_support_private",
"Qt6",
"Qt::LinuxOfonoSupportPrivate",
- extra=["COMPONENTS", "LinuxOfonoSupportPrivate"],
- ),
- LibraryMapping("tools", "Qt6", "Qt::Tools", extra=["COMPONENTS", "Tools"]),
- LibraryMapping("axcontainer", "Qt6", "Qt::AxContainer", extra=["COMPONENTS", "AxContainer"]),
- LibraryMapping(
- "webkitwidgets", "Qt6", "Qt::WebKitWidgets", extra=["COMPONENTS", "WebKitWidgets"]
- ),
- LibraryMapping("zlib", "Qt6", "Qt::Zlib", extra=["COMPONENTS", "Zlib"]),
- LibraryMapping("httpserver", "Qt6", "Qt::HttpServer", extra=["COMPONENTS", "HttpServer"]),
- LibraryMapping("sslserver", "Qt6", "Qt::SslServer", extra=["COMPONENTS", "HttpServer"]),
+ components=["LinuxOfonoSupportPrivate"],
+ ),
+ LibraryMapping("tools", "Qt6", "Qt::Tools", components=["Tools"]),
+ LibraryMapping("axcontainer", "Qt6", "Qt::AxContainer", components=["AxContainer"]),
+ LibraryMapping("webkitwidgets", "Qt6", "Qt::WebKitWidgets", components=["WebKitWidgets"]),
+ LibraryMapping("zlib", "Qt6", "Qt::Zlib", components=["Zlib"]),
+ LibraryMapping("httpserver", "Qt6", "Qt::HttpServer", components=["HttpServer"]),
+ LibraryMapping("sslserver", "Qt6", "Qt::SslServer", components=["HttpServer"]),
]
# Note that the library map is adjusted dynamically further down.
_library_map = [
# 3rd party:
LibraryMapping("atspi", "ATSPI2", "PkgConfig::ATSPI2"),
+ LibraryMapping(
+ "backtrace", "WrapBacktrace", "WrapBacktrace::WrapBacktrace", emit_if="config.unix"
+ ),
LibraryMapping("bluez", "BlueZ", "PkgConfig::BlueZ"),
LibraryMapping("brotli", "WrapBrotli", "WrapBrotli::WrapBrotliDec"),
LibraryMapping("corewlan", None, None),
@@ -406,8 +365,10 @@ _library_map = [
LibraryMapping("db2", "DB2", "DB2::DB2"),
LibraryMapping("dbus", "WrapDBus1", "dbus-1", resultVariable="DBus1", extra=["1.2"]),
LibraryMapping(
- "doubleconversion", "WrapDoubleConversion", "WrapDoubleConversion::WrapDoubleConversion"
+ "doubleconversion", "WrapSystemDoubleConversion",
+ "WrapSystemDoubleConversion::WrapSystemDoubleConversion"
),
+ LibraryMapping("dlt", "DLT", "DLT::DLT"),
LibraryMapping("drm", "Libdrm", "Libdrm::Libdrm"),
LibraryMapping("egl", "EGL", "EGL::EGL"),
LibraryMapping("flite", "Flite", "Flite::Flite"),
@@ -435,9 +396,7 @@ _library_map = [
extra=["2.6.0"],
),
LibraryMapping("host_dbus", None, None),
- LibraryMapping(
- "icu", "ICU", "ICU::i18n ICU::uc ICU::data", extra=["COMPONENTS", "i18n", "uc", "data"]
- ),
+ LibraryMapping("icu", "ICU", "ICU::i18n ICU::uc ICU::data", components=["i18n", "uc", "data"]),
LibraryMapping("journald", "Libsystemd", "PkgConfig::Libsystemd"),
LibraryMapping("jpeg", "JPEG", "JPEG::JPEG"), # see also libjpeg
LibraryMapping("libatomic", "WrapAtomic", "WrapAtomic::WrapAtomic"),
@@ -451,6 +410,7 @@ _library_map = [
LibraryMapping("librt", "WrapRt", "WrapRt::WrapRt"),
LibraryMapping("libudev", "Libudev", "PkgConfig::Libudev"),
LibraryMapping("lttng-ust", "LTTngUST", "LTTng::UST", resultVariable="LTTNGUST"),
+ LibraryMapping("libmd4c", "WrapMd4c", "WrapMd4c::WrapMd4c", is_bundled_with_qt=True),
LibraryMapping("mtdev", "Mtdev", "PkgConfig::Mtdev"),
LibraryMapping("mysql", "MySQL", "MySQL::MySQL"),
LibraryMapping("odbc", "ODBC", "ODBC::ODBC"),
@@ -489,10 +449,13 @@ _library_map = [
LibraryMapping("sqlite2", None, None), # No more sqlite2 support in Qt6!
LibraryMapping("sqlite3", "SQLite3", "SQLite::SQLite3"),
LibraryMapping("sqlite", "SQLite3", "SQLite::SQLite3"),
+ LibraryMapping(
+ "taglib", "WrapTagLib", "WrapTagLib::WrapTagLib", is_bundled_with_qt=True
+ ), # used in qtivi
LibraryMapping("tslib", "Tslib", "PkgConfig::Tslib"),
LibraryMapping("udev", "Libudev", "PkgConfig::Libudev"),
LibraryMapping("udev", "Libudev", "PkgConfig::Libudev"), # see also libudev!
- LibraryMapping("vulkan", "Vulkan", "Vulkan::Vulkan"),
+ LibraryMapping("vulkan", "WrapVulkanHeaders", "WrapVulkanHeaders::WrapVulkanHeaders"),
LibraryMapping("wayland_server", "Wayland", "Wayland::Server"), # used in qtbase/src/gui
LibraryMapping("wayland-server", "Wayland", "Wayland::Server"), # used in qtwayland
LibraryMapping("wayland-client", "Wayland", "Wayland::Client"),
@@ -511,61 +474,66 @@ _library_map = [
resultVariable="TARGET XCB::XCB",
appendFoundSuffix=False,
),
+ LibraryMapping("xcb_glx", "XCB", "XCB::GLX", components=["GLX"], resultVariable="XCB_GLX"),
LibraryMapping(
- "xcb_glx", "XCB", "XCB::GLX", extra=["COMPONENTS", "GLX"], resultVariable="XCB_GLX"
+ "xcb_cursor",
+ "XCB",
+ "XCB::CURSOR",
+ extra=["0.1.1", "COMPONENTS", "CURSOR"],
+ resultVariable="XCB_CURSOR",
),
LibraryMapping(
"xcb_icccm",
"XCB",
"XCB::ICCCM",
- extra=["0.3.9", "COMPONENTS", "ICCCM"],
+ extra=["0.3.9"],
+ components=["ICCCM"],
resultVariable="XCB_ICCCM",
),
LibraryMapping(
"xcb_image",
"XCB",
"XCB::IMAGE",
- extra=["0.3.9", "COMPONENTS", "IMAGE"],
+ extra=["0.3.9"],
+ components=["IMAGE"],
resultVariable="XCB_IMAGE",
),
LibraryMapping(
"xcb_keysyms",
"XCB",
"XCB::KEYSYMS",
- extra=["0.3.9", "COMPONENTS", "KEYSYMS"],
+ extra=["0.3.9"],
+ components=["KEYSYMS"],
resultVariable="XCB_KEYSYMS",
),
LibraryMapping(
- "xcb_randr", "XCB", "XCB::RANDR", extra=["COMPONENTS", "RANDR"], resultVariable="XCB_RANDR"
+ "xcb_randr", "XCB", "XCB::RANDR", components=["RANDR"], resultVariable="XCB_RANDR"
),
LibraryMapping(
"xcb_render",
"XCB",
"XCB::RENDER",
- extra=["COMPONENTS", "RENDER"],
+ components=["RENDER"],
resultVariable="XCB_RENDER",
),
LibraryMapping(
"xcb_renderutil",
"XCB",
"XCB::RENDERUTIL",
- extra=["0.3.9", "COMPONENTS", "RENDERUTIL"],
+ extra=["0.3.9"],
+ 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"
+ "xcb_shape", "XCB", "XCB::SHAPE", components=["SHAPE"], resultVariable="XCB_SHAPE"
),
+ LibraryMapping("xcb_shm", "XCB", "XCB::SHM", components=["SHM"], resultVariable="XCB_SHM"),
+ LibraryMapping("xcb_sync", "XCB", "XCB::SYNC", components=["SYNC"], resultVariable="XCB_SYNC"),
LibraryMapping(
"xcb_xfixes",
"XCB",
"XCB::XFIXES",
- extra=["COMPONENTS", "XFIXES"],
+ components=["XFIXES"],
resultVariable="TARGET XCB::XFIXES",
appendFoundSuffix=False,
),
@@ -573,7 +541,7 @@ _library_map = [
"xcb-xfixes",
"XCB",
"XCB::XFIXES",
- extra=["COMPONENTS", "XFIXES"],
+ components=["XFIXES"],
resultVariable="TARGET XCB::XFIXES",
appendFoundSuffix=False,
),
@@ -581,12 +549,11 @@ _library_map = [
"xcb_xinput",
"XCB",
"XCB::XINPUT",
- extra=["1.12", "COMPONENTS", "XINPUT"],
+ extra=["1.12"],
+ components=["XINPUT"],
resultVariable="XCB_XINPUT",
),
- LibraryMapping(
- "xcb_xkb", "XCB", "XCB::XKB", extra=["COMPONENTS", "XKB"], resultVariable="XCB_XKB"
- ),
+ LibraryMapping("xcb_xkb", "XCB", "XCB::XKB", components=["XKB"], resultVariable="XCB_XKB"),
LibraryMapping("xcb_xlib", "X11_XCB", "X11::XCB"),
LibraryMapping("xcomposite", "XComposite", "PkgConfig::XComposite"),
LibraryMapping("xkbcommon_evdev", "XKB", "XKB::XKB", extra=["0.5.0"]), # see also xkbcommon
@@ -594,8 +561,8 @@ _library_map = [
LibraryMapping("xkbcommon", "XKB", "XKB::XKB", extra=["0.5.0"]),
LibraryMapping("xlib", "X11", "X11::X11"),
LibraryMapping("xrender", "XRender", "PkgConfig::XRender", extra=["0.6"]),
- LibraryMapping("zlib", "ZLIB", "ZLIB::ZLIB", extra=["1.0.8"]),
- LibraryMapping("zstd", "ZSTD", "ZSTD::ZSTD", extra=["1.3"]),
+ LibraryMapping("zlib", "WrapZLIB", "WrapZLIB::WrapZLIB", extra=["1.0.8"]),
+ LibraryMapping("zstd", "WrapZSTD", "WrapZSTD::WrapZSTD", extra=["1.3"]),
LibraryMapping("tiff", "TIFF", "TIFF::TIFF"),
LibraryMapping("webp", "WrapWebP", "WrapWebP::WrapWebP"),
LibraryMapping("jasper", "WrapJasper", "WrapJasper::WrapJasper"),
@@ -624,14 +591,18 @@ _library_map = [
def _adjust_library_map():
- # Assign a Linux condition on all x and wayland related packages.
+ # Assign a Linux condition on all wayland related packages.
+ # Assign platforms that have X11 condition on all X11 related packages.
# 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 = ["wayland"]
+ x11_package_prefixes = ["xcb", "x11", "xkb", "xrender", "xlib"]
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"
+ if any([_library_map[i].soName.startswith(p) for p in x11_package_prefixes]):
+ _library_map[i].emit_if = "X11_SUPPORTED"
_adjust_library_map()
@@ -669,7 +640,7 @@ def find_library_info_for_target(targetName: str) -> typing.Optional[LibraryMapp
# For a given qmake library (e.g. 'openssl_headers'), check whether this is a fake library used
# for the /nolink annotation, and return the actual annotated qmake library ('openssl/nolink').
-def find_annotated_qmake_lib_name(lib : str) -> str:
+def find_annotated_qmake_lib_name(lib: str) -> str:
for entry in _library_map:
if entry.no_link_so_name == lib:
return entry.soName + "/nolink"
@@ -708,9 +679,7 @@ platform_mapping = {
"qnx": "QNX",
"vxworks": "VXWORKS",
"hpux": "HPUX",
- "nacl": "NACL",
"android": "ANDROID",
- "android-embedded": "ANDROID_EMBEDDED",
"uikit": "UIKIT",
"tvos": "TVOS",
"watchos": "WATCHOS",
@@ -737,7 +706,7 @@ platform_mapping = {
def map_platform(platform: str) -> str:
- """ Return the qmake platform as cmake platform or the unchanged string. """
+ """Return the qmake platform as cmake platform or the unchanged string."""
return platform_mapping.get(platform, platform)
@@ -799,15 +768,21 @@ def generate_find_package_info(
indent: int = 0,
emit_if: str = "",
use_system_package_name: bool = False,
+ remove_REQUIRED_from_extra: bool = True,
+ components_required: bool = True,
module: str = "",
) -> str:
isRequired = False
extra = lib.extra.copy()
+ if lib.components:
+ extra.append("COMPONENTS" if components_required else "OPTIONAL_COMPONENTS")
+ extra += lib.components
if "REQUIRED" in extra and use_qt_find_package:
isRequired = True
- extra.remove("REQUIRED")
+ if remove_REQUIRED_from_extra:
+ extra.remove("REQUIRED")
cmake_target_name = lib.targetName
assert cmake_target_name
@@ -879,6 +854,15 @@ def _set_up_py_parsing_nicer_debug_output(pp):
return wrapper_function
- pp._defaultStartDebugAction = increase_indent(pp._defaultStartDebugAction)
- pp._defaultSuccessDebugAction = decrease_indent(pp._defaultSuccessDebugAction)
- pp._defaultExceptionDebugAction = decrease_indent(pp._defaultExceptionDebugAction)
+ if hasattr(pp, "_defaultStartDebugAction"):
+ pp._defaultStartDebugAction = increase_indent(pp._defaultStartDebugAction)
+ pp._defaultSuccessDebugAction = decrease_indent(pp._defaultSuccessDebugAction)
+ pp._defaultExceptionDebugAction = decrease_indent(pp._defaultExceptionDebugAction)
+ elif hasattr(pp.core, "_default_start_debug_action"):
+ pp.core._default_start_debug_action = increase_indent(pp.core._default_start_debug_action)
+ pp.core._default_success_debug_action = decrease_indent(
+ pp.core._default_success_debug_action
+ )
+ pp.core._default_exception_debug_action = decrease_indent(
+ pp.core._default_exception_debug_action
+ )
diff --git a/util/cmake/json_parser.py b/util/cmake/json_parser.py
index a0aaecab9d..f8e0fa6017 100644
--- a/util/cmake/json_parser.py
+++ b/util/cmake/json_parser.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2019 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import pyparsing as pp # type: ignore
import json
diff --git a/util/cmake/pro2cmake.py b/util/cmake/pro2cmake.py
index 601947285b..0ef35410ce 100755
--- a/util/cmake/pro2cmake.py
+++ b/util/cmake/pro2cmake.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
# Requires Python 3.7. The import statement needs to be the first line of code
@@ -39,6 +14,7 @@ import posixpath
import sys
import re
import io
+import itertools
import glob
import fnmatch
@@ -81,9 +57,8 @@ from helper import (
LibraryMapping,
)
-
cmake_version_string = "3.16"
-cmake_api_version = 2
+cmake_api_version = 3
def _parse_commandline():
@@ -135,7 +110,13 @@ def _parse_commandline():
"--is-example",
action="store_true",
dest="is_example",
- help="Treat the input .pro file as an example.",
+ help="Treat the input .pro file as a Qt example.",
+ )
+ parser.add_argument(
+ "--is-user-project",
+ action="store_true",
+ dest="is_user_project",
+ help="Treat the input .pro file as a user project.",
)
parser.add_argument(
"-s",
@@ -179,7 +160,7 @@ def _parse_commandline():
"--api-version",
dest="api_version",
type=int,
- help="Specify which cmake api version should be generated. 1 or 2, 2 is latest.",
+ help="Specify which cmake api version should be generated. 1, 2 or 3, 3 is latest.",
)
parser.add_argument(
@@ -202,102 +183,128 @@ def _parse_commandline():
def get_top_level_repo_project_path(project_file_path: str = "") -> str:
- qmake_conf_path = find_qmake_conf(project_file_path)
- qmake_conf_dir_path = os.path.dirname(qmake_conf_path)
- return qmake_conf_dir_path
+ qmake_or_cmake_conf_path = find_qmake_or_cmake_conf(project_file_path)
+ qmake_or_cmake_conf_dir_path = os.path.dirname(qmake_or_cmake_conf_path)
+ return qmake_or_cmake_conf_dir_path
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)
+ qmake_or_cmake_conf_path = find_qmake_or_cmake_conf(project_file_path)
+ qmake_or_cmake_conf_dir_path = os.path.dirname(qmake_or_cmake_conf_path)
project_dir_path = os.path.dirname(project_file_path)
- return qmake_conf_dir_path == project_dir_path
+ return qmake_or_cmake_conf_dir_path == project_dir_path
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)
+ qmake_or_cmake_conf_path = find_qmake_or_cmake_conf(project_file_path)
+ qmake_or_cmake_conf_dir_path = os.path.dirname(qmake_or_cmake_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)
return (
- qmake_conf_dir_path == normalized_maybe_same_level_dir_path and project_dir_name == "tests"
+ qmake_or_cmake_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:
- qmake_conf_path = find_qmake_conf(project_file_path)
- qmake_conf_dir_path = os.path.dirname(qmake_conf_path)
+ qmake_or_cmake_conf_path = find_qmake_or_cmake_conf(project_file_path)
+ qmake_or_cmake_conf_dir_path = os.path.dirname(qmake_or_cmake_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)
return (
- qmake_conf_dir_path == normalized_maybe_same_level_dir_path
+ qmake_or_cmake_conf_dir_path == normalized_maybe_same_level_dir_path
and project_dir_name == "examples"
)
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)
+ # If there's a .qmake.conf or .cmake.conf file in the parent
+ # directories of the given project path, it is likely that the
+ # project is an internal Qt project that uses private Qt CMake
+ # API.
+ found_qt_repo_version = False
+ qmake_conf = find_qmake_conf(project_file_path)
+ if qmake_conf:
+ repo_version = parse_qt_repo_module_version_from_qmake_conf(qmake_conf)
+ if repo_version:
+ found_qt_repo_version = True
+
+ cmake_conf = find_cmake_conf(project_file_path)
+ if cmake_conf:
+ repo_version = parse_qt_repo_module_version_from_cmake_conf(cmake_conf)
+ if repo_version:
+ found_qt_repo_version = True
+
+ # If we haven't found a conf file, we assume this is an example
+ # project and not a project under a qt source repository.
+ if not found_qt_repo_version:
+ return True
- 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, but
# some examples contain 3rdparty libraries that do not need to be
# built as examples.
- return project_relative_path.startswith("examples") and "3rdparty" not in project_relative_path
+ qmake_or_cmake_conf_path = find_qmake_or_cmake_conf(project_file_path)
+ qmake_or_cmake_conf_dir_path = os.path.dirname(qmake_or_cmake_conf_path)
+ project_relative_path = os.path.relpath(project_file_path, qmake_or_cmake_conf_dir_path)
+
+ is_example_under_repo_sources = (
+ project_relative_path.startswith("examples") and "3rdparty" not in project_relative_path
+ )
+ return is_example_under_repo_sources
def is_config_test_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)
- dir_name_with_qmake_confg = os.path.basename(qmake_conf_dir_path)
+ qmake_or_cmake_conf_path = find_qmake_or_cmake_conf(project_file_path)
+ qmake_or_cmake_conf_dir_path = os.path.dirname(qmake_or_cmake_conf_path)
+ dir_name_with_qmake_or_cmake_conf = os.path.basename(qmake_or_cmake_conf_dir_path)
- project_relative_path = os.path.relpath(project_file_path, qmake_conf_dir_path)
+ project_relative_path = os.path.relpath(project_file_path, qmake_or_cmake_conf_dir_path)
# If the project file is found in a subdir called 'config.tests'
# relative to the repo source dir, then it's probably a config test.
# Also if the .qmake.conf is found within config.tests dir (like in qtbase)
# then the project is probably a config .test
return (
project_relative_path.startswith("config.tests")
- or dir_name_with_qmake_confg == "config.tests"
+ or dir_name_with_qmake_or_cmake_conf == "config.tests"
)
def is_benchmark_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)
+ qmake_or_cmake_conf_path = find_qmake_or_cmake_conf(project_file_path)
+ qmake_or_cmake_conf_dir_path = os.path.dirname(qmake_or_cmake_conf_path)
- project_relative_path = os.path.relpath(project_file_path, qmake_conf_dir_path)
+ project_relative_path = os.path.relpath(project_file_path, qmake_or_cmake_conf_dir_path)
# If the project file is found in a subdir called 'tests/benchmarks'
# relative to the repo source dir, then it must be a benchmark
return project_relative_path.startswith("tests/benchmarks")
def is_manual_test_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)
+ qmake_or_cmake_conf_path = find_qmake_or_cmake_conf(project_file_path)
+ qmake_or_cmake_conf_dir_path = os.path.dirname(qmake_or_cmake_conf_path)
- project_relative_path = os.path.relpath(project_file_path, qmake_conf_dir_path)
+ project_relative_path = os.path.relpath(project_file_path, qmake_or_cmake_conf_dir_path)
# If the project file is found in a subdir called 'tests/manual'
# relative to the repo source dir, then it must be a manual test
return project_relative_path.startswith("tests/manual")
@lru_cache(maxsize=None)
-def find_qmake_conf(project_file_path: str = "") -> str:
+def find_file_walking_parent_dirs(file_name: str, project_file_path: str = "") -> str:
+ assert file_name
if not os.path.isabs(project_file_path):
print(
- f"Warning: could not find .qmake.conf file, given path is not an "
+ f"Warning: could not find {file_name} file, given path is not an "
f"absolute path: {project_file_path}"
)
return ""
cwd = os.path.dirname(project_file_path)
- file_name = ".qmake.conf"
while os.path.isdir(cwd):
maybe_file = posixpath.join(cwd, file_name)
@@ -310,10 +317,39 @@ def find_qmake_conf(project_file_path: str = "") -> str:
# reached the top level directory, stop looking
break
- print(f"Warning: could not find .qmake.conf file")
return ""
+def find_qmake_conf(project_file_path: str = "") -> str:
+ return find_file_walking_parent_dirs(".qmake.conf", project_file_path)
+
+
+def find_cmake_conf(project_file_path: str = "") -> str:
+ return find_file_walking_parent_dirs(".cmake.conf", project_file_path)
+
+
+def find_qmake_or_cmake_conf(project_file_path: str = "") -> str:
+ qmake_conf = find_qmake_conf(project_file_path)
+ if qmake_conf:
+ return qmake_conf
+ cmake_conf = find_cmake_conf(project_file_path)
+ return cmake_conf
+
+
+def parse_qt_repo_module_version_from_qmake_conf(qmake_conf_path: str = "") -> str:
+ with open(qmake_conf_path) as f:
+ file_contents = f.read()
+ m = re.search(r"MODULE_VERSION\s*=\s*([0-9.]+)", file_contents)
+ return m.group(1) if m else ""
+
+
+def parse_qt_repo_module_version_from_cmake_conf(cmake_conf_path: str = "") -> str:
+ with open(cmake_conf_path) as f:
+ file_contents = f.read()
+ m = re.search(r'set\(QT_REPO_MODULE_VERSION\s*"([0-9.]+)"\)', file_contents)
+ return m.group(1) if m else ""
+
+
def set_up_cmake_api_calls():
def nested_dict():
return defaultdict(nested_dict)
@@ -423,25 +459,40 @@ def get_cmake_api_call(api_name: str, api_version: Optional[int] = None) -> str:
return cmake_api_calls[api_version][api_name]
-def process_qrc_file(
- target: str,
- scope: Scope,
+class QtResource:
+ def __init__(
+ self,
+ name: str = "",
+ prefix: str = "",
+ base_dir: str = "",
+ files: Dict[str, str] = {},
+ lang: str = None,
+ generated: bool = False,
+ skip_qtquick_compiler: bool = False,
+ ) -> None:
+ self.name = name
+ self.prefix = prefix
+ self.base_dir = base_dir
+ self.files = files
+ self.lang = lang
+ self.generated = generated
+ self.skip_qtquick_compiler = skip_qtquick_compiler
+
+
+def read_qrc_file(
filepath: str,
base_dir: str = "",
project_file_path: str = "",
skip_qtquick_compiler: bool = False,
- is_example: bool = False,
-) -> str:
- assert target
-
+) -> List[QtResource]:
# 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}"
if qt_source_tree_literal in filepath:
- qmake_conf = find_qmake_conf(project_file_path)
+ qmake_or_cmake_conf = find_qmake_or_cmake_conf(project_file_path)
- if qmake_conf:
- qt_source_tree = os.path.dirname(qmake_conf)
+ if qmake_or_cmake_conf:
+ qt_source_tree = os.path.dirname(qmake_or_cmake_conf)
filepath = filepath.replace(qt_source_tree_literal, qt_source_tree)
else:
print(
@@ -455,7 +506,6 @@ def process_qrc_file(
# 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("..")
if not os.path.isfile(filepath):
raise RuntimeError(f"Invalid file path given to process_qrc_file: {filepath}")
@@ -463,81 +513,50 @@ def process_qrc_file(
root = tree.getroot()
assert root.tag == "RCC"
- output = ""
-
- resource_count = 0
+ result: List[QtResource] = []
for resource in root:
assert resource.tag == "qresource"
- lang = resource.get("lang", "")
- prefix = resource.get("prefix", "/")
- if not prefix.startswith("/"):
- prefix = f"/{prefix}"
+ r = QtResource(
+ name=resource_name,
+ prefix=resource.get("prefix", "/"),
+ base_dir=base_dir,
+ lang=resource.get("lang", ""),
+ skip_qtquick_compiler=skip_qtquick_compiler,
+ )
+
+ if len(result) > 0:
+ r.name += str(len(result))
- full_resource_name = resource_name + (str(resource_count) if resource_count > 0 else "")
+ if not r.prefix.startswith("/"):
+ r.prefix = f"/{r.prefix}"
- files: Dict[str, str] = {}
for file in resource:
path = file.text
assert path
# 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
- if not alias and is_parent_path:
- alias = path
- files[path] = alias
-
- output += write_add_qt_resource_call(
- target,
- scope,
- full_resource_name,
- prefix,
- base_dir,
- lang,
- files,
- skip_qtquick_compiler,
- is_example,
- )
- resource_count += 1
+ r.files[path] = alias
- return output
+ result.append(r)
+ return result
-def write_add_qt_resource_call(
- target: str,
- scope: Scope,
- resource_name: str,
- prefix: Optional[str],
- base_dir: str,
- lang: Optional[str],
- files: Dict[str, str],
- skip_qtquick_compiler: bool,
- is_example: bool,
+
+def write_resource_source_file_properties(
+ sorted_files: List[str], files: Dict[str, str], base_dir: str, skip_qtquick_compiler: bool
) -> str:
output = ""
-
- sorted_files = sorted(files.keys())
-
- assert sorted_files
-
- if base_dir:
- base_dir_expanded = scope.expandString(base_dir)
- if base_dir_expanded:
- base_dir = base_dir_expanded
-
source_file_properties = defaultdict(list)
for source in sorted_files:
- full_source = posixpath.join(base_dir, source)
alias = files[source]
if alias:
- source_file_properties[full_source].append(f'QT_RESOURCE_ALIAS "{alias}"')
+ source_file_properties[source].append(f'QT_RESOURCE_ALIAS "{alias}"')
# If a base dir is given, we have to write the source file property
# assignments that disable the quick compiler per file.
if base_dir and skip_qtquick_compiler:
- source_file_properties[full_source].append("QT_SKIP_QUICKCOMPILER 1")
+ source_file_properties[source].append("QT_SKIP_QUICKCOMPILER 1")
for full_source in source_file_properties:
per_file_props = source_file_properties[full_source]
@@ -552,6 +571,39 @@ def write_add_qt_resource_call(
"""
)
+ return output
+
+
+def write_add_qt_resource_call(
+ target: str,
+ scope: Scope,
+ resource_name: str,
+ prefix: Optional[str],
+ base_dir: str,
+ lang: Optional[str],
+ files: Dict[str, str],
+ skip_qtquick_compiler: bool,
+ is_example: bool,
+) -> str:
+ output = ""
+
+ if base_dir:
+ base_dir_expanded = scope.expandString(base_dir)
+ if base_dir_expanded:
+ base_dir = base_dir_expanded
+ new_files = {}
+ for file_path, alias in files.items():
+ full_file_path = posixpath.join(base_dir, file_path)
+ new_files[full_file_path] = alias
+ files = new_files
+
+ sorted_files = sorted(files.keys())
+ assert sorted_files
+
+ output += write_resource_source_file_properties(
+ sorted_files, files, base_dir, skip_qtquick_compiler
+ )
+
# Quote file paths in case there are spaces.
sorted_files_backup = sorted_files
sorted_files = []
@@ -1349,9 +1401,9 @@ class Scope(object):
relative_path = posixpath.relpath(self.currentdir, self.basedir)
if key == "QQC2_SOURCE_TREE":
- qmake_conf_path = find_qmake_conf(os.path.abspath(self.currentdir))
- qmake_conf_dir_path = os.path.dirname(qmake_conf_path)
- project_relative_path = os.path.relpath(qmake_conf_dir_path, self.currentdir)
+ qmake_or_cmake_conf_path = find_qmake_or_cmake_conf(os.path.abspath(self.currentdir))
+ qmake_or_cmake_conf_dir_path = os.path.dirname(qmake_or_cmake_conf_path)
+ project_relative_path = os.path.relpath(qmake_or_cmake_conf_dir_path, self.currentdir)
return ["${CMAKE_CURRENT_SOURCE_DIR}/" + project_relative_path]
if key == "QT_ARCH":
@@ -1597,6 +1649,28 @@ def map_condition(condition: str) -> str:
pattern = r"(equals|greaterThan|lessThan)\(WINDOWS_SDK_VERSION,[ ]*([0-9]+)\)"
condition = re.sub(pattern, windows_sdk_version_handler, condition)
+ def qt_version_handler(match_obj: Match):
+ operator = match_obj.group(1)
+ if operator == "equals":
+ operator = "EQUAL"
+ elif operator == "greaterThan":
+ operator = "GREATER"
+ elif operator == "lessThan":
+ operator = "LESS"
+
+ operator_prefix = "VERSION_"
+ version_variable = "QT_VERSION"
+ version_flavor = match_obj.group(2)
+ if version_flavor:
+ version_variable += "_" + version_flavor[:-1]
+ operator_prefix = ""
+
+ version = match_obj.group(3)
+ return f"({version_variable} {operator_prefix}{operator} {version})"
+
+ pattern = r"(equals|greaterThan|lessThan)\(QT_(MAJOR_|MINOR_|PATCH_)?VERSION,[ ]*([0-9.]+)\)"
+ condition = re.sub(pattern, qt_version_handler, condition)
+
# Generic lessThan|equals|lessThan()
def generic_version_handler(match_obj: Match):
@@ -1720,7 +1794,7 @@ _path_replacements = {
def replace_path_constants(path: str, scope: Scope) -> str:
- """ Clean up DESTDIR and target.path """
+ """Clean up DESTDIR and target.path"""
if path.startswith("./"):
path = f"${{CMAKE_CURRENT_BINARY_DIR}}/{path[2:]}"
elif path.startswith("../"):
@@ -1732,7 +1806,12 @@ def replace_path_constants(path: str, scope: Scope) -> str:
def handle_subdir(
- scope: Scope, cm_fh: IO[str], *, indent: int = 0, is_example: bool = False
+ scope: Scope,
+ cm_fh: IO[str],
+ *,
+ indent: int = 0,
+ is_example: bool = False,
+ is_user_project: bool = False,
) -> None:
# Global nested dictionary that will contain sub_dir assignments and their conditions.
@@ -1797,7 +1876,13 @@ def handle_subdir(
)
do_include(subdir_scope)
- cmakeify_scope(subdir_scope, cm_fh, indent=indent, is_example=is_example)
+ cmakeify_scope(
+ subdir_scope,
+ cm_fh,
+ indent=indent,
+ is_example=is_example,
+ is_user_project=is_user_project,
+ )
else:
print(f" XXXX: SUBDIR {sd} in {scope}: Not found.")
@@ -2399,48 +2484,44 @@ def expand_resource_glob(cm_fh: IO[str], expression: str) -> str:
return expanded_var
-def write_resources(
- cm_fh: IO[str],
+def extract_resources(
target: str,
scope: Scope,
- indent: int = 0,
- is_example=False,
- target_ref: str = None,
-):
- if target_ref is None:
- target_ref = target
- # vpath = scope.expand('VPATH')
+) -> Tuple[List[QtResource], List[str]]:
+ """Read the resources of the given scope.
+ Return a tuple:
+ - list of QtResource objects
+ - list of standalone sources files that are marked as QTQUICK_COMPILER_SKIPPED_RESOURCES"""
+
+ resource_infos: List[QtResource] = []
+ skipped_standalone_files: List[str] = []
- # Handle QRC files by turning them into qt_add_resource:
resources = scope.get_files("RESOURCES")
qtquickcompiler_skipped = scope.get_files("QTQUICK_COMPILER_SKIPPED_RESOURCES")
- qrc_output = ""
if resources:
standalone_files: List[str] = []
for r in resources:
skip_qtquick_compiler = r in qtquickcompiler_skipped
if r.endswith(".qrc"):
if "${CMAKE_CURRENT_BINARY_DIR}" in r:
- cm_fh.write(f"#### Ignored generated resource: {r}")
+ resource_infos.append(
+ QtResource(
+ name=r, generated=True, skip_qtquick_compiler=skip_qtquick_compiler
+ )
+ )
continue
- qrc_output += process_qrc_file(
- target_ref,
- scope,
+ resource_infos += read_qrc_file(
r,
scope.basedir,
scope.file_absolute_path,
- skip_qtquick_compiler,
- is_example,
+ skip_qtquick_compiler=skip_qtquick_compiler,
)
else:
immediate_files = {f: "" for f in scope.get_files(f"{r}.files")}
if immediate_files:
immediate_files_filtered = []
for f in immediate_files:
- if "*" in f:
- immediate_files_filtered.append(expand_resource_glob(cm_fh, f))
- else:
- immediate_files_filtered.append(f)
+ immediate_files_filtered.append(f)
immediate_files = {f: "" for f in immediate_files_filtered}
scope_prefix = scope.get(f"{r}.prefix")
if scope_prefix:
@@ -2450,50 +2531,74 @@ def write_resources(
immediate_base_list = scope.get(f"{r}.base")
assert (
len(immediate_base_list) < 2
- ), f"immediate base directory must be at most one entry"
+ ), "immediate base directory must be at most one entry"
immediate_base = replace_path_constants("".join(immediate_base_list), scope)
immediate_lang = None
immediate_name = f"qmake_{r}"
- qrc_output += write_add_qt_resource_call(
- target=target_ref,
- scope=scope,
- resource_name=immediate_name,
- prefix=immediate_prefix,
- base_dir=immediate_base,
- lang=immediate_lang,
- files=immediate_files,
- skip_qtquick_compiler=skip_qtquick_compiler,
- is_example=is_example,
+ resource_infos.append(
+ QtResource(
+ name=immediate_name,
+ prefix=immediate_prefix,
+ base_dir=immediate_base,
+ lang=immediate_lang,
+ files=immediate_files,
+ skip_qtquick_compiler=skip_qtquick_compiler,
+ )
)
else:
- if "*" in r:
- standalone_files.append(expand_resource_glob(cm_fh, r))
- else:
- # stadalone source file properties need to be set as they
- # are parsed.
- if skip_qtquick_compiler:
- qrc_output += (
- f'set_source_files_properties("{r}" PROPERTIES '
- f"QT_SKIP_QUICKCOMPILER 1)\n\n"
- )
- standalone_files.append(r)
+ standalone_files.append(r)
+ if not ("*" in r) and skip_qtquick_compiler:
+ skipped_standalone_files.append(r)
if standalone_files:
- name = "qmake_immediate"
- prefix = "/"
- base = ""
- lang = None
- files = {f: "" for f in standalone_files}
- qrc_output += write_add_qt_resource_call(
- target=target_ref,
- scope=scope,
- resource_name=name,
- prefix=prefix,
- base_dir=base,
- lang=lang,
- files=files,
- skip_qtquick_compiler=False,
- is_example=is_example,
+ resource_infos.append(
+ QtResource(
+ name="qmake_immediate",
+ prefix="/",
+ base_dir="",
+ files={f: "" for f in standalone_files},
+ )
+ )
+
+ return (resource_infos, skipped_standalone_files)
+
+
+def write_resources(
+ cm_fh: IO[str],
+ target: str,
+ scope: Scope,
+ indent: int = 0,
+ is_example=False,
+ target_ref: str = None,
+ resources: List[QtResource] = None,
+ skipped_standalone_files: List[str] = None,
+):
+ if resources is None:
+ (resources, skipped_standalone_files) = extract_resources(target, scope)
+ if target_ref is None:
+ target_ref = target
+
+ qrc_output = ""
+ for r in resources:
+ name = r.name
+ if "*" in name:
+ name = expand_resource_glob(cm_fh, name)
+ qrc_output += write_add_qt_resource_call(
+ target=target_ref,
+ scope=scope,
+ resource_name=name,
+ prefix=r.prefix,
+ base_dir=r.base_dir,
+ lang=r.lang,
+ files=r.files,
+ skip_qtquick_compiler=r.skip_qtquick_compiler,
+ is_example=is_example,
+ )
+
+ if skipped_standalone_files:
+ for f in skipped_standalone_files:
+ qrc_output += (
+ f'set_source_files_properties("{f}" PROPERTIES ' f"QT_SKIP_QUICKCOMPILER 1)\n\n"
)
if qrc_output:
@@ -2527,7 +2632,7 @@ def write_qlalrsources(cm_fh: IO[str], target: str, scope: Scope, indent: int =
if not sources:
return
cm_fh.write("\n# QLALR Grammars:\n")
- cm_fh.write(f"qt_process_qlalr(\n")
+ cm_fh.write("qt_process_qlalr(\n")
indent += 1
cm_fh.write(f"{spaces(indent)}{target}\n")
cm_fh.write(f"{spaces(indent)}{';'.join(sources)}\n")
@@ -2598,7 +2703,7 @@ def write_target_sources(
):
command_name = "target_sources"
header = f"{command_name}({target} {visibility}\n"
- write_list(cm_fh, sources, "", indent, footer=f")", header=header)
+ write_list(cm_fh, sources, "", indent, footer=")", header=header)
def expand_project_requirements(scope: Scope, skip_message: bool = False) -> str:
@@ -3193,6 +3298,14 @@ def write_main_part(
# collect all testdata and insert globbing commands
has_test_data = False
if typename == "Test":
+ cm_fh.write(f"{spaces(indent)}if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)\n")
+ cm_fh.write(f"{spaces(indent+1)}cmake_minimum_required(VERSION 3.16)\n")
+ cm_fh.write(f"{spaces(indent+1)}project({name} LANGUAGES C CXX ASM)\n")
+ cm_fh.write(
+ f"{spaces(indent+1)}find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)\n"
+ )
+ cm_fh.write(f"{spaces(indent)}endif()\n\n")
+
test_data = scope.expand("TESTDATA")
if test_data:
has_test_data = True
@@ -3241,6 +3354,9 @@ def write_main_part(
# Footer:
cm_fh.write(f"{spaces(indent)})\n")
+ if typename == "Tool":
+ cm_fh.write(f"{spaces(indent)}qt_internal_return_unless_building_tools()\n")
+
write_resources(cm_fh, name, scope, indent, target_ref=target_ref)
write_statecharts(cm_fh, name, scope, indent)
@@ -3441,6 +3557,7 @@ def write_module(cm_fh: IO[str], scope: Scope, *, indent: int = 0) -> str:
extra.append("STATIC")
if "internal_module" in scope.get("CONFIG"):
is_public_module = False
+ cmake_target_name += "Private" # Assume all internal modules have the 'Private' suffix
extra.append("INTERNAL_MODULE")
if "no_module_headers" in scope.get("CONFIG"):
extra.append("NO_MODULE_HEADERS")
@@ -3452,8 +3569,8 @@ def write_module(cm_fh: IO[str], scope: Scope, *, indent: int = 0) -> str:
scope._has_private_module = True
if "header_module" in scope.get("CONFIG"):
extra.append("HEADER_MODULE")
- if "metatypes" in scope.get("CONFIG") or "qmltypes" in scope.get("CONFIG"):
- extra.append("GENERATE_METATYPES")
+ if not("metatypes" in scope.get("CONFIG") or "qmltypes" in scope.get("CONFIG")):
+ extra.append("NO_GENERATE_METATYPES")
module_config = scope.get("MODULE_CONFIG")
if len(module_config):
@@ -3627,7 +3744,14 @@ def write_binary(cm_fh: IO[str], scope: Scope, gui: bool = False, *, indent: int
def write_find_package_section(
- cm_fh: IO[str], public_libs: List[str], private_libs: List[str], *, indent: int = 0
+ cm_fh: IO[str],
+ public_libs: List[str],
+ private_libs: List[str],
+ *,
+ indent: int = 0,
+ is_required: bool = True,
+ end_with_extra_newline: bool = True,
+ qt_package_name: str = "Qt6",
):
packages = [] # type: List[LibraryMapping]
all_libs = public_libs + private_libs
@@ -3637,12 +3761,31 @@ def write_find_package_section(
if info and info not in packages:
packages.append(info)
- # ind = spaces(indent)
+ qt_components: List[str] = []
+ for p in filter(LibraryMapping.is_qt, packages):
+ if p.components is not None:
+ qt_components += p.components
+ if qt_components:
+ if "Core" in qt_components:
+ qt_components.remove("Core")
+ qt_components = sorted(qt_components)
+ qt_package = LibraryMapping("unknown", qt_package_name, "unknown", components=qt_components)
+ if is_required:
+ qt_package.extra = ["REQUIRED"]
+ cm_fh.write(
+ generate_find_package_info(
+ qt_package,
+ use_qt_find_package=False,
+ remove_REQUIRED_from_extra=False,
+ components_required=is_required,
+ indent=indent,
+ )
+ )
- for p in packages:
+ for p in itertools.filterfalse(LibraryMapping.is_qt, packages):
cm_fh.write(generate_find_package_info(p, use_qt_find_package=False, indent=indent))
- if packages:
+ if packages and end_with_extra_newline:
cm_fh.write("\n")
@@ -3664,7 +3807,7 @@ def write_jar(cm_fh: IO[str], scope: Scope, *, indent: int = 0) -> str:
android_sdk_jar = "${android_sdk}"
write_source_file_list(
- cm_fh, scope, "", ["JAVASOURCES"], indent=indent, header=f"set(java_sources\n", footer=")\n"
+ cm_fh, scope, "", ["JAVASOURCES"], indent=indent, header="set(java_sources\n", footer=")\n"
)
cm_fh.write(f"{spaces(indent)}qt_internal_add_jar({target}\n")
@@ -3681,13 +3824,19 @@ def write_jar(cm_fh: IO[str], scope: Scope, *, indent: int = 0) -> str:
return target
-def write_win32_and_mac_bundle_properties(
- cm_fh: IO[str], scope: Scope, target: str, *, handling_first_scope=False, indent: int = 0
-):
+def get_win32_and_mac_bundle_properties(scope: Scope) -> tuple:
config = scope.get("CONFIG")
win32 = all(val not in config for val in ["cmdline", "console"])
mac_bundle = all(val not in config for val in ["cmdline", "-app_bundle"])
+ return win32, mac_bundle
+
+
+def write_win32_and_mac_bundle_properties(
+ cm_fh: IO[str], scope: Scope, target: str, *, handling_first_scope=False, indent: int = 0
+):
+ win32, mac_bundle = get_win32_and_mac_bundle_properties(scope)
+
true_value = "TRUE"
false_value = "FALSE"
@@ -3705,38 +3854,71 @@ def write_win32_and_mac_bundle_properties(
# without creating excess noise of setting the properties in every
# single scope.
for name, value in properties_mapping.items():
- if handling_first_scope or (not handling_first_scope and value != true_value):
+ if not handling_first_scope and value != true_value:
properties.extend([name, value])
if properties:
write_set_target_properties(cm_fh, [target], properties, indent=indent)
+def is_qtquick_source_file(filename: str):
+ return filename.endswith(".qml") or filename.endswith(".js") or filename.endswith(".mjs")
+
+
+def looks_like_qml_resource(resource: QtResource):
+ if resource.generated or "*" in resource.name:
+ return False
+ for f in resource.files:
+ if is_qtquick_source_file(f):
+ return True
+ return False
+
+
+def find_qml_resource(resources: List[QtResource]):
+ """Return the resource object that's most likely the one that should be used for
+ qt_add_qml_module. Return None if there's no such resource."""
+ return next(filter(looks_like_qml_resource, resources), None)
+
+
def write_example(
- cm_fh: IO[str], scope: Scope, gui: bool = False, *, indent: int = 0, is_plugin: bool = False
+ cm_fh: IO[str],
+ scope: Scope,
+ gui: bool = False,
+ *,
+ indent: int = 0,
+ is_plugin: bool = False,
+ is_user_project: bool = False,
) -> str:
binary_name = scope.TARGET
assert binary_name
+ config = scope.get("CONFIG")
+ is_qml_plugin = ("qml" in scope.get("QT")) or "qmltypes" in config
+
+ if not is_user_project:
+ example_install_dir = scope.expandString("target.path")
+ if not example_install_dir:
+ example_install_dir = "${INSTALL_EXAMPLESDIR}"
+ example_install_dir = example_install_dir.replace(
+ "$$[QT_INSTALL_EXAMPLES]", "${INSTALL_EXAMPLESDIR}"
+ )
- example_install_dir = scope.expandString("target.path")
- if not example_install_dir:
- example_install_dir = "${INSTALL_EXAMPLESDIR}"
- example_install_dir = example_install_dir.replace(
- "$$[QT_INSTALL_EXAMPLES]", "${INSTALL_EXAMPLESDIR}"
- )
-
+ project_version = scope.get_string("VERSION", "1.0")
cm_fh.write(
- "cmake_minimum_required(VERSION 3.14)\n"
- f"project({binary_name} LANGUAGES CXX)\n\n"
+ f"cmake_minimum_required(VERSION {cmake_version_string})\n"
+ f"project({binary_name} VERSION {project_version} 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"
- "if(NOT DEFINED INSTALL_EXAMPLESDIR)\n"
- ' set(INSTALL_EXAMPLESDIR "examples")\n'
- "endif()\n\n"
- f'set(INSTALL_EXAMPLEDIR "{example_install_dir}")\n\n'
)
+ if scope.get_files("FORMS"):
+ cm_fh.write("set(CMAKE_AUTOUIC ON)\n")
+ cm_fh.write("\n")
+ if not is_user_project:
+ cm_fh.write(
+ "if(NOT DEFINED INSTALL_EXAMPLESDIR)\n"
+ ' set(INSTALL_EXAMPLESDIR "examples")\n'
+ "endif()\n\n"
+ f'set(INSTALL_EXAMPLEDIR "{example_install_dir}")\n\n'
+ )
recursive_evaluate_scope(scope)
@@ -3750,110 +3932,86 @@ def write_example(
handle_source_subtractions(scopes)
scopes = merge_scopes(scopes)
+ # Write find_package call for Qt5/Qt6 and make it available as package QT.
+ cm_fh.write("find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core)\n")
+
+ # Write find_package calls for required packages.
+ # We consider packages as required if they appear at the top-level scope.
(public_libs, private_libs) = extract_cmake_libraries(scope, is_example=True)
- write_find_package_section(cm_fh, public_libs, private_libs, indent=indent)
+ write_find_package_section(
+ cm_fh,
+ public_libs,
+ private_libs,
+ indent=indent,
+ end_with_extra_newline=False,
+ qt_package_name="Qt${QT_VERSION_MAJOR}",
+ )
- add_target = ""
+ # Write find_package calls for optional packages.
+ # We consider packages inside scopes other than the top-level one as optional.
+ optional_public_libs: List[str] = []
+ optional_private_libs: List[str] = []
+ handling_first_scope = True
+ for inner_scope in scopes:
+ if handling_first_scope:
+ handling_first_scope = False
+ continue
+ (public_libs, private_libs) = extract_cmake_libraries(inner_scope, is_example=True)
+ optional_public_libs += public_libs
+ optional_private_libs += private_libs
+ write_find_package_section(
+ cm_fh,
+ optional_public_libs,
+ optional_private_libs,
+ indent=indent,
+ is_required=False,
+ end_with_extra_newline=False,
+ qt_package_name="Qt${QT_VERSION_MAJOR}",
+ )
- if is_plugin:
- if "qml" in scope.get("QT"):
- # Get the uri from the destination directory
- dest_dir = scope.expandString("DESTDIR")
- if not dest_dir:
- dest_dir = "${CMAKE_CURRENT_BINARY_DIR}"
- else:
- uri = os.path.basename(dest_dir)
- dest_dir = f"${{CMAKE_CURRENT_BINARY_DIR}}/{dest_dir}"
-
- add_target = ""
-
- qml_dir = None
- qml_dir_dynamic_imports = False
-
- qmldir_file_path_list = scope.get_files("qmldir.files")
- assert len(qmldir_file_path_list) < 2, "File path must only contain one path"
- qmldir_file_path = qmldir_file_path_list[0] if qmldir_file_path_list else "qmldir"
- qmldir_file_path = os.path.join(os.getcwd(), qmldir_file_path[0])
-
- dynamic_qmldir = scope.get("DYNAMIC_QMLDIR")
- if os.path.exists(qmldir_file_path):
- qml_dir = QmlDir()
- qml_dir.from_file(qmldir_file_path)
- elif dynamic_qmldir:
- qml_dir = QmlDir()
- qml_dir.from_lines(dynamic_qmldir)
- qml_dir_dynamic_imports = True
-
- add_target += "set(module_dynamic_qml_imports\n "
- if len(qml_dir.imports) != 0:
- add_target += "\n ".join(qml_dir.imports)
- add_target += "\n)\n\n"
-
- for sc in scopes[1:]:
- import_list = []
- qml_imports = sc.get("DYNAMIC_QMLDIR")
- for qml_import in qml_imports:
- if not qml_import.startswith("import "):
- raise RuntimeError(
- "Only qmldir import statements expected in conditional scope!"
- )
- import_list.append(qml_import[len("import ") :].replace(" ", "/"))
- if len(import_list) == 0:
- continue
+ cm_fh.write("\n")
- assert sc.condition
+ (resources, standalone_qtquick_compiler_skipped_files) = extract_resources(binary_name, scope)
+ qml_resource = find_qml_resource(resources) if is_qml_plugin else None
- add_target += f"if ({sc.condition})\n"
- add_target += f" list(APPEND module_dynamic_qml_imports\n "
- add_target += "\n ".join(import_list)
- add_target += f"\n )\nendif()\n\n"
+ add_target = ""
- add_target += dedent(
- f"""\
- qt6_add_qml_module({binary_name}
- OUTPUT_DIRECTORY "{dest_dir}"
- VERSION 1.0
- URI "{uri}"
- """
+ if is_plugin:
+ if is_qml_plugin:
+ extra_args = [f"PLUGIN_TARGET {binary_name}"]
+ io_string = io.StringIO()
+ write_qml_module(
+ io_string,
+ binary_name,
+ scope,
+ scopes,
+ indent=indent,
+ resource=qml_resource,
+ extra_add_qml_module_args=extra_args,
)
-
- if qml_dir is not None:
- if qml_dir.designer_supported:
- add_target += " DESIGNER_SUPPORTED\n"
- if len(qml_dir.classname) != 0:
- add_target += f" CLASSNAME {qml_dir.classname}\n"
- if len(qml_dir.depends) != 0:
- add_target += " DEPENDENCIES\n"
- for dep in qml_dir.depends:
- add_target += f" {dep[0]}/{dep[1]}\n"
- if len(qml_dir.type_names) == 0:
- add_target += " SKIP_TYPE_REGISTRATION\n"
- if len(qml_dir.imports) != 0 and not qml_dir_dynamic_imports:
- qml_dir_imports_line = " \n".join(qml_dir.imports)
- add_target += f" IMPORTS\n{qml_dir_imports_line}"
- if qml_dir_dynamic_imports:
- add_target += " IMPORTS ${module_dynamic_qml_imports}\n"
- if len(qml_dir.optional_imports) != 0:
- qml_dir_optional_imports_line = " \n".join(qml_dir.optional_imports)
- add_target += f" OPTIONAL_IMPORTS\n{qml_dir_optional_imports_line}"
- if qml_dir.plugin_optional:
- add_target += " PLUGIN_OPTIONAL\n"
-
- add_target += " INSTALL_LOCATION ${INSTALL_EXAMPLEDIR}\n)\n\n"
- add_target += f"target_sources({binary_name} PRIVATE"
+ add_target += io_string.getvalue()
else:
add_target = f"qt_add_plugin({binary_name}"
if "static" in scope.get("CONFIG"):
add_target += " STATIC"
add_target += ")\n"
- add_target += f"target_sources({binary_name} PRIVATE"
-
+ add_target += f"target_sources({binary_name} PRIVATE"
else:
add_target = f"qt_add_executable({binary_name}"
+ property_win32, property_mac_bundle = get_win32_and_mac_bundle_properties(scope)
+
+ if property_win32:
+ add_target += " " + "WIN32"
+ if property_mac_bundle:
+ add_target += " " + "MACOSX_BUNDLE"
+
write_all_source_file_lists(cm_fh, scope, add_target, indent=0)
cm_fh.write(")\n")
+ if is_qml_plugin and not is_plugin:
+ write_qml_module(cm_fh, binary_name, scope, scopes, indent=indent, resource=qml_resource)
+
handling_first_scope = True
for scope in scopes:
@@ -3918,7 +4076,23 @@ def write_example(
io_string, scope, f"target_compile_options({binary_name}", indent=indent, footer=")\n"
)
- write_resources(io_string, binary_name, scope, indent=indent, is_example=True)
+ (resources, standalone_qtquick_compiler_skipped_files) = extract_resources(
+ binary_name, scope
+ )
+
+ # Remove the QML resource, because we've handled it in write_qml_module.
+ if qml_resource is not None:
+ resources = list(filter(lambda r: r.name != qml_resource.name, resources))
+
+ write_resources(
+ io_string,
+ binary_name,
+ scope,
+ indent=indent,
+ is_example=True,
+ resources=resources,
+ skipped_standalone_files=standalone_qtquick_compiler_skipped_files,
+ )
write_statecharts(io_string, binary_name, scope, indent=indent, is_example=True)
write_repc_files(io_string, binary_name, scope, indent=indent)
@@ -3933,13 +4107,14 @@ def write_example(
handling_first_scope = False
- cm_fh.write(
- f"\ninstall(TARGETS {binary_name}\n"
- f' RUNTIME DESTINATION "${{INSTALL_EXAMPLEDIR}}"\n'
- f' BUNDLE DESTINATION "${{INSTALL_EXAMPLEDIR}}"\n'
- f' LIBRARY DESTINATION "${{INSTALL_EXAMPLEDIR}}"\n'
- f")\n"
- )
+ if not is_user_project:
+ cm_fh.write(
+ f"\ninstall(TARGETS {binary_name}\n"
+ f' RUNTIME DESTINATION "${{INSTALL_EXAMPLEDIR}}"\n'
+ f' BUNDLE DESTINATION "${{INSTALL_EXAMPLEDIR}}"\n'
+ f' LIBRARY DESTINATION "${{INSTALL_EXAMPLEDIR}}"\n'
+ f")\n"
+ )
return binary_name
@@ -4041,14 +4216,145 @@ def get_qml_import_version(scope: Scope, target: str) -> str:
if import_version:
replacements = [
- ("$$QT_MINOR_VERSION", "${CMAKE_PROJECT_VERSION_MINOR}"),
- ("$$QT_VERSION", "${CMAKE_PROJECT_VERSION}"),
+ ("$$QT_MINOR_VERSION", "${PROJECT_VERSION_MINOR}"),
+ ("$$QT_VERSION", "${PROJECT_VERSION}"),
]
for needle, replacement in replacements:
import_version = import_version.replace(needle, replacement)
return import_version
+def write_qml_module(
+ cm_fh: IO[str],
+ target: str,
+ scope: Scope,
+ scopes: List[Scope],
+ resource: QtResource,
+ extra_add_qml_module_args: List[str] = [],
+ indent: int = 0,
+):
+ uri = scope.get_string("QML_IMPORT_NAME")
+ if not uri:
+ uri = target
+
+ try:
+ version = get_qml_import_version(scope, target)
+ except RuntimeError:
+ version = "${PROJECT_VERSION}"
+
+ dest_dir = scope.expandString("DESTDIR")
+ if dest_dir:
+ dest_dir = f"${{CMAKE_CURRENT_BINARY_DIR}}/{dest_dir}"
+
+ content = ""
+
+ qml_dir = None
+ qml_dir_dynamic_imports = False
+
+ qmldir_file_path_list = scope.get_files("qmldir.files")
+ assert len(qmldir_file_path_list) < 2, "File path must only contain one path"
+ qmldir_file_path = qmldir_file_path_list[0] if qmldir_file_path_list else "qmldir"
+ qmldir_file_path = os.path.join(os.getcwd(), qmldir_file_path[0])
+
+ dynamic_qmldir = scope.get("DYNAMIC_QMLDIR")
+ if os.path.exists(qmldir_file_path):
+ qml_dir = QmlDir()
+ qml_dir.from_file(qmldir_file_path)
+ elif dynamic_qmldir:
+ qml_dir = QmlDir()
+ qml_dir.from_lines(dynamic_qmldir)
+ qml_dir_dynamic_imports = True
+
+ content += "set(module_dynamic_qml_imports\n "
+ if len(qml_dir.imports) != 0:
+ content += "\n ".join(qml_dir.imports)
+ content += "\n)\n\n"
+
+ for sc in scopes[1:]:
+ import_list = []
+ qml_imports = sc.get("DYNAMIC_QMLDIR")
+ for qml_import in qml_imports:
+ if not qml_import.startswith("import "):
+ raise RuntimeError(
+ "Only qmldir import statements expected in conditional scope!"
+ )
+ import_list.append(qml_import[len("import ") :].replace(" ", "/"))
+ if len(import_list) == 0:
+ continue
+
+ assert sc.condition
+
+ content += f"if ({sc.condition})\n"
+ content += " list(APPEND module_dynamic_qml_imports\n "
+ content += "\n ".join(import_list)
+ content += "\n )\nendif()\n\n"
+
+ content += dedent(
+ f"""\
+ qt_add_qml_module({target}
+ URI {uri}
+ VERSION {version}
+ """
+ )
+
+ if resource is not None:
+ qml_files = list(filter(is_qtquick_source_file, resource.files.keys()))
+ if qml_files:
+ content += " QML_FILES\n"
+ for file in qml_files:
+ content += f" {file}\n"
+ other_files = list(itertools.filterfalse(is_qtquick_source_file, resource.files.keys()))
+ if other_files:
+ content += " RESOURCES\n"
+ for file in other_files:
+ content += f" {file}\n"
+ if resource.prefix != "/":
+ content += f" RESOURCE_PREFIX {resource.prefix}\n"
+ if scope.TEMPLATE == "app":
+ content += " NO_RESOURCE_TARGET_PATH\n"
+ if dest_dir:
+ content += f" OUTPUT_DIRECTORY {dest_dir}\n"
+
+ if qml_dir is not None:
+ if qml_dir.designer_supported:
+ content += " DESIGNER_SUPPORTED\n"
+ if len(qml_dir.classname) != 0:
+ content += f" CLASSNAME {qml_dir.classname}\n"
+ if len(qml_dir.depends) != 0:
+ content += " DEPENDENCIES\n"
+ for dep in qml_dir.depends:
+ content += f" {dep[0]}/{dep[1]}\n"
+ if len(qml_dir.type_names) == 0:
+ content += " SKIP_TYPE_REGISTRATION\n"
+ if len(qml_dir.imports) != 0 and not qml_dir_dynamic_imports:
+ qml_dir_imports_line = " \n".join(qml_dir.imports)
+ content += f" IMPORTS\n{qml_dir_imports_line}"
+ if qml_dir_dynamic_imports:
+ content += " IMPORTS ${module_dynamic_qml_imports}\n"
+ if len(qml_dir.optional_imports) != 0:
+ qml_dir_optional_imports_line = " \n".join(qml_dir.optional_imports)
+ content += f" OPTIONAL_IMPORTS\n{qml_dir_optional_imports_line}"
+ if qml_dir.plugin_optional:
+ content += " PLUGIN_OPTIONAL\n"
+
+ for arg in extra_add_qml_module_args:
+ content += " "
+ content += arg
+ content += "\n"
+ content += ")\n"
+
+ if resource:
+ content += write_resource_source_file_properties(
+ sorted(resource.files.keys()),
+ resource.files,
+ resource.base_dir,
+ resource.skip_qtquick_compiler,
+ )
+
+ content += "\n"
+ cm_fh.write(content)
+
+
def write_qml_plugin(
cm_fh: IO[str],
target: str,
@@ -4124,9 +4430,9 @@ def write_qml_plugin(
assert sc.condition
cm_fh.write(f"if ({sc.condition})\n")
- cm_fh.write(f" list(APPEND module_dynamic_qml_imports\n ")
+ cm_fh.write(" list(APPEND module_dynamic_qml_imports\n ")
cm_fh.write("\n ".join(import_list))
- cm_fh.write(f"\n )\nendif()\n\n")
+ cm_fh.write("\n )\nendif()\n\n")
if qml_dir is not None:
if qml_dir.designer_supported:
@@ -4199,7 +4505,12 @@ def write_qml_plugin_epilogue(
def handle_app_or_lib(
- scope: Scope, cm_fh: IO[str], *, indent: int = 0, is_example: bool = False
+ scope: Scope,
+ cm_fh: IO[str],
+ *,
+ indent: int = 0,
+ is_example: bool = False,
+ is_user_project=False,
) -> None:
assert scope.TEMPLATE in ("app", "lib")
@@ -4221,7 +4532,9 @@ def handle_app_or_lib(
assert not is_example
target = write_3rdparty_library(cm_fh, scope, indent=indent)
elif is_example:
- target = write_example(cm_fh, scope, gui, indent=indent, is_plugin=is_plugin)
+ target = write_example(
+ cm_fh, scope, gui, indent=indent, is_plugin=is_plugin, is_user_project=is_user_project
+ )
elif is_qt_plugin:
assert not is_example
target = write_plugin(cm_fh, scope, indent=indent)
@@ -4262,7 +4575,11 @@ def handle_app_or_lib(
# Generate qmltypes instruction for anything that may have CONFIG += qmltypes
# that is not a qml plugin
- if "qmltypes" in scope.get("CONFIG") and "qml_plugin" not in scope.get("_LOADED"):
+ if (
+ not is_example
+ and "qmltypes" in scope.get("CONFIG")
+ and "qml_plugin" not in scope.get("_LOADED")
+ ):
cm_fh.write(f"\n{spaces(indent)}set_target_properties({target_ref} PROPERTIES\n")
install_dir = scope.expandString("QMLTYPES_INSTALL_DIR")
@@ -4337,7 +4654,7 @@ def handle_top_level_repo_project(scope: Scope, cm_fh: IO[str]):
)
build_repo = dedent(
- f"""\
+ """\
qt_build_repo()
"""
)
@@ -4349,18 +4666,18 @@ def create_top_level_cmake_conf():
conf_file_name = ".cmake.conf"
try:
with open(conf_file_name, "x") as file:
- file.write('set(QT_REPO_MODULE_VERSION "6.1.0")\n')
+ file.write('set(QT_REPO_MODULE_VERSION "6.8.0")\n')
except FileExistsError:
pass
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)
+ qmake_or_cmake_conf_path = find_qmake_or_cmake_conf(project_file_path)
+ qmake_or_cmake_dir = os.path.dirname(qmake_or_cmake_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_or_cmake_dir, "*.pro"))
if len(glob_result) > 0:
return glob_result[0]
return None
@@ -4369,7 +4686,7 @@ def find_top_level_repo_project_file(project_file_path: str = "") -> Optional[st
def handle_top_level_repo_tests_project(scope: Scope, cm_fh: IO[str]):
content = dedent(
- f"""\
+ """\
if(QT_BUILD_STANDALONE_TESTS)
# Add qt_find_package calls for extra dependencies that need to be found when building
# the standalone tests here.
@@ -4391,14 +4708,14 @@ def write_regular_cmake_target_scope_section(
write_include_paths(
cm_fh,
scope,
- f"target_include_directories(${{PROJECT_NAME}} PUBLIC",
+ "target_include_directories(${{PROJECT_NAME}} PUBLIC",
indent=indent,
footer=")",
)
write_defines(
cm_fh,
scope,
- f"target_compile_definitions(${{PROJECT_NAME}} PUBLIC",
+ "target_compile_definitions(${{PROJECT_NAME}} PUBLIC",
indent=indent,
footer=")",
)
@@ -4408,7 +4725,7 @@ def write_regular_cmake_target_scope_section(
private_libs,
"",
indent=indent,
- header=f"target_link_libraries(${{PROJECT_NAME}} PRIVATE\n",
+ header="target_link_libraries(${{PROJECT_NAME}} PRIVATE\n",
footer=")",
)
write_list(
@@ -4416,20 +4733,27 @@ def write_regular_cmake_target_scope_section(
public_libs,
"",
indent=indent,
- header=f"target_link_libraries(${{PROJECT_NAME}} PUBLIC\n",
+ header="target_link_libraries(${{PROJECT_NAME}} PUBLIC\n",
footer=")",
)
write_compile_options(
- cm_fh, scope, f"target_compile_options(${{PROJECT_NAME}}", indent=indent, footer=")"
+ cm_fh, scope, "target_compile_options(${{PROJECT_NAME}}", indent=indent, footer=")"
)
def handle_config_test_project(scope: Scope, cm_fh: IO[str]):
project_name = os.path.splitext(os.path.basename(scope.file_absolute_path))[0]
content = (
- f"cmake_minimum_required(VERSION 3.14.0)\n"
+ f"cmake_minimum_required(VERSION 3.16)\n"
f"project(config_test_{project_name} LANGUAGES C CXX)\n"
"""
+if(DEFINED QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_PREFIX_PATH)
+ set(CMAKE_SYSTEM_PREFIX_PATH "${QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_PREFIX_PATH}")
+endif()
+if(DEFINED QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_FRAMEWORK_PATH)
+ set(CMAKE_SYSTEM_FRAMEWORK_PATH "${QT_CONFIG_COMPILE_TEST_CMAKE_SYSTEM_FRAMEWORK_PATH}")
+endif()
+
foreach(p ${QT_CONFIG_COMPILE_TEST_PACKAGES})
find_package(${p})
endforeach()
@@ -4451,7 +4775,7 @@ endif()
# Remove default QT libs.
scope._append_operation("QT", RemoveOperation(["core", "gui"]))
- add_target = f"add_executable(${{PROJECT_NAME}}"
+ add_target = "add_executable(${{PROJECT_NAME}}"
temp_buffer = io.StringIO()
write_all_source_file_lists(temp_buffer, scope, add_target, indent=0)
@@ -4489,40 +4813,53 @@ endif()
def cmakeify_scope(
- scope: Scope, cm_fh: IO[str], *, indent: int = 0, is_example: bool = False
+ scope: Scope,
+ cm_fh: IO[str],
+ *,
+ indent: int = 0,
+ is_example: bool = False,
+ is_user_project: bool = False,
) -> None:
template = scope.TEMPLATE
- temp_buffer = io.StringIO()
-
- # Handle top level repo project in a special way.
- if is_top_level_repo_project(scope.file_absolute_path):
- create_top_level_cmake_conf()
- handle_top_level_repo_project(scope, temp_buffer)
- # 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 is_config_test_project(scope.file_absolute_path):
- handle_config_test_project(scope, temp_buffer)
- elif template == "subdirs":
- handle_subdir(scope, temp_buffer, indent=indent, is_example=is_example)
- elif template in ("app", "lib"):
- handle_app_or_lib(scope, temp_buffer, indent=indent, is_example=is_example)
+ if is_user_project:
+ if template == "subdirs":
+ handle_subdir(scope, cm_fh, indent=indent, is_example=True, is_user_project=True)
+ elif template in ("app", "lib"):
+ handle_app_or_lib(scope, cm_fh, indent=indent, is_example=True, is_user_project=True)
else:
- print(f" XXXX: {scope.file}: Template type {template} not yet supported.")
+ temp_buffer = io.StringIO()
+
+ # Handle top level repo project in a special way.
+ if is_top_level_repo_project(scope.file_absolute_path):
+ create_top_level_cmake_conf()
+ handle_top_level_repo_project(scope, temp_buffer)
+ # 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 is_config_test_project(scope.file_absolute_path):
+ handle_config_test_project(scope, temp_buffer)
+ elif template == "subdirs":
+ handle_subdir(scope, temp_buffer, indent=indent, is_example=is_example)
+ elif template in ("app", "lib"):
+ handle_app_or_lib(scope, temp_buffer, indent=indent, is_example=is_example)
+ else:
+ print(f" XXXX: {scope.file}: Template type {template} not yet supported.")
- buffer_value = temp_buffer.getvalue()
+ buffer_value = temp_buffer.getvalue()
- if is_top_level_repo_examples_project(scope.file_absolute_path):
- # Wrap top level examples project with some commands which
- # are necessary to build examples as part of the overall
- # build.
- buffer_value = f"qt_examples_build_begin()\n\n{buffer_value}\nqt_examples_build_end()\n"
+ if is_top_level_repo_examples_project(scope.file_absolute_path):
+ # Wrap top level examples project with some commands which
+ # are necessary to build examples as part of the overall
+ # build.
+ buffer_value = f"qt_examples_build_begin()\n\n{buffer_value}\nqt_examples_build_end()\n"
- cm_fh.write(buffer_value)
+ cm_fh.write(buffer_value)
-def generate_new_cmakelists(scope: Scope, *, is_example: bool = False, debug: bool = False) -> None:
+def generate_new_cmakelists(
+ scope: Scope, *, is_example: bool = False, is_user_project: bool = True, debug: bool = False
+) -> None:
if debug:
print("Generating CMakeLists.gen.txt")
with open(scope.generated_cmake_lists_path, "w") as cm_fh:
@@ -4531,7 +4868,9 @@ def generate_new_cmakelists(scope: Scope, *, is_example: bool = False, debug: bo
is_example_heuristic = is_example_project(scope.file_absolute_path)
final_is_example_decision = is_example or is_example_heuristic
- cmakeify_scope(scope, cm_fh, is_example=final_is_example_decision)
+ cmakeify_scope(
+ scope, cm_fh, is_example=final_is_example_decision, is_user_project=is_user_project
+ )
def do_include(scope: Scope, *, debug: bool = False) -> None:
@@ -4605,10 +4944,10 @@ def cmake_project_has_skip_marker(project_file_path: str = "") -> bool:
def should_convert_project(project_file_path: str = "", ignore_skip_marker: bool = False) -> bool:
- qmake_conf_path = find_qmake_conf(project_file_path)
- qmake_conf_dir_path = os.path.dirname(qmake_conf_path)
+ qmake_or_cmake_conf_path = find_qmake_or_cmake_conf(project_file_path)
+ qmake_or_cmake_conf_dir_path = os.path.dirname(qmake_or_cmake_conf_path)
- project_relative_path = os.path.relpath(project_file_path, qmake_conf_dir_path)
+ project_relative_path = os.path.relpath(project_file_path, qmake_or_cmake_conf_dir_path)
# Skip cmake auto tests, they should not be converted.
if project_relative_path.startswith("tests/auto/cmake"):
@@ -4688,7 +5027,7 @@ def main() -> None:
cmake_api_version = args.api_version
else:
# Otherwise detect the api version in the old CMakeLists.txt
- # if it exsists.
+ # if it exists.
detected_cmake_api_version = detect_cmake_api_version_used_in_file_content(
file_relative_path
)
@@ -4727,7 +5066,12 @@ def main() -> None:
print(f'Skipping conversion of project: "{project_file_absolute_path}"')
continue
- generate_new_cmakelists(file_scope, is_example=args.is_example, debug=args.debug)
+ generate_new_cmakelists(
+ file_scope,
+ is_example=args.is_example,
+ is_user_project=args.is_user_project,
+ debug=args.debug,
+ )
copy_generated_file = True
diff --git a/util/cmake/pro_conversion_rate.py b/util/cmake/pro_conversion_rate.py
index 3c0c7e3070..30aae95b06 100755
--- a/util/cmake/pro_conversion_rate.py
+++ b/util/cmake/pro_conversion_rate.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2019 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
from __future__ import annotations
@@ -57,7 +32,7 @@ def _parse_commandline():
class Blacklist:
- """ Class to check if a certain dir_name / dir_path is blacklisted """
+ """Class to check if a certain dir_name / dir_path is blacklisted"""
def __init__(self, names: typing.List[str], path_parts: typing.List[str]):
self.names = names
@@ -99,7 +74,7 @@ class Blacklist:
def recursive_scan(path: str, extension: str, result_paths: typing.List[str], blacklist: Blacklist):
- """ Find files ending with a certain extension, filtering out blacklisted entries """
+ """Find files ending with a certain extension, filtering out blacklisted entries"""
try:
for entry in os.scandir(path):
if entry.is_file() and entry.path.endswith(extension):
diff --git a/util/cmake/qmake_parser.py b/util/cmake/qmake_parser.py
index 357a529e5a..8cf7b1c46e 100644..100755
--- a/util/cmake/qmake_parser.py
+++ b/util/cmake/qmake_parser.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import collections
import os
@@ -73,7 +48,7 @@ def fixup_comments(contents: str) -> str:
def flatten_list(input_list):
- """ Flattens an irregular nested list into a simple list."""
+ """Flattens an irregular nested list into a simple list."""
for el in input_list:
if isinstance(el, collections.abc.Iterable) and not isinstance(el, (str, bytes)):
yield from flatten_list(el)
@@ -333,12 +308,61 @@ class QmakeParser:
"ConditionWhiteSpace", pp.Suppress(pp.Optional(pp.White(" ")))
)
+ # Unfortunately qmake condition operators have no precedence,
+ # and are simply evaluated left to right. To emulate that, wrap
+ # each condition sub-expression in parentheses.
+ # So c1|c2:c3 is evaluated by qmake as (c1|c2):c3.
+ # The following variable keeps count on how many parentheses
+ # should be added to the beginning of the condition. Each
+ # condition sub-expression always gets an ")", and in the
+ # end the whole condition gets many "(". Note that instead
+ # inserting the actual parentheses, we insert special markers
+ # which get replaced in the end.
+ condition_parts_count = 0
+ # Whitespace in the markers is important. Assumes the markers
+ # never appear in .pro files.
+ l_paren_marker = "_(_ "
+ r_paren_marker = " _)_"
+
+ def handle_condition_part(condition_part_parse_result: pp.ParseResults) -> str:
+ condition_part_list = [*condition_part_parse_result]
+ nonlocal condition_parts_count
+ condition_parts_count += 1
+ condition_part_joined = "".join(condition_part_list)
+ # Add ending parenthesis marker. The counterpart is added
+ # in handle_condition.
+ return f"{condition_part_joined}{r_paren_marker}"
+
+ ConditionPart.setParseAction(handle_condition_part)
ConditionRepeated = add_element(
"ConditionRepeated", pp.ZeroOrMore(ConditionOp + ConditionWhiteSpace + ConditionPart)
)
+ def handle_condition(condition_parse_results: pp.ParseResults) -> str:
+ nonlocal condition_parts_count
+ prepended_parentheses = l_paren_marker * condition_parts_count
+ result = prepended_parentheses + " ".join(condition_parse_results).strip().replace(
+ ":", " && "
+ ).strip(" && ")
+ # If there are only 2 condition sub-expressions, there is no
+ # need for parentheses.
+ if condition_parts_count < 3:
+ result = result.replace(l_paren_marker, "")
+ result = result.replace(r_paren_marker, "")
+ result = result.strip(" ")
+ else:
+ result = result.replace(l_paren_marker, "( ")
+ result = result.replace(r_paren_marker, " )")
+ # Strip parentheses and spaces around the final
+ # condition.
+ result = result[1:-1]
+ result = result.strip(" ")
+ # Reset the parenthesis count for the next condition.
+ condition_parts_count = 0
+ return result
+
Condition = add_element("Condition", pp.Combine(ConditionPart + ConditionRepeated))
- Condition.setParseAction(lambda x: " ".join(x).strip().replace(":", " && ").strip(" && "))
+ Condition.setParseAction(handle_condition)
# 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
diff --git a/util/cmake/run_pro2cmake.py b/util/cmake/run_pro2cmake.py
index 4a12c57b83..3e860e90b2 100755
--- a/util/cmake/run_pro2cmake.py
+++ b/util/cmake/run_pro2cmake.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import glob
import os
@@ -100,7 +75,7 @@ def parse_command_line() -> argparse.Namespace:
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. """
+ """Sorter that tries to prioritize main pro files in a directory."""
pro_file_without_suffix = pro_file.rsplit("/", 1)[-1][:-4]
dir_name = os.path.dirname(pro_file)
if dir_name == ".":
diff --git a/util/cmake/special_case_helper.py b/util/cmake/special_case_helper.py
index 28295b3143..a7343d32c3 100644
--- a/util/cmake/special_case_helper.py
+++ b/util/cmake/special_case_helper.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2019 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
"""
This is a helper script that takes care of reapplying special case
diff --git a/util/cmake/tests/data/condition_operator_precedence.pro b/util/cmake/tests/data/condition_operator_precedence.pro
new file mode 100644
index 0000000000..8af628404d
--- /dev/null
+++ b/util/cmake/tests/data/condition_operator_precedence.pro
@@ -0,0 +1,11 @@
+a1|a2 {
+ DEFINES += d
+}
+
+b1|b2:b3 {
+ DEFINES += d
+}
+
+c1|c2:c3|c4 {
+ DEFINES += d
+}
diff --git a/util/cmake/tests/data/conversion/optional_qt_modules.pro b/util/cmake/tests/data/conversion/optional_qt_modules.pro
new file mode 100644
index 0000000000..b9522169fc
--- /dev/null
+++ b/util/cmake/tests/data/conversion/optional_qt_modules.pro
@@ -0,0 +1,4 @@
+TARGET = myapp
+QT = core network widgets
+win32: QT += opengl
+SOURCES = main.cpp
diff --git a/util/cmake/tests/data/conversion/qt_version_check.pro b/util/cmake/tests/data/conversion/qt_version_check.pro
new file mode 100644
index 0000000000..cf3697bb64
--- /dev/null
+++ b/util/cmake/tests/data/conversion/qt_version_check.pro
@@ -0,0 +1,8 @@
+QT += core gui
+SOURCES += main.cpp
+greaterThan(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 1):equals(QT_PATCH_VERSION, 0) {
+ DEFINES += SUPER_FRESH_MAJOR_QT_RELEASE
+}
+greaterThan(QT_VERSION, 6.6.5):lessThan(QT_VERSION, 6.6.7):equals(QT_VERSION, 6.6.6): {
+ DEFINES += QT_VERSION_OF_THE_BEAST
+}
diff --git a/util/cmake/tests/data/conversion/required_qt_modules.pro b/util/cmake/tests/data/conversion/required_qt_modules.pro
new file mode 100644
index 0000000000..287bb46831
--- /dev/null
+++ b/util/cmake/tests/data/conversion/required_qt_modules.pro
@@ -0,0 +1,3 @@
+TARGET = myapp
+QT = core network widgets
+SOURCES = main.cpp
diff --git a/util/cmake/tests/data/standardpaths.pro b/util/cmake/tests/data/standardpaths.pro
index 4b45788e4f..b9896b8e29 100644
--- a/util/cmake/tests/data/standardpaths.pro
+++ b/util/cmake/tests/data/standardpaths.pro
@@ -7,7 +7,7 @@ win32 {
} else:unix {
mac {
OBJECTIVE_SOURCES += io/qstandardpaths_mac.mm
- } else:android:!android-embedded {
+ } else:android {
SOURCES += io/qstandardpaths_android.cpp
} else:haiku {
SOURCES += io/qstandardpaths_haiku.cpp
diff --git a/util/cmake/tests/test_conversion.py b/util/cmake/tests/test_conversion.py
new file mode 100755
index 0000000000..0cdfb51976
--- /dev/null
+++ b/util/cmake/tests/test_conversion.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+from pro2cmake import Scope, SetOperation, merge_scopes, recursive_evaluate_scope
+from tempfile import TemporaryDirectory
+
+import os
+import pathlib
+import pytest
+import re
+import shutil
+import subprocess
+import tempfile
+import typing
+
+debug_mode = bool(os.environ.get("DEBUG_PRO2CMAKE_TEST_CONVERSION"))
+test_script_dir = pathlib.Path(__file__).parent.resolve()
+pro2cmake_dir = test_script_dir.parent.resolve()
+pro2cmake_py = pro2cmake_dir.joinpath("pro2cmake.py")
+test_data_dir = test_script_dir.joinpath("data", "conversion")
+
+
+def convert(base_name: str):
+ pro_file_name = str(base_name) + ".pro"
+ pro_file_path = test_data_dir.joinpath(pro_file_name)
+ assert(pro_file_path.exists())
+ with TemporaryDirectory(prefix="testqmake2cmake") as tmp_dir_str:
+ tmp_dir = pathlib.Path(tmp_dir_str)
+ output_file_path = tmp_dir.joinpath("CMakeLists.txt")
+ exit_code = subprocess.call([pro2cmake_py, "--is-example", "-o", output_file_path, pro_file_path])
+ assert(exit_code == 0)
+ if debug_mode:
+ shutil.copyfile(output_file_path, tempfile.gettempdir() + "/pro2cmake/CMakeLists.txt")
+ f = open(output_file_path, "r")
+ assert(f)
+ content = f.read()
+ assert(content)
+ return content
+
+
+def test_qt_modules():
+ output = convert("required_qt_modules")
+ find_package_lines = []
+ for line in output.split("\n"):
+ if "find_package(" in line:
+ find_package_lines.append(line.strip())
+ assert(["find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core)",
+ "find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Network Widgets)"] == find_package_lines)
+
+ output = convert("optional_qt_modules")
+ find_package_lines = []
+ for line in output.split("\n"):
+ if "find_package(" in line:
+ find_package_lines.append(line.strip())
+ assert(["find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Core)",
+ "find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Network Widgets)",
+ "find_package(Qt${QT_VERSION_MAJOR} OPTIONAL_COMPONENTS OpenGL)"] == find_package_lines)
+
+def test_qt_version_check():
+ output = convert("qt_version_check")
+ interesting_lines = []
+ for line in output.split("\n"):
+ if line.startswith("if(") and "QT_VERSION" in line:
+ interesting_lines.append(line.strip())
+ assert(["if(( ( (QT_VERSION_MAJOR GREATER 5) ) AND (QT_VERSION_MINOR LESS 1) ) AND (QT_VERSION_PATCH EQUAL 0))", "if(( ( (QT_VERSION VERSION_GREATER 6.6.5) ) AND (QT_VERSION VERSION_LESS 6.6.7) ) AND (QT_VERSION VERSION_EQUAL 6.6.6))"] == interesting_lines)
diff --git a/util/cmake/tests/test_lc_fixup.py b/util/cmake/tests/test_lc_fixup.py
index 42094a5288..aa63e02fe1 100755
--- a/util/cmake/tests/test_lc_fixup.py
+++ b/util/cmake/tests/test_lc_fixup.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
from qmake_parser import fixup_linecontinuation
diff --git a/util/cmake/tests/test_logic_mapping.py b/util/cmake/tests/test_logic_mapping.py
index 6e4fd20590..cc7d5a3636 100755
--- a/util/cmake/tests/test_logic_mapping.py
+++ b/util/cmake/tests/test_logic_mapping.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
from condition_simplifier import simplify_condition
@@ -182,5 +157,4 @@ def test_simplify_complex_false():
def test_simplify_android_not_apple():
- validate_simplify('ANDROID AND NOT ANDROID_EMBEDDED AND NOT MACOS',
- 'ANDROID AND NOT ANDROID_EMBEDDED')
+ validate_simplify('ANDROID AND NOT MACOS', 'ANDROID')
diff --git a/util/cmake/tests/test_operations.py b/util/cmake/tests/test_operations.py
index c1e5f1b250..95f894dae4 100755
--- a/util/cmake/tests/test_operations.py
+++ b/util/cmake/tests/test_operations.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
from pro2cmake import AddOperation, SetOperation, UniqueAddOperation, RemoveOperation
diff --git a/util/cmake/tests/test_parsing.py b/util/cmake/tests/test_parsing.py
index 9acee46007..ceda348f53 100755
--- a/util/cmake/tests/test_parsing.py
+++ b/util/cmake/tests/test_parsing.py
@@ -1,34 +1,11 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2018 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import os
+from pro2cmake import map_condition
from qmake_parser import QmakeParser
+from condition_simplifier import simplify_condition
_tests_path = os.path.dirname(os.path.abspath(__file__))
@@ -239,7 +216,7 @@ def test_realworld_standardpaths():
# android / else:
(cond4, if_branch4, else_branch4) = evaluate_condition(else_branch3[0])
- assert cond4 == 'android && !android-embedded'
+ assert cond4 == 'android'
assert len(if_branch4) == 1
validate_op('SOURCES', '+=', ['io/qstandardpaths_android.cpp'], if_branch4[0])
assert len(else_branch4) == 1
@@ -259,7 +236,7 @@ def test_realworld_comment_scope():
(cond, if_branch, else_branch) = evaluate_condition(result[0])
assert cond == 'freebsd|openbsd'
assert len(if_branch) == 1
- validate_op('QMAKE_LFLAGS_NOUNDEF', '=', None, if_branch[0])
+ validate_op('QMAKE_LFLAGS_NOUNDEF', '=', [], if_branch[0])
assert 'included' in result[1]
assert result[1]['included'].get('value', '') == 'animation/animation.pri'
@@ -352,3 +329,15 @@ def test_value_function():
assert target == 'Dummy'
value = result[1]['value']
assert value[0] == '$$TARGET'
+
+
+def test_condition_operator_precedence():
+ result = parse_file(_tests_path + '/data/condition_operator_precedence.pro')
+
+ def validate_simplify(input_str: str, expected: str) -> None:
+ output = simplify_condition(map_condition(input_str))
+ assert output == expected
+
+ validate_simplify(result[0]["condition"], "a1 OR a2")
+ validate_simplify(result[1]["condition"], "b3 AND (b1 OR b2)")
+ validate_simplify(result[2]["condition"], "c4 OR (c1 AND c3) OR (c2 AND c3)")
diff --git a/util/cmake/tests/test_scope_handling.py b/util/cmake/tests/test_scope_handling.py
index 51e569fb09..b36c5d5bcd 100755
--- a/util/cmake/tests/test_scope_handling.py
+++ b/util/cmake/tests/test_scope_handling.py
@@ -1,31 +1,6 @@
#!/usr/bin/env python3
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the plugins of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2021 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
from pro2cmake import Scope, SetOperation, merge_scopes, recursive_evaluate_scope
@@ -306,12 +281,10 @@ def test_qstandardpaths_scopes():
# mac {
# OBJECTIVE_SOURCES += io/qstandardpaths_mac.mm
scope7 = _new_scope(parent_scope=scope6, condition='MACOS', SOURCES='qsp_mac.mm')
- # } else:android:!android-embedded {
+ # } else:android {
# SOURCES += io/qstandardpaths_android.cpp
scope8 = _new_scope(parent_scope=scope6, condition='else')
- scope9 = _new_scope(parent_scope=scope8,
- condition='ANDROID AND NOT ANDROID_EMBEDDED',
- SOURCES='qsp_android.cpp')
+ scope9 = _new_scope(parent_scope=scope8, condition='ANDROID AND NOT UNKNOWN_PLATFORM', SOURCES='qsp_android.cpp')
# } else:haiku {
# SOURCES += io/qstandardpaths_haiku.cpp
scope10 = _new_scope(parent_scope=scope8, condition='else')
@@ -332,10 +305,10 @@ def test_qstandardpaths_scopes():
assert scope6.total_condition == 'UNIX'
assert scope7.total_condition == 'MACOS'
assert scope8.total_condition == 'UNIX AND NOT MACOS'
- assert scope9.total_condition == 'ANDROID AND NOT ANDROID_EMBEDDED'
- assert scope10.total_condition == 'UNIX AND NOT MACOS AND (ANDROID_EMBEDDED OR NOT ANDROID)'
- assert scope11.total_condition == 'HAIKU AND (ANDROID_EMBEDDED OR NOT ANDROID)'
- assert scope12.total_condition == 'UNIX AND NOT MACOS AND NOT HAIKU AND (ANDROID_EMBEDDED OR NOT ANDROID)'
+ assert scope9.total_condition == 'ANDROID AND NOT UNKNOWN_PLATFORM'
+ assert scope10.total_condition == 'UNIX AND NOT MACOS AND (UNKNOWN_PLATFORM OR NOT ANDROID)'
+ assert scope11.total_condition == 'HAIKU AND (UNKNOWN_PLATFORM OR NOT ANDROID)'
+ assert scope12.total_condition == 'UNIX AND NOT HAIKU AND NOT MACOS AND (UNKNOWN_PLATFORM OR NOT ANDROID)'
def test_recursive_expansion():
scope = _new_scope(A='Foo',B='$$A/Bar')
@@ -343,4 +316,3 @@ def test_recursive_expansion():
assert scope.get_string('B') == '$$A/Bar'
assert scope._expand_value('$$B/Source.cpp') == ['Foo/Bar/Source.cpp']
assert scope._expand_value('$$B') == ['Foo/Bar']
-