summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVenugopal Shivashankar <Venugopal.Shivashankar@qt.io>2020-03-16 15:08:20 +0100
committerTopi Reinio <topi.reinio@qt.io>2020-03-20 09:57:26 +0100
commit02265f9bbc213d219afc345594307affb900e07e (patch)
tree882a41d2bba43c256a4ae565a65c89e07d29ce79
parentcc92cb9329e1fc17758ef432cfa5e2c938a18da0 (diff)
qdoc: Extend \example command to consider CMake projects
QDoc looks for project file(s) in the example directories before generating docs for the example. Now that we are moving towards CMake, it's ideal that qdoc is aware of this new project file type. Refactor the code that looks for project files - add a new function to Config for this purpose, and store the project file name into ExampleNode. This allows removal of duplicated logic when generating the example-manifest.xml file. Add a unit test for Config::getExampleProjectFile(), and modify the generatedoutput test to cover output for a CMake-based example. [ChangeLog][qdoc] Added support for CMake-based example projects. Fixes: QTBUG-82908 Change-Id: If9f061c613fee94b35df277043c2f4df93da7ec0 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
-rw-r--r--src/qdoc/config.cpp30
-rw-r--r--src/qdoc/config.h3
-rw-r--r--src/qdoc/cppcodeparser.cpp74
-rw-r--r--src/qdoc/cppcodeparser.h4
-rw-r--r--src/qdoc/htmlgenerator.cpp28
-rw-r--r--src/qdoc/node.h8
-rw-r--r--tests/auto/qdoc/config/testdata/configs/exampletest.qdocconf2
-rw-r--r--tests/auto/qdoc/config/testdata/exampletest/examples/test/empty/test.pro1
-rw-r--r--tests/auto/qdoc/config/testdata/exampletest/examples/test/example1/example1.pro1
-rw-r--r--tests/auto/qdoc/config/testdata/exampletest/examples/test/example2/example2.qmlproject1
-rw-r--r--tests/auto/qdoc/config/testdata/exampletest/examples/test/example3/example3.pyproject1
-rw-r--r--tests/auto/qdoc/config/testdata/exampletest/examples/test/example4/CMakeLists.txt1
-rw-r--r--tests/auto/qdoc/config/tst_config.cpp29
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/examples-manifest.xml5
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/test-cmaketest-example.html22
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/test.qhp4
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/CMakeLists.txt2
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/doc/src/cmaketest.qdoc32
-rw-r--r--tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/main.cpp1
-rw-r--r--tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp1
21 files changed, 169 insertions, 83 deletions
diff --git a/src/qdoc/config.cpp b/src/qdoc/config.cpp
index 695d59444..1387fb411 100644
--- a/src/qdoc/config.cpp
+++ b/src/qdoc/config.cpp
@@ -344,6 +344,10 @@ void Config::load(const QString &fileName)
// always added to what's defined in configuration file.
insertStringList(CONFIG_DEFINES, m_defines);
insertStringList(CONFIG_INCLUDEPATHS, m_includePaths);
+
+ // Prefetch values that are used internally
+ m_exampleFiles = getCanonicalPathList(CONFIG_EXAMPLES);
+ m_exampleDirs = getCanonicalPathList(CONFIG_EXAMPLEDIRS);
}
/*!
@@ -795,6 +799,32 @@ QStringList Config::getExampleImageFiles(const QSet<QString> &excludedDirs,
}
/*!
+ Returns the path to the project file for \a examplePath, or an empty string
+ if no project file was found.
+ */
+QString Config::getExampleProjectFile(const QString &examplePath)
+{
+ QFileInfo fileInfo(examplePath);
+ QStringList validNames;
+ validNames << fileInfo.fileName() + QLatin1String(".pro")
+ << fileInfo.fileName() + QLatin1String(".qmlproject")
+ << fileInfo.fileName() + QLatin1String(".pyproject")
+ << QLatin1String("CMakeLists.txt")
+ << QLatin1String("qbuild.pro"); // legacy
+
+ QString projectFile;
+
+ for (const auto &name : qAsConst(validNames)) {
+ projectFile = Config::findFile(Location(), m_exampleFiles, m_exampleDirs,
+ examplePath + QLatin1Char('/') + name);
+ if (!projectFile.isEmpty())
+ return projectFile;
+ }
+
+ return projectFile;
+}
+
+/*!
\a fileName is the path of the file to find.
\a files and \a dirs are the lists where we must find the
diff --git a/src/qdoc/config.h b/src/qdoc/config.h
index 29ad59afb..f8823d521 100644
--- a/src/qdoc/config.h
+++ b/src/qdoc/config.h
@@ -135,6 +135,7 @@ public:
const QSet<QString> &excludedFiles);
QStringList getExampleImageFiles(const QSet<QString> &excludedDirs,
const QSet<QString> &excludedFiles);
+ QString getExampleProjectFile(const QString &examplePath);
static QStringList loadMaster(const QString &fileName);
static bool isFileExcluded(const QString &fileName, const QSet<QString> &excludedFiles);
@@ -189,6 +190,8 @@ private:
QStringList m_defines {};
QStringList m_includePaths {};
QStringList m_indexDirs {};
+ QStringList m_exampleFiles {};
+ QStringList m_exampleDirs {};
QString m_currentDir {};
QString m_previousCurrentDir {};
diff --git a/src/qdoc/cppcodeparser.cpp b/src/qdoc/cppcodeparser.cpp
index 647631c27..ed12f64c2 100644
--- a/src/qdoc/cppcodeparser.cpp
+++ b/src/qdoc/cppcodeparser.cpp
@@ -48,8 +48,6 @@ QT_BEGIN_NAMESPACE
/* qmake ignore Q_OBJECT */
-QStringList CppCodeParser::exampleFiles;
-QStringList CppCodeParser::exampleDirs;
QSet<QString> CppCodeParser::excludeDirs;
QSet<QString> CppCodeParser::excludeFiles;
@@ -120,8 +118,6 @@ void CppCodeParser::initializeParser()
nodeTypeTestFuncMap_.insert(COMMAND_VARIABLE, &Node::isVariable);
Config &config = Config::instance();
- exampleFiles = config.getCanonicalPathList(CONFIG_EXAMPLES);
- exampleDirs = config.getCanonicalPathList(CONFIG_EXAMPLEDIRS);
QStringList exampleFilePatterns =
config.getStringList(CONFIG_EXAMPLES + Config::dot + CONFIG_FILEEXTENSIONS);
@@ -771,58 +767,29 @@ FunctionNode *CppCodeParser::parseMacroArg(const Location &location, const QStri
return macro;
}
-void CppCodeParser::setExampleFileLists(PageNode *pn)
+void CppCodeParser::setExampleFileLists(ExampleNode *en)
{
- QString examplePath = pn->name();
- QString proFileName =
- examplePath + QLatin1Char('/') + examplePath.split(QLatin1Char('/')).last() + ".pro";
- QString fullPath =
- Config::findFile(pn->doc().location(), exampleFiles, exampleDirs, proFileName);
-
+ Config &config = Config::instance();
+ QString fullPath = config.getExampleProjectFile(en->name());
if (fullPath.isEmpty()) {
- QString tmp = proFileName;
- proFileName = examplePath + QLatin1Char('/') + "qbuild.pro";
- fullPath = Config::findFile(pn->doc().location(), exampleFiles, exampleDirs, proFileName);
- if (fullPath.isEmpty()) {
- proFileName = examplePath + QLatin1Char('/')
- + examplePath.split(QLatin1Char('/')).last() + ".qmlproject";
- fullPath =
- Config::findFile(pn->doc().location(), exampleFiles, exampleDirs, proFileName);
- if (fullPath.isEmpty()) {
- proFileName = examplePath + QLatin1Char('/')
- + examplePath.split(QLatin1Char('/')).last() + ".pyproject";
- fullPath = Config::findFile(pn->doc().location(), exampleFiles, exampleDirs,
- proFileName);
- if (fullPath.isEmpty()) {
- QString details = QLatin1String("Example directories: ")
- + exampleDirs.join(QLatin1Char(' '));
- if (!exampleFiles.isEmpty())
- details += QLatin1String(", example files: ")
- + exampleFiles.join(QLatin1Char(' '));
- pn->location().warning(
- tr("Cannot find file '%1' or '%2'").arg(tmp).arg(proFileName), details);
- pn->location().warning(tr(" EXAMPLE PATH DOES NOT EXIST: %1").arg(examplePath),
- details);
- return;
- }
- }
- }
+ QString details = QLatin1String("Example directories: ")
+ + config.getCanonicalPathList(CONFIG_EXAMPLEDIRS).join(QLatin1Char(' '));
+ en->location().warning(
+ tr("Cannot find project file for example '%1'").arg(en->name()), details);
+ return;
}
- int sizeOfBoringPartOfName = fullPath.size() - proFileName.size();
- if (fullPath.startsWith("./"))
- sizeOfBoringPartOfName = sizeOfBoringPartOfName - 2;
- fullPath.truncate(fullPath.lastIndexOf('/'));
+ QDir exampleDir(QFileInfo(fullPath).dir());
- QStringList exampleFiles = Config::getFilesHere(fullPath, exampleNameFilter, Location(),
+ QStringList exampleFiles = Config::getFilesHere(exampleDir.path(), exampleNameFilter, Location(),
excludeDirs, excludeFiles);
// Search for all image files under the example project, excluding doc/images directory.
QSet<QString> excludeDocDirs(excludeDirs);
- excludeDocDirs.insert(QDir(fullPath).canonicalPath() + "/doc/images");
- QStringList imageFiles = Config::getFilesHere(fullPath, exampleImageFilter, Location(),
+ excludeDocDirs.insert(exampleDir.path() + QLatin1String("/doc/images"));
+ QStringList imageFiles = Config::getFilesHere(exampleDir.path(), exampleImageFilter, Location(),
excludeDocDirs, excludeFiles);
if (!exampleFiles.isEmpty()) {
- // move main.cpp and to the end, if it exists
+ // move main.cpp to the end, if it exists
QString mainCpp;
const auto isGeneratedOrMainCpp = [&mainCpp](const QString &fileName) {
@@ -842,16 +809,19 @@ void CppCodeParser::setExampleFileLists(PageNode *pn)
if (!mainCpp.isEmpty())
exampleFiles.append(mainCpp);
- // add any qmake Qt resource files and qmake project files
- exampleFiles += Config::getFilesHere(fullPath, "*.qrc *.pro *.qmlproject qmldir");
+ // Add any resource and project files
+ exampleFiles += Config::getFilesHere(exampleDir.path(),
+ QLatin1String("*.qrc *.pro *.qmlproject *.pyproject CMakeLists.txt qmldir"));
}
+ exampleDir.cdUp();
+ int pathLen = exampleDir.path().size() + 1;
for (auto &file : exampleFiles)
- file = file.mid(sizeOfBoringPartOfName);
+ file = file.mid(pathLen);
for (auto &file : imageFiles)
- file = file.mid(sizeOfBoringPartOfName);
- ExampleNode *en = static_cast<ExampleNode *>(pn);
- en->setFiles(exampleFiles);
+ file = file.mid(pathLen);
+
+ en->setFiles(exampleFiles, fullPath.mid(pathLen));
en->setImages(imageFiles);
}
diff --git a/src/qdoc/cppcodeparser.h b/src/qdoc/cppcodeparser.h
index 41607434f..df92b71c4 100644
--- a/src/qdoc/cppcodeparser.h
+++ b/src/qdoc/cppcodeparser.h
@@ -86,7 +86,7 @@ protected:
bool hasTooManyTopics(const Doc &doc) const;
private:
- void setExampleFileLists(PageNode *pn);
+ void setExampleFileLists(ExampleNode *en);
protected:
typedef bool (Node::*NodeTypeTestFunc)() const;
@@ -94,8 +94,6 @@ protected:
QMap<QString, Node::NodeType> nodeTypeMap_;
private:
- static QStringList exampleFiles;
- static QStringList exampleDirs;
static QSet<QString> excludeDirs;
static QSet<QString> excludeFiles;
QString exampleNameFilter;
diff --git a/src/qdoc/htmlgenerator.cpp b/src/qdoc/htmlgenerator.cpp
index c32e26b4b..104d97bc2 100644
--- a/src/qdoc/htmlgenerator.cpp
+++ b/src/qdoc/htmlgenerator.cpp
@@ -3919,33 +3919,9 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString
writer.writeAttribute("name", en->title());
QString docUrl = manifestDir + fileBase(en) + ".html";
writer.writeAttribute("docUrl", docUrl);
- QStringList proFiles;
const auto exampleFiles = en->files();
- for (const QString &file : exampleFiles) {
- if (file.endsWith(".pro") || file.endsWith(".qmlproject")
- || file.endsWith(".pyproject"))
- proFiles << file;
- }
- if (!proFiles.isEmpty()) {
- if (proFiles.size() == 1) {
- writer.writeAttribute("projectPath", installPath + proFiles[0]);
- } else {
- QString exampleName = en->name().split('/').last();
- bool proWithExampleNameFound = false;
- for (int j = 0; j < proFiles.size(); j++) {
- if (proFiles[j].endsWith(QStringLiteral("%1/%1.pro").arg(exampleName))
- || proFiles[j].endsWith(QStringLiteral("%1/%1.qmlproject").arg(exampleName))
- || proFiles[j].endsWith(
- QStringLiteral("%1/%1.pyproject").arg(exampleName))) {
- writer.writeAttribute("projectPath", installPath + proFiles[j]);
- proWithExampleNameFound = true;
- break;
- }
- }
- if (!proWithExampleNameFound)
- writer.writeAttribute("projectPath", installPath + proFiles[0]);
- }
- }
+ if (!en->projectFile().isEmpty())
+ writer.writeAttribute("projectPath", installPath + en->projectFile());
if (!en->imageFileName().isEmpty()) {
writer.writeAttribute("imageUrl", manifestDir + en->imageFileName());
usedAttributes << "imageUrl";
diff --git a/src/qdoc/node.h b/src/qdoc/node.h
index 9f78cc824..b7293f408 100644
--- a/src/qdoc/node.h
+++ b/src/qdoc/node.h
@@ -705,13 +705,19 @@ public:
void setImageFileName(const QString &ifn) override { imageFileName_ = ifn; }
const QStringList &files() const { return files_; }
const QStringList &images() const { return images_; }
- void setFiles(const QStringList files) { files_ = files; }
+ const QString &projectFile() const { return projectFile_; }
+ void setFiles(const QStringList files, const QString &projectFile)
+ {
+ files_ = files;
+ projectFile_ = projectFile;
+ }
void setImages(const QStringList images) { images_ = images; }
void appendFile(QString &file) { files_.append(file); }
void appendImage(QString &image) { images_.append(image); }
private:
QString imageFileName_;
+ QString projectFile_;
QStringList files_;
QStringList images_;
};
diff --git a/tests/auto/qdoc/config/testdata/configs/exampletest.qdocconf b/tests/auto/qdoc/config/testdata/configs/exampletest.qdocconf
new file mode 100644
index 000000000..a1459f977
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/configs/exampletest.qdocconf
@@ -0,0 +1,2 @@
+project = ExampleTest
+exampledirs = ../exampletest/examples
diff --git a/tests/auto/qdoc/config/testdata/exampletest/examples/test/empty/test.pro b/tests/auto/qdoc/config/testdata/exampletest/examples/test/empty/test.pro
new file mode 100644
index 000000000..556df42ea
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/exampletest/examples/test/empty/test.pro
@@ -0,0 +1 @@
+# nothing
diff --git a/tests/auto/qdoc/config/testdata/exampletest/examples/test/example1/example1.pro b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example1/example1.pro
new file mode 100644
index 000000000..556df42ea
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example1/example1.pro
@@ -0,0 +1 @@
+# nothing
diff --git a/tests/auto/qdoc/config/testdata/exampletest/examples/test/example2/example2.qmlproject b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example2/example2.qmlproject
new file mode 100644
index 000000000..556df42ea
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example2/example2.qmlproject
@@ -0,0 +1 @@
+# nothing
diff --git a/tests/auto/qdoc/config/testdata/exampletest/examples/test/example3/example3.pyproject b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example3/example3.pyproject
new file mode 100644
index 000000000..556df42ea
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example3/example3.pyproject
@@ -0,0 +1 @@
+# nothing
diff --git a/tests/auto/qdoc/config/testdata/exampletest/examples/test/example4/CMakeLists.txt b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example4/CMakeLists.txt
new file mode 100644
index 000000000..556df42ea
--- /dev/null
+++ b/tests/auto/qdoc/config/testdata/exampletest/examples/test/example4/CMakeLists.txt
@@ -0,0 +1 @@
+# nothing
diff --git a/tests/auto/qdoc/config/tst_config.cpp b/tests/auto/qdoc/config/tst_config.cpp
index 1e9383fb9..44a1ba953 100644
--- a/tests/auto/qdoc/config/tst_config.cpp
+++ b/tests/auto/qdoc/config/tst_config.cpp
@@ -28,6 +28,8 @@
#include "config.h"
+#include <QtCore/qdir.h>
+#include <QtCore/qfileinfo.h>
#include <QtCore/qhash.h>
#include <QtCore/qstringlist.h>
#include <QtTest/QtTest>
@@ -43,6 +45,7 @@ class tst_Config : public QObject
private slots:
void classMembersInitializeToFalseOrEmpty();
void includePathsFromCommandLine();
+ void getExampleProjectFile();
};
void tst_Config::classMembersInitializeToFalseOrEmpty()
@@ -80,6 +83,32 @@ void tst_Config::includePathsFromCommandLine()
QCOMPARE(actual, expected);
}
+void::tst_Config::getExampleProjectFile()
+{
+ QStringList commandLineArgs = { QStringLiteral("./qdoc") };
+ Config::instance().init("QDoc Test", commandLineArgs);
+ auto &config = Config::instance();
+
+ const auto docConfig = QFINDTESTDATA("/testdata/configs/exampletest.qdocconf");
+ config.load(docConfig);
+
+ auto rootDir = QFileInfo(docConfig).dir();
+ QVERIFY(rootDir.cd("../exampletest/examples/test"));
+
+ QVERIFY(config.getExampleProjectFile("invalid").isEmpty());
+ QVERIFY(config.getExampleProjectFile("test/empty").isEmpty());
+
+ QCOMPARE(config.getExampleProjectFile("test/example1"),
+ rootDir.absoluteFilePath("example1/example1.pro"));
+ QCOMPARE(config.getExampleProjectFile("test/example2"),
+ rootDir.absoluteFilePath("example2/example2.qmlproject"));
+ QCOMPARE(config.getExampleProjectFile("test/example3"),
+ rootDir.absoluteFilePath("example3/example3.pyproject"));
+ QCOMPARE(config.getExampleProjectFile("test/example4"),
+ rootDir.absoluteFilePath("example4/CMakeLists.txt"));
+}
+
+
QTEST_APPLESS_MAIN(tst_Config)
#include "tst_config.moc"
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/examples-manifest.xml b/tests/auto/qdoc/generatedoutput/expected_output/examples-manifest.xml
index 7f206d0e8..8aa9ce303 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/examples-manifest.xml
+++ b/tests/auto/qdoc/generatedoutput/expected_output/examples-manifest.xml
@@ -1,6 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<instructionals module="Test">
<examples>
+ <example name="CMake Example Project" docUrl="qthelp://org.qt-project.test.001/test/test-cmaketest-example.html" projectPath="test/cmaketest/CMakeLists.txt" isTest="true">
+ <description><![CDATA[No description available]]></description>
+ <tags>cmake,project,test</tags>
+ <fileToOpen mainFile="true">test/cmaketest/main.cpp</fileToOpen>
+ </example>
<example name="QML Documentation Example" docUrl="qthelp://org.qt-project.test.001/test/test-componentset-example.html" projectPath="tutorials/componentset/componentset.pro" isTest="true">
<description><![CDATA[Example for documenting QML types.]]></description>
<tags>documentation,qml,sample,test</tags>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/test-cmaketest-example.html b/tests/auto/qdoc/generatedoutput/expected_output/test-cmaketest-example.html
new file mode 100644
index 000000000..dc123674d
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/test-cmaketest-example.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- cmaketest.qdoc -->
+ <title>CMake Example Project | Test</title>
+</head>
+<body>
+<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">CMake Example Project</h1>
+<span class="subtitle"></span>
+<!-- $$$cmaketest-description -->
+<div class="descr"> <a name="details"></a>
+<p>Files:</p>
+<ul>
+<li><a href="test-cmaketest-cmakelists-txt.html">cmaketest/CMakeLists.txt</a></li>
+<li><a href="test-cmaketest-main-cpp.html">cmaketest/main.cpp</a></li>
+</ul>
+</div>
+<!-- @@@cmaketest -->
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/test.qhp b/tests/auto/qdoc/generatedoutput/expected_output/test.qhp
index 4816ef1d5..459892df1 100644
--- a/tests/auto/qdoc/generatedoutput/expected_output/test.qhp
+++ b/tests/auto/qdoc/generatedoutput/expected_output/test.qhp
@@ -8,6 +8,7 @@
<section ref="uicomponents-qmlmodule.html" title="UI Components">
<section ref="uicomponents-qmlmodule.html" title="Test">
<section ref="qdoc-test-qmlmodule.html" title=""/>
+ <section ref="test-cmaketest-example.html" title="CMake Example Project"/>
<section ref="testcpp-module.html" title="QDoc Test C++ Classes"/>
<section ref="test-componentset-example.html" title="QML Documentation Example"/>
<section ref="uicomponents-qmlmodule.html" title="UI Components"/>
@@ -119,6 +120,9 @@
<file>qml-uicomponents-switch.html</file>
<file>qml-uicomponents-tabwidget-members.html</file>
<file>qml-uicomponents-tabwidget.html</file>
+ <file>test-cmaketest-cmakelists-txt.html</file>
+ <file>test-cmaketest-example.html</file>
+ <file>test-cmaketest-main-cpp.html</file>
<file>test-componentset-componentset-pro.html</file>
<file>test-componentset-example.html</file>
<file>test-componentset-progressbar-qml.html</file>
diff --git a/tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf b/tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf
index 2eb2c5036..8eec4ea4d 100644
--- a/tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf
+++ b/tests/auto/qdoc/generatedoutput/testdata/configs/testqml.qdocconf
@@ -16,7 +16,7 @@ excludedirs = ../bug80259
sources.fileextensions = "*.qml *.cpp *.qdoc"
headers.fileextensions = "*.h"
-examples.fileextensions = "*.qml"
+examples.fileextensions = "*.qml *.cpp"
macro.begincomment = "\\c{/*}"
macro.QDocTestVer = "1.1"
diff --git a/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/CMakeLists.txt b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/CMakeLists.txt
new file mode 100644
index 000000000..c6a5c654b
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/CMakeLists.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required (VERSION 2.8.11)
+project (QDOCTEST)
diff --git a/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/doc/src/cmaketest.qdoc b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/doc/src/cmaketest.qdoc
new file mode 100644
index 000000000..13767e147
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/doc/src/cmaketest.qdoc
@@ -0,0 +1,32 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example cmaketest
+ \title CMake Example Project
+*/
diff --git a/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/main.cpp b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/main.cpp
new file mode 100644
index 000000000..68d71eb71
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/testdata/qml/cmaketest/main.cpp
@@ -0,0 +1 @@
+void main(){}
diff --git a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
index ead94584a..b3c69af71 100644
--- a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
+++ b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
@@ -204,6 +204,7 @@ void tst_generatedOutput::htmlFromQml()
{
testAndCompare("testdata/configs/testqml.qdocconf",
"test-componentset-example.html "
+ "test-cmaketest-example.html "
"uicomponents-qmlmodule.html "
"qdoc-test-qmlmodule.html "
"qml-qdoc-test-abstractparent.html "