aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2017-06-22 15:54:06 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2017-07-17 13:19:37 +0000
commitaaaeea6a55ca1242689f4cf16e3aac173ff7d8c4 (patch)
tree8922c7b2f74c2c6814a2f229f8a6a2f8cb36e799
parentd479de3d9b6042bf14a905ec3ba3bf2a451f7b55 (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.qdoc41
-rw-r--r--src/lib/qtprofilesetup/qtprofilesetup.cpp8
-rw-r--r--src/lib/qtprofilesetup/templates.qrc1
-rw-r--r--src/lib/qtprofilesetup/templates/qml.qbs13
-rw-r--r--src/lib/qtprofilesetup/templates/qmlcache.qbs67
-rw-r--r--tests/auto/blackbox/testdata-qt/cached-qml/MainForm.ui.qml29
-rw-r--r--tests/auto/blackbox/testdata-qt/cached-qml/cached-qml.qbs30
-rw-r--r--tests/auto/blackbox/testdata-qt/cached-qml/main.cpp14
-rw-r--r--tests/auto/blackbox/testdata-qt/cached-qml/main.qml17
-rw-r--r--tests/auto/blackbox/testdata-qt/cached-qml/qml.qrc7
-rw-r--r--tests/auto/blackbox/testdata-qt/cached-qml/stuff.js1
-rw-r--r--tests/auto/blackbox/tst_blackboxqt.cpp14
-rw-r--r--tests/auto/blackbox/tst_blackboxqt.h1
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();