1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#include "configutil.h"
6#include "cmake/project/mainframe/cmakeasynparse.h"
7#include "cmake/project/mainframe/cmakeprojectgenerator.h"
8#include "targetsmanager.h"
9
10#include "services/option/optionmanager.h"
11
12#include <QJsonObject>
13#include <QJsonDocument>
14#include <QByteArray>
15#include <QFile>
16#include <QJsonArray>
17#include <QVector>
18#include <QFileInfo>
19#include <QDir>
20namespace config {
21
22class ConfigUtilPrivate
23{
24 friend class ConfigUtil;
25 ConfigureParam configureParam;
26 QMap<ConfigType, QString> configTypeStringMap;
27};
28
29ConfigUtil::ConfigUtil(QObject *parent)
30 : QObject(parent), d(new ConfigUtilPrivate())
31{
32 d->configTypeStringMap = { { Debug, "Debug" },
33 { Release, "Release" } };
34}
35
36ConfigUtil::~ConfigUtil()
37{
38 if (d) {
39 delete d;
40 }
41}
42
43ConfigUtil *ConfigUtil::instance()
44{
45 static ConfigUtil ins;
46 return &ins;
47}
48
49ConfigureParam *ConfigUtil::getConfigureParamPointer()
50{
51 return &d->configureParam;
52}
53
54QString ConfigUtil::getNameFromType(ConfigType type)
55{
56 if (d->configTypeStringMap.contains(type)) {
57 return d->configTypeStringMap.value(type);
58 }
59
60 return "Unkown";
61}
62
63ConfigType ConfigUtil::getTypeFromName(QString name)
64{
65 ConfigType type = d->configTypeStringMap.key(name);
66 return type;
67}
68
69bool ConfigUtil::isNeedConfig(const QString &workspace, ConfigureParam &param)
70{
71 QString propertyFile = getConfigPath(workspace);
72 if (QFileInfo(propertyFile).exists() || QFileInfo(propertyFile).isFile()) {
73 readConfig(propertyFile, param);
74 if (!param.buildConfigures.isEmpty()) {
75 return false;
76 }
77 }
78 return true;
79}
80
81dpfservice::ProjectInfo ConfigUtil::createProjectInfo(const ConfigureParam *param)
82{
83 dpfservice::ProjectInfo info;
84 for (auto iter = param->buildConfigures.begin(); iter != param->buildConfigures.end(); ++iter) {
85 if (d->configureParam.tempSelType == iter->type) {
86 info.setLanguage(param->language);
87 info.setKitName(CmakeProjectGenerator::toolKitName());
88 info.setWorkspaceFolder(param->workspace);
89 info.setBuildType(ConfigUtil::instance()->getNameFromType(iter->type));
90 info.setBuildFolder(iter->directory);
91 info.setBuildProgram(OptionManager::getInstance()->getCMakeToolPath());
92
93 QStringList configArguments;
94 configArguments << "-S";
95 configArguments << info.workspaceFolder();
96 configArguments << "-B";
97 configArguments << info.buildFolder();
98 configArguments << "-G";
99 configArguments << CDT_PROJECT_KIT::get()->CBP_GENERATOR;
100 configArguments << "-DCMAKE_BUILD_TYPE=" + info.buildType();
101 configArguments << "-DCMAKE_EXPORT_COMPILE_COMMANDS=1";
102 info.setConfigCustomArgs(configArguments);
103
104 QStringList buildArguments;
105 buildArguments << "--build";
106 buildArguments << ".";
107 buildArguments << "--target";
108 buildArguments << "all";
109 info.setBuildCustomArgs(buildArguments);
110
111 QStringList cleanArguments;
112 cleanArguments << "--build";
113 cleanArguments << ".";
114 cleanArguments << "--target";
115 cleanArguments << "clean";
116 info.setCleanCustomArgs(buildArguments);
117 }
118 }
119
120 return info;
121}
122
123void ConfigUtil::configProject(const ConfigureParam *param)
124{
125 dpfservice::ProjectInfo info = createProjectInfo(param);
126 if (info.isVaild()) {
127 emit configureDone(info);
128 }
129}
130
131void ConfigUtil::checkConfigInfo(const QString &buildType, const QString &directory)
132{
133 ConfigType type = getTypeFromName(buildType);
134 auto iter = d->configureParam.buildConfigures.begin();
135 for (; iter != d->configureParam.buildConfigures.end(); ++iter) {
136 if (type == iter->type) {
137 if (!directory.isEmpty())
138 iter->directory = directory;
139 QString cfgFile = iter->directory + QDir::separator() + TargetsManager::instance()->getCMakeConfigFile();
140 if (!QFileInfo(cfgFile).isFile()) {
141 // not config
142// configProject(&d->configureParam);
143 }
144 }
145 }
146}
147
148QString ConfigUtil::getConfigPath(const QString &projectPath)
149{
150 return CustomPaths::projectCachePath(projectPath) + QDir::separator() + "project.properties";
151}
152
153void ConfigUtil::readConfig(const QString &filePath, ConfigureParam &param)
154{
155 param.clear();
156
157 QFile file(filePath);
158 if (file.open(QIODevice::ReadOnly)) {
159 QDataStream stream(&file);
160 stream >> param;
161 file.close();
162 }
163}
164
165void ConfigUtil::saveConfig(const QString &filePath, const ConfigureParam &param)
166{
167 QFile file(filePath);
168 if (file.open(QIODevice::ReadWrite)) {
169 QDataStream stream(&file);
170 stream << param;
171 file.close();
172 }
173}
174
175bool ConfigUtil::updateProjectInfo(dpfservice::ProjectInfo &info, const ConfigureParam *param)
176{
177 if (!param)
178 return false;
179
180 for (auto iter = param->buildConfigures.begin(); iter != param->buildConfigures.end(); ++iter) {
181 if (d->configureParam.defaultType == iter->type) {
182 info.setLanguage(param->language);
183 info.setKitName(CmakeProjectGenerator::toolKitName());
184 info.setWorkspaceFolder(param->workspace);
185 info.setBuildType(ConfigUtil::instance()->getNameFromType(iter->type));
186 info.setBuildFolder(iter->directory);
187 info.setBuildProgram(OptionManager::getInstance()->getCMakeToolPath());
188
189 QStringList arguments;
190 arguments << "-S";
191 arguments << info.workspaceFolder();
192 arguments << "-B";
193 arguments << info.buildFolder();
194 arguments << "-G";
195 arguments << CDT_PROJECT_KIT::get()->CBP_GENERATOR;
196 arguments << "-DCMAKE_BUILD_TYPE=" + info.buildType();
197 arguments << "-DCMAKE_EXPORT_COMPILE_COMMANDS=1";
198 info.setConfigCustomArgs(arguments);
199
200 for (auto iterStep = iter->steps.begin(); iterStep != iter->steps.end(); ++iterStep) {
201 QStringList arguments;
202 arguments << "--build";
203 arguments << ".";
204 arguments << "--target";
205
206 if (iterStep->type == StepType::Build) {
207 QString buildTarget = iterStep->targetName;
208 if (buildTarget.isEmpty()) {
209 buildTarget = "all";
210 }
211 TargetsManager::instance()->updateActivedBuildTarget(buildTarget);
212 arguments << buildTarget;
213 } else if (iterStep->type == StepType::Clean) {
214 QString cleanTarget = iterStep->targetName;
215 if (cleanTarget.isEmpty()) {
216 cleanTarget = "clean";
217 }
218 TargetsManager::instance()->updateActivedCleanTarget(cleanTarget);
219 arguments << cleanTarget;
220 }
221
222 if (!iterStep->arguments.isEmpty()) {
223 arguments << "--";
224 arguments << iterStep->arguments;
225 }
226
227 if (iterStep->type == StepType::Build) {
228 info.setBuildCustomArgs(arguments);
229 } else if (iterStep->type == StepType::Clean) {
230 info.setCleanCustomArgs(arguments);
231 }
232 }
233 // update run config according to ui parameters.
234 auto iterRun = iter->runConfigure.params.begin();
235 for (; iterRun != iter->runConfigure.params.end(); ++iterRun) {
236 if (iterRun->targetName == iter->runConfigure.defaultTargetName) {
237 info.setRunProgram(iterRun->targetPath);
238 QStringList arguments;
239 if (!iterRun->arguments.isEmpty())
240 arguments << iterRun->arguments;
241 info.setRunCustomArgs(arguments);
242 info.setRunWorkspaceDir(iterRun->workDirectory);
243
244 TargetsManager::instance()->updateActiveExceTarget(iterRun->targetName);
245 break;
246 }
247 }
248 return true;
249 }
250 }
251 return false;
252}
253
254} //namespace config
255