summaryrefslogtreecommitdiffstats
path: root/util/cmake/configurejson2cmake.py
diff options
context:
space:
mode:
Diffstat (limited to 'util/cmake/configurejson2cmake.py')
-rwxr-xr-xutil/cmake/configurejson2cmake.py1559
1 files changed, 0 insertions, 1559 deletions
diff --git a/util/cmake/configurejson2cmake.py b/util/cmake/configurejson2cmake.py
deleted file mode 100755
index 50a40f61121..00000000000
--- a/util/cmake/configurejson2cmake.py
+++ /dev/null
@@ -1,1559 +0,0 @@
-#!/usr/bin/env python3
-# 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
-import re
-import sys
-from typing import Optional, Set
-from textwrap import dedent
-import os
-
-from special_case_helper import SpecialCaseHandler
-from helper import (
- map_qt_library,
- featureName,
- map_platform,
- find_3rd_party_library_mapping,
- generate_find_package_info,
- get_compile_test_dependent_library_mapping,
-)
-
-knownTests = set() # type: Set[str]
-
-
-class LibraryMapping:
- def __init__(self, package: str, resultVariable: str, appendFoundSuffix: bool = True) -> None:
- self.package = package
- self.resultVariable = resultVariable
- self.appendFoundSuffix = appendFoundSuffix
-
-
-def map_tests(test: str) -> Optional[str]:
- testmap = {
- "c99": "c_std_99 IN_LIST CMAKE_C_COMPILE_FEATURES",
- "c11": "c_std_11 IN_LIST CMAKE_C_COMPILE_FEATURES",
- "x86SimdAlways": "ON", # FIXME: Make this actually do a compile test.
- "aesni": "TEST_subarch_aesni",
- "avx": "TEST_subarch_avx",
- "avx2": "TEST_subarch_avx2",
- "avx512f": "TEST_subarch_avx512f",
- "avx512cd": "TEST_subarch_avx512cd",
- "avx512dq": "TEST_subarch_avx512dq",
- "avx512bw": "TEST_subarch_avx512bw",
- "avx512er": "TEST_subarch_avx512er",
- "avx512pf": "TEST_subarch_avx512pf",
- "avx512vl": "TEST_subarch_avx512vl",
- "avx512ifma": "TEST_subarch_avx512ifma",
- "avx512vbmi": "TEST_subarch_avx512vbmi",
- "avx512vbmi2": "TEST_subarch_avx512vbmi2",
- "avx512vpopcntdq": "TEST_subarch_avx512vpopcntdq",
- "avx5124fmaps": "TEST_subarch_avx5124fmaps",
- "avx5124vnniw": "TEST_subarch_avx5124vnniw",
- "bmi": "TEST_subarch_bmi",
- "bmi2": "TEST_subarch_bmi2",
- "cx16": "TEST_subarch_cx16",
- "f16c": "TEST_subarch_f16c",
- "fma": "TEST_subarch_fma",
- "fma4": "TEST_subarch_fma4",
- "fsgsbase": "TEST_subarch_fsgsbase",
- "gfni": "TEST_subarch_gfni",
- "ibt": "TEST_subarch_ibt",
- "libclang": "TEST_libclang",
- "lwp": "TEST_subarch_lwp",
- "lzcnt": "TEST_subarch_lzcnt",
- "mmx": "TEST_subarch_mmx",
- "movbe": "TEST_subarch_movbe",
- "mpx": "TEST_subarch_mpx",
- "no-sahf": "TEST_subarch_no_shaf",
- "pclmul": "TEST_subarch_pclmul",
- "popcnt": "TEST_subarch_popcnt",
- "prefetchwt1": "TEST_subarch_prefetchwt1",
- "prfchw": "TEST_subarch_prfchw",
- "pdpid": "TEST_subarch_rdpid",
- "rdpid": "TEST_subarch_rdpid",
- "rdseed": "TEST_subarch_rdseed",
- "rdrnd": "TEST_subarch_rdrnd",
- "rtm": "TEST_subarch_rtm",
- "shani": "TEST_subarch_shani",
- "shstk": "TEST_subarch_shstk",
- "sse2": "TEST_subarch_sse2",
- "sse3": "TEST_subarch_sse3",
- "ssse3": "TEST_subarch_ssse3",
- "sse4a": "TEST_subarch_sse4a",
- "sse4_1": "TEST_subarch_sse4_1",
- "sse4_2": "TEST_subarch_sse4_2",
- "tbm": "TEST_subarch_tbm",
- "xop": "TEST_subarch_xop",
- "neon": "TEST_subarch_neon",
- "iwmmxt": "TEST_subarch_iwmmxt",
- "crc32": "TEST_subarch_crc32",
- "vis": "TEST_subarch_vis",
- "vis2": "TEST_subarch_vis2",
- "vis3": "TEST_subarch_vis3",
- "dsp": "TEST_subarch_dsp",
- "dspr2": "TEST_subarch_dspr2",
- "altivec": "TEST_subarch_altivec",
- "spe": "TEST_subarch_spe",
- "vsx": "TEST_subarch_vsx",
- "openssl11": '(OPENSSL_VERSION VERSION_GREATER_EQUAL "1.1.0")',
- "libinput_axis_api": "ON",
- "xlib": "X11_FOUND",
- "wayland-scanner": "WaylandScanner_FOUND",
- "3rdparty-hunspell": "VKB_HAVE_3RDPARTY_HUNSPELL",
- "t9write-alphabetic": "VKB_HAVE_T9WRITE_ALPHA",
- "t9write-cjk": "VKB_HAVE_T9WRITE_CJK",
- }
- if test in testmap:
- return testmap.get(test, None)
- if test in knownTests:
- return f"TEST_{featureName(test)}"
- return None
-
-
-def cm(ctx, *output):
- txt = ctx["output"]
- if txt != "" and not txt.endswith("\n"):
- txt += "\n"
- txt += "\n".join(output)
-
- ctx["output"] = txt
- return ctx
-
-
-def readJsonFromDir(path: str) -> str:
- path = posixpath.join(path, "configure.json")
-
- print(f"Reading {path}...")
- assert posixpath.exists(path)
-
- parser = json_parser.QMakeSpecificJSONParser()
- return parser.parse(path)
-
-
-def processFiles(ctx, data):
- print(" files:")
- if "files" in data:
- for (k, v) in data["files"].items():
- ctx[k] = v
- return ctx
-
-
-def parseLib(ctx, lib, data, cm_fh, cmake_find_packages_set):
- newlib = find_3rd_party_library_mapping(lib)
- if not newlib:
- print(f' XXXX Unknown library "{lib}".')
- return
-
- if newlib.packageName is None:
- print(f' **** Skipping library "{lib}" -- was masked.')
- return
-
- print(f" mapped library {lib} to {newlib.targetName}.")
-
- # Avoid duplicate find_package calls.
- if newlib.targetName in cmake_find_packages_set:
- return
-
- # If certain libraries are used within a feature, but the feature
- # is only emitted conditionally with a simple condition (like
- # 'on Windows' or 'on Linux'), we should enclose the find_package
- # call for the library into the same condition.
- emit_if = newlib.emit_if
-
- # Only look through features if a custom emit_if wasn't provided.
- if not emit_if:
- for feature in data["features"]:
- feature_data = data["features"][feature]
- if (
- "condition" in feature_data
- and f"libs.{lib}" in feature_data["condition"]
- and "emitIf" in feature_data
- and "config." in feature_data["emitIf"]
- ):
- emit_if = feature_data["emitIf"]
- break
-
- if emit_if:
- emit_if = map_condition(emit_if)
-
- cmake_find_packages_set.add(newlib.targetName)
-
- find_package_kwargs = {"emit_if": emit_if}
- if newlib.is_bundled_with_qt:
- # If a library is bundled with Qt, it has 2 FindFoo.cmake
- # modules: WrapFoo and WrapSystemFoo.
- # FindWrapSystemFoo.cmake will try to find the 'Foo' library in
- # the usual CMake locations, and will create a
- # WrapSystemFoo::WrapSystemFoo target pointing to the library.
- #
- # FindWrapFoo.cmake will create a WrapFoo::WrapFoo target which
- # will link either against the WrapSystemFoo or QtBundledFoo
- # target depending on certain feature values.
- #
- # Because the following qt_find_package call is for
- # configure.cmake consumption, we make the assumption that
- # configure.cmake is interested in finding the system library
- # for the purpose of enabling or disabling a system_foo feature.
- find_package_kwargs["use_system_package_name"] = True
- find_package_kwargs["module"] = ctx["module"]
-
- cm_fh.write(generate_find_package_info(newlib, **find_package_kwargs))
-
- if "use" in data["libraries"][lib]:
- use_entry = data["libraries"][lib]["use"]
- if isinstance(use_entry, str):
- print(f"1use: {use_entry}")
- cm_fh.write(f"qt_add_qmake_lib_dependency({newlib.soName} {use_entry})\n")
- else:
- for use in use_entry:
- print(f"2use: {use}")
- indentation = ""
- has_condition = False
- if "condition" in use:
- has_condition = True
- indentation = " "
- condition = map_condition(use["condition"])
- cm_fh.write(f"if({condition})\n")
- cm_fh.write(
- f"{indentation}qt_add_qmake_lib_dependency({newlib.soName} {use['lib']})\n"
- )
- if has_condition:
- cm_fh.write("endif()\n")
-
- run_library_test = False
- mapped_library = find_3rd_party_library_mapping(lib)
- if mapped_library:
- run_library_test = mapped_library.run_library_test
-
- if run_library_test and "test" in data["libraries"][lib]:
- test = data["libraries"][lib]["test"]
- write_compile_test(
- ctx, lib, test, data, cm_fh, manual_library_list=[lib], is_library_test=True
- )
-
-
-def lineify(label, value, quote=True):
- if value:
- if quote:
- escaped_value = value.replace('"', '\\"')
- return f' {label} "{escaped_value}"\n'
- return f" {label} {value}\n"
- return ""
-
-
-def map_condition(condition):
- # Handle NOT:
- if isinstance(condition, list):
- condition = "(" + ") AND (".join(condition) + ")"
- if isinstance(condition, bool):
- if condition:
- return "ON"
- else:
- return "OFF"
- assert isinstance(condition, str)
-
- mapped_features = {"gbm": "gbm_FOUND"}
-
- # Turn foo != "bar" into (NOT foo STREQUAL 'bar')
- condition = re.sub(r"([^ ]+)\s*!=\s*('.*?')", "(! \\1 == \\2)", condition)
- # Turn foo != 156 into (NOT foo EQUAL 156)
- condition = re.sub(r"([^ ]+)\s*!=\s*([0-9]?)", "(! \\1 EQUAL \\2)", condition)
-
- condition = condition.replace("!", "NOT ")
- condition = condition.replace("&&", " AND ")
- condition = condition.replace("||", " OR ")
- condition = condition.replace("==", " STREQUAL ")
-
- # explicitly handle input.sdk == '':
- condition = re.sub(r"input\.sdk\s*==\s*''", "NOT INPUT_SDK", condition)
-
- last_pos = 0
- mapped_condition = ""
- has_failed = False
- for match in re.finditer(r"([a-zA-Z0-9_]+)\.([a-zA-Z0-9_+-]+)", condition):
- substitution = None
- # appendFoundSuffix = True
- if match.group(1) == "libs":
- libmapping = find_3rd_party_library_mapping(match.group(2))
-
- if libmapping and libmapping.packageName:
- substitution = libmapping.packageName
- if libmapping.resultVariable:
- substitution = libmapping.resultVariable
- if libmapping.appendFoundSuffix:
- substitution += "_FOUND"
-
- # Assume that feature conditions are interested whether
- # a system library is found, rather than the bundled one
- # which we always know we can build.
- if libmapping.is_bundled_with_qt:
- substitution = substitution.replace("Wrap", "WrapSystem")
-
- elif match.group(1) == "features":
- feature = match.group(2)
- if feature in mapped_features:
- substitution = mapped_features.get(feature)
- else:
- substitution = f"QT_FEATURE_{featureName(match.group(2))}"
-
- elif match.group(1) == "subarch":
- substitution = f"TEST_arch_{'${TEST_architecture_arch}'}_subarch_{match.group(2)}"
-
- elif match.group(1) == "call":
- if match.group(2) == "crossCompile":
- substitution = "CMAKE_CROSSCOMPILING"
-
- elif match.group(1) == "tests":
- substitution = map_tests(match.group(2))
-
- elif match.group(1) == "input":
- substitution = f"INPUT_{featureName(match.group(2))}"
-
- elif match.group(1) == "config":
- substitution = map_platform(match.group(2))
- elif match.group(1) == "module":
- substitution = f"TARGET {map_qt_library(match.group(2))}"
-
- elif match.group(1) == "arch":
- if match.group(2) == "i386":
- # FIXME: Does this make sense?
- substitution = "(TEST_architecture_arch STREQUAL i386)"
- elif match.group(2) == "x86_64":
- substitution = "(TEST_architecture_arch STREQUAL x86_64)"
- elif match.group(2) == "arm":
- # FIXME: Does this make sense?
- substitution = "(TEST_architecture_arch STREQUAL arm)"
- elif match.group(2) == "arm64":
- # FIXME: Does this make sense?
- substitution = "(TEST_architecture_arch STREQUAL arm64)"
- elif match.group(2) == "mips":
- # FIXME: Does this make sense?
- substitution = "(TEST_architecture_arch STREQUAL mips)"
-
- if substitution is None:
- print(f' XXXX Unknown condition "{match.group(0)}"')
- has_failed = True
- else:
- mapped_condition += condition[last_pos : match.start(1)] + substitution
- last_pos = match.end(2)
-
- mapped_condition += condition[last_pos:]
-
- # Space out '(' and ')':
- mapped_condition = mapped_condition.replace("(", " ( ")
- mapped_condition = mapped_condition.replace(")", " ) ")
-
- # Prettify:
- condition = re.sub("\\s+", " ", mapped_condition)
- condition = condition.strip()
-
- # Special case for WrapLibClang in qttools
- condition = condition.replace("TEST_libclang.has_clangcpp", "TEST_libclang")
-
- if has_failed:
- condition += " OR FIXME"
-
- return condition
-
-
-def parseInput(ctx, sinput, data, cm_fh):
- skip_inputs = {
- "prefix",
- "hostprefix",
- "extprefix",
- "archdatadir",
- "bindir",
- "datadir",
- "docdir",
- "examplesdir",
- "external-hostbindir",
- "headerdir",
- "hostbindir",
- "hostdatadir",
- "hostlibdir",
- "importdir",
- "libdir",
- "libexecdir",
- "plugindir",
- "qmldir",
- "settingsdir",
- "sysconfdir",
- "testsdir",
- "translationdir",
- "android-arch",
- "android-ndk",
- "android-ndk-host",
- "android-ndk-platform",
- "android-sdk",
- "android-toolchain-version",
- "android-style-assets",
- "appstore-compliant",
- "avx",
- "avx2",
- "avx512",
- "c++std",
- "ccache",
- "commercial",
- "confirm-license",
- "dbus",
- "dbus-runtime",
- "debug",
- "debug-and-release",
- "developer-build",
- "device",
- "device-option",
- "f16c",
- "force-asserts",
- "force-debug-info",
- "force-pkg-config",
- "framework",
- "gc-binaries",
- "gdb-index",
- "gcc-sysroot",
- "gcov",
- "gnumake",
- "gui",
- "headersclean",
- "incredibuild-xge",
- "libudev",
- "ltcg",
- "make",
- "make-tool",
- "mips_dsp",
- "mips_dspr2",
- "mp",
- "nomake",
- "opensource",
- "optimize-debug",
- "optimize-size",
- "optimized-qmake",
- "optimized-tools",
- "pch",
- "pkg-config",
- "platform",
- "plugin-manifests",
- "profile",
- "qreal",
- "reduce-exports",
- "reduce-relocations",
- "release",
- "rpath",
- "sanitize",
- "sdk",
- "separate-debug-info",
- "shared",
- "silent",
- "qdbus",
- "sse2",
- "sse3",
- "sse4.1",
- "sse4.2",
- "ssse3",
- "static",
- "static-runtime",
- "strip",
- "syncqt",
- "sysroot",
- "testcocoon",
- "use-gold-linker",
- "warnings-are-errors",
- "Werror",
- "widgets",
- "xplatform",
- "zlib",
- "eventfd",
- "glib",
- "icu",
- "inotify",
- "journald",
- "pcre",
- "posix-ipc",
- "pps",
- "slog2",
- "syslog",
- }
-
- if sinput in skip_inputs:
- print(f" **** Skipping input {sinput}: masked.")
- return
-
- dtype = data
- if isinstance(data, dict):
- dtype = data["type"]
-
- if dtype == "boolean":
- print(f" **** Skipping boolean input {sinput}: masked.")
- return
-
- if dtype == "enum":
- values_line = " ".join(data["values"])
- cm_fh.write(f"# input {sinput}\n")
- cm_fh.write(f'set(INPUT_{featureName(sinput)} "undefined" CACHE STRING "")\n')
- cm_fh.write(
- f"set_property(CACHE INPUT_{featureName(sinput)} PROPERTY STRINGS undefined {values_line})\n\n"
- )
- return
-
- print(f" XXXX UNHANDLED INPUT TYPE {dtype} in input description")
- return
-
-
-def get_library_usage_for_compile_test(library):
- result = {}
- mapped_library = find_3rd_party_library_mapping(library)
- if not mapped_library:
- result["fixme"] = f"# FIXME: use: unmapped library: {library}\n"
- return result
-
- if mapped_library.test_library_overwrite:
- target_name = mapped_library.test_library_overwrite
- else:
- target_name = mapped_library.targetName
- result["target_name"] = target_name
- result["package_name"] = mapped_library.packageName
- result["extra"] = mapped_library.extra
- return result
-
-
-# Handles config.test/foo/foo.pro projects.
-def write_standalone_compile_test(cm_fh, ctx, data, config_test_name, is_library_test):
- rel_test_project_path = f"{ctx['test_dir']}/{config_test_name}"
- if posixpath.exists(f"{ctx['project_dir']}/{rel_test_project_path}/CMakeLists.txt"):
- label = ""
- libraries = []
- packages = []
-
- if "label" in data:
- label = data["label"]
-
- if is_library_test and config_test_name in data["libraries"]:
- if "label" in data["libraries"][config_test_name]:
- label = data["libraries"][config_test_name]["label"]
-
- # If a library entry in configure.json has a test, and
- # the test uses a config.tests standalone project, we
- # need to get the package and target info for the
- # library, and pass it to the test so compiling and
- # linking succeeds.
- library_usage = get_library_usage_for_compile_test(config_test_name)
- if "target_name" in library_usage:
- libraries.append(library_usage["target_name"])
- if "package_name" in library_usage:
- find_package_arguments = []
- find_package_arguments.append(library_usage["package_name"])
- if "extra" in library_usage:
- find_package_arguments.extend(library_usage["extra"])
- package_line = "PACKAGE " + " ".join(find_package_arguments)
- packages.append(package_line)
-
- cm_fh.write(
- f"""
-qt_config_compile_test("{config_test_name}"
- LABEL "{label}"
- PROJECT_PATH "${{CMAKE_CURRENT_SOURCE_DIR}}/{rel_test_project_path}"
-"""
- )
- if libraries:
- libraries_string = " ".join(libraries)
- cm_fh.write(f" LIBRARIES {libraries_string}\n")
- if packages:
- packages_string = " ".join(packages)
- cm_fh.write(f" PACKAGES {packages_string}")
- cm_fh.write(")\n")
-
-
-def write_compile_test(
- ctx, name, details, data, cm_fh, manual_library_list=None, is_library_test=False
-):
-
- if manual_library_list is None:
- manual_library_list = []
-
- inherited_test_name = details["inherit"] if "inherit" in details else None
- inherit_details = None
- if inherited_test_name and is_library_test:
- inherit_details = data["libraries"][inherited_test_name]["test"]
- if not inherit_details:
- print(f" XXXX Failed to locate inherited library test {inherited_test_name}")
-
- if isinstance(details, str):
- write_standalone_compile_test(cm_fh, ctx, data, details, is_library_test)
- return
-
- def resolve_head(detail):
- head = detail.get("head")
- if isinstance(head, list):
- head = "\n".join(head)
- return head + "\n" if head else ""
-
- head = ""
- if inherit_details:
- head += resolve_head(inherit_details)
- head += resolve_head(details)
-
- sourceCode = head
-
- def resolve_include(detail, keyword):
- include = detail.get(keyword, "")
- if isinstance(include, list):
- include = "#include <" + ">\n#include <".join(include) + ">\n"
- elif include:
- include = f"#include <{include}>\n"
- return include
-
- include = ""
- if is_library_test:
- if inherit_details:
- inherited_lib_data = data["libraries"][inherited_test_name]
- include += resolve_include(inherited_lib_data, "headers")
- this_lib_data = data["libraries"][name]
- include += resolve_include(this_lib_data, "headers")
- else:
- if inherit_details:
- include += resolve_include(inherit_details, "include")
- include += resolve_include(details, "include")
-
- sourceCode += include
-
- def resolve_tail(detail):
- tail = detail.get("tail")
- if isinstance(tail, list):
- tail = "\n".join(tail)
- return tail + "\n" if tail else ""
-
- tail = ""
- if inherit_details:
- tail += resolve_tail(inherit_details)
- tail += resolve_tail(details)
-
- sourceCode += tail
-
- if sourceCode: # blank line before main
- sourceCode += "\n"
- sourceCode += "int main(void)\n"
- sourceCode += "{\n"
- sourceCode += " /* BEGIN TEST: */\n"
-
- def resolve_main(detail):
- main = detail.get("main")
- if isinstance(main, list):
- main = "\n".join(main)
- return main + "\n" if main else ""
-
- main = ""
- if inherit_details:
- main += resolve_main(inherit_details)
- main += resolve_main(details)
-
- sourceCode += main
-
- sourceCode += " /* END TEST: */\n"
- sourceCode += " return 0;\n"
- sourceCode += "}\n"
-
- sourceCode = sourceCode.replace('"', '\\"')
-
- librariesCmakeName = ""
- languageStandard = ""
- compileOptions = ""
- qmakeFixme = ""
-
- cm_fh.write(f"# {name}\n")
-
- if "qmake" in details: # We don't really have many so we can just enumerate them all
- if details["qmake"] == "unix:LIBS += -lpthread":
- librariesCmakeName = format(featureName(name)) + "_TEST_LIBRARIES"
- cm_fh.write("if (UNIX)\n")
- cm_fh.write(" set(" + librariesCmakeName + " pthread)\n")
- cm_fh.write("endif()\n")
- elif details["qmake"] == "linux: LIBS += -lpthread -lrt":
- librariesCmakeName = format(featureName(name)) + "_TEST_LIBRARIES"
- cm_fh.write("if (LINUX)\n")
- cm_fh.write(" set(" + librariesCmakeName + " pthread rt)\n")
- cm_fh.write("endif()\n")
- elif details["qmake"] == "!winrt: LIBS += runtimeobject.lib":
- librariesCmakeName = format(featureName(name)) + "_TEST_LIBRARIES"
- cm_fh.write("if (NOT WINRT)\n")
- cm_fh.write(" set(" + librariesCmakeName + " runtimeobject)\n")
- cm_fh.write("endif()\n")
- elif details["qmake"] == "CONFIG += c++11":
- # do nothing we're always in c++11 mode
- pass
- elif details["qmake"] == "CONFIG += c++11 c++14":
- languageStandard = "CXX_STANDARD 14"
- elif details["qmake"] == "CONFIG += c++11 c++14 c++17":
- languageStandard = "CXX_STANDARD 17"
- elif details["qmake"] == "CONFIG += c++11 c++14 c++17 c++20":
- languageStandard = "CXX_STANDARD 20"
- elif details["qmake"] == "QMAKE_CXXFLAGS += -fstack-protector-strong":
- compileOptions = details["qmake"][18:]
- else:
- qmakeFixme = f"# FIXME: qmake: {details['qmake']}\n"
-
- library_list = []
- test_libraries = manual_library_list
-
- if "use" in data:
- test_libraries += data["use"].split(" ")
-
- for library in test_libraries:
- if len(library) == 0:
- continue
-
- adjusted_library = get_compile_test_dependent_library_mapping(name, library)
- library_usage = get_library_usage_for_compile_test(adjusted_library)
- if "fixme" in library_usage:
- qmakeFixme += library_usage["fixme"]
- continue
- else:
- library_list.append(library_usage["target_name"])
-
- cm_fh.write(f"qt_config_compile_test({featureName(name)}\n")
- cm_fh.write(lineify("LABEL", data.get("label", "")))
- if librariesCmakeName != "" or len(library_list) != 0:
- cm_fh.write(" LIBRARIES\n")
- if librariesCmakeName != "":
- cm_fh.write(lineify("", "${" + librariesCmakeName + "}"))
- if len(library_list) != 0:
- cm_fh.write(" ")
- cm_fh.write("\n ".join(library_list))
- cm_fh.write("\n")
- if compileOptions != "":
- cm_fh.write(f" COMPILE_OPTIONS {compileOptions}\n")
- cm_fh.write(" CODE\n")
- cm_fh.write('"' + sourceCode + '"')
- if qmakeFixme != "":
- cm_fh.write(qmakeFixme)
- if languageStandard != "":
- cm_fh.write(f"\n {languageStandard}\n")
- cm_fh.write(")\n\n")
-
-
-# "tests": {
-# "cxx11_future": {
-# "label": "C++11 <future>",
-# "type": "compile",
-# "test": {
-# "include": "future",
-# "main": [
-# "std::future<int> f = std::async([]() { return 42; });",
-# "(void)f.get();"
-# ],
-# "qmake": "unix:LIBS += -lpthread"
-# }
-# },
-
-
-def write_compiler_supports_flag_test(
- ctx, name, details, data, cm_fh, manual_library_list=None, is_library_test=False
-):
- cm_fh.write(f"qt_config_compiler_supports_flag_test({featureName(name)}\n")
- cm_fh.write(lineify("LABEL", data.get("label", "")))
- cm_fh.write(lineify("FLAG", data.get("flag", "")))
- cm_fh.write(")\n\n")
-
-
-def write_linker_supports_flag_test(
- ctx, name, details, data, cm_fh, manual_library_list=None, is_library_test=False
-):
- cm_fh.write(f"qt_config_linker_supports_flag_test({featureName(name)}\n")
- cm_fh.write(lineify("LABEL", data.get("label", "")))
- cm_fh.write(lineify("FLAG", data.get("flag", "")))
- cm_fh.write(")\n\n")
-
-
-def parseTest(ctx, test, data, cm_fh):
- skip_tests = {
- "c11",
- "c99",
- "gc_binaries",
- "precomile_header",
- "reduce_exports",
- "gc_binaries",
- "libinput_axis_api",
- "wayland-scanner",
- "xlib",
- }
-
- if test in skip_tests:
- print(f" **** Skipping features {test}: masked.")
- return
-
- if data["type"] == "compile":
- knownTests.add(test)
-
- if "test" in data:
- details = data["test"]
- else:
- details = test
-
- write_compile_test(ctx, test, details, data, cm_fh)
-
- if data["type"] == "compilerSupportsFlag":
- knownTests.add(test)
-
- if "test" in data:
- details = data["test"]
- else:
- details = test
-
- write_compiler_supports_flag_test(ctx, test, details, data, cm_fh)
-
- if data["type"] == "linkerSupportsFlag":
- knownTests.add(test)
-
- if "test" in data:
- details = data["test"]
- else:
- details = test
-
- write_linker_supports_flag_test(ctx, test, details, data, cm_fh)
-
- elif data["type"] == "libclang":
- knownTests.add(test)
-
- cm_fh.write(f"# {test}\n")
- lib_clang_lib = find_3rd_party_library_mapping("libclang")
- cm_fh.write(generate_find_package_info(lib_clang_lib))
- cm_fh.write(
- dedent(
- """
- if(TARGET WrapLibClang::WrapLibClang)
- set(TEST_libclang "ON" CACHE BOOL "Required libclang version found." FORCE)
- endif()
- """
- )
- )
- cm_fh.write("\n")
-
- elif data["type"] == "x86Simd":
- knownTests.add(test)
-
- label = data["label"]
-
- cm_fh.write(f"# {test}\n")
- cm_fh.write(f'qt_config_compile_test_x86simd({test} "{label}")\n')
- cm_fh.write("\n")
-
- elif data["type"] == "machineTuple":
- knownTests.add(test)
-
- label = data["label"]
-
- cm_fh.write(f"# {test}\n")
- cm_fh.write(f'qt_config_compile_test_machine_tuple("{label}")\n')
- cm_fh.write("\n")
-
- # "features": {
- # "android-style-assets": {
- # "label": "Android Style Assets",
- # "condition": "config.android",
- # "output": [ "privateFeature" ],
- # "comment": "This belongs into gui, but the license check needs it here already."
- # },
- else:
- print(f" XXXX UNHANDLED TEST TYPE {data['type']} in test description")
-
-
-def get_feature_mapping():
- # This is *before* the feature name gets normalized! So keep - and + chars, etc.
- feature_mapping = {
- "alloc_h": None, # handled by alloc target
- "alloc_malloc_h": None,
- "alloc_stdlib_h": None,
- "build_all": None,
- "ccache": {"autoDetect": "1", "condition": "QT_USE_CCACHE"},
- "compiler-flags": None,
- "cross_compile": {"condition": "CMAKE_CROSSCOMPILING"},
- "debug_and_release": {
- "autoDetect": "1", # Setting this to None has weird effects...
- "condition": "QT_GENERATOR_IS_MULTI_CONFIG",
- },
- "debug": {
- "autoDetect": "ON",
- "condition": "CMAKE_BUILD_TYPE STREQUAL Debug OR Debug IN_LIST CMAKE_CONFIGURATION_TYPES",
- },
- "dlopen": {"condition": "UNIX"},
- "force_debug_info": {
- "autoDetect": "CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo OR RelWithDebInfo IN_LIST CMAKE_CONFIGURATION_TYPES"
- },
- "framework": {
- "condition": "APPLE AND BUILD_SHARED_LIBS AND NOT CMAKE_BUILD_TYPE STREQUAL Debug"
- },
- "gc_binaries": {"condition": "NOT QT_FEATURE_shared"},
- "gcc-sysroot": None,
- "gcov": None,
- "GNUmake": None,
- "host-dbus": None,
- "iconv": {
- "condition": "NOT QT_FEATURE_icu AND QT_FEATURE_textcodec AND NOT WIN32 AND NOT QNX AND NOT ANDROID AND NOT APPLE AND WrapIconv_FOUND",
- },
- "incredibuild_xge": None,
- "ltcg": {
- "autoDetect": "ON",
- "cmakePrelude": """set(__qt_ltcg_detected FALSE)
-if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
- set(__qt_ltcg_detected TRUE)
-else()
- foreach(config ${CMAKE_BUILD_TYPE} ${CMAKE_CONFIGURATION_TYPES})
- string(TOUPPER "${config}" __qt_uc_config)
- if(CMAKE_INTERPROCEDURAL_OPTIMIZATION_${__qt_uc_config})
- set(__qt_ltcg_detected TRUE)
- break()
- endif()
- endforeach()
- unset(__qt_uc_config)
-endif()""",
- "condition": "__qt_ltcg_detected",
- },
- "msvc_mp": None,
- "simulator_and_device": {"condition": "UIKIT AND NOT QT_APPLE_SDK"},
- "pkg-config": {"condition": "PKG_CONFIG_FOUND"},
- "precompile_header": {"condition": "BUILD_WITH_PCH"},
- "profile": None,
- "qmakeargs": None,
- "qpa_default_platform": None, # Not a bool!
- "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_STRING",
- "value": '\\"${QT_COORD_TYPE}\\"',
- },
- ],
- },
- "reduce_exports": {
- "condition": "NOT MSVC",
- },
- "release": None,
- "release_tools": None,
- "rpath": {
- "autoDetect": "1",
- "condition": "BUILD_SHARED_LIBS AND UNIX AND NOT WIN32 AND NOT ANDROID",
- },
- "shared": {
- "condition": "BUILD_SHARED_LIBS",
- "output": [
- "publicFeature",
- "publicQtConfig",
- "publicConfig",
- {
- "type": "define",
- "name": "QT_STATIC",
- "prerequisite": "!defined(QT_SHARED) && !defined(QT_STATIC)",
- "negative": True,
- },
- ],
- },
- "silent": None,
- "sql-sqlite": {"condition": "QT_FEATURE_datestring"},
- "stl": None, # Do we really need to test for this in 2018?!
- "strip": None,
- "verifyspec": None, # qmake specific...
- "warnings_are_errors": None, # FIXME: Do we need these?
- "xkbcommon-system": None, # another system library, just named a bit different from the rest
- }
- return feature_mapping
-
-
-def parseFeature(ctx, feature, data, cm_fh):
- feature_mapping = get_feature_mapping()
- mapping = feature_mapping.get(feature, {})
-
- if mapping is None:
- print(f" **** Skipping features {feature}: masked.")
- return
-
- handled = {
- "autoDetect",
- "comment",
- "condition",
- "description",
- "disable",
- "emitIf",
- "enable",
- "label",
- "output",
- "purpose",
- "section",
- }
- label = mapping.get("label", data.get("label", ""))
- purpose = mapping.get("purpose", data.get("purpose", data.get("description", label)))
- autoDetect = map_condition(mapping.get("autoDetect", data.get("autoDetect", "")))
- condition = map_condition(mapping.get("condition", data.get("condition", "")))
- output = mapping.get("output", data.get("output", []))
- comment = mapping.get("comment", data.get("comment", ""))
- section = mapping.get("section", data.get("section", ""))
- enable = map_condition(mapping.get("enable", data.get("enable", "")))
- disable = map_condition(mapping.get("disable", data.get("disable", "")))
- emitIf = map_condition(mapping.get("emitIf", data.get("emitIf", "")))
- cmakePrelude = mapping.get("cmakePrelude", None)
- cmakeEpilogue = mapping.get("cmakeEpilogue", None)
-
- for k in [k for k in data.keys() if k not in handled]:
- print(f" XXXX UNHANDLED KEY {k} in feature description")
-
- if not output:
- # feature that is only used in the conditions of other features
- output = ["internalFeature"]
-
- publicFeature = False # #define QT_FEATURE_featurename in public header
- privateFeature = False # #define QT_FEATURE_featurename in private header
- negativeFeature = False # #define QT_NO_featurename in public header
- internalFeature = False # No custom or QT_FEATURE_ defines
- publicDefine = False # #define MY_CUSTOM_DEFINE in public header
- publicConfig = False # add to CONFIG in public pri file
- privateConfig = False # add to CONFIG in private pri file
- publicQtConfig = False # add to QT_CONFIG in public pri file
-
- for o in output:
- outputType = o
- if isinstance(o, dict):
- outputType = o["type"]
-
- if outputType in [
- "varAssign",
- "varAppend",
- "varRemove",
- "useBFDLinker",
- "useGoldLinker",
- "useLLDLinker",
- ]:
- continue
- elif outputType == "define":
- publicDefine = True
- elif outputType == "feature":
- negativeFeature = True
- elif outputType == "publicFeature":
- publicFeature = True
- elif outputType == "privateFeature":
- privateFeature = True
- elif outputType == "internalFeature":
- internalFeature = True
- elif outputType == "publicConfig":
- publicConfig = True
- elif outputType == "privateConfig":
- privateConfig = True
- elif outputType == "publicQtConfig":
- publicQtConfig = True
- else:
- print(f" XXXX UNHANDLED OUTPUT TYPE {outputType} in feature {feature}.")
- continue
-
- if not any(
- [
- publicFeature,
- privateFeature,
- internalFeature,
- publicDefine,
- negativeFeature,
- publicConfig,
- privateConfig,
- publicQtConfig,
- ]
- ):
- print(f" **** Skipping feature {feature}: Not relevant for C++.")
- return
-
- normalized_feature_name = featureName(feature)
-
- def writeFeature(
- name,
- publicFeature=False,
- privateFeature=False,
- labelAppend="",
- superFeature=None,
- autoDetect="",
- cmakePrelude=None,
- cmakeEpilogue=None,
- ):
- if comment:
- cm_fh.write(f"# {comment}\n")
-
- if cmakePrelude is not None:
- cm_fh.write(cmakePrelude)
- cm_fh.write("\n")
-
- cm_fh.write(f'qt_feature("{name}"')
- if publicFeature:
- cm_fh.write(" PUBLIC")
- if privateFeature:
- cm_fh.write(" PRIVATE")
- cm_fh.write("\n")
-
- cm_fh.write(lineify("SECTION", section))
- cm_fh.write(lineify("LABEL", label + labelAppend))
- if purpose != label:
- cm_fh.write(lineify("PURPOSE", purpose))
- cm_fh.write(lineify("AUTODETECT", autoDetect, quote=False))
- if superFeature:
- feature_condition = f"QT_FEATURE_{superFeature}"
- else:
- feature_condition = condition
- cm_fh.write(lineify("CONDITION", feature_condition, quote=False))
- cm_fh.write(lineify("ENABLE", enable, quote=False))
- cm_fh.write(lineify("DISABLE", disable, quote=False))
- cm_fh.write(lineify("EMIT_IF", emitIf, quote=False))
- cm_fh.write(")\n")
-
- if cmakeEpilogue is not None:
- cm_fh.write(cmakeEpilogue)
- cm_fh.write("\n")
-
- # Write qt_feature() calls before any qt_feature_definition() calls
-
- # Default internal feature case.
- featureCalls = {}
- featureCalls[feature] = {
- "name": feature,
- "labelAppend": "",
- "autoDetect": autoDetect,
- "cmakePrelude": cmakePrelude,
- "cmakeEpilogue": cmakeEpilogue,
- }
-
- # Go over all outputs to compute the number of features that have to be declared
- for o in output:
- outputType = o
- name = feature
-
- # The label append is to provide a unique label for features that have more than one output
- # with different names.
- labelAppend = ""
-
- if isinstance(o, dict):
- outputType = o["type"]
- if "name" in o:
- name = o["name"]
- labelAppend = f": {o['name']}"
-
- if outputType not in ["feature", "publicFeature", "privateFeature"]:
- continue
- if name not in featureCalls:
- featureCalls[name] = {"name": name, "labelAppend": labelAppend}
-
- if name != feature:
- featureCalls[name]["superFeature"] = normalized_feature_name
-
- if outputType in ["feature", "publicFeature"]:
- featureCalls[name]["publicFeature"] = True
- elif outputType == "privateFeature":
- featureCalls[name]["privateFeature"] = True
- elif outputType == "publicConfig":
- featureCalls[name]["publicConfig"] = True
- elif outputType == "privateConfig":
- featureCalls[name]["privateConfig"] = True
- elif outputType == "publicQtConfig":
- featureCalls[name]["publicQtConfig"] = True
-
- # Write the qt_feature() calls from the computed feature map
- for _, args in featureCalls.items():
- writeFeature(**args)
-
- # Write qt_feature_definition() calls
- for o in output:
- outputType = o
- outputArgs = {}
- if isinstance(o, dict):
- outputType = o["type"]
- outputArgs = o
-
- # Map negative feature to define:
- if outputType == "feature":
- outputType = "define"
- outputArgs = {
- "name": f"QT_NO_{normalized_feature_name.upper()}",
- "negative": True,
- "value": 1,
- "type": "define",
- }
-
- if outputType != "define":
- continue
-
- if outputArgs.get("name") is None:
- print(f" XXXX DEFINE output without name in feature {feature}.")
- continue
-
- out_name = outputArgs.get("name")
- cm_fh.write(f'qt_feature_definition("{feature}" "{out_name}"')
- if outputArgs.get("negative", False):
- cm_fh.write(" NEGATE")
- if outputArgs.get("value") is not None:
- cm_fh.write(f' VALUE "{outputArgs.get("value")}"')
- if outputArgs.get("prerequisite") is not None:
- cm_fh.write(f' PREREQUISITE "{outputArgs.get("prerequisite")}"')
- cm_fh.write(")\n")
-
- # Write qt_feature_config() calls
- for o in output:
- outputType = o
- name = feature
- modified_name = name
-
- outputArgs = {}
- if isinstance(o, dict):
- outputType = o["type"]
- outputArgs = o
- if "name" in o:
- modified_name = o["name"]
-
- if outputType not in ["publicConfig", "privateConfig", "publicQtConfig"]:
- continue
-
- config_type = ""
- if outputType == "publicConfig":
- config_type = "QMAKE_PUBLIC_CONFIG"
- elif outputType == "privateConfig":
- config_type = "QMAKE_PRIVATE_CONFIG"
- elif outputType == "publicQtConfig":
- config_type = "QMAKE_PUBLIC_QT_CONFIG"
-
- if not config_type:
- print(" XXXX config output without type in feature {}.".format(feature))
- continue
-
- cm_fh.write('qt_feature_config("{}" {}'.format(name, config_type))
- if outputArgs.get("negative", False):
- cm_fh.write("\n NEGATE")
- if modified_name != name:
- cm_fh.write("\n")
- cm_fh.write(lineify("NAME", modified_name, quote=True))
-
- cm_fh.write(")\n")
-
-
-def processSummaryHelper(ctx, entries, cm_fh):
- for entry in entries:
- if isinstance(entry, str):
- name = entry
- cm_fh.write(f'qt_configure_add_summary_entry(ARGS "{name}")\n')
- elif "type" in entry and entry["type"] in [
- "feature",
- "firstAvailableFeature",
- "featureList",
- ]:
- function_args = []
- entry_type = entry["type"]
-
- if entry_type in ["firstAvailableFeature", "featureList"]:
- feature_mapping = get_feature_mapping()
- unhandled_feature = False
- for feature_name, value in feature_mapping.items():
- # Skip entries that mention a feature which is
- # skipped by configurejson2cmake in the feature
- # mapping. This is not ideal, but prevents errors at
- # CMake configuration time.
- if not value and f"{feature_name}" in entry["args"]:
- unhandled_feature = True
- break
-
- if unhandled_feature:
- print(f" XXXX UNHANDLED FEATURE in SUMMARY TYPE {entry}.")
- continue
-
- if entry_type != "feature":
- function_args.append(lineify("TYPE", entry_type))
- if "args" in entry:
- args = entry["args"]
- function_args.append(lineify("ARGS", args))
- if "message" in entry:
- message = entry["message"]
- function_args.append(lineify("MESSAGE", message))
- if "condition" in entry:
- condition = map_condition(entry["condition"])
- function_args.append(lineify("CONDITION", condition, quote=False))
- entry_args_string = "".join(function_args)
- cm_fh.write(f"qt_configure_add_summary_entry(\n{entry_args_string})\n")
- elif "type" in entry and entry["type"] == "buildTypeAndConfig":
- cm_fh.write("qt_configure_add_summary_build_type_and_config()\n")
- elif "type" in entry and entry["type"] == "buildMode":
- message = entry["message"]
- cm_fh.write(f"qt_configure_add_summary_build_mode({message})\n")
- elif "type" in entry and entry["type"] == "buildParts":
- message = entry["message"]
- cm_fh.write(f'qt_configure_add_summary_build_parts("{message}")\n')
- elif "section" in entry:
- section = entry["section"]
- cm_fh.write(f'qt_configure_add_summary_section(NAME "{section}")\n')
- processSummaryHelper(ctx, entry["entries"], cm_fh)
- cm_fh.write(f'qt_configure_end_summary_section() # end of "{section}" section\n')
- else:
- print(f" XXXX UNHANDLED SUMMARY TYPE {entry}.")
-
-
-report_condition_mapping = {
- "(features.rpath || features.rpath_dir) && !features.shared": "(features.rpath || QT_EXTRA_RPATHS) && !features.shared",
- "(features.rpath || features.rpath_dir) && var.QMAKE_LFLAGS_RPATH == ''": None,
-}
-
-
-def processReportHelper(ctx, entries, cm_fh):
- feature_mapping = get_feature_mapping()
-
- for entry in entries:
- if isinstance(entry, dict):
- entry_args = []
- if "type" not in entry:
- print(f" XXXX UNHANDLED REPORT TYPE missing type in {entry}.")
- continue
-
- report_type = entry["type"]
- if report_type not in ["note", "warning", "error"]:
- print(f" XXXX UNHANDLED REPORT TYPE unknown type in {entry}.")
- continue
-
- report_type = report_type.upper()
- entry_args.append(lineify("TYPE", report_type, quote=False))
- message = entry["message"]
-
- # Replace semicolons, qt_parse_all_arguments can't handle
- # them due to an escaping bug in CMake regarding escaping
- # macro arguments.
- # https://gitlab.kitware.com/cmake/cmake/issues/19972
- message = message.replace(";", ",")
-
- entry_args.append(lineify("MESSAGE", message))
- # Need to overhaul everything to fix conditions.
- if "condition" in entry:
- condition = entry["condition"]
-
- unhandled_condition = False
- for feature_name, value in feature_mapping.items():
- # Skip reports that mention a feature which is
- # skipped by configurejson2cmake in the feature
- # mapping. This is not ideal, but prevents errors at
- # CMake configuration time.
- if not value and f"features.{feature_name}" in condition:
- unhandled_condition = True
- break
-
- if unhandled_condition:
- print(f" XXXX UNHANDLED CONDITION in REPORT TYPE {entry}.")
- continue
-
- if isinstance(condition, str) and condition in report_condition_mapping:
- new_condition = report_condition_mapping[condition]
- if new_condition is None:
- continue
- else:
- condition = new_condition
- condition = map_condition(condition)
- entry_args.append(lineify("CONDITION", condition, quote=False))
- entry_args_string = "".join(entry_args)
- cm_fh.write(f"qt_configure_add_report_entry(\n{entry_args_string})\n")
- else:
- print(f" XXXX UNHANDLED REPORT TYPE {entry}.")
-
-
-def parseCommandLineCustomHandler(ctx, data, cm_fh):
- cm_fh.write(f"qt_commandline_custom({data})\n")
-
-
-def parseCommandLineOptions(ctx, data, cm_fh):
- for key in data:
- args = [key]
- option = data[key]
- if isinstance(option, str):
- args += ["TYPE", option]
- else:
- if "type" in option:
- args += ["TYPE", option["type"]]
- if "name" in option:
- args += ["NAME", option["name"]]
- if "value" in option:
- args += ["VALUE", option["value"]]
- if "values" in option:
- values = option["values"]
- if isinstance(values, list):
- args += ["VALUES", " ".join(option["values"])]
- else:
- args += ["MAPPING"]
- for lhs in values:
- args += [lhs, values[lhs]]
-
- cm_fh.write(f"qt_commandline_option({' '.join(args)})\n")
-
-
-def parseCommandLinePrefixes(ctx, data, cm_fh):
- for key in data:
- cm_fh.write(f"qt_commandline_prefix({key} {data[key]})\n")
-
-
-def processCommandLine(ctx, data, cm_fh):
- print(" commandline:")
-
- if "subconfigs" in data:
- for subconf in data["subconfigs"]:
- cm_fh.write(f"qt_commandline_subconfig({subconf})\n")
-
- if "commandline" not in data:
- return
-
- commandLine = data["commandline"]
- if "custom" in commandLine:
- print(" custom:")
- parseCommandLineCustomHandler(ctx, commandLine["custom"], cm_fh)
- if "options" in commandLine:
- print(" options:")
- parseCommandLineOptions(ctx, commandLine["options"], cm_fh)
- if "prefix" in commandLine:
- print(" prefix:")
- parseCommandLinePrefixes(ctx, commandLine["prefix"], cm_fh)
- if "assignments" in commandLine:
- print(" assignments are ignored")
-
-
-def processInputs(ctx, data, cm_fh):
- print(" inputs:")
- if "commandline" not in data:
- return
-
- commandLine = data["commandline"]
- if "options" not in commandLine:
- return
-
- for input_option in commandLine["options"]:
- parseInput(ctx, input_option, commandLine["options"][input_option], cm_fh)
-
-
-def processTests(ctx, data, cm_fh):
- print(" tests:")
- if "tests" not in data:
- return
-
- for test in data["tests"]:
- parseTest(ctx, test, data["tests"][test], cm_fh)
-
-
-def processFeatures(ctx, data, cm_fh):
- print(" features:")
- if "features" not in data:
- return
-
- for feature in data["features"]:
- parseFeature(ctx, feature, data["features"][feature], cm_fh)
-
-
-def processLibraries(ctx, data, cm_fh):
- cmake_find_packages_set = set()
- print(" libraries:")
- if "libraries" not in data:
- return
-
- for lib in data["libraries"]:
- parseLib(ctx, lib, data, cm_fh, cmake_find_packages_set)
-
-
-def processReports(ctx, data, cm_fh):
- if "summary" in data:
- print(" summary:")
- processSummaryHelper(ctx, data["summary"], cm_fh)
- if "report" in data:
- print(" report:")
- processReportHelper(ctx, data["report"], cm_fh)
- if "earlyReport" in data:
- print(" earlyReport:")
- processReportHelper(ctx, data["earlyReport"], cm_fh)
-
-
-def processSubconfigs(path, ctx, data):
- assert ctx is not None
- if "subconfigs" in data:
- for subconf in data["subconfigs"]:
- subconfDir = posixpath.join(path, subconf)
- subconfData = readJsonFromDir(subconfDir)
- subconfCtx = ctx
- processJson(subconfDir, subconfCtx, subconfData)
-
-
-class special_cased_file:
- def __init__(self, base_dir: str, file_name: str, skip_special_case_preservation: bool):
- self.base_dir = base_dir
- self.file_path = posixpath.join(base_dir, file_name)
- self.gen_file_path = self.file_path + ".gen"
- self.preserve_special_cases = not skip_special_case_preservation
-
- def __enter__(self):
- self.file = open(self.gen_file_path, "w")
- if self.preserve_special_cases:
- self.sc_handler = SpecialCaseHandler(
- os.path.abspath(self.file_path),
- os.path.abspath(self.gen_file_path),
- os.path.abspath(self.base_dir),
- debug=False,
- )
- return self.file
-
- def __exit__(self, type, value, trace_back):
- self.file.close()
- if self.preserve_special_cases:
- 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")
- ctx["test_dir"] = data.get("testDir", "config.tests")
-
- ctx = processFiles(ctx, data)
-
- with special_cased_file(path, "qt_cmdline.cmake", skip_special_case_preservation) as cm_fh:
- processCommandLine(ctx, data, cm_fh)
-
- with special_cased_file(path, "configure.cmake", skip_special_case_preservation) as cm_fh:
- cm_fh.write("\n\n#### Inputs\n\n")
-
- processInputs(ctx, data, cm_fh)
-
- cm_fh.write("\n\n#### Libraries\n\n")
-
- processLibraries(ctx, data, cm_fh)
-
- cm_fh.write("\n\n#### Tests\n\n")
-
- processTests(ctx, data, cm_fh)
-
- cm_fh.write("\n\n#### Features\n\n")
-
- processFeatures(ctx, data, cm_fh)
-
- processReports(ctx, data, cm_fh)
-
- if ctx.get("module") == "global":
- cm_fh.write(
- '\nqt_extra_definition("QT_VERSION_STR" "\\"${PROJECT_VERSION}\\"" PUBLIC)\n'
- )
- cm_fh.write('qt_extra_definition("QT_VERSION_MAJOR" ${PROJECT_VERSION_MAJOR} PUBLIC)\n')
- cm_fh.write('qt_extra_definition("QT_VERSION_MINOR" ${PROJECT_VERSION_MINOR} PUBLIC)\n')
- cm_fh.write('qt_extra_definition("QT_VERSION_PATCH" ${PROJECT_VERSION_PATCH} PUBLIC)\n')
-
- # do this late:
- processSubconfigs(path, ctx, data)
-
-
-def main():
- if len(sys.argv) < 2:
- print("This scripts needs one directory to process!")
- quit(1)
-
- directory = sys.argv[1]
- skip_special_case_preservation = "-s" in sys.argv[2:]
-
- print(f"Processing: {directory}.")
-
- data = readJsonFromDir(directory)
- processJson(directory, {}, data, skip_special_case_preservation=skip_special_case_preservation)
-
-
-if __name__ == "__main__":
- main()