configure: add check for Qml runtime modules

fix: #28392
This commit is contained in:
Pierre Lamot 2023-10-04 15:50:30 +02:00 committed by Jean-Baptiste Kempf
parent 3fbedea9e5
commit 177d049950
2 changed files with 191 additions and 5 deletions

View File

@ -0,0 +1,168 @@
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import json
import argparse
import sys
import os
import subprocess
from tempfile import NamedTemporaryFile
def checkQmakePath(path):
if path is None:
return False
if path == "**Unknown**":
return False
if not os.path.isdir(path):
return False
return True
def findProgram(path, progName):
if not checkQmakePath(path):
return None
progPath = os.path.join(path, progName)
if not os.path.isfile(progPath):
return None
return progPath
class QmlModuleChecker:
def __init__(self):
self.qt5 = True
self.qmlimportscanner = None
self.qmlpath = None
def genQmlFile(self, f, modules):
for module, version in modules:
f.write("import {} {}\n".format(module, version))
f.write("Item {}\n")
f.flush()
def scanImports(self, f, modules):
ret = subprocess.run(
[
self.qmlimportscanner,
"-qmlFiles", f.name,
"-importPath", self.qmlpath
],
capture_output=True,
)
if ret.returncode != 0:
return None
return json.loads(ret.stdout)
def checkImports(self, scanlist, modules):
ret = True
for name, version in modules:
found = False
for entry in scanlist:
if entry["type"] == "module" and entry["name"] == name:
#qt6 modules have no version
if self.qt5 and not entry["version"] == version:
continue
if "classname" in entry:
found = True
break
print("checking for {} {}... {}".format(name, version, "yes" if found else "no"))
if not found:
ret = False
return ret
def getInstallInfo(self, qmake):
if not os.path.isfile(qmake):
print("qmake not found")
return False
ret = subprocess.run(
[ qmake, "-query"],
capture_output=True,
encoding="utf8"
)
if ret.returncode != 0:
return None
binpath = None
libexec = None
qmlpath = None
qtmajor = ""
for l in ret.stdout.splitlines():
l.strip()
if l.startswith("QT_HOST_BINS:"):
binpath = l.split(":", 1)[1]
elif l.startswith("QT_HOST_LIBEXECS:"):
libexec = l.split(":", 1)[1]
elif l.startswith("QT_INSTALL_QML:"):
self.qmlpath = l.split(":", 1)[1]
elif l.startswith("QT_VERSION:"):
qmlversion = l.split(":", 1)[1]
qtmajor = qmlversion.split(".")[0]
if qtmajor == "6":
self.qt5 = False
if not checkQmakePath(self.qmlpath):
print("Qml path not found")
return False
self.qmlimportscanner = findProgram(binpath, "qmlimportscanner")
if self.qmlimportscanner is not None:
return True
#Qt6 may place qmlimportscanner in libexec
self.qmlimportscanner = findProgram(libexec, "qmlimportscanner")
if self.qmlimportscanner is not None:
return True
print("qmlimportscanner not found")
return False
class KeyValue(argparse.Action):
def __call__( self , parser, namespace,
values, option_string = None):
setattr(namespace, self.dest, [])
for value in values:
key, value = value.split('=')
getattr(namespace, self.dest).append((key, value))
def main():
parser = argparse.ArgumentParser("check for qml runtime dependencies")
parser.add_argument(
"--qmake", type=str, required=True,
help="qmake path")
parser.add_argument(
"--modules", nargs="+", action=KeyValue, required=True,
help="list of modules to check in the form module=version (ex QtQuick=2.12)")
args = parser.parse_args()
moduleChecker = QmlModuleChecker()
if not moduleChecker.getInstallInfo(args.qmake):
exit(-1)
with NamedTemporaryFile(mode="w+", suffix=".qml") as f:
moduleChecker.genQmlFile(f, args.modules)
scanlist = moduleChecker.scanImports(f, args.modules)
if scanlist is None:
exit(-1)
if not moduleChecker.checkImports(scanlist, args.modules):
exit(-1)
exit(0)
if __name__ == "__main__":
main()

View File

@ -3950,15 +3950,11 @@ AS_IF([test "${enable_qt}" != "no"], [
AC_MSG_WARN([Not building Qt Interface with wayland support.])
])
PKG_CHECK_MODULES([QT5_QUICK_TEST], [Qt5QuickTest], [
have_qt5_quick_test="yes"
],[
])
QT_PATH="$(eval $PKG_CONFIG --variable=exec_prefix Qt5Core)"
QT_HOST_PATH="$(eval $PKG_CONFIG --variable=host_bins Qt5Core)"
QT_INCLUDE_DIRECTORY="$(eval $PKG_CONFIG --variable=includedir Qt5Core)"
QT_VERSION="$(eval $PKG_CONFIG --modversion Qt5Gui)"
AC_PATH_PROGS(QMAKE, [qmake], qmake, ["${QT_HOST_PATH}" "${QT_PATH}/bin"])
AC_PATH_PROGS(MOC, [moc-qt5 moc], moc, ["${QT_HOST_PATH}" "${QT_PATH}/bin"])
AC_PATH_PROGS(RCC, [rcc-qt5 rcc], rcc, ["${QT_HOST_PATH}" "${QT_PATH}/bin"])
AC_PATH_PROGS(UIC, [uic-qt5 uic], uic, ["${QT_HOST_PATH}" "${QT_PATH}/bin"])
@ -3967,6 +3963,28 @@ AS_IF([test "${enable_qt}" != "no"], [
AC_MSG_WARN([qmlcachegen not found])
])
AC_CHECK_PROGS(PYTHON3, [python3], [no])
AS_IF([test "$PYTHON3" != "no" && ${PYTHON3} ${srcdir}/buildsystem/check_qml_module.py \
--qmake "${QMAKE}" \
--modules \
QtQml.Models=2.12 \
QtQuick.Layouts=1.12 \
QtQuick.Window=2.12 \
QtQuick.Controls=2.12 \
QtGraphicalEffects=1.12],
[],[
AC_MSG_WARN([qt runtime dependencies are missing, disabling qt interface])
enable_qt="no"
])
PKG_CHECK_MODULES([QT5_QUICK_TEST], [Qt5QuickTest], [
AS_IF([test "$PYTHON3" != "no" && ${PYTHON3} ${srcdir}/buildsystem/check_qml_module.py --qmake "${QMAKE}" --modules QtTest=1.12], [], [
have_qt5_quick_test="yes"
])
],[
])
dnl Check private headers avaibility
VLC_SAVE_FLAGS
CPPFLAGS="${CPPFLAGS} ${QT_CFLAGS}"