forked from qt-creator/qt-creator
CMake generating: Modify to generate files according to new dir structure
Task-number: QDS-5380 Change-Id: Ic3a4d6f4cd05185ded31b5d40adef43ff6508407 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
<RCC>
|
||||
<qresource prefix="/boilerplatetemplates">
|
||||
<file>qmlprojectmaincpp.tpl</file>
|
||||
<file>qmlprojectmaincppheader.tpl</file>
|
||||
<file>qmlprojectmodules.tpl</file>
|
||||
<file>qmlprojectmaincmakelists.tpl</file>
|
||||
<file>qmlprojectmodulecmakelists.tpl</file>
|
||||
<file>qmlprojectmainqml.tpl</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -78,7 +78,7 @@ void onGenerateCmakeLists()
|
||||
{
|
||||
queuedFiles.clear();
|
||||
FilePath rootDir = ProjectExplorer::SessionManager::startupProject()->projectDirectory();
|
||||
GenerateCmakeLists::generateMainCmake(rootDir);
|
||||
GenerateCmakeLists::generateCmakes(rootDir);
|
||||
GenerateEntryPoints::generateMainCpp(rootDir);
|
||||
GenerateEntryPoints::generateMainQml(rootDir);
|
||||
if (showConfirmationDialog(rootDir))
|
||||
@@ -139,138 +139,125 @@ bool writeFile(const GeneratableFile &file)
|
||||
return true;
|
||||
}
|
||||
|
||||
QString readTemplate(const QString &templatePath)
|
||||
{
|
||||
QFile templatefile(templatePath);
|
||||
templatefile.open(QIODevice::ReadOnly);
|
||||
QTextStream stream(&templatefile);
|
||||
QString content = stream.readAll();
|
||||
templatefile.close();
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace GenerateCmakeLists {
|
||||
|
||||
QStringList moduleNames;
|
||||
|
||||
const QDir::Filters FILES_ONLY = QDir::Files;
|
||||
const QDir::Filters DIRS_ONLY = QDir::Dirs|QDir::Readable|QDir::NoDotAndDotDot;
|
||||
|
||||
const char CMAKEFILENAME[] = "CMakeLists.txt";
|
||||
const char QMLDIRFILENAME[] = "qmldir";
|
||||
const char MODULEFILENAME[] = "qmlmodules";
|
||||
|
||||
QStringList processDirectory(const FilePath &dir)
|
||||
bool generateCmakes(const FilePath &rootDir)
|
||||
{
|
||||
QStringList moduleNames;
|
||||
moduleNames.clear();
|
||||
|
||||
FilePaths files = dir.dirEntries(FILES_ONLY);
|
||||
for (FilePath &file : files) {
|
||||
if (!file.fileName().compare(CMAKEFILENAME))
|
||||
files.removeAll(file);
|
||||
FilePath contentDir = rootDir.pathAppended("content");
|
||||
FilePath importDir = rootDir.pathAppended("imports");
|
||||
|
||||
generateModuleCmake(contentDir);
|
||||
generateImportCmake(importDir);
|
||||
generateMainCmake(rootDir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (files.isEmpty()) {
|
||||
generateSubdirCmake(dir);
|
||||
FilePaths subDirs = dir.dirEntries(DIRS_ONLY);
|
||||
for (FilePath &subDir : subDirs) {
|
||||
QStringList subDirModules = processDirectory(subDir);
|
||||
moduleNames.append(subDirModules);
|
||||
}
|
||||
}
|
||||
else {
|
||||
QString moduleName = generateModuleCmake(dir);
|
||||
if (!moduleName.isEmpty()) {
|
||||
moduleNames.append(moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
return moduleNames;
|
||||
}
|
||||
|
||||
const char MAINFILE_REQUIRED_VERSION[] = "cmake_minimum_required(VERSION 3.18)\n\n";
|
||||
const char MAINFILE_PROJECT[] = "project(%1 LANGUAGES CXX)\n\n";
|
||||
const char MAINFILE_CMAKE_OPTIONS[] = "set(CMAKE_INCLUDE_CURRENT_DIR ON)\nset(CMAKE_AUTOMOC ON)\n\n";
|
||||
const char MAINFILE_PACKAGES[] = "find_package(Qt6 COMPONENTS Gui Qml Quick)\n";
|
||||
const char MAINFILE_LIBRARIES[] = "set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/qml)\n\n";
|
||||
const char MAINFILE_CPP[] = "add_executable(%1 main.cpp)\n\n";
|
||||
const char MAINFILE_MAINMODULE[] = "qt6_add_qml_module(%1\n\tURI \"Main\"\n\tVERSION 1.0\n\tNO_PLUGIN\n\tQML_FILES main.qml\n)\n\n";
|
||||
const char MAINFILE_LINK_LIBRARIES[] = "target_link_libraries(%1 PRIVATE\n\tQt${QT_VERSION_MAJOR}::Core\n\tQt${QT_VERSION_MAJOR}::Gui\n\tQt${QT_VERSION_MAJOR}::Quick\n\tQt${QT_VERSION_MAJOR}::Qml\n)\n\n";
|
||||
|
||||
const char ADD_SUBDIR[] = "add_subdirectory(%1)\n";
|
||||
const char MAIN_CMAKEFILE_TEMPLATE_PATH[] = ":/boilerplatetemplates/qmlprojectmaincmakelists.tpl";
|
||||
const char QMLMODULES_FILE_TEMPLATE_PATH[] = ":/boilerplatetemplates/qmlprojectmodules.tpl";
|
||||
|
||||
void generateMainCmake(const FilePath &rootDir)
|
||||
{
|
||||
//TODO startupProject() may be a terrible way to try to get "current project". It's not necessarily the same thing at all.
|
||||
QString projectName = ProjectExplorer::SessionManager::startupProject()->displayName();
|
||||
QString appName = projectName + "App";
|
||||
|
||||
FilePaths subDirs = rootDir.dirEntries(DIRS_ONLY);
|
||||
QString cmakeFileContent = GenerateCmake::readTemplate(MAIN_CMAKEFILE_TEMPLATE_PATH).arg(appName);
|
||||
queueCmakeFile(rootDir, cmakeFileContent);
|
||||
|
||||
QString fileContent;
|
||||
fileContent.append(MAINFILE_REQUIRED_VERSION);
|
||||
fileContent.append(QString(MAINFILE_PROJECT).arg(projectName));
|
||||
fileContent.append(MAINFILE_CMAKE_OPTIONS);
|
||||
fileContent.append(MAINFILE_PACKAGES);
|
||||
fileContent.append(QString(MAINFILE_CPP).arg(projectName));
|
||||
fileContent.append(QString(MAINFILE_MAINMODULE).arg(projectName));
|
||||
fileContent.append(MAINFILE_LIBRARIES);
|
||||
QString modulesAsPlugins;
|
||||
for (const QString &moduleName : moduleNames)
|
||||
modulesAsPlugins.append(" " + moduleName + "plugin\n");
|
||||
|
||||
for (FilePath &subDir : subDirs) {
|
||||
QStringList subDirModules = processDirectory(subDir);
|
||||
if (!subDirModules.isEmpty())
|
||||
fileContent.append(QString(ADD_SUBDIR).arg(subDir.fileName()));
|
||||
QString moduleFileContent = GenerateCmake::readTemplate(QMLMODULES_FILE_TEMPLATE_PATH).arg(appName).arg(modulesAsPlugins);
|
||||
GenerateCmake::queueFile(rootDir.pathAppended(MODULEFILENAME), moduleFileContent);
|
||||
}
|
||||
fileContent.append("\n");
|
||||
|
||||
fileContent.append(QString(MAINFILE_LINK_LIBRARIES).arg(projectName));
|
||||
const char DO_NOT_EDIT_FILE_COMMENT[] = "### This file is automatically generated by Qt Design Studio.\n### Do not change\n\n";
|
||||
const char ADD_SUBDIR[] = "add_subdirectory(%1)\n";
|
||||
|
||||
createCmakeFile(rootDir, fileContent);
|
||||
void generateImportCmake(const FilePath &dir)
|
||||
{
|
||||
QString fileContent;
|
||||
|
||||
fileContent.append(DO_NOT_EDIT_FILE_COMMENT);
|
||||
|
||||
FilePaths subDirs = dir.dirEntries(DIRS_ONLY);
|
||||
for (FilePath &subDir : subDirs) {
|
||||
fileContent.append(QString(ADD_SUBDIR).arg(subDir.fileName()));
|
||||
generateModuleCmake(subDir);
|
||||
}
|
||||
|
||||
queueCmakeFile(dir, fileContent);
|
||||
}
|
||||
|
||||
const char MODULEFILE_PROPERTY_SINGLETON[] = "QT_QML_SINGLETON_TYPE";
|
||||
const char MODULEFILE_PROPERTY_SET[] = "set_source_files_properties(%1\n\tPROPERTIES\n\t\t%2 %3\n)\n\n";
|
||||
const char MODULEFILE_CREATE_MODULE[] = "qt6_add_qml_module(%1\n\tURI \"%1\"\n\tVERSION 1.0\n%2)\n\n";
|
||||
const char MODULEFILE_PROPERTY_SET[] = "set_source_files_properties(%1\n PROPERTIES\n %2 %3\n)\n\n";
|
||||
const char MODULEFILE_TEMPLATE_PATH[] = ":/boilerplatetemplates/qmlprojectmodulecmakelists.tpl";
|
||||
|
||||
|
||||
QString generateModuleCmake(const FilePath &dir)
|
||||
void generateModuleCmake(const FilePath &dir)
|
||||
{
|
||||
QString fileContent;
|
||||
QString fileTemplate = GenerateCmake::readTemplate(MODULEFILE_TEMPLATE_PATH);
|
||||
const QStringList qmldirFilesOnly(QMLDIRFILENAME);
|
||||
|
||||
QString singletonContent;
|
||||
FilePaths qmldirFileList = dir.dirEntries(qmldirFilesOnly, FILES_ONLY);
|
||||
if (!qmldirFileList.isEmpty()) {
|
||||
QStringList singletons = getSingletonsFromQmldirFile(qmldirFileList.first());
|
||||
for (QString &singleton : singletons) {
|
||||
fileContent.append(QString(MODULEFILE_PROPERTY_SET).arg(singleton).arg(MODULEFILE_PROPERTY_SINGLETON).arg("true"));
|
||||
singletonContent.append(QString(MODULEFILE_PROPERTY_SET).arg(singleton).arg(MODULEFILE_PROPERTY_SINGLETON).arg("true"));
|
||||
}
|
||||
}
|
||||
|
||||
QStringList qmlFileList = getDirectoryTreeQmls(dir);
|
||||
QString qmlFiles;
|
||||
for (QString &qmlFile : qmlFileList)
|
||||
qmlFiles.append(QString("\t\t%1\n").arg(qmlFile));
|
||||
qmlFiles.append(QString(" %1\n").arg(qmlFile));
|
||||
|
||||
QStringList resourceFileList = getDirectoryTreeResources(dir);
|
||||
QString resourceFiles;
|
||||
for (QString &resourceFile : resourceFileList)
|
||||
resourceFiles.append(QString("\t\t%1\n").arg(resourceFile));
|
||||
resourceFiles.append(QString(" %1\n").arg(resourceFile));
|
||||
|
||||
QString moduleContent;
|
||||
if (!qmlFiles.isEmpty()) {
|
||||
moduleContent.append(QString("\tQML_FILES\n%1").arg(qmlFiles));
|
||||
moduleContent.append(QString(" QML_FILES\n%1").arg(qmlFiles));
|
||||
}
|
||||
if (!resourceFiles.isEmpty()) {
|
||||
moduleContent.append(QString("\tRESOURCES\n%1").arg(resourceFiles));
|
||||
moduleContent.append(QString(" RESOURCES\n%1").arg(resourceFiles));
|
||||
}
|
||||
|
||||
QString moduleName = dir.fileName();
|
||||
|
||||
fileContent.append(QString(MODULEFILE_CREATE_MODULE).arg(moduleName).arg(moduleContent));
|
||||
moduleNames.append(moduleName);
|
||||
|
||||
createCmakeFile(dir, fileContent);
|
||||
|
||||
return moduleName;
|
||||
}
|
||||
|
||||
void generateSubdirCmake(const FilePath &dir)
|
||||
{
|
||||
QString fileContent;
|
||||
FilePaths subDirs = dir.dirEntries(DIRS_ONLY);
|
||||
|
||||
for (FilePath &subDir : subDirs) {
|
||||
fileContent.append(QString(ADD_SUBDIR).arg(subDir.fileName()));
|
||||
}
|
||||
|
||||
createCmakeFile(dir, fileContent);
|
||||
fileContent.append(fileTemplate.arg(singletonContent).arg(moduleName).arg(moduleContent));
|
||||
queueCmakeFile(dir, fileContent);
|
||||
}
|
||||
|
||||
QStringList getSingletonsFromQmldirFile(const FilePath &filePath)
|
||||
@@ -347,7 +334,7 @@ QStringList getDirectoryTreeResources(const FilePath &dir)
|
||||
return resourceFileList;
|
||||
}
|
||||
|
||||
void createCmakeFile(const FilePath &dir, const QString &content)
|
||||
void queueCmakeFile(const FilePath &dir, const QString &content)
|
||||
{
|
||||
FilePath filePath = dir.pathAppended(CMAKEFILENAME);
|
||||
GenerateCmake::queueFile(filePath, content);
|
||||
@@ -370,35 +357,42 @@ bool generateEntryPointFiles(const FilePath &dir)
|
||||
return cppOk && qmlOk;
|
||||
}
|
||||
|
||||
const char MAIN_CPPFILE_CONTENT[] = ":/boilerplatetemplates/qmlprojectmaincpp.tpl";
|
||||
const char MAIN_CPPFILE_TEMPLATE_PATH[] = ":/boilerplatetemplates/qmlprojectmaincpp.tpl";
|
||||
const char MAIN_CPPFILE_DIR[] = "src";
|
||||
const char MAIN_CPPFILE_NAME[] = "main.cpp";
|
||||
const char MAIN_CPPFILE_HEADER_TEMPLATE_PATH[] = ":/boilerplatetemplates/qmlprojectmaincppheader.tpl";
|
||||
const char MAIN_CPPFILE_HEADER_NAME[] = "import_qml_plugins.h";
|
||||
const char MAIN_CPPFILE_HEADER_PLUGIN_LINE[] = "Q_IMPORT_QML_PLUGIN(%1)\n";
|
||||
|
||||
bool generateMainCpp(const FilePath &dir)
|
||||
{
|
||||
QFile templatefile(MAIN_CPPFILE_CONTENT);
|
||||
templatefile.open(QIODevice::ReadOnly);
|
||||
QTextStream stream(&templatefile);
|
||||
QString content = stream.readAll();
|
||||
templatefile.close();
|
||||
FilePath srcDir = dir.pathAppended(MAIN_CPPFILE_DIR);
|
||||
|
||||
FilePath filePath = dir.pathAppended(MAIN_CPPFILE_NAME);
|
||||
return GenerateCmake::queueFile(filePath, content);
|
||||
QString cppContent = GenerateCmake::readTemplate(MAIN_CPPFILE_TEMPLATE_PATH);
|
||||
FilePath cppFilePath = srcDir.pathAppended(MAIN_CPPFILE_NAME);
|
||||
bool cppOk = GenerateCmake::queueFile(cppFilePath, cppContent);
|
||||
|
||||
QString modulesAsPlugins;
|
||||
for (const QString &moduleName : GenerateCmakeLists::moduleNames)
|
||||
modulesAsPlugins.append(
|
||||
QString(MAIN_CPPFILE_HEADER_PLUGIN_LINE).arg(moduleName + "plugin"));
|
||||
|
||||
QString headerContent = GenerateCmake::readTemplate(MAIN_CPPFILE_HEADER_TEMPLATE_PATH)
|
||||
.arg(modulesAsPlugins);
|
||||
FilePath headerFilePath = srcDir.pathAppended(MAIN_CPPFILE_HEADER_NAME);
|
||||
bool headerOk = GenerateCmake::queueFile(headerFilePath, headerContent);
|
||||
|
||||
return cppOk && headerOk;
|
||||
}
|
||||
|
||||
const char MAIN_QMLFILE_CONTENT[] = "import %1Qml\n\n%2 {\n}\n";
|
||||
const char MAIN_QMLFILE_PATH[] = ":/boilerplatetemplates/qmlprojectmainqml.tpl";
|
||||
const char MAIN_QMLFILE_NAME[] = "main.qml";
|
||||
|
||||
bool generateMainQml(const FilePath &dir)
|
||||
{
|
||||
QString content = GenerateCmake::readTemplate(MAIN_QMLFILE_PATH);
|
||||
FilePath filePath = dir.pathAppended(MAIN_QMLFILE_NAME);
|
||||
QString projectName = ProjectExplorer::SessionManager::startupProject()->displayName();
|
||||
ProjectExplorer::RunConfiguration *runConfiguration = ProjectExplorer::SessionManager::startupRunConfiguration();
|
||||
QString mainClass;
|
||||
|
||||
if (const auto aspect = runConfiguration->aspect<QmlProjectManager::QmlMainFileAspect>())
|
||||
mainClass = FilePath::fromString(aspect->mainScript()).baseName();
|
||||
|
||||
return GenerateCmake::queueFile(filePath, QString(MAIN_QMLFILE_CONTENT).arg(projectName).arg(mainClass));
|
||||
return GenerateCmake::queueFile(filePath, content);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -45,16 +45,17 @@ bool showConfirmationDialog(const Utils::FilePath &rootDir);
|
||||
bool queueFile(const Utils::FilePath &filePath, const QString &fileContent);
|
||||
bool writeFile(const GeneratableFile &file);
|
||||
bool writeQueuedFiles();
|
||||
QString readTemplate(const QString &templatePath);
|
||||
}
|
||||
namespace GenerateCmakeLists {
|
||||
bool generateCmakes(const Utils::FilePath &rootDir);
|
||||
void generateMainCmake(const Utils::FilePath &rootDir);
|
||||
void generateSubdirCmake(const Utils::FilePath &dir);
|
||||
QString generateModuleCmake(const Utils::FilePath &dir);
|
||||
QStringList processDirectory(const Utils::FilePath &dir);
|
||||
void generateImportCmake(const Utils::FilePath &dir);
|
||||
void generateModuleCmake(const Utils::FilePath &dir);
|
||||
QStringList getSingletonsFromQmldirFile(const Utils::FilePath &filePath);
|
||||
QStringList getDirectoryTreeQmls(const Utils::FilePath &dir);
|
||||
QStringList getDirectoryTreeResources(const Utils::FilePath &dir);
|
||||
void createCmakeFile(const Utils::FilePath &filePath, const QString &content);
|
||||
void queueCmakeFile(const Utils::FilePath &filePath, const QString &content);
|
||||
bool isFileBlacklisted(const QString &fileName);
|
||||
}
|
||||
namespace GenerateEntryPoints {
|
||||
|
19
src/plugins/qmldesigner/qmlprojectmaincmakelists.tpl
Normal file
19
src/plugins/qmldesigner/qmlprojectmaincmakelists.tpl
Normal file
@@ -0,0 +1,19 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
project(%1 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
find_package(Qt6 COMPONENTS Gui Qml Quick)
|
||||
add_executable(%1 src/main.cpp)
|
||||
|
||||
target_link_libraries(%1 PRIVATE
|
||||
Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Quick
|
||||
Qt${QT_VERSION_MAJOR}::Qml
|
||||
)
|
||||
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/qmlmodules)
|
||||
|
8
src/plugins/qmldesigner/qmlprojectmaincppheader.tpl
Normal file
8
src/plugins/qmldesigner/qmlprojectmaincppheader.tpl
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* This file is automatically generated by Qt Design Studio.
|
||||
* Do not change.
|
||||
*/
|
||||
|
||||
#include <QtQml/qqmlextensionplugin.h>
|
||||
|
||||
%1
|
6
src/plugins/qmldesigner/qmlprojectmainqml.tpl
Normal file
6
src/plugins/qmldesigner/qmlprojectmainqml.tpl
Normal file
@@ -0,0 +1,6 @@
|
||||
import QtQuick
|
||||
import content
|
||||
|
||||
App {
|
||||
}
|
||||
|
11
src/plugins/qmldesigner/qmlprojectmodulecmakelists.tpl
Normal file
11
src/plugins/qmldesigner/qmlprojectmodulecmakelists.tpl
Normal file
@@ -0,0 +1,11 @@
|
||||
### This file is automatically generated by Qt Design Studio.
|
||||
### Do not change
|
||||
|
||||
%1
|
||||
|
||||
qt_add_library(%2 STATIC)
|
||||
qt6_add_qml_module(%2
|
||||
URI "%2"
|
||||
VERSION 1.0
|
||||
%3
|
||||
)
|
16
src/plugins/qmldesigner/qmlprojectmodules.tpl
Normal file
16
src/plugins/qmldesigner/qmlprojectmodules.tpl
Normal file
@@ -0,0 +1,16 @@
|
||||
### This file is automatically generated by Qt Design Studio.
|
||||
### Do not change
|
||||
|
||||
qt6_add_qml_module(%1
|
||||
URI "Main"
|
||||
VERSION 1.0
|
||||
NO_PLUGIN
|
||||
QML_FILES main.qml
|
||||
)
|
||||
|
||||
add_subdirectory(content)
|
||||
add_subdirectory(imports)
|
||||
|
||||
target_link_libraries(%1 PRIVATE
|
||||
%2
|
||||
)
|
Reference in New Issue
Block a user