Improve styling of util/cmake scripts

flake8 was used to evaluate the file, with a couple of exeptions:
    E501,E266,W503

black was used to reformat the code automatically

The changes were:
* Added a README that explains how to use pipenv and pip,
* Remove unnecessary return statements,
* Remove '\' from the end of the lines,
* Use f-strings (>= 3.6) since we are requiring Python 3.7,
* Commenting unused variables,
* Adding assert when Python >= 3.7 is not being used,
* Wrapping long lines to 100 (Qt Style),
* Re-factoring some lines,
* Re-ordering imports,
* Naming `except` for sympy (SympifyError, TypeError)

Change-Id: Ie05f754e7d8ee4bf427117c58e0eb1b903202933
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
Cristian Maureira-Fredes 2019-09-17 00:11:17 +02:00
parent c1cf305be0
commit 91634c3c9b
10 changed files with 2712 additions and 2008 deletions

54
util/cmake/README.md Normal file
View File

@ -0,0 +1,54 @@
# CMake Utils
This directory holds scripts to help the porting process from `qmake` to `cmake` for Qt6.
# Requirements
* [Python 3.7](https://www.python.org/downloads/),
* `pipenv` or `pip` to manage the modules.
## Python modules
Since Python has many ways of handling projects, you have a couple of options to
install the dependencies of the scripts:
### Using `pipenv`
The dependencies are specified on the `Pipfile`, so you just need to run
`pipenv install` and that will automatically create a virtual environment
that you can activate with a `pipenv shell`.
### Using `pip`
It's highly recommended to use a [virtualenvironment](https://virtualenv.pypa.io/en/latest/)
to avoid conflict with other packages that are already installed: `pip install virtualenv`.
* Create an environment: `virtualenv env`,
* Activate the environment: `source env/bin/activate`
(on Windows: `source env\Scripts\activate.bat`)
* Install the requirements: `pip install -r requirements.txt`
# Contributing to the scripts
You can verify if the styling of a script complaint with PEP8, with a couple of exceptions:
Install [flake8](http://flake8.pycqa.org/en/latest/) (`pip install flake8`) and run it
on the script you want to test:
```
flake8 <file>.py --ignore=E501,E266,W503
```
* `E501`: Line too long (82>79 characters),
* `E266`: Too many leading '#' for block comment,
* `W503`: Line break occurred before a binary operator)
You can also modify the file with an automatic formatter,
like [black](https://black.readthedocs.io/en/stable/) (`pip install black`),
and execute it:
```
black -l 100 <file>.py
```
Using Qt's maximum line length, 100.

View File

@ -32,27 +32,37 @@ from argparse import ArgumentParser
import os
import re
import subprocess
import sys
import typing
def _parse_commandline():
parser = ArgumentParser(description='Calculate the conversion rate to cmake.')
parser.add_argument('--debug', dest='debug', action='store_true',
help='Turn on debug output')
parser.add_argument('source_directory', metavar='<Source Directory>', type=str,
help='The Qt module source directory')
parser.add_argument('binary_directory', metavar='<CMake build direcotry>', type=str,
help='The CMake build directory (might be empty)')
parser = ArgumentParser(description="Calculate the conversion rate to cmake.")
parser.add_argument("--debug", dest="debug", action="store_true", help="Turn on debug output")
parser.add_argument(
"source_directory",
metavar="<Source Directory>",
type=str,
help="The Qt module source directory",
)
parser.add_argument(
"binary_directory",
metavar="<CMake build direcotry>",
type=str,
help="The CMake build directory (might be empty)",
)
return parser.parse_args()
def calculate_baseline(source_directory: str, *, debug: bool=False) -> int:
def calculate_baseline(source_directory: str, *, debug: bool = False) -> int:
if debug:
print('Scanning "{}" for qmake-based tests.'.format(source_directory))
result = subprocess.run('/usr/bin/git grep -E "^\\s*CONFIG\\s*\\+?=.*\\btestcase\\b" | sort -u | wc -l',
shell=True, capture_output=True, cwd=source_directory)
print(f'Scanning "{source_directory}" for qmake-based tests.')
result = subprocess.run(
'/usr/bin/git grep -E "^\\s*CONFIG\\s*\\+?=.*\\btestcase\\b" | sort -u | wc -l',
shell=True,
capture_output=True,
cwd=source_directory,
)
return int(result.stdout)
@ -60,41 +70,45 @@ def build(source_directory: str, binary_directory: str, *, debug=False) -> None:
abs_source = os.path.abspath(source_directory)
if not os.path.isdir(binary_directory):
os.makedirs(binary_directory)
if not os.path.exists(os.path.join(binary_directory, 'CMakeCache.txt')):
if not os.path.exists(os.path.join(binary_directory, "CMakeCache.txt")):
if debug:
print('Running cmake in "{}".'.format(binary_directory))
result = subprocess.run(['/usr/bin/cmake', '-GNinja', abs_source], cwd=binary_directory)
print(f'Running cmake in "{binary_directory}"')
result = subprocess.run(["/usr/bin/cmake", "-GNinja", abs_source], cwd=binary_directory)
if debug:
print('CMake return code: {}.'.format(result.returncode))
print(f"CMake return code: {result.returncode}.")
assert result.returncode == 0
if debug:
print('Running ninja in "{}".'.format(binary_directory))
result = subprocess.run('/usr/bin/ninja', cwd=binary_directory)
print(f'Running ninja in "{binary_directory}".')
result = subprocess.run("/usr/bin/ninja", cwd=binary_directory)
if debug:
print('Ninja return code: {}.'.format(result.returncode))
print(f"Ninja return code: {result.returncode}.")
assert result.returncode == 0
def test(binary_directory: str, *, debug=False) -> typing.Tuple[int, int]:
if debug:
print('Running ctest in "{}".'.format(binary_directory))
result = subprocess.run('/usr/bin/ctest -j 250 | grep "tests passed, "',
shell=True, capture_output=True, cwd=binary_directory)
summary = result.stdout.decode('utf-8').replace('\n', '')
print(f'Running ctest in "{binary_directory}".')
result = subprocess.run(
'/usr/bin/ctest -j 250 | grep "tests passed, "',
shell=True,
capture_output=True,
cwd=binary_directory,
)
summary = result.stdout.decode("utf-8").replace("\n", "")
if debug:
print('Test summary: {} ({}).'.format(summary, result.returncode))
print(f"Test summary: {summary} ({result.returncode}).")
matches = re.fullmatch(r'\d+% tests passed, (\d+) tests failed out of (\d+)', summary)
matches = re.fullmatch(r"\d+% tests passed, (\d+) tests failed out of (\d+)", summary)
if matches:
if debug:
print('Matches: failed {}, total {}.'.format(matches.group(1), matches.group(2)))
return (int(matches.group(2)), int(matches.group(2)) - int(matches.group(1)), )
print(f"Matches: failed {matches.group(1)}, total {matches.group(2)}.")
return (int(matches.group(2)), int(matches.group(2)) - int(matches.group(1)))
return (0, 0,)
return (0, 0)
def main() -> int:
@ -102,26 +116,26 @@ def main() -> int:
base_line = calculate_baseline(args.source_directory, debug=args.debug)
if base_line <= 0:
print('Could not find the qmake baseline in {}.'.format(args.source_directory))
print(f"Could not find the qmake baseline in {args.source_directory}.")
return 1
if args.debug:
print('qmake baseline: {} test binaries.'.format(base_line))
print(f"qmake baseline: {base_line} test binaries.")
cmake_total = 0
cmake_success = 0
try:
build(args.source_directory, args.binary_directory, debug=args.debug)
(cmake_total, cmake_success, ) = test(args.binary_directory, debug=args.debug)
(cmake_total, cmake_success) = test(args.binary_directory, debug=args.debug)
finally:
if cmake_total == 0:
print('\n\n\nCould not calculate the cmake state.')
print("\n\n\nCould not calculate the cmake state.")
return 2
else:
print('\n\n\nCMake test conversion rate: {:.2%}.'.format(cmake_total / base_line))
print('CMake test success rate : {:.2%}.'.format(cmake_success / base_line))
print(f"\n\n\nCMake test conversion rate: {cmake_total/base_line:.2f}.")
print(f"CMake test success rate : {cmake_success/base_line:.2f}.")
return 0
if __name__ == '__main__':
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

View File

@ -29,14 +29,19 @@
import re
import typing
class LibraryMapping:
def __init__(self, soName: str,
packageName: typing.Optional[str],
targetName: typing.Optional[str], *,
resultVariable: typing.Optional[str] = None,
extra: typing.List[str] = [],
appendFoundSuffix: bool = True,
emit_if: str = '') -> None:
def __init__(
self,
soName: str,
packageName: typing.Optional[str],
targetName: typing.Optional[str],
*,
resultVariable: typing.Optional[str] = None,
extra: typing.List[str] = [],
appendFoundSuffix: bool = True,
emit_if: str = ""
) -> None:
self.soName = soName
self.packageName = packageName
self.resultVariable = resultVariable
@ -49,232 +54,448 @@ class LibraryMapping:
self.emit_if = emit_if
def is_qt(self) -> bool:
return self.packageName == 'Qt' \
or self.packageName == 'Qt5' \
or self.packageName == 'Qt6'
return self.packageName == "Qt" or self.packageName == "Qt5" or self.packageName == "Qt6"
_qt_library_map = [
# Qt:
LibraryMapping('accessibility_support', 'Qt6', 'Qt::AccessibilitySupport', extra = ['COMPONENTS', 'AccessibilitySupport']),
LibraryMapping('androidextras', 'Qt6', 'Qt::AndroidExtras', extra = ['COMPONENTS', 'AndroidExtras']),
LibraryMapping('animation', 'Qt6', 'Qt::3DAnimation', extra = ['COMPONENTS', '3DAnimation']),
LibraryMapping('application-lib', 'Qt6', 'Qt::AppManApplication', extra = ['COMPONENTS', 'AppManApplication']),
LibraryMapping('bluetooth', 'Qt6', 'Qt::Bluetooth', extra = ['COMPONENTS', 'Bluetooth']),
LibraryMapping('bootstrap', 'Qt6', 'Qt::Bootstrap', extra = ['COMPONENTS', 'Bootstrap']),
LibraryMapping(
"accessibility_support",
"Qt6",
"Qt::AccessibilitySupport",
extra=["COMPONENTS", "AccessibilitySupport"],
),
LibraryMapping(
"androidextras", "Qt6", "Qt::AndroidExtras", extra=["COMPONENTS", "AndroidExtras"]
),
LibraryMapping("animation", "Qt6", "Qt::3DAnimation", extra=["COMPONENTS", "3DAnimation"]),
LibraryMapping(
"application-lib", "Qt6", "Qt::AppManApplication", extra=["COMPONENTS", "AppManApplication"]
),
LibraryMapping("bluetooth", "Qt6", "Qt::Bluetooth", extra=["COMPONENTS", "Bluetooth"]),
LibraryMapping("bootstrap", "Qt6", "Qt::Bootstrap", extra=["COMPONENTS", "Bootstrap"]),
# bootstrap-dbus: Not needed in Qt6!
LibraryMapping('client', 'Qt6', 'Qt::WaylandClient', extra = ['COMPONENTS', 'WaylandClient']),
LibraryMapping('clipboard_support', 'Qt6', 'Qt::ClipboardSupport', extra = ['COMPONENTS', 'ClipboardSupport']),
LibraryMapping('coap', 'Qt6', 'Qt::Coap', extra = ['COMPONENTS', 'Coap']),
LibraryMapping('common-lib', 'Qt6', 'Qt::AppManCommon', extra = ['COMPONENTS', 'AppManCommon']),
LibraryMapping('compositor', 'Qt6', 'Qt::WaylandCompositor', extra = ['COMPONENTS', 'WaylandCompositor']),
LibraryMapping('concurrent', 'Qt6', 'Qt::Concurrent', extra = ['COMPONENTS', 'Concurrent']),
LibraryMapping('container', 'Qt6', 'Qt::AxContainer', extra = ['COMPONENTS', 'AxContainer']),
LibraryMapping('control', 'Qt6', 'Qt::AxServer', extra = ['COMPONENTS', 'AxServer']),
LibraryMapping('core_headers', 'Qt6', 'Qt::WebEngineCore', extra = ['COMPONENTS', 'WebEngineCore']),
LibraryMapping('core', 'Qt6', 'Qt::Core', extra = ['COMPONENTS', 'Core']),
LibraryMapping('coretest', 'Qt6', 'Qt::3DCoreTest', extra = ['COMPONENTS', '3DCoreTest']),
LibraryMapping('crypto-lib', 'Qt6', 'Qt::AppManCrypto', extra = ['COMPONENTS', 'AppManCrypto']),
LibraryMapping('dbus', 'Qt6', 'Qt::DBus', extra = ['COMPONENTS', 'DBus']),
LibraryMapping('designer', 'Qt6', 'Qt::Designer', extra = ['COMPONENTS', 'Designer']),
LibraryMapping('designercomponents', 'Qt6', 'Qt::DesignerComponents', extra = ['COMPONENTS', 'DesignerComponents']),
LibraryMapping('devicediscovery', 'Qt6', 'Qt::DeviceDiscoverySupport', extra = ['COMPONENTS', 'DeviceDiscoverySupport']),
LibraryMapping('devicediscovery_support', 'Qt6', 'Qt::DeviceDiscoverySupport', extra = ['COMPONENTS', 'DeviceDiscoverySupport']),
LibraryMapping('edid', 'Qt6', 'Qt::EdidSupport', extra = ['COMPONENTS', 'EdidSupport']),
LibraryMapping('edid_support', 'Qt6', 'Qt::EdidSupport', extra = ['COMPONENTS', 'EdidSupport']),
LibraryMapping('eglconvenience', 'Qt6', 'Qt::EglSupport', extra = ['COMPONENTS', 'EglSupport']),
LibraryMapping('eglfsdeviceintegration', 'Qt6', 'Qt::EglFSDeviceIntegration', extra = ['COMPONENTS', 'EglFSDeviceIntegration']),
LibraryMapping('eglfs_kms_support', 'Qt6', 'Qt::EglFsKmsSupport', extra = ['COMPONENTS', 'EglFsKmsSupport']),
LibraryMapping('egl_support', 'Qt6', 'Qt::EglSupport', extra = ['COMPONENTS', 'EglSupport']),
LibraryMapping("client", "Qt6", "Qt::WaylandClient", extra=["COMPONENTS", "WaylandClient"]),
LibraryMapping(
"clipboard_support", "Qt6", "Qt::ClipboardSupport", extra=["COMPONENTS", "ClipboardSupport"]
),
LibraryMapping("coap", "Qt6", "Qt::Coap", extra=["COMPONENTS", "Coap"]),
LibraryMapping("common-lib", "Qt6", "Qt::AppManCommon", extra=["COMPONENTS", "AppManCommon"]),
LibraryMapping(
"compositor", "Qt6", "Qt::WaylandCompositor", extra=["COMPONENTS", "WaylandCompositor"]
),
LibraryMapping("concurrent", "Qt6", "Qt::Concurrent", extra=["COMPONENTS", "Concurrent"]),
LibraryMapping("container", "Qt6", "Qt::AxContainer", extra=["COMPONENTS", "AxContainer"]),
LibraryMapping("control", "Qt6", "Qt::AxServer", extra=["COMPONENTS", "AxServer"]),
LibraryMapping(
"core_headers", "Qt6", "Qt::WebEngineCore", extra=["COMPONENTS", "WebEngineCore"]
),
LibraryMapping("core", "Qt6", "Qt::Core", extra=["COMPONENTS", "Core"]),
LibraryMapping("coretest", "Qt6", "Qt::3DCoreTest", extra=["COMPONENTS", "3DCoreTest"]),
LibraryMapping("crypto-lib", "Qt6", "Qt::AppManCrypto", extra=["COMPONENTS", "AppManCrypto"]),
LibraryMapping("dbus", "Qt6", "Qt::DBus", extra=["COMPONENTS", "DBus"]),
LibraryMapping("designer", "Qt6", "Qt::Designer", extra=["COMPONENTS", "Designer"]),
LibraryMapping(
"designercomponents",
"Qt6",
"Qt::DesignerComponents",
extra=["COMPONENTS", "DesignerComponents"],
),
LibraryMapping(
"devicediscovery",
"Qt6",
"Qt::DeviceDiscoverySupport",
extra=["COMPONENTS", "DeviceDiscoverySupport"],
),
LibraryMapping(
"devicediscovery_support",
"Qt6",
"Qt::DeviceDiscoverySupport",
extra=["COMPONENTS", "DeviceDiscoverySupport"],
),
LibraryMapping("edid", "Qt6", "Qt::EdidSupport", extra=["COMPONENTS", "EdidSupport"]),
LibraryMapping("edid_support", "Qt6", "Qt::EdidSupport", extra=["COMPONENTS", "EdidSupport"]),
LibraryMapping("eglconvenience", "Qt6", "Qt::EglSupport", extra=["COMPONENTS", "EglSupport"]),
LibraryMapping(
"eglfsdeviceintegration",
"Qt6",
"Qt::EglFSDeviceIntegration",
extra=["COMPONENTS", "EglFSDeviceIntegration"],
),
LibraryMapping(
"eglfs_kms_support", "Qt6", "Qt::EglFsKmsSupport", extra=["COMPONENTS", "EglFsKmsSupport"]
),
LibraryMapping("egl_support", "Qt6", "Qt::EglSupport", extra=["COMPONENTS", "EglSupport"]),
# enginio: Not needed in Qt6!
LibraryMapping('eventdispatchers', 'Qt6', 'Qt::EventDispatcherSupport', extra = ['COMPONENTS', 'EventDispatcherSupport']),
LibraryMapping('eventdispatcher_support', 'Qt6', 'Qt::EventDispatcherSupport', extra = ['COMPONENTS', 'EventDispatcherSupport']),
LibraryMapping('extras', 'Qt6', 'Qt::3DExtras', extra = ['COMPONENTS', '3DExtras']),
LibraryMapping('fbconvenience', 'Qt6', 'Qt::FbSupport', extra = ['COMPONENTS', 'FbSupport']),
LibraryMapping('fb_support', 'Qt6', 'Qt::FbSupport', extra = ['COMPONENTS', 'FbSupport']),
LibraryMapping('fontdatabase_support', 'Qt6', 'Qt::FontDatabaseSupport', extra = ['COMPONENTS', 'FontDatabaseSupport']),
LibraryMapping('gamepad', 'Qt6', 'Qt::Gamepad', extra = ['COMPONENTS', 'Gamepad']),
LibraryMapping('global', 'Qt6', 'Qt::Core', extra = ['COMPONENTS', 'Core']), # manually added special case
LibraryMapping('glx_support', 'Qt6', 'Qt::GlxSupport', extra = ['COMPONENTS', 'GlxSupport']),
LibraryMapping('graphics_support', 'Qt6', 'Qt::GraphicsSupport', extra = ['COMPONENTS', 'GraphicsSupport']),
LibraryMapping('gsttools', 'Qt6', 'Qt::MultimediaGstTools', extra = ['COMPONENTS', 'MultimediaGstTools']),
LibraryMapping('gui', 'Qt6', 'Qt::Gui', extra = ['COMPONENTS', 'Gui']),
LibraryMapping('help', 'Qt6', 'Qt::Help', extra = ['COMPONENTS', 'Help']),
LibraryMapping('hunspellinputmethod', 'Qt6', 'Qt::HunspellInputMethod', extra = ['COMPONENTS', 'HunspellInputMethod']),
LibraryMapping('input', 'Qt6', 'Qt::InputSupport', extra = ['COMPONENTS', 'InputSupport']),
LibraryMapping('input_support', 'Qt6', 'Qt::InputSupport', extra = ['COMPONENTS', 'InputSupport']),
LibraryMapping('installer-lib', 'Qt6', 'Qt::AppManInstaller', extra = ['COMPONENTS', 'AppManInstaller']),
LibraryMapping('knx', 'Qt6', 'Qt::Knx', extra = ['COMPONENTS', 'Knx']),
LibraryMapping('kmsconvenience', 'Qt6', 'Qt::KmsSupport', extra = ['COMPONENTS', 'KmsSupport']),
LibraryMapping('kms_support', 'Qt6', 'Qt::KmsSupport', extra = ['COMPONENTS', 'KmsSupport']),
LibraryMapping('launcher-lib', 'Qt6', 'Qt::AppManLauncher', extra = ['COMPONENTS', 'AppManLauncher']),
LibraryMapping('lib', 'Qt6', 'Qt::Designer', extra = ['COMPONENTS', 'Designer']),
LibraryMapping('linuxaccessibility_support', 'Qt6', 'Qt::LinuxAccessibilitySupport', extra = ['COMPONENTS', 'LinuxAccessibilitySupport']),
LibraryMapping('location', 'Qt6', 'Qt::Location', extra = ['COMPONENTS', 'Location']),
LibraryMapping('logic', 'Qt6', 'Qt::3DLogic', extra = ['COMPONENTS', '3DLogic']),
LibraryMapping('macextras', 'Qt6', 'Qt::MacExtras', extra = ['COMPONENTS', 'MacExtras']),
LibraryMapping('main-lib', 'Qt6', 'Qt::AppManMain', extra = ['COMPONENTS', 'AppManMain']),
LibraryMapping('manager-lib', 'Qt6', 'Qt::AppManManager', extra = ['COMPONENTS', 'AppManManager']),
LibraryMapping('monitor-lib', 'Qt6', 'Qt::AppManMonitor', extra = ['COMPONENTS', 'AppManMonitor']),
LibraryMapping('mqtt', 'Qt6', 'Qt::Mqtt', extra = ['COMPONENTS', 'Mqtt']),
LibraryMapping('multimedia', 'Qt6', 'Qt::Multimedia', extra = ['COMPONENTS', 'Multimedia']),
LibraryMapping('multimediawidgets', 'Qt6', 'Qt::MultimediaWidgets', extra = ['COMPONENTS', 'MultimediaWidgets']),
LibraryMapping('network', 'Qt6', 'Qt::Network', extra = ['COMPONENTS', 'Network']),
LibraryMapping('networkauth', 'Qt6', 'Qt::NetworkAuth', extra = ['COMPONENTS', 'NetworkAuth']),
LibraryMapping('nfc', 'Qt6', 'Qt::Nfc', extra = ['COMPONENTS', 'Nfc']),
LibraryMapping('oauth', 'Qt6', 'Qt::NetworkAuth', extra = ['COMPONENTS', 'NetworkAuth']),
LibraryMapping('openglextensions', 'Qt6', 'Qt::OpenGLExtensions', extra = ['COMPONENTS', 'OpenGLExtensions']),
LibraryMapping('opengl', 'Qt6', 'Qt::OpenGL', extra = ['COMPONENTS', 'OpenGL']),
LibraryMapping('package-lib', 'Qt6', 'Qt::AppManPackage', extra = ['COMPONENTS', 'AppManPackage']),
LibraryMapping('packetprotocol', 'Qt6', 'Qt::PacketProtocol', extra = ['COMPONENTS', 'PacketProtocol']),
LibraryMapping('particles', 'Qt6', 'Qt::QuickParticles', extra = ['COMPONENTS', 'QuickParticles']),
LibraryMapping('platformcompositor', 'Qt6', 'Qt::PlatformCompositorSupport', extra = ['COMPONENTS', 'PlatformCompositorSupport']),
LibraryMapping('platformcompositor_support', 'Qt6', 'Qt::PlatformCompositorSupport', extra = ['COMPONENTS', 'PlatformCompositorSupport']),
LibraryMapping('plugin-interfaces', 'Qt6', 'Qt::AppManPluginInterfaces', extra = ['COMPONENTS', 'AppManPluginInterfaces']),
LibraryMapping('positioning', 'Qt6', 'Qt::Positioning', extra = ['COMPONENTS', 'Positioning']),
LibraryMapping('positioningquick', 'Qt6', 'Qt::PositioningQuick', extra = ['COMPONENTS', 'PositioningQuick']),
LibraryMapping('printsupport', 'Qt6', 'Qt::PrintSupport', extra = ['COMPONENTS', 'PrintSupport']),
LibraryMapping('purchasing', 'Qt6', 'Qt::Purchasing', extra = ['COMPONENTS', 'Purchasing']),
LibraryMapping('qmldebug', 'Qt6', 'Qt::QmlDebug', extra = ['COMPONENTS', 'QmlDebug']),
LibraryMapping('qmldevtools', 'Qt6', 'Qt::QmlDevTools', extra = ['COMPONENTS', 'QmlDevTools']),
LibraryMapping('qml', 'Qt6', 'Qt::Qml', extra = ['COMPONENTS', 'Qml']),
LibraryMapping('qmlmodels', 'Qt6', 'Qt::QmlModels', extra = ['COMPONENTS', 'QmlModels']),
LibraryMapping('qmltest', 'Qt6', 'Qt::QuickTest', extra = ['COMPONENTS', 'QuickTest']),
LibraryMapping('qtmultimediaquicktools', 'Qt6', 'Qt::MultimediaQuick', extra = ['COMPONENTS', 'MultimediaQuick']),
LibraryMapping('quick3danimation', 'Qt6', 'Qt::3DQuickAnimation', extra = ['COMPONENTS', '3DQuickAnimation']),
LibraryMapping('quick3dextras', 'Qt6', 'Qt::3DQuickExtras', extra = ['COMPONENTS', '3DQuickExtras']),
LibraryMapping('quick3dinput', 'Qt6', 'Qt::3DQuickInput', extra = ['COMPONENTS', '3DQuickInput']),
LibraryMapping('quick3d', 'Qt6', 'Qt::3DQuick', extra = ['COMPONENTS', '3DQuick']),
LibraryMapping('quick3drender', 'Qt6', 'Qt::3DQuickRender', extra = ['COMPONENTS', '3DQuickRender']),
LibraryMapping('quick3dscene2d', 'Qt6', 'Qt::3DQuickScene2D', extra = ['COMPONENTS', '3DQuickScene2D']),
LibraryMapping('quickcontrols2', 'Qt6', 'Qt::QuickControls2', extra = ['COMPONENTS', 'QuickControls2']),
LibraryMapping('quick', 'Qt6', 'Qt::Quick', extra = ['COMPONENTS', 'Quick']),
LibraryMapping('quickshapes', 'Qt6', 'Qt::QuickShapes', extra = ['COMPONENTS', 'QuickShapes']),
LibraryMapping('quicktemplates2', 'Qt6', 'Qt::QuickTemplates2', extra = ['COMPONENTS', 'QuickTemplates2']),
LibraryMapping('quickwidgets', 'Qt6', 'Qt::QuickWidgets', extra = ['COMPONENTS', 'QuickWidgets']),
LibraryMapping('render', 'Qt6', 'Qt::3DRender', extra = ['COMPONENTS', '3DRender']),
LibraryMapping('script', 'Qt6', 'Qt::Script', extra = ['COMPONENTS', 'Script']),
LibraryMapping('scripttools', 'Qt6', 'Qt::ScriptTools', extra = ['COMPONENTS', 'ScriptTools']),
LibraryMapping('sensors', 'Qt6', 'Qt::Sensors', extra = ['COMPONENTS', 'Sensors']),
LibraryMapping('serialport', 'Qt6', 'Qt::SerialPort', extra = ['COMPONENTS', 'SerialPort']),
LibraryMapping('serialbus', 'Qt6', 'Qt::SerialBus', extra = ['COMPONENTS', 'SerialBus']),
LibraryMapping('services', 'Qt6', 'Qt::ServiceSupport', extra = ['COMPONENTS', 'ServiceSupport']),
LibraryMapping('service_support', 'Qt6', 'Qt::ServiceSupport', extra = ['COMPONENTS', 'ServiceSupport']),
LibraryMapping('sql', 'Qt6', 'Qt::Sql', extra = ['COMPONENTS', 'Sql']),
LibraryMapping('svg', 'Qt6', 'Qt::Svg', extra = ['COMPONENTS', 'Svg']),
LibraryMapping('testlib', 'Qt6', 'Qt::Test', extra = ['COMPONENTS', 'Test']),
LibraryMapping('texttospeech', 'Qt6', 'Qt::TextToSpeech', extra = ['COMPONENTS', 'TextToSpeech']),
LibraryMapping('theme_support', 'Qt6', 'Qt::ThemeSupport', extra = ['COMPONENTS', 'ThemeSupport']),
LibraryMapping('tts', 'Qt6', 'Qt::TextToSpeech', extra = ['COMPONENTS', 'TextToSpeech']),
LibraryMapping('uiplugin', 'Qt6', 'Qt::UiPlugin', extra = ['COMPONENTS', 'UiPlugin']),
LibraryMapping('uitools', 'Qt6', 'Qt::UiTools', extra = ['COMPONENTS', 'UiTools']),
LibraryMapping('virtualkeyboard', 'Qt6', 'Qt::VirtualKeyboard', extra = ['COMPONENTS', 'VirtualKeyboard']),
LibraryMapping('vulkan_support', 'Qt6', 'Qt::VulkanSupport', extra = ['COMPONENTS', 'VulkanSupport']),
LibraryMapping('waylandclient', 'Qt6', 'Qt::WaylandClient', extra = ['COMPONENTS', 'WaylandClient']),
LibraryMapping('webchannel', 'Qt6', 'Qt::WebChannel', extra = ['COMPONENTS', 'WebChannel']),
LibraryMapping('webengine', 'Qt6', 'Qt::WebEngine', extra = ['COMPONENTS', 'WebEngine']),
LibraryMapping('webenginewidgets', 'Qt6', 'Qt::WebEngineWidgets', extra = ['COMPONENTS', 'WebEngineWidgets']),
LibraryMapping('websockets', 'Qt6', 'Qt::WebSockets', extra = ['COMPONENTS', 'WebSockets']),
LibraryMapping('webview', 'Qt6', 'Qt::WebView', extra = ['COMPONENTS', 'WebView']),
LibraryMapping('widgets', 'Qt6', 'Qt::Widgets', extra = ['COMPONENTS', 'Widgets']),
LibraryMapping('window-lib', 'Qt6', 'Qt::AppManWindow', extra = ['COMPONENTS', 'AppManWindow']),
LibraryMapping('windowsuiautomation_support', 'Qt6', 'Qt::WindowsUIAutomationSupport', extra = ['COMPONENTS', 'WindowsUIAutomationSupport']),
LibraryMapping('winextras', 'Qt6', 'Qt::WinExtras', extra = ['COMPONENTS', 'WinExtras']),
LibraryMapping('x11extras', 'Qt6', 'Qt::X11Extras', extra = ['COMPONENTS', 'X11Extras']),
LibraryMapping('xcb_qpa_lib', 'Qt6', 'Qt::XcbQpa', extra = ['COMPONENTS', 'XcbQpa']),
LibraryMapping('xkbcommon_support', 'Qt6', 'Qt::XkbCommonSupport', extra = ['COMPONENTS', 'XkbCommonSupport']),
LibraryMapping('xmlpatterns', 'Qt6', 'Qt::XmlPatterns', extra = ['COMPONENTS', 'XmlPatterns']),
LibraryMapping('xml', 'Qt6', 'Qt::Xml', extra = ['COMPONENTS', 'Xml']),
LibraryMapping('qmlworkerscript', 'Qt6', 'Qt::QmlWorkerScript', extra = ['COMPONENTS', 'QmlWorkerScript']),
LibraryMapping('quickparticles', 'Qt6', 'Qt::QuickParticles', extra = ['COMPONENTS', 'QuickParticles'])
LibraryMapping(
"eventdispatchers",
"Qt6",
"Qt::EventDispatcherSupport",
extra=["COMPONENTS", "EventDispatcherSupport"],
),
LibraryMapping(
"eventdispatcher_support",
"Qt6",
"Qt::EventDispatcherSupport",
extra=["COMPONENTS", "EventDispatcherSupport"],
),
LibraryMapping("extras", "Qt6", "Qt::3DExtras", extra=["COMPONENTS", "3DExtras"]),
LibraryMapping("fbconvenience", "Qt6", "Qt::FbSupport", extra=["COMPONENTS", "FbSupport"]),
LibraryMapping("fb_support", "Qt6", "Qt::FbSupport", extra=["COMPONENTS", "FbSupport"]),
LibraryMapping(
"fontdatabase_support",
"Qt6",
"Qt::FontDatabaseSupport",
extra=["COMPONENTS", "FontDatabaseSupport"],
),
LibraryMapping("gamepad", "Qt6", "Qt::Gamepad", extra=["COMPONENTS", "Gamepad"]),
LibraryMapping(
"global", "Qt6", "Qt::Core", extra=["COMPONENTS", "Core"]
), # manually added special case
LibraryMapping("glx_support", "Qt6", "Qt::GlxSupport", extra=["COMPONENTS", "GlxSupport"]),
LibraryMapping(
"graphics_support", "Qt6", "Qt::GraphicsSupport", extra=["COMPONENTS", "GraphicsSupport"]
),
LibraryMapping(
"gsttools", "Qt6", "Qt::MultimediaGstTools", extra=["COMPONENTS", "MultimediaGstTools"]
),
LibraryMapping("gui", "Qt6", "Qt::Gui", extra=["COMPONENTS", "Gui"]),
LibraryMapping("help", "Qt6", "Qt::Help", extra=["COMPONENTS", "Help"]),
LibraryMapping(
"hunspellinputmethod",
"Qt6",
"Qt::HunspellInputMethod",
extra=["COMPONENTS", "HunspellInputMethod"],
),
LibraryMapping("input", "Qt6", "Qt::InputSupport", extra=["COMPONENTS", "InputSupport"]),
LibraryMapping(
"input_support", "Qt6", "Qt::InputSupport", extra=["COMPONENTS", "InputSupport"]
),
LibraryMapping(
"installer-lib", "Qt6", "Qt::AppManInstaller", extra=["COMPONENTS", "AppManInstaller"]
),
LibraryMapping("knx", "Qt6", "Qt::Knx", extra=["COMPONENTS", "Knx"]),
LibraryMapping("kmsconvenience", "Qt6", "Qt::KmsSupport", extra=["COMPONENTS", "KmsSupport"]),
LibraryMapping("kms_support", "Qt6", "Qt::KmsSupport", extra=["COMPONENTS", "KmsSupport"]),
LibraryMapping(
"launcher-lib", "Qt6", "Qt::AppManLauncher", extra=["COMPONENTS", "AppManLauncher"]
),
LibraryMapping("lib", "Qt6", "Qt::Designer", extra=["COMPONENTS", "Designer"]),
LibraryMapping(
"linuxaccessibility_support",
"Qt6",
"Qt::LinuxAccessibilitySupport",
extra=["COMPONENTS", "LinuxAccessibilitySupport"],
),
LibraryMapping("location", "Qt6", "Qt::Location", extra=["COMPONENTS", "Location"]),
LibraryMapping("logic", "Qt6", "Qt::3DLogic", extra=["COMPONENTS", "3DLogic"]),
LibraryMapping("macextras", "Qt6", "Qt::MacExtras", extra=["COMPONENTS", "MacExtras"]),
LibraryMapping("main-lib", "Qt6", "Qt::AppManMain", extra=["COMPONENTS", "AppManMain"]),
LibraryMapping(
"manager-lib", "Qt6", "Qt::AppManManager", extra=["COMPONENTS", "AppManManager"]
),
LibraryMapping(
"monitor-lib", "Qt6", "Qt::AppManMonitor", extra=["COMPONENTS", "AppManMonitor"]
),
LibraryMapping("mqtt", "Qt6", "Qt::Mqtt", extra=["COMPONENTS", "Mqtt"]),
LibraryMapping("multimedia", "Qt6", "Qt::Multimedia", extra=["COMPONENTS", "Multimedia"]),
LibraryMapping(
"multimediawidgets",
"Qt6",
"Qt::MultimediaWidgets",
extra=["COMPONENTS", "MultimediaWidgets"],
),
LibraryMapping("network", "Qt6", "Qt::Network", extra=["COMPONENTS", "Network"]),
LibraryMapping("networkauth", "Qt6", "Qt::NetworkAuth", extra=["COMPONENTS", "NetworkAuth"]),
LibraryMapping("nfc", "Qt6", "Qt::Nfc", extra=["COMPONENTS", "Nfc"]),
LibraryMapping("oauth", "Qt6", "Qt::NetworkAuth", extra=["COMPONENTS", "NetworkAuth"]),
LibraryMapping(
"openglextensions", "Qt6", "Qt::OpenGLExtensions", extra=["COMPONENTS", "OpenGLExtensions"]
),
LibraryMapping("opengl", "Qt6", "Qt::OpenGL", extra=["COMPONENTS", "OpenGL"]),
LibraryMapping(
"package-lib", "Qt6", "Qt::AppManPackage", extra=["COMPONENTS", "AppManPackage"]
),
LibraryMapping(
"packetprotocol", "Qt6", "Qt::PacketProtocol", extra=["COMPONENTS", "PacketProtocol"]
),
LibraryMapping(
"particles", "Qt6", "Qt::QuickParticles", extra=["COMPONENTS", "QuickParticles"]
),
LibraryMapping(
"platformcompositor",
"Qt6",
"Qt::PlatformCompositorSupport",
extra=["COMPONENTS", "PlatformCompositorSupport"],
),
LibraryMapping(
"platformcompositor_support",
"Qt6",
"Qt::PlatformCompositorSupport",
extra=["COMPONENTS", "PlatformCompositorSupport"],
),
LibraryMapping(
"plugin-interfaces",
"Qt6",
"Qt::AppManPluginInterfaces",
extra=["COMPONENTS", "AppManPluginInterfaces"],
),
LibraryMapping("positioning", "Qt6", "Qt::Positioning", extra=["COMPONENTS", "Positioning"]),
LibraryMapping(
"positioningquick", "Qt6", "Qt::PositioningQuick", extra=["COMPONENTS", "PositioningQuick"]
),
LibraryMapping("printsupport", "Qt6", "Qt::PrintSupport", extra=["COMPONENTS", "PrintSupport"]),
LibraryMapping("purchasing", "Qt6", "Qt::Purchasing", extra=["COMPONENTS", "Purchasing"]),
LibraryMapping("qmldebug", "Qt6", "Qt::QmlDebug", extra=["COMPONENTS", "QmlDebug"]),
LibraryMapping("qmldevtools", "Qt6", "Qt::QmlDevTools", extra=["COMPONENTS", "QmlDevTools"]),
LibraryMapping("qml", "Qt6", "Qt::Qml", extra=["COMPONENTS", "Qml"]),
LibraryMapping("qmlmodels", "Qt6", "Qt::QmlModels", extra=["COMPONENTS", "QmlModels"]),
LibraryMapping("qmltest", "Qt6", "Qt::QuickTest", extra=["COMPONENTS", "QuickTest"]),
LibraryMapping(
"qtmultimediaquicktools",
"Qt6",
"Qt::MultimediaQuick",
extra=["COMPONENTS", "MultimediaQuick"],
),
LibraryMapping(
"quick3danimation", "Qt6", "Qt::3DQuickAnimation", extra=["COMPONENTS", "3DQuickAnimation"]
),
LibraryMapping(
"quick3dextras", "Qt6", "Qt::3DQuickExtras", extra=["COMPONENTS", "3DQuickExtras"]
),
LibraryMapping("quick3dinput", "Qt6", "Qt::3DQuickInput", extra=["COMPONENTS", "3DQuickInput"]),
LibraryMapping("quick3d", "Qt6", "Qt::3DQuick", extra=["COMPONENTS", "3DQuick"]),
LibraryMapping(
"quick3drender", "Qt6", "Qt::3DQuickRender", extra=["COMPONENTS", "3DQuickRender"]
),
LibraryMapping(
"quick3dscene2d", "Qt6", "Qt::3DQuickScene2D", extra=["COMPONENTS", "3DQuickScene2D"]
),
LibraryMapping(
"quickcontrols2", "Qt6", "Qt::QuickControls2", extra=["COMPONENTS", "QuickControls2"]
),
LibraryMapping("quick", "Qt6", "Qt::Quick", extra=["COMPONENTS", "Quick"]),
LibraryMapping("quickshapes", "Qt6", "Qt::QuickShapes", extra=["COMPONENTS", "QuickShapes"]),
LibraryMapping(
"quicktemplates2", "Qt6", "Qt::QuickTemplates2", extra=["COMPONENTS", "QuickTemplates2"]
),
LibraryMapping("quickwidgets", "Qt6", "Qt::QuickWidgets", extra=["COMPONENTS", "QuickWidgets"]),
LibraryMapping("render", "Qt6", "Qt::3DRender", extra=["COMPONENTS", "3DRender"]),
LibraryMapping("script", "Qt6", "Qt::Script", extra=["COMPONENTS", "Script"]),
LibraryMapping("scripttools", "Qt6", "Qt::ScriptTools", extra=["COMPONENTS", "ScriptTools"]),
LibraryMapping("sensors", "Qt6", "Qt::Sensors", extra=["COMPONENTS", "Sensors"]),
LibraryMapping("serialport", "Qt6", "Qt::SerialPort", extra=["COMPONENTS", "SerialPort"]),
LibraryMapping("serialbus", "Qt6", "Qt::SerialBus", extra=["COMPONENTS", "SerialBus"]),
LibraryMapping("services", "Qt6", "Qt::ServiceSupport", extra=["COMPONENTS", "ServiceSupport"]),
LibraryMapping(
"service_support", "Qt6", "Qt::ServiceSupport", extra=["COMPONENTS", "ServiceSupport"]
),
LibraryMapping("sql", "Qt6", "Qt::Sql", extra=["COMPONENTS", "Sql"]),
LibraryMapping("svg", "Qt6", "Qt::Svg", extra=["COMPONENTS", "Svg"]),
LibraryMapping("testlib", "Qt6", "Qt::Test", extra=["COMPONENTS", "Test"]),
LibraryMapping("texttospeech", "Qt6", "Qt::TextToSpeech", extra=["COMPONENTS", "TextToSpeech"]),
LibraryMapping(
"theme_support", "Qt6", "Qt::ThemeSupport", extra=["COMPONENTS", "ThemeSupport"]
),
LibraryMapping("tts", "Qt6", "Qt::TextToSpeech", extra=["COMPONENTS", "TextToSpeech"]),
LibraryMapping("uiplugin", "Qt6", "Qt::UiPlugin", extra=["COMPONENTS", "UiPlugin"]),
LibraryMapping("uitools", "Qt6", "Qt::UiTools", extra=["COMPONENTS", "UiTools"]),
LibraryMapping(
"virtualkeyboard", "Qt6", "Qt::VirtualKeyboard", extra=["COMPONENTS", "VirtualKeyboard"]
),
LibraryMapping(
"vulkan_support", "Qt6", "Qt::VulkanSupport", extra=["COMPONENTS", "VulkanSupport"]
),
LibraryMapping(
"waylandclient", "Qt6", "Qt::WaylandClient", extra=["COMPONENTS", "WaylandClient"]
),
LibraryMapping("webchannel", "Qt6", "Qt::WebChannel", extra=["COMPONENTS", "WebChannel"]),
LibraryMapping("webengine", "Qt6", "Qt::WebEngine", extra=["COMPONENTS", "WebEngine"]),
LibraryMapping(
"webenginewidgets", "Qt6", "Qt::WebEngineWidgets", extra=["COMPONENTS", "WebEngineWidgets"]
),
LibraryMapping("websockets", "Qt6", "Qt::WebSockets", extra=["COMPONENTS", "WebSockets"]),
LibraryMapping("webview", "Qt6", "Qt::WebView", extra=["COMPONENTS", "WebView"]),
LibraryMapping("widgets", "Qt6", "Qt::Widgets", extra=["COMPONENTS", "Widgets"]),
LibraryMapping("window-lib", "Qt6", "Qt::AppManWindow", extra=["COMPONENTS", "AppManWindow"]),
LibraryMapping(
"windowsuiautomation_support",
"Qt6",
"Qt::WindowsUIAutomationSupport",
extra=["COMPONENTS", "WindowsUIAutomationSupport"],
),
LibraryMapping("winextras", "Qt6", "Qt::WinExtras", extra=["COMPONENTS", "WinExtras"]),
LibraryMapping("x11extras", "Qt6", "Qt::X11Extras", extra=["COMPONENTS", "X11Extras"]),
LibraryMapping("xcb_qpa_lib", "Qt6", "Qt::XcbQpa", extra=["COMPONENTS", "XcbQpa"]),
LibraryMapping(
"xkbcommon_support", "Qt6", "Qt::XkbCommonSupport", extra=["COMPONENTS", "XkbCommonSupport"]
),
LibraryMapping("xmlpatterns", "Qt6", "Qt::XmlPatterns", extra=["COMPONENTS", "XmlPatterns"]),
LibraryMapping("xml", "Qt6", "Qt::Xml", extra=["COMPONENTS", "Xml"]),
LibraryMapping(
"qmlworkerscript", "Qt6", "Qt::QmlWorkerScript", extra=["COMPONENTS", "QmlWorkerScript"]
),
LibraryMapping(
"quickparticles", "Qt6", "Qt::QuickParticles", extra=["COMPONENTS", "QuickParticles"]
)
# qtzlib: No longer supported.
]
# Note that the library map is adjusted dynamically further down.
_library_map = [
# 3rd party:
LibraryMapping('atspi', 'ATSPI2', 'PkgConfig::ATSPI2'),
LibraryMapping('corewlan', None, None),
LibraryMapping('cups', 'Cups', 'Cups::Cups'),
LibraryMapping('db2', 'DB2', 'DB2::DB2'),
LibraryMapping('dbus', 'WrapDBus1', 'dbus-1', resultVariable="DBus1"),
LibraryMapping('doubleconversion', None, None),
LibraryMapping('drm', 'Libdrm', 'Libdrm::Libdrm'),
LibraryMapping('egl', 'EGL', 'EGL::EGL'),
LibraryMapping('flite', 'Flite', 'Flite::Flite'),
LibraryMapping('flite_alsa', 'ALSA', 'ALSA::ALSA'),
LibraryMapping('fontconfig', 'Fontconfig', 'Fontconfig::Fontconfig', resultVariable="FONTCONFIG"),
LibraryMapping('freetype', 'WrapFreetype', 'WrapFreetype::WrapFreetype', extra=['REQUIRED']),
LibraryMapping('gbm', 'gbm', 'gbm::gbm'),
LibraryMapping('glib', 'GLIB2', 'GLIB2::GLIB2'),
LibraryMapping('gnu_iconv', None, None),
LibraryMapping('gtk3', 'GTK3', 'PkgConfig::GTK3'),
LibraryMapping('harfbuzz', 'harfbuzz', 'harfbuzz::harfbuzz'),
LibraryMapping('host_dbus', None, None),
LibraryMapping('icu', 'ICU', 'ICU::i18n ICU::uc ICU::data', extra=['COMPONENTS', 'i18n', 'uc', 'data']),
LibraryMapping('journald', 'Libsystemd', 'PkgConfig::Libsystemd'),
LibraryMapping('jpeg', 'JPEG', 'JPEG::JPEG'), # see also libjpeg
LibraryMapping('libatomic', 'Atomic', 'Atomic'),
LibraryMapping('libclang', 'WrapLibClang', 'WrapLibClang::WrapLibClang'),
LibraryMapping('libdl', None, '${CMAKE_DL_LIBS}'),
LibraryMapping('libinput', 'Libinput', 'Libinput::Libinput'),
LibraryMapping('libjpeg', 'JPEG', 'JPEG::JPEG'), # see also jpeg
LibraryMapping('libpng', 'PNG', 'PNG::PNG'),
LibraryMapping('libproxy', 'Libproxy', 'PkgConfig::Libproxy'),
LibraryMapping('librt', 'WrapRt','WrapRt'),
LibraryMapping('libudev', 'Libudev', 'PkgConfig::Libudev'),
LibraryMapping('lttng-ust', 'LTTngUST', 'LTTng::UST', resultVariable='LTTNGUST'),
LibraryMapping('mtdev', 'Mtdev', 'PkgConfig::Mtdev'),
LibraryMapping('mysql', 'MySQL', 'MySQL::MySQL'),
LibraryMapping('odbc', 'ODBC', 'ODBC::ODBC'),
LibraryMapping('opengl_es2', 'GLESv2', 'GLESv2::GLESv2'),
LibraryMapping('opengl', 'OpenGL', 'OpenGL::GL', resultVariable='OpenGL_OpenGL'),
LibraryMapping('openssl_headers', 'OpenSSL', 'OpenSSL::SSL_nolink', resultVariable='OPENSSL_INCLUDE_DIR', appendFoundSuffix=False),
LibraryMapping('openssl', 'OpenSSL', 'OpenSSL::SSL'),
LibraryMapping('oci', 'Oracle', 'Oracle::OCI'),
LibraryMapping('pcre2', 'WrapPCRE2', 'WrapPCRE2::WrapPCRE2', extra = ['REQUIRED']),
LibraryMapping('posix_iconv', None, None),
LibraryMapping('pps', 'PPS', 'PPS::PPS'),
LibraryMapping('psql', 'PostgreSQL', 'PostgreSQL::PostgreSQL'),
LibraryMapping('slog2', 'Slog2', 'Slog2::Slog2'),
LibraryMapping('speechd', 'SpeechDispatcher', 'SpeechDispatcher::SpeechDispatcher'),
LibraryMapping('sqlite2', None, None), # No more sqlite2 support in Qt6!
LibraryMapping('sqlite3', 'SQLite3', 'SQLite::SQLite3'),
LibraryMapping('sun_iconv', None, None),
LibraryMapping('tslib', 'Tslib', 'PkgConfig::Tslib'),
LibraryMapping('udev', 'Libudev', 'PkgConfig::Libudev'),
LibraryMapping('udev', 'Libudev', 'PkgConfig::Libudev'), # see also libudev!
LibraryMapping('vulkan', 'Vulkan', 'Vulkan::Vulkan'),
LibraryMapping('wayland-server', 'Wayland', 'Wayland::Server'),
LibraryMapping('wayland-client', 'Wayland', 'Wayland::Client'),
LibraryMapping('wayland-cursor', 'Wayland', 'Wayland::Cursor'),
LibraryMapping('wayland-egl', 'Wayland', 'Wayland::Egl'),
LibraryMapping('x11sm', 'X11', '${X11_SM_LIB} ${X11_ICE_LIB}', resultVariable="X11_SM"),
LibraryMapping('xcb', 'XCB', 'XCB::XCB', extra = ['1.9'], resultVariable='TARGET XCB::XCB', appendFoundSuffix=False),
LibraryMapping('xcb_glx', 'XCB', 'XCB::GLX', extra = ['COMPONENTS', 'GLX'], resultVariable='XCB_GLX'),
LibraryMapping('xcb_icccm', 'XCB', 'XCB::ICCCM', extra = ['COMPONENTS', 'ICCCM'], resultVariable='XCB_ICCCM'),
LibraryMapping('xcb_image', 'XCB', 'XCB::IMAGE', extra = ['COMPONENTS', 'IMAGE'], resultVariable='XCB_IMAGE'),
LibraryMapping('xcb_keysyms', 'XCB', 'XCB::KEYSYMS', extra = ['COMPONENTS', 'KEYSYMS'], resultVariable='XCB_KEYSYMS'),
LibraryMapping('xcb_randr', 'XCB', 'XCB::RANDR', extra = ['COMPONENTS', 'RANDR'], resultVariable='XCB_RANDR'),
LibraryMapping('xcb_render', 'XCB', 'XCB::RENDER', extra = ['COMPONENTS', 'RENDER'], resultVariable='XCB_RENDER'),
LibraryMapping('xcb_renderutil', 'XCB', 'XCB::RENDERUTIL', extra = ['COMPONENTS', 'RENDERUTIL'], resultVariable='XCB_RENDERUTIL'),
LibraryMapping('xcb_shape', 'XCB', 'XCB::SHAPE', extra = ['COMPONENTS', 'SHAPE'], resultVariable='XCB_SHAPE'),
LibraryMapping('xcb_shm', 'XCB', 'XCB::SHM', extra = ['COMPONENTS', 'SHM'], resultVariable='XCB_SHM'),
LibraryMapping('xcb_sync', 'XCB', 'XCB::SYNC', extra = ['COMPONENTS', 'SYNC'], resultVariable='XCB_SYNC'),
LibraryMapping('xcb_xfixes', 'XCB', 'XCB::XFIXES', extra = ['COMPONENTS', 'XFIXES'], resultVariable='XCB_XFIXES'),
LibraryMapping('xcb_xinerama', 'XCB', 'XCB::XINERAMA', extra = ['COMPONENTS', 'XINERAMA'], resultVariable='XCB_XINERAMA'),
LibraryMapping('xcb_xinput', 'XCB', 'XCB::XINPUT', extra = ['COMPONENTS', 'XINPUT'], resultVariable='XCB_XINPUT'),
LibraryMapping('xcb_xkb', 'XCB', 'XCB::XKB', extra = ['COMPONENTS', 'XKB'], resultVariable='XCB_XKB'),
LibraryMapping('xcb_xlib', 'X11_XCB', 'X11::XCB'),
LibraryMapping('xkbcommon_evdev', 'XKB', 'XKB::XKB', extra = ['0.4.1']), # see also xkbcommon
LibraryMapping('xkbcommon_x11', 'XKB', 'XKB::XKB', extra = ['0.4.1']), # see also xkbcommon
LibraryMapping('xkbcommon', 'XKB', 'XKB::XKB', extra = ['0.4.1']),
LibraryMapping('xlib', 'X11', 'X11::XCB'), # FIXME: Is this correct?
LibraryMapping('xrender', 'XRender', 'PkgConfig::XRender'),
LibraryMapping('zlib', 'ZLIB', 'ZLIB::ZLIB', extra=['REQUIRED']),
LibraryMapping('zstd', 'ZSTD', 'ZSTD::ZSTD'),
LibraryMapping('tiff', 'TIFF', 'TIFF::TIFF'),
LibraryMapping('webp', 'WrapWebP', 'WrapWebP::WrapWebP'),
LibraryMapping('jasper', 'WrapJasper', 'WrapJasper::WrapJasper'),
LibraryMapping("atspi", "ATSPI2", "PkgConfig::ATSPI2"),
LibraryMapping("corewlan", None, None),
LibraryMapping("cups", "Cups", "Cups::Cups"),
LibraryMapping("db2", "DB2", "DB2::DB2"),
LibraryMapping("dbus", "WrapDBus1", "dbus-1", resultVariable="DBus1"),
LibraryMapping("doubleconversion", None, None),
LibraryMapping("drm", "Libdrm", "Libdrm::Libdrm"),
LibraryMapping("egl", "EGL", "EGL::EGL"),
LibraryMapping("flite", "Flite", "Flite::Flite"),
LibraryMapping("flite_alsa", "ALSA", "ALSA::ALSA"),
LibraryMapping(
"fontconfig", "Fontconfig", "Fontconfig::Fontconfig", resultVariable="FONTCONFIG"
),
LibraryMapping("freetype", "WrapFreetype", "WrapFreetype::WrapFreetype", extra=["REQUIRED"]),
LibraryMapping("gbm", "gbm", "gbm::gbm"),
LibraryMapping("glib", "GLIB2", "GLIB2::GLIB2"),
LibraryMapping("gnu_iconv", None, None),
LibraryMapping("gtk3", "GTK3", "PkgConfig::GTK3"),
LibraryMapping("harfbuzz", "harfbuzz", "harfbuzz::harfbuzz"),
LibraryMapping("host_dbus", None, None),
LibraryMapping(
"icu", "ICU", "ICU::i18n ICU::uc ICU::data", extra=["COMPONENTS", "i18n", "uc", "data"]
),
LibraryMapping("journald", "Libsystemd", "PkgConfig::Libsystemd"),
LibraryMapping("jpeg", "JPEG", "JPEG::JPEG"), # see also libjpeg
LibraryMapping("libatomic", "Atomic", "Atomic"),
LibraryMapping("libclang", "WrapLibClang", "WrapLibClang::WrapLibClang"),
LibraryMapping("libdl", None, "${CMAKE_DL_LIBS}"),
LibraryMapping("libinput", "Libinput", "Libinput::Libinput"),
LibraryMapping("libjpeg", "JPEG", "JPEG::JPEG"), # see also jpeg
LibraryMapping("libpng", "PNG", "PNG::PNG"),
LibraryMapping("libproxy", "Libproxy", "PkgConfig::Libproxy"),
LibraryMapping("librt", "WrapRt", "WrapRt"),
LibraryMapping("libudev", "Libudev", "PkgConfig::Libudev"),
LibraryMapping("lttng-ust", "LTTngUST", "LTTng::UST", resultVariable="LTTNGUST"),
LibraryMapping("mtdev", "Mtdev", "PkgConfig::Mtdev"),
LibraryMapping("mysql", "MySQL", "MySQL::MySQL"),
LibraryMapping("odbc", "ODBC", "ODBC::ODBC"),
LibraryMapping("opengl_es2", "GLESv2", "GLESv2::GLESv2"),
LibraryMapping("opengl", "OpenGL", "OpenGL::GL", resultVariable="OpenGL_OpenGL"),
LibraryMapping(
"openssl_headers",
"OpenSSL",
"OpenSSL::SSL_nolink",
resultVariable="OPENSSL_INCLUDE_DIR",
appendFoundSuffix=False,
),
LibraryMapping("openssl", "OpenSSL", "OpenSSL::SSL"),
LibraryMapping("oci", "Oracle", "Oracle::OCI"),
LibraryMapping("pcre2", "WrapPCRE2", "WrapPCRE2::WrapPCRE2", extra=["REQUIRED"]),
LibraryMapping("posix_iconv", None, None),
LibraryMapping("pps", "PPS", "PPS::PPS"),
LibraryMapping("psql", "PostgreSQL", "PostgreSQL::PostgreSQL"),
LibraryMapping("slog2", "Slog2", "Slog2::Slog2"),
LibraryMapping("speechd", "SpeechDispatcher", "SpeechDispatcher::SpeechDispatcher"),
LibraryMapping("sqlite2", None, None), # No more sqlite2 support in Qt6!
LibraryMapping("sqlite3", "SQLite3", "SQLite::SQLite3"),
LibraryMapping("sun_iconv", None, None),
LibraryMapping("tslib", "Tslib", "PkgConfig::Tslib"),
LibraryMapping("udev", "Libudev", "PkgConfig::Libudev"),
LibraryMapping("udev", "Libudev", "PkgConfig::Libudev"), # see also libudev!
LibraryMapping("vulkan", "Vulkan", "Vulkan::Vulkan"),
LibraryMapping("wayland-server", "Wayland", "Wayland::Server"),
LibraryMapping("wayland-client", "Wayland", "Wayland::Client"),
LibraryMapping("wayland-cursor", "Wayland", "Wayland::Cursor"),
LibraryMapping("wayland-egl", "Wayland", "Wayland::Egl"),
LibraryMapping("x11sm", "X11", "${X11_SM_LIB} ${X11_ICE_LIB}", resultVariable="X11_SM"),
LibraryMapping(
"xcb",
"XCB",
"XCB::XCB",
extra=["1.9"],
resultVariable="TARGET XCB::XCB",
appendFoundSuffix=False,
),
LibraryMapping(
"xcb_glx", "XCB", "XCB::GLX", extra=["COMPONENTS", "GLX"], resultVariable="XCB_GLX"
),
LibraryMapping(
"xcb_icccm", "XCB", "XCB::ICCCM", extra=["COMPONENTS", "ICCCM"], resultVariable="XCB_ICCCM"
),
LibraryMapping(
"xcb_image", "XCB", "XCB::IMAGE", extra=["COMPONENTS", "IMAGE"], resultVariable="XCB_IMAGE"
),
LibraryMapping(
"xcb_keysyms",
"XCB",
"XCB::KEYSYMS",
extra=["COMPONENTS", "KEYSYMS"],
resultVariable="XCB_KEYSYMS",
),
LibraryMapping(
"xcb_randr", "XCB", "XCB::RANDR", extra=["COMPONENTS", "RANDR"], resultVariable="XCB_RANDR"
),
LibraryMapping(
"xcb_render",
"XCB",
"XCB::RENDER",
extra=["COMPONENTS", "RENDER"],
resultVariable="XCB_RENDER",
),
LibraryMapping(
"xcb_renderutil",
"XCB",
"XCB::RENDERUTIL",
extra=["COMPONENTS", "RENDERUTIL"],
resultVariable="XCB_RENDERUTIL",
),
LibraryMapping(
"xcb_shape", "XCB", "XCB::SHAPE", extra=["COMPONENTS", "SHAPE"], resultVariable="XCB_SHAPE"
),
LibraryMapping(
"xcb_shm", "XCB", "XCB::SHM", extra=["COMPONENTS", "SHM"], resultVariable="XCB_SHM"
),
LibraryMapping(
"xcb_sync", "XCB", "XCB::SYNC", extra=["COMPONENTS", "SYNC"], resultVariable="XCB_SYNC"
),
LibraryMapping(
"xcb_xfixes",
"XCB",
"XCB::XFIXES",
extra=["COMPONENTS", "XFIXES"],
resultVariable="XCB_XFIXES",
),
LibraryMapping(
"xcb_xinerama",
"XCB",
"XCB::XINERAMA",
extra=["COMPONENTS", "XINERAMA"],
resultVariable="XCB_XINERAMA",
),
LibraryMapping(
"xcb_xinput",
"XCB",
"XCB::XINPUT",
extra=["COMPONENTS", "XINPUT"],
resultVariable="XCB_XINPUT",
),
LibraryMapping(
"xcb_xkb", "XCB", "XCB::XKB", extra=["COMPONENTS", "XKB"], resultVariable="XCB_XKB"
),
LibraryMapping("xcb_xlib", "X11_XCB", "X11::XCB"),
LibraryMapping("xkbcommon_evdev", "XKB", "XKB::XKB", extra=["0.4.1"]), # see also xkbcommon
LibraryMapping("xkbcommon_x11", "XKB", "XKB::XKB", extra=["0.4.1"]), # see also xkbcommon
LibraryMapping("xkbcommon", "XKB", "XKB::XKB", extra=["0.4.1"]),
LibraryMapping("xlib", "X11", "X11::XCB"), # FIXME: Is this correct?
LibraryMapping("xrender", "XRender", "PkgConfig::XRender"),
LibraryMapping("zlib", "ZLIB", "ZLIB::ZLIB", extra=["REQUIRED"]),
LibraryMapping("zstd", "ZSTD", "ZSTD::ZSTD"),
LibraryMapping("tiff", "TIFF", "TIFF::TIFF"),
LibraryMapping("webp", "WrapWebP", "WrapWebP::WrapWebP"),
LibraryMapping("jasper", "WrapJasper", "WrapJasper::WrapJasper"),
]
@ -283,10 +504,10 @@ def _adjust_library_map():
# We don't want to get pages of package not found messages on
# Windows and macOS, and this also improves configure time on
# those platforms.
linux_package_prefixes = ['xcb', 'x11', 'xkb', 'xrender', 'xlib', 'wayland']
linux_package_prefixes = ["xcb", "x11", "xkb", "xrender", "xlib", "wayland"]
for i, _ in enumerate(_library_map):
if any([_library_map[i].soName.startswith(p) for p in linux_package_prefixes]):
_library_map[i].emit_if = 'config.linux'
_library_map[i].emit_if = "config.linux"
_adjust_library_map()
@ -308,7 +529,7 @@ def find_qt_library_mapping(soName: str) -> typing.Optional[LibraryMapping]:
def find_library_info_for_target(targetName: str) -> typing.Optional[LibraryMapping]:
qt_target = targetName
if targetName.endswith('Private'):
if targetName.endswith("Private"):
qt_target = qt_target[:-7]
for i in _qt_library_map:
@ -323,61 +544,61 @@ def find_library_info_for_target(targetName: str) -> typing.Optional[LibraryMapp
def featureName(input: str) -> str:
replacement_char = '_'
if input.startswith('c++'):
replacement_char = 'x'
return re.sub(r'[^a-zA-Z0-9_]', replacement_char, input)
replacement_char = "_"
if input.startswith("c++"):
replacement_char = "x"
return re.sub(r"[^a-zA-Z0-9_]", replacement_char, input)
def map_qt_library(lib: str) -> str:
private = False
if lib.endswith('-private'):
if lib.endswith("-private"):
private = True
lib = lib[:-8]
mapped = find_qt_library_mapping(lib)
qt_name = lib
if mapped:
assert mapped.targetName # Qt libs must have a target name set
assert mapped.targetName # Qt libs must have a target name set
qt_name = mapped.targetName
if private:
qt_name += 'Private'
qt_name += "Private"
return qt_name
platform_mapping = {
'win32': 'WIN32',
'win': 'WIN32',
'unix': 'UNIX',
'darwin': 'APPLE',
'linux': 'LINUX',
'integrity': 'INTEGRITY',
'qnx': 'QNX',
'vxworks': 'VXWORKS',
'hpux': 'HPUX',
'nacl': 'NACL',
'android': 'ANDROID',
'android-embedded': 'ANDROID_EMBEDDED',
'uikit': 'APPLE_UIKIT',
'tvos': 'APPLE_TVOS',
'watchos': 'APPLE_WATCHOS',
'winrt': 'WINRT',
'wasm': 'WASM',
'msvc': 'MSVC',
'clang': 'CLANG',
'gcc': 'GCC',
'icc': 'ICC',
'intel_icc': 'ICC',
'osx': 'APPLE_OSX',
'ios': 'APPLE_IOS',
'freebsd': 'FREEBSD',
'openbsd': 'OPENBSD',
'netbsd': 'NETBSD',
'haiku': 'HAIKU',
'netbsd': 'NETBSD',
'mac': 'APPLE',
'macx': 'APPLE_OSX',
'macos': 'APPLE_OSX',
'macx-icc': '(APPLE_OSX AND ICC)',
"win32": "WIN32",
"win": "WIN32",
"unix": "UNIX",
"darwin": "APPLE",
"linux": "LINUX",
"integrity": "INTEGRITY",
"qnx": "QNX",
"vxworks": "VXWORKS",
"hpux": "HPUX",
"nacl": "NACL",
"android": "ANDROID",
"android-embedded": "ANDROID_EMBEDDED",
"uikit": "APPLE_UIKIT",
"tvos": "APPLE_TVOS",
"watchos": "APPLE_WATCHOS",
"winrt": "WINRT",
"wasm": "WASM",
"msvc": "MSVC",
"clang": "CLANG",
"gcc": "GCC",
"icc": "ICC",
"intel_icc": "ICC",
"osx": "APPLE_OSX",
"ios": "APPLE_IOS",
"freebsd": "FREEBSD",
"openbsd": "OPENBSD",
"netbsd": "NETBSD",
"haiku": "HAIKU",
"netbsd": "NETBSD",
"mac": "APPLE",
"macx": "APPLE_OSX",
"macos": "APPLE_OSX",
"macx-icc": "(APPLE_OSX AND ICC)",
}
@ -387,7 +608,7 @@ def map_platform(platform: str) -> str:
def is_known_3rd_party_library(lib: str) -> bool:
if lib.endswith('/nolink') or lib.endswith('_nolink'):
if lib.endswith("/nolink") or lib.endswith("_nolink"):
lib = lib[:-7]
mapping = find_3rd_party_library_mapping(lib)
@ -395,20 +616,19 @@ def is_known_3rd_party_library(lib: str) -> bool:
def map_3rd_party_library(lib: str) -> str:
libpostfix = ''
if lib.endswith('/nolink'):
libpostfix = ""
if lib.endswith("/nolink"):
lib = lib[:-7]
libpostfix = '_nolink'
libpostfix = "_nolink"
mapping = find_3rd_party_library_mapping(lib)
if not mapping or not mapping.targetName:
return lib
return mapping.targetName + libpostfix
def generate_find_package_info(lib: LibraryMapping,
use_qt_find_package: bool=True, *,
indent: int = 0,
emit_if: str = '') -> str:
def generate_find_package_info(
lib: LibraryMapping, use_qt_find_package: bool = True, *, indent: int = 0, emit_if: str = ""
) -> str:
isRequired = False
extra = lib.extra.copy()
@ -418,40 +638,41 @@ def generate_find_package_info(lib: LibraryMapping,
extra.remove("REQUIRED")
cmake_target_name = lib.targetName
assert(cmake_target_name);
assert cmake_target_name
# _nolink or not does not matter at this point:
if cmake_target_name.endswith('_nolink') or cmake_target_name.endswith('/nolink'):
if cmake_target_name.endswith("_nolink") or cmake_target_name.endswith("/nolink"):
cmake_target_name = cmake_target_name[:-7]
if cmake_target_name and use_qt_find_package:
extra += ['PROVIDED_TARGETS', cmake_target_name]
extra += ["PROVIDED_TARGETS", cmake_target_name]
result = ''
one_ind = ' '
result = ""
one_ind = " "
ind = one_ind * indent
if use_qt_find_package:
if extra:
result = '{}qt_find_package({} {})\n'.format(ind, lib.packageName, ' '.join(extra))
result = "{}qt_find_package({} {})\n".format(ind, lib.packageName, " ".join(extra))
else:
result = '{}qt_find_package({})\n'.format(ind, lib.packageName)
result = "{}qt_find_package({})\n".format(ind, lib.packageName)
if isRequired:
result += '{}set_package_properties({} PROPERTIES TYPE REQUIRED)\n'.format(ind, lib.packageName)
result += "{}set_package_properties({} PROPERTIES TYPE REQUIRED)\n".format(
ind, lib.packageName
)
else:
if extra:
result = '{}find_package({} {})\n'.format(ind, lib.packageName, ' '.join(extra))
result = "{}find_package({} {})\n".format(ind, lib.packageName, " ".join(extra))
else:
result = '{}find_package({})\n'.format(ind, lib.packageName)
result = "{}find_package({})\n".format(ind, lib.packageName)
# If a package should be found only in certain conditions, wrap
# the find_package call within that condition.
if emit_if:
result = "if(({emit_if}) OR QT_FIND_ALL_PACKAGES_ALWAYS)\n" \
"{ind}{result}endif()\n".format(emit_if=emit_if,
result=result,
ind=one_ind)
result = "if(({emit_if}) OR QT_FIND_ALL_PACKAGES_ALWAYS)\n" "{ind}{result}endif()\n".format(
emit_if=emit_if, result=result, ind=one_ind
)
return result

View File

@ -31,6 +31,7 @@ import pyparsing as pp
import json
import re
from helper import _set_up_py_parsing_nicer_debug_output
_set_up_py_parsing_nicer_debug_output(pp)
@ -41,7 +42,7 @@ class QMakeSpecificJSONParser:
def create_py_parsing_grammar(self):
# Keep around all whitespace.
pp.ParserElement.setDefaultWhitespaceChars('')
pp.ParserElement.setDefaultWhitespaceChars("")
def add_element(name: str, value: pp.ParserElement):
nonlocal self
@ -57,44 +58,44 @@ class QMakeSpecificJSONParser:
# skip to the next quote, and repeat that until the end of the
# file.
EOF = add_element('EOF', pp.StringEnd())
SkipToQuote = add_element('SkipToQuote', pp.SkipTo('"'))
SkipToEOF = add_element('SkipToEOF', pp.SkipTo(EOF))
EOF = add_element("EOF", pp.StringEnd())
SkipToQuote = add_element("SkipToQuote", pp.SkipTo('"'))
SkipToEOF = add_element("SkipToEOF", pp.SkipTo(EOF))
def remove_newlines_and_whitespace_in_quoted_string(tokens):
first_string = tokens[0]
replaced_string = re.sub(r'\n[ ]*', ' ', first_string)
replaced_string = re.sub(r"\n[ ]*", " ", first_string)
return replaced_string
QuotedString = add_element('QuotedString', pp.QuotedString(quoteChar='"',
multiline=True,
unquoteResults=False))
QuotedString = add_element(
"QuotedString", pp.QuotedString(quoteChar='"', multiline=True, unquoteResults=False)
)
QuotedString.setParseAction(remove_newlines_and_whitespace_in_quoted_string)
QuotedTerm = add_element('QuotedTerm', pp.Optional(SkipToQuote) + QuotedString)
Grammar = add_element('Grammar', pp.OneOrMore(QuotedTerm) + SkipToEOF)
QuotedTerm = add_element("QuotedTerm", pp.Optional(SkipToQuote) + QuotedString)
Grammar = add_element("Grammar", pp.OneOrMore(QuotedTerm) + SkipToEOF)
return Grammar
def parse_file_using_py_parsing(self, file: str):
print('Pre processing "{}" using py parsing to remove incorrect newlines.'.format(file))
print(f'Pre processing "{file}" using py parsing to remove incorrect newlines.')
try:
with open(file, 'r') as file_fd:
with open(file, "r") as file_fd:
contents = file_fd.read()
parser_result = self.grammar.parseString(contents, parseAll=True)
token_list = parser_result.asList()
joined_string = ''.join(token_list)
joined_string = "".join(token_list)
return joined_string
except pp.ParseException as pe:
print(pe.line)
print(' '*(pe.col-1) + '^')
print(" " * (pe.col - 1) + "^")
print(pe)
raise pe
def parse(self, file: str):
pre_processed_string = self.parse_file_using_py_parsing(file)
print('Parsing "{}" using json.loads().'.format(file))
print(f'Parsing "{file}" using json.loads().')
json_parsed = json.loads(pre_processed_string)
return json_parsed

File diff suppressed because it is too large Load Diff

View File

@ -47,9 +47,10 @@ from timeit import default_timer
def _parse_commandline():
parser = ArgumentParser(description='Find pro files for which there are no CMakeLists.txt.')
parser.add_argument('source_directory', metavar='<src dir>', type=str,
help='The source directory')
parser = ArgumentParser(description="Find pro files for which there are no CMakeLists.txt.")
parser.add_argument(
"source_directory", metavar="<src dir>", type=str, help="The source directory"
)
return parser.parse_args()
@ -68,6 +69,7 @@ class Blacklist:
try:
# If package is available, use Aho-Corasick algorithm,
from ahocorapy.keywordtree import KeywordTree
self.tree = KeywordTree(case_insensitive=True)
for p in self.path_parts:
@ -117,45 +119,58 @@ def check_for_cmake_project(pro_path: str) -> bool:
return os.path.exists(cmake_project_path)
def compute_stats(src_path: str, pros_with_missing_project: typing.List[str],
total_pros: int, existing_pros: int, missing_pros: int) -> dict:
def compute_stats(
src_path: str,
pros_with_missing_project: typing.List[str],
total_pros: int,
existing_pros: int,
missing_pros: int,
) -> dict:
stats = {}
stats['total projects'] = {'label': 'Total pro files found',
'value': total_pros}
stats['existing projects'] = {'label': 'Existing CMakeLists.txt files found',
'value': existing_pros}
stats['missing projects'] = {'label': 'Missing CMakeLists.txt files found',
'value': missing_pros}
stats['missing examples'] = {'label': 'Missing examples', 'value': 0}
stats['missing tests'] = {'label': 'Missing tests', 'value': 0}
stats['missing src'] = {'label': 'Missing src/**/**', 'value': 0}
stats['missing plugins'] = {'label': 'Missing plugins', 'value': 0}
stats["total projects"] = {"label": "Total pro files found", "value": total_pros}
stats["existing projects"] = {
"label": "Existing CMakeLists.txt files found",
"value": existing_pros,
}
stats["missing projects"] = {
"label": "Missing CMakeLists.txt files found",
"value": missing_pros,
}
stats["missing examples"] = {"label": "Missing examples", "value": 0}
stats["missing tests"] = {"label": "Missing tests", "value": 0}
stats["missing src"] = {"label": "Missing src/**/**", "value": 0}
stats["missing plugins"] = {"label": "Missing plugins", "value": 0}
for p in pros_with_missing_project:
rel_path = os.path.relpath(p, src_path)
if rel_path.startswith("examples"):
stats['missing examples']['value'] += 1
stats["missing examples"]["value"] += 1
elif rel_path.startswith("tests"):
stats['missing tests']['value'] += 1
stats["missing tests"]["value"] += 1
elif rel_path.startswith(os.path.join("src", "plugins")):
stats['missing plugins']['value'] += 1
stats["missing plugins"]["value"] += 1
elif rel_path.startswith("src"):
stats['missing src']['value'] += 1
stats["missing src"]["value"] += 1
for stat in stats:
if stats[stat]['value'] > 0:
stats[stat]['percentage'] = round(stats[stat]['value'] * 100 / total_pros, 2)
if stats[stat]["value"] > 0:
stats[stat]["percentage"] = round(stats[stat]["value"] * 100 / total_pros, 2)
return stats
def print_stats(src_path: str, pros_with_missing_project: typing.List[str], stats: dict,
scan_time: float, script_time: float):
def print_stats(
src_path: str,
pros_with_missing_project: typing.List[str],
stats: dict,
scan_time: float,
script_time: float,
):
if stats['total projects']['value'] == 0:
if stats["total projects"]["value"] == 0:
print("No .pro files found. Did you specify a correct source path?")
return
if stats['total projects']['value'] == stats['existing projects']['value']:
if stats["total projects"]["value"] == stats["existing projects"]["value"]:
print("All projects were converted.")
else:
print("Missing CMakeLists.txt files for the following projects: \n")
@ -167,10 +182,12 @@ def print_stats(src_path: str, pros_with_missing_project: typing.List[str], stat
print("\nStatistics: \n")
for stat in stats:
if stats[stat]['value'] > 0:
print("{:<40}: {} ({}%)".format(stats[stat]['label'],
stats[stat]['value'],
stats[stat]['percentage']))
if stats[stat]["value"] > 0:
print(
"{:<40}: {} ({}%)".format(
stats[stat]["label"], stats[stat]["value"], stats[stat]["percentage"]
)
)
print("\n{:<40}: {:.10f} seconds".format("Scan time", scan_time))
print("{:<40}: {:.10f} seconds".format("Total script time", script_time))
@ -184,9 +201,7 @@ def main():
extension = ".pro"
blacklist_names = ["config.tests", "doc", "3rdparty", "angle"]
blacklist_path_parts = [
os.path.join("util", "cmake")
]
blacklist_path_parts = [os.path.join("util", "cmake")]
script_start_time = default_timer()
blacklist = Blacklist(blacklist_names, blacklist_path_parts)
@ -206,13 +221,14 @@ def main():
missing_pros = len(pros_with_missing_project)
existing_pros = total_pros - missing_pros
stats = compute_stats(src_path, pros_with_missing_project, total_pros, existing_pros,
missing_pros)
stats = compute_stats(
src_path, pros_with_missing_project, total_pros, existing_pros, missing_pros
)
script_end_time = default_timer()
script_time = script_end_time - script_start_time
print_stats(src_path, pros_with_missing_project, stats, scan_time, script_time)
if __name__ == '__main__':
if __name__ == "__main__":
main()

View File

@ -0,0 +1,4 @@
pytest; python_version >= '3.7'
mypy; python_version >= '3.7'
pyparsing; python_version >= '3.7'
sympy; python_version >= '3.7'

View File

@ -38,56 +38,70 @@ from argparse import ArgumentParser
def parse_command_line():
parser = ArgumentParser(description='Run pro2cmake on all .pro files recursively in given path.')
parser.add_argument('--only-existing', dest='only_existing', action='store_true',
help='Run pro2cmake only on .pro files that already have a CMakeLists.txt.')
parser.add_argument('--only-qtbase-main-modules', dest='only_qtbase_main_modules', action='store_true',
help='Run pro2cmake only on the main modules in qtbase.')
parser.add_argument('--is-example', dest='is_example', action='store_true',
help='Run pro2cmake with --is-example flag.')
parser.add_argument('path', metavar='<path>', type=str,
help='The path where to look for .pro files.')
parser = ArgumentParser(
description="Run pro2cmake on all .pro files recursively in given path."
)
parser.add_argument(
"--only-existing",
dest="only_existing",
action="store_true",
help="Run pro2cmake only on .pro files that already have a CMakeLists.txt.",
)
parser.add_argument(
"--only-qtbase-main-modules",
dest="only_qtbase_main_modules",
action="store_true",
help="Run pro2cmake only on the main modules in qtbase.",
)
parser.add_argument(
"--is-example",
dest="is_example",
action="store_true",
help="Run pro2cmake with --is-example flag.",
)
parser.add_argument(
"path", metavar="<path>", type=str, help="The path where to look for .pro files."
)
return parser.parse_args()
def find_all_pro_files(base_path: str, args: argparse.Namespace):
def sorter(pro_file: str) -> str:
""" Sorter that tries to prioritize main pro files in a directory. """
pro_file_without_suffix = pro_file.rsplit('/', 1)[-1][:-4]
pro_file_without_suffix = pro_file.rsplit("/", 1)[-1][:-4]
dir_name = os.path.dirname(pro_file)
if dir_name.endswith('/' + pro_file_without_suffix):
if dir_name.endswith("/" + pro_file_without_suffix):
return dir_name
return dir_name + "/__" + pro_file
all_files = []
previous_dir_name: str = None
print('Finding .pro files.')
glob_result = glob.glob(os.path.join(base_path, '**/*.pro'), recursive=True)
print("Finding .pro files.")
glob_result = glob.glob(os.path.join(base_path, "**/*.pro"), recursive=True)
def cmake_lists_exists_filter(path):
path_dir_name = os.path.dirname(path)
if os.path.exists(os.path.join(path_dir_name, 'CMakeLists.txt')):
if os.path.exists(os.path.join(path_dir_name, "CMakeLists.txt")):
return True
return False
def qtbase_main_modules_filter(path):
main_modules = [
'corelib',
'network',
'gui',
'widgets',
'testlib',
'printsupport',
'opengl',
'sql',
'dbus',
'concurrent',
'xml',
"corelib",
"network",
"gui",
"widgets",
"testlib",
"printsupport",
"opengl",
"sql",
"dbus",
"concurrent",
"xml",
]
path_suffixes = ['src/{}/{}.pro'.format(m, m, '.pro') for m in main_modules]
path_suffixes = ["src/{m}/{m}.pro" for m in main_modules]
for path_suffix in path_suffixes:
if path.endswith(path_suffix):
@ -102,7 +116,7 @@ def find_all_pro_files(base_path: str, args: argparse.Namespace):
filter_func = qtbase_main_modules_filter
if filter_func:
print('Filtering.')
print("Filtering.")
filter_result = [p for p in filter_result if filter_func(p)]
for pro_file in sorted(filter_result, key=sorter):
@ -118,14 +132,14 @@ def find_all_pro_files(base_path: str, args: argparse.Namespace):
def run(all_files: typing.List[str], pro2cmake: str, args: argparse.Namespace) -> typing.List[str]:
failed_files = []
files_count = len(all_files)
workers = (os.cpu_count() or 1)
workers = os.cpu_count() or 1
if args.only_qtbase_main_modules:
# qtbase main modules take longer than usual to process.
workers = 2
with concurrent.futures.ThreadPoolExecutor(max_workers=workers, initargs=(10,)) as pool:
print('Firing up thread pool executor.')
print("Firing up thread pool executor.")
def _process_a_file(data: typing.Tuple[str, int, int]) -> typing.Tuple[int, str, str]:
filename, index, total = data
@ -134,18 +148,21 @@ def run(all_files: typing.List[str], pro2cmake: str, args: argparse.Namespace) -
pro2cmake_args.append(sys.executable)
pro2cmake_args.append(pro2cmake)
if args.is_example:
pro2cmake_args.append('--is-example')
pro2cmake_args.append("--is-example")
pro2cmake_args.append(os.path.basename(filename))
result = subprocess.run(pro2cmake_args,
cwd=os.path.dirname(filename),
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout = 'Converted[{}/{}]: {}\n'.format(index, total, filename)
result = subprocess.run(
pro2cmake_args,
cwd=os.path.dirname(filename),
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
stdout = f"Converted[{index}/{total}]: {filename}\n"
return result.returncode, filename, stdout + result.stdout.decode()
for return_code, filename, stdout in pool.map(_process_a_file,
zip(all_files,
range(1, files_count + 1),
(files_count for _ in all_files))):
for return_code, filename, stdout in pool.map(
_process_a_file,
zip(all_files, range(1, files_count + 1), (files_count for _ in all_files)),
):
if return_code:
failed_files.append(filename)
print(stdout)
@ -157,21 +174,23 @@ def main() -> None:
args = parse_command_line()
script_path = os.path.dirname(os.path.abspath(__file__))
pro2cmake = os.path.join(script_path, 'pro2cmake.py')
pro2cmake = os.path.join(script_path, "pro2cmake.py")
base_path = args.path
all_files = find_all_pro_files(base_path, args)
files_count = len(all_files)
failed_files = run(all_files, pro2cmake, args)
if len(all_files) == 0:
print('No files found.')
print("No files found.")
if failed_files:
print('The following files were not successfully '
'converted ({} of {}):'.format(len(failed_files), files_count))
print(
f"The following files were not successfully "
f"converted ({len(failed_files)} of {files_count}):"
)
for f in failed_files:
print(' "{}"'.format(f))
print(f' "{f}"')
if __name__ == '__main__':
if __name__ == "__main__":
main()

View File

@ -93,31 +93,34 @@ import stat
from shutil import copyfile
from shutil import rmtree
from textwrap import dedent
def remove_special_cases(original: str) -> str:
# Remove content between the following markers
# '# special case begin' and '# special case end'.
# This also remove the markers.
replaced = re.sub(r'\n[^#\n]*?#[^\n]*?special case begin.*?#[^\n]*special case end[^\n]*?\n',
'\n',
original,
0,
re.DOTALL)
replaced = re.sub(
r"\n[^#\n]*?#[^\n]*?special case begin.*?#[^\n]*special case end[^\n]*?\n",
"\n",
original,
0,
re.DOTALL,
)
# Remove individual lines that have the "# special case" marker.
replaced = re.sub(r'\n.*#.*special case[^\n]*\n', '\n', replaced)
replaced = re.sub(r"\n.*#.*special case[^\n]*\n", "\n", replaced)
return replaced
def read_content_from_file(file_path: str) -> str:
with open(file_path, 'r') as file_fd:
with open(file_path, "r") as file_fd:
content = file_fd.read()
return content
def write_content_to_file(file_path: str, content: str) -> None:
with open(file_path, 'w') as file_fd:
with open(file_path, "w") as file_fd:
file_fd.write(content)
@ -126,23 +129,23 @@ def resolve_simple_git_conflicts(file_path: str, debug=False) -> None:
# If the conflict represents the addition of a new content hunk,
# keep the content and remove the conflict markers.
if debug:
print('Resolving simple conflicts automatically.')
replaced = re.sub(r'\n<<<<<<< HEAD\n=======(.+?)>>>>>>> master\n', r'\1', content, 0, re.DOTALL)
print("Resolving simple conflicts automatically.")
replaced = re.sub(r"\n<<<<<<< HEAD\n=======(.+?)>>>>>>> master\n", r"\1", content, 0, re.DOTALL)
write_content_to_file(file_path, replaced)
def copyfile_log(src: str, dst: str, debug=False):
if debug:
print('Copying {} to {}.'.format(src, dst))
print(f"Copying {src} to {dst}.")
copyfile(src, dst)
def check_if_git_in_path() -> bool:
is_win = os.name == 'nt'
for path in os.environ['PATH'].split(os.pathsep):
git_path = os.path.join(path, 'git')
is_win = os.name == "nt"
for path in os.environ["PATH"].split(os.pathsep):
git_path = os.path.join(path, "git")
if is_win:
git_path += '.exe'
git_path += ".exe"
if os.path.isfile(git_path) and os.access(git_path, os.X_OK):
return True
return False
@ -150,31 +153,38 @@ def check_if_git_in_path() -> bool:
def run_process_quiet(args_string: str, debug=False) -> bool:
if debug:
print('Running command: "{}\"'.format(args_string))
print(f'Running command: "{args_string}"')
args_list = args_string.split()
try:
subprocess.run(args_list, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
# git merge with conflicts returns with exit code 1, but that's not
# an error for us.
if 'git merge' not in args_string:
print('Error while running: "{}"\n{}'.format(args_string, e.stdout))
if "git merge" not in args_string:
print(
dedent(
f"""\
Error while running: "{args_string}"
{e.stdout}"""
)
)
return False
return True
def does_file_have_conflict_markers(file_path: str, debug=False) -> bool:
if debug:
print('Checking if {} has no leftover conflict markers.'.format(file_path))
print(f"Checking if {file_path} has no leftover conflict markers.")
content_actual = read_content_from_file(file_path)
if '<<<<<<< HEAD' in content_actual:
print('Conflict markers found in {}. '
'Please remove or solve them first.'.format(file_path))
if "<<<<<<< HEAD" in content_actual:
print(f"Conflict markers found in {file_path}. " "Please remove or solve them first.")
return True
return False
def create_file_with_no_special_cases(original_file_path: str, no_special_cases_file_path: str, debug=False):
def create_file_with_no_special_cases(
original_file_path: str, no_special_cases_file_path: str, debug=False
):
"""
Reads content of original CMakeLists.txt, removes all content
between "# special case" markers or lines, saves the result into a
@ -182,35 +192,36 @@ def create_file_with_no_special_cases(original_file_path: str, no_special_cases_
"""
content_actual = read_content_from_file(original_file_path)
if debug:
print('Removing special case blocks from {}.'.format(original_file_path))
print(f"Removing special case blocks from {original_file_path}.")
content_no_special_cases = remove_special_cases(content_actual)
if debug:
print('Saving original contents of {} '
'with removed special case blocks to {}'.format(original_file_path,
no_special_cases_file_path))
print(
f"Saving original contents of {original_file_path} "
f"with removed special case blocks to {no_special_cases_file_path}"
)
write_content_to_file(no_special_cases_file_path, content_no_special_cases)
def rm_tree_on_error_handler(func: typing.Callable[..., None],
path: str, exception_info: tuple):
def rm_tree_on_error_handler(func: typing.Callable[..., None], path: str, exception_info: tuple):
# If the path is read only, try to make it writable, and try
# to remove the path again.
if not os.access(path, os.W_OK):
os.chmod(path, stat.S_IWRITE)
func(path)
else:
print('Error while trying to remove path: {}. Exception: {}'.format(path, exception_info))
print(f"Error while trying to remove path: {path}. Exception: {exception_info}")
class SpecialCaseHandler(object):
def __init__(self,
original_file_path: str,
generated_file_path: str,
base_dir: str,
keep_temporary_files=False,
debug=False) -> None:
def __init__(
self,
original_file_path: str,
generated_file_path: str,
base_dir: str,
keep_temporary_files=False,
debug=False,
) -> None:
self.base_dir = base_dir
self.original_file_path = original_file_path
self.generated_file_path = generated_file_path
@ -220,29 +231,28 @@ class SpecialCaseHandler(object):
@property
def prev_file_path(self) -> str:
return os.path.join(self.base_dir, '.prev_CMakeLists.txt')
return os.path.join(self.base_dir, ".prev_CMakeLists.txt")
@property
def post_merge_file_path(self) -> str:
return os.path.join(self.base_dir, 'CMakeLists-post-merge.txt')
return os.path.join(self.base_dir, "CMakeLists-post-merge.txt")
@property
def no_special_file_path(self) -> str:
return os.path.join(self.base_dir, 'CMakeLists.no-special.txt')
return os.path.join(self.base_dir, "CMakeLists.no-special.txt")
def apply_git_merge_magic(self, no_special_cases_file_path: str) -> None:
# Create new folder for temporary repo, and ch dir into it.
repo = os.path.join(self.base_dir, 'tmp_repo')
repo = os.path.join(self.base_dir, "tmp_repo")
repo_absolute_path = os.path.abspath(repo)
txt = 'CMakeLists.txt'
txt = "CMakeLists.txt"
try:
os.mkdir(repo)
current_dir = os.getcwd()
os.chdir(repo)
except Exception as e:
print('Failed to create temporary directory for temporary git repo. Exception: {}'
.format(e))
print(f"Failed to create temporary directory for temporary git repo. Exception: {e}")
raise e
generated_file_path = os.path.join("..", self.generated_file_path)
@ -252,34 +262,34 @@ class SpecialCaseHandler(object):
try:
# Create new repo with the "clean" CMakeLists.txt file.
run_process_quiet('git init .', debug=self.debug)
run_process_quiet('git config user.name fake', debug=self.debug)
run_process_quiet('git config user.email fake@fake', debug=self.debug)
run_process_quiet("git init .", debug=self.debug)
run_process_quiet("git config user.name fake", debug=self.debug)
run_process_quiet("git config user.email fake@fake", debug=self.debug)
copyfile_log(no_special_cases_file_path, txt, debug=self.debug)
run_process_quiet('git add {}'.format(txt), debug=self.debug)
run_process_quiet('git commit -m no_special', debug=self.debug)
run_process_quiet('git checkout -b no_special', debug=self.debug)
run_process_quiet(f"git add {txt}", debug=self.debug)
run_process_quiet("git commit -m no_special", debug=self.debug)
run_process_quiet("git checkout -b no_special", debug=self.debug)
# Copy the original "modified" file (with the special cases)
# and make a new commit.
run_process_quiet('git checkout -b original', debug=self.debug)
run_process_quiet("git checkout -b original", debug=self.debug)
copyfile_log(original_file_path, txt, debug=self.debug)
run_process_quiet('git add {}'.format(txt), debug=self.debug)
run_process_quiet('git commit -m original', debug=self.debug)
run_process_quiet(f"git add {txt}", debug=self.debug)
run_process_quiet("git commit -m original", debug=self.debug)
# Checkout the commit with "clean" file again, and create a
# new branch.
run_process_quiet('git checkout no_special', debug=self.debug)
run_process_quiet('git checkout -b newly_generated', debug=self.debug)
run_process_quiet("git checkout no_special", debug=self.debug)
run_process_quiet("git checkout -b newly_generated", debug=self.debug)
# Copy the new "modified" file and make a commit.
copyfile_log(generated_file_path, txt, debug=self.debug)
run_process_quiet('git add {}'.format(txt), debug=self.debug)
run_process_quiet('git commit -m newly_generated', debug=self.debug)
run_process_quiet(f"git add {txt}", debug=self.debug)
run_process_quiet("git commit -m newly_generated", debug=self.debug)
# Merge the "old" branch with modifications into the "new"
# branch with the newly generated file.
run_process_quiet('git merge original', debug=self.debug)
run_process_quiet("git merge original", debug=self.debug)
# Resolve some simple conflicts (just remove the markers)
# for cases that don't need intervention.
@ -288,7 +298,7 @@ class SpecialCaseHandler(object):
# Copy the resulting file from the merge.
copyfile_log(txt, post_merge_file_path)
except Exception as e:
print('Git merge conflict resolution process failed. Exception: {}'.format(e))
print(f"Git merge conflict resolution process failed. Exception: {e}")
raise e
finally:
os.chdir(current_dir)
@ -298,7 +308,7 @@ class SpecialCaseHandler(object):
if not self.keep_temporary_files:
rmtree(repo_absolute_path, onerror=rm_tree_on_error_handler)
except Exception as e:
print('Error removing temporary repo. Exception: {}'.format(e))
print(f"Error removing temporary repo. Exception: {e}")
def save_next_clean_file(self):
files_are_equivalent = filecmp.cmp(self.generated_file_path, self.post_merge_file_path)
@ -316,20 +326,18 @@ class SpecialCaseHandler(object):
failed_once = False
i = 0
while not success and i < 20:
success = run_process_quiet("git add {}".format(self.prev_file_path),
debug=self.debug)
success = run_process_quiet(f"git add {self.prev_file_path}", debug=self.debug)
if not success:
failed_once = True
i += 1
time.sleep(0.1)
if failed_once and not success:
print('Retrying git add, the index.lock was probably acquired.')
print("Retrying git add, the index.lock was probably acquired.")
if failed_once and success:
print('git add succeeded.')
print("git add succeeded.")
elif failed_once and not success:
print('git add failed. Make sure to git add {} yourself.'.format(
self.prev_file_path))
print(f"git add failed. Make sure to git add {self.prev_file_path} yourself.")
def handle_special_cases_helper(self) -> bool:
"""
@ -348,15 +356,18 @@ class SpecialCaseHandler(object):
return False
if self.use_heuristic:
create_file_with_no_special_cases(self.original_file_path,
self.no_special_file_path)
create_file_with_no_special_cases(
self.original_file_path, self.no_special_file_path
)
no_special_cases_file_path = self.no_special_file_path
else:
no_special_cases_file_path = self.prev_file_path
if self.debug:
print('Using git to reapply special case modifications to newly generated {} '
'file'.format(self.generated_file_path))
print(
f"Using git to reapply special case modifications to newly "
f"generated {self.generated_file_path} file"
)
self.apply_git_merge_magic(no_special_cases_file_path)
self.save_next_clean_file()
@ -365,11 +376,13 @@ class SpecialCaseHandler(object):
if not self.keep_temporary_files:
os.remove(self.post_merge_file_path)
print('Special case reapplication using git is complete. '
'Make sure to fix remaining conflict markers.')
print(
"Special case reapplication using git is complete. "
"Make sure to fix remaining conflict markers."
)
except Exception as e:
print('Error occurred while trying to reapply special case modifications: {}'.format(e))
print(f"Error occurred while trying to reapply special case modifications: {e}")
return False
finally:
if not self.keep_temporary_files and self.use_heuristic:
@ -386,8 +399,10 @@ class SpecialCaseHandler(object):
keep_special_cases = original_file_exists and git_available
if not git_available:
print('You need to have git in PATH in order to reapply the special '
'case modifications.')
print(
"You need to have git in PATH in order to reapply the special "
"case modifications."
)
copy_generated_file = True