diff options
author | Joerg Bornemann <joerg.bornemann@qt.io> | 2017-06-22 15:54:06 +0200 |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@qt.io> | 2017-07-17 13:19:37 +0000 |
commit | aaaeea6a55ca1242689f4cf16e3aac173ff7d8c4 (patch) | |
tree | 8922c7b2f74c2c6814a2f229f8a6a2f8cb36e799 | |
parent | d479de3d9b6042bf14a905ec3ba3bf2a451f7b55 (diff) |
Add support for qmlcachegen
[ChangeLog] Support for qmlcachegen has been added.
To enable it in a QML project, set Qt.qml.generateCacheFiles to true.
Task-number: QBS-1132
Change-Id: I061eb1afd8994306958376e1cd7f5a98a8f4b03e
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r-- | doc/reference/modules/qt-modules.qdoc | 41 | ||||
-rw-r--r-- | src/lib/qtprofilesetup/qtprofilesetup.cpp | 8 | ||||
-rw-r--r-- | src/lib/qtprofilesetup/templates.qrc | 1 | ||||
-rw-r--r-- | src/lib/qtprofilesetup/templates/qml.qbs | 13 | ||||
-rw-r--r-- | src/lib/qtprofilesetup/templates/qmlcache.qbs | 67 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata-qt/cached-qml/MainForm.ui.qml | 29 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs | 30 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata-qt/cached-qml/main.cpp | 14 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata-qt/cached-qml/main.qml | 17 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata-qt/cached-qml/qml.qrc | 7 | ||||
-rw-r--r-- | tests/auto/blackbox/testdata-qt/cached-qml/stuff.js | 1 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackboxqt.cpp | 14 | ||||
-rw-r--r-- | tests/auto/blackbox/tst_blackboxqt.h | 1 |
13 files changed, 243 insertions, 0 deletions
diff --git a/doc/reference/modules/qt-modules.qdoc b/doc/reference/modules/qt-modules.qdoc index 44b516af7..085e97ae7 100644 --- a/doc/reference/modules/qt-modules.qdoc +++ b/doc/reference/modules/qt-modules.qdoc @@ -519,6 +519,41 @@ \li The absolute path to the directory where Qt's QML files are installed. \endtable + The following properties control the generation of QML cache files. + + \table + \header + \li Property + \li Type + \li Default + \li Description + \row + \li generateCacheFiles + \li \c{bool} + \li \c{false} + \li Enables the generation of QML cache files. + \row + \li cachingEnabled + \li \c{readonly bool} + \li \c{false} + \li Is true if \c{generateCacheFiles} is \c{true} + and the platform supports QML cache generation. + \row + \li qmlCacheGenPath + \li \c{string} + \li set by \c{qbs-setup-qt} + \li The absolute path to the qmlcachegen executable. + \row + \li cacheFilesInstallDir + \li \c{string} + \li \c{undefined} + \li The path to the directory where the cache files are installed. + If this property is set then QML cache files are automatically installed. + \endtable + + \note If the current value of qbs.architecture is not supported + by qmlcachegen then the cache generator rule is disabled. + \section2 scxml Properties @@ -669,6 +704,12 @@ \li Since \li Description \row + \li \c{"qt.qml.js"} + \li \c{*.js} + \li 1.10 + \li QML companion JavaScript files. Source files with this tag serve as input for the QML + cache file generator. + \row \li \c{"qt.qml.qml"} \li \c{*.qml} \li 1.8 diff --git a/src/lib/qtprofilesetup/qtprofilesetup.cpp b/src/lib/qtprofilesetup/qtprofilesetup.cpp index 7ad837105..643fa2a0a 100644 --- a/src/lib/qtprofilesetup/qtprofilesetup.cpp +++ b/src/lib/qtprofilesetup/qtprofilesetup.cpp @@ -44,6 +44,7 @@ #include <logging/translator.h> #include <tools/architectures.h> #include <tools/error.h> +#include <tools/hostosinfo.h> #include <tools/jsliterals.h> #include <tools/profile.h> #include <tools/settings.h> @@ -313,6 +314,13 @@ static void createModules(Profile &profile, Settings *settings, moduleTemplateFileName = QLatin1String("qml.qbs"); copyTemplateFile(QLatin1String("qml.js"), qbsQtModuleDir, profile, qtEnvironment, &allFiles); + const QString qmlcacheStr = QStringLiteral("qmlcache"); + if (QFileInfo::exists(HostOsInfo::appendExecutableSuffix( + qtEnvironment.binaryPath + QStringLiteral("/qmlcachegen")))) { + copyTemplateFile(qmlcacheStr + QStringLiteral(".qbs"), + qbsQtModuleBaseDir + QLatin1Char('/') + qmlcacheStr, profile, + qtEnvironment, &allFiles); + } } else if (module.qbsName == QLatin1String("phonon")) { moduleTemplateFileName = QLatin1String("phonon.qbs"); } else if (module.isPlugin) { diff --git a/src/lib/qtprofilesetup/templates.qrc b/src/lib/qtprofilesetup/templates.qrc index d65582a1c..9c706c574 100644 --- a/src/lib/qtprofilesetup/templates.qrc +++ b/src/lib/qtprofilesetup/templates.qrc @@ -14,5 +14,6 @@ <file>templates/scxml.qbs</file> <file>templates/qml.qbs</file> <file>templates/qml.js</file> + <file>templates/qmlcache.qbs</file> </qresource> </RCC> diff --git a/src/lib/qtprofilesetup/templates/qml.qbs b/src/lib/qtprofilesetup/templates/qml.qbs index 0f3a9cb77..5a9d3f9cb 100644 --- a/src/lib/qtprofilesetup/templates/qml.qbs +++ b/src/lib/qtprofilesetup/templates/qml.qbs @@ -11,6 +11,14 @@ QtModule { property string qmlImportScannerFilePath: Qt.core.binPath + '/' + qmlImportScannerName property string qmlPath: @qmlPath@ + property bool generateCacheFiles: false + Depends { name: "Qt.qmlcache"; condition: generateCacheFiles; required: false } + readonly property bool cachingEnabled: generateCacheFiles && Qt.qmlcache.present + property string qmlCacheGenPath + Qt.qmlcache.qmlCacheGenPath: qmlCacheGenPath || original + property string cacheFilesInstallDir + Qt.qmlcache.installDir: cacheFilesInstallDir || original + readonly property string pluginListFilePathDebug: product.buildDirectory + "/plugins.list.d" readonly property string pluginListFilePathRelease: product.buildDirectory + "/plugins.list" @@ -40,6 +48,11 @@ QtModule { fileTags: ["qt.qml.qml"] } + FileTagger { + patterns: ["*.js"] + fileTags: ["qt.qml.js"] + } + Rule { condition: isStaticLibrary multiplex: true diff --git a/src/lib/qtprofilesetup/templates/qmlcache.qbs b/src/lib/qtprofilesetup/templates/qmlcache.qbs new file mode 100644 index 000000000..246486c53 --- /dev/null +++ b/src/lib/qtprofilesetup/templates/qmlcache.qbs @@ -0,0 +1,67 @@ +import qbs.FileInfo +import qbs.Process + +Module { + additionalProductTypes: ["qt.qml.qmlc", "qt.qml.jsc"] + validate: qmlcachegenProbe.found + property string qmlCacheGenPath: FileInfo.joinPaths(Qt.core.binPath, "qmlcachegen") + + (qbs.hostOS.contains("windows") ? ".exe" : "") + property string installDir + + readonly property stringList _targetArgs: { + function translateArch(arch) { + if (arch === "x86") + return "i386"; + if (arch.startsWith("armv")) + return "arm"; + return arch; + } + + var args = ["--target-architecture", translateArch(qbs.architecture)]; + return args; + } + + Depends { name: "Qt.core" } + Probe { + id: qmlcachegenProbe + configure: { + var process = new Process(); + found = false; + try { + found = process.exec(qmlCacheGenPath, + _targetArgs.concat("--check-if-supported")) == 0; + if (!found) { + var msg = "QML cache generation was requested but is unsupported on " + + "architecture '" + qbs.architecture + "'."; + console.warn(msg); + } + } finally { + process.close(); + } + } + } + Rule { + condition: qmlcachegenProbe.found + inputs: ["qt.qml.qml", "qt.qml.js"] + outputArtifacts: [{ + filePath: input.fileName + 'c', + fileTags: input.fileTags.filter(function(tag) { + return tag === "qt.qml.qml" || tag === "qt.qml.js"; + })[0] + 'c' + }] + outputFileTags: ["qt.qml.qmlc", "qt.qml.jsc"] + prepare: { + var args = input.Qt.qmlcache._targetArgs.concat(input.filePath, "-o", output.filePath); + var cmd = new Command(input.Qt.qmlcache.qmlCacheGenPath, args); + cmd.description = "precompiling " + input.fileName; + cmd.highlight = "compiler"; + return cmd; + } + } + Group { + condition: product.Qt.qmlcache.installDir !== undefined + fileTagsFilter: product.Qt.qmlcache.additionalProductTypes + qbs.install: true + qbs.installDir: product.Qt.qmlcache.installDir + } +} diff --git a/tests/auto/blackbox/testdata-qt/cached-qml/MainForm.ui.qml b/tests/auto/blackbox/testdata-qt/cached-qml/MainForm.ui.qml new file mode 100644 index 000000000..3fe8b6f04 --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/cached-qml/MainForm.ui.qml @@ -0,0 +1,29 @@ +import QtQuick 2.6 + +Rectangle { + property alias mouseArea: mouseArea + property alias textEdit: textEdit + + width: 360 + height: 360 + + MouseArea { + id: mouseArea + anchors.fill: parent + } + + TextEdit { + id: textEdit + text: qsTr("Enter some text...") + verticalAlignment: Text.AlignVCenter + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 20 + Rectangle { + anchors.fill: parent + anchors.margins: -10 + color: "transparent" + border.width: 1 + } + } +} diff --git a/tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs b/tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs new file mode 100644 index 000000000..2a7171fc2 --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs @@ -0,0 +1,30 @@ +import qbs + +CppApplication { + name: "app" + Depends { name: "Qt.core" } + Depends { name: "Qt.quick" } + Depends { name: "Qt.qml" } + Qt.qml.generateCacheFiles: true + Qt.qml.cacheFilesInstallDir: "data" + + files: [ + "main.cpp", + "MainForm.ui.qml", + "main.qml", + "stuff.js" + ] + + Group { + fileTagsFilter: product.type + qbs.install: true + } + + // Install the C++ sources to tell the blackbox test that Qt.qmlcache is not available. + Group { + condition: !Qt.qml.cachingEnabled + fileTagsFilter: ["cpp"] + qbs.install: true + qbs.installDir: "data" + } +} diff --git a/tests/auto/blackbox/testdata-qt/cached-qml/main.cpp b/tests/auto/blackbox/testdata-qt/cached-qml/main.cpp new file mode 100644 index 000000000..ac82ac0cf --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/cached-qml/main.cpp @@ -0,0 +1,14 @@ +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(qApp->applicationDirPath() + QStringLiteral("/data/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/tests/auto/blackbox/testdata-qt/cached-qml/main.qml b/tests/auto/blackbox/testdata-qt/cached-qml/main.qml new file mode 100644 index 000000000..f5f32f6bd --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/cached-qml/main.qml @@ -0,0 +1,17 @@ +import QtQuick 2.6 +import QtQuick.Window 2.2 +import "stuff.js" as Stuff + +Window { + visible: true + width: 640 + height: 480 + title: Stuff.title() + + MainForm { + anchors.fill: parent + mouseArea.onClicked: { + console.log(qsTr('Clicked on background. Text: "' + textEdit.text + '"')) + } + } +} diff --git a/tests/auto/blackbox/testdata-qt/cached-qml/qml.qrc b/tests/auto/blackbox/testdata-qt/cached-qml/qml.qrc new file mode 100644 index 000000000..57c8988b9 --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/cached-qml/qml.qrc @@ -0,0 +1,7 @@ +<!DOCTYPE RCC> +<RCC version="1.0"> + <qresource prefix="/"> + <file>main.qml</file> + <file>MainForm.ui.qml</file> + </qresource> +</RCC> diff --git a/tests/auto/blackbox/testdata-qt/cached-qml/stuff.js b/tests/auto/blackbox/testdata-qt/cached-qml/stuff.js new file mode 100644 index 000000000..3c19feacd --- /dev/null +++ b/tests/auto/blackbox/testdata-qt/cached-qml/stuff.js @@ -0,0 +1 @@ +function title() { return "Wello Horld!"; } diff --git a/tests/auto/blackbox/tst_blackboxqt.cpp b/tests/auto/blackbox/tst_blackboxqt.cpp index 8bf892fb0..71f384b7a 100644 --- a/tests/auto/blackbox/tst_blackboxqt.cpp +++ b/tests/auto/blackbox/tst_blackboxqt.cpp @@ -69,6 +69,20 @@ void TestBlackboxQt::autoQrc() m_qbsStdout.constData()); } +void TestBlackboxQt::cachedQml() +{ + QDir::setCurrent(testDataDir + "/cached-qml"); + QCOMPARE(runQbs(), 0); + QString dataDir = relativeBuildDir() + "/install-root/data"; + if (QFile::exists(dataDir + "/main.cpp")) { + // If C++ source files were installed then Qt.qmlcache is not available. See project file. + QSKIP("No QML cache files generated."); + } + QVERIFY(QFile::exists(dataDir + "/main.qmlc")); + QVERIFY(QFile::exists(dataDir + "/MainForm.ui.qmlc")); + QVERIFY(QFile::exists(dataDir + "/stuff.jsc")); +} + void TestBlackboxQt::combinedMoc() { QDir::setCurrent(testDataDir + "/combined-moc"); diff --git a/tests/auto/blackbox/tst_blackboxqt.h b/tests/auto/blackbox/tst_blackboxqt.h index 5b8ceaae4..5c1da8746 100644 --- a/tests/auto/blackbox/tst_blackboxqt.h +++ b/tests/auto/blackbox/tst_blackboxqt.h @@ -43,6 +43,7 @@ protected: private slots: void autoQrc(); + void cachedQml(); void combinedMoc(); void createProject(); void dbusAdaptors(); |