1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "makefileparse.h"
27
28 #include <qtsupport/qtversionmanager.h>
29 #include <qtsupport/baseqtversion.h>
30 #include <utils/qtcprocess.h>
31
32 #include <QDebug>
33 #include <QDir>
34 #include <QFileInfo>
35 #include <QRegularExpression>
36 #include <QTextStream>
37 #include <QLoggingCategory>
38
39 using namespace ProjectExplorer;
40 using namespace Utils;;
41
42 using QtSupport::QtVersionManager;
43 using QtSupport::BaseQtVersion;
44
45 namespace QmakeProjectManager {
46 namespace Internal {
47
48 static QString findQMakeLine(const QString &makefile, const QString &key)
49 {
50 QFile fi(makefile);
fi.existsnull51 if (fi.exists() && fi.open(QFile::ReadOnly)) {
52 QTextStream ts(&fi);
53 while (!ts.atEnd()) {
54 const QString line = ts.readLine();
55 if (line.startsWith(key))
56 return line;
57 }
58 }
QStringnull59 return QString();
60 }
61
trimsnull62 /// This function trims the "#Command /path/to/qmake" from the line
63 static QString trimLine(const QString &line)
64 {
65
66 // Actually the first space after #Command: /path/to/qmake
67 const int firstSpace = line.indexOf(QLatin1Char(' '), 11);
68 return line.mid(firstSpace).trimmed();
69 }
70
71 void MakeFileParse::parseArgs(const QString &args, const QString &project,
72 QList<QMakeAssignment> *assignments,
73 QList<QMakeAssignment> *afterAssignments)
74 {
75 const QRegularExpression regExp(QLatin1String("^([^\\s\\+-]*)\\s*(\\+=|=|-=|~=)(.*)$"));
76 bool after = false;
77 bool ignoreNext = false;
78 m_unparsedArguments = args;
79 ProcessArgs::ArgIterator ait(&m_unparsedArguments);
ait.nextnull80 while (ait.next()) {
81 if (ignoreNext) {
82 // Ignoring
83 ignoreNext = false;
84 ait.deleteArg();
85 } else if (ait.value() == project) {
86 ait.deleteArg();
87 } else if (ait.value() == QLatin1String("-after")) {
88 after = true;
89 ait.deleteArg();
90 } else if (ait.value().contains(QLatin1Char('='))) {
91 const QRegularExpressionMatch match = regExp.match(ait.value());
92 if (match.hasMatch()) {
93 QMakeAssignment qa;
94 qa.variable = match.captured(1);
95 qa.op = match.captured(2);
96 qa.value = match.captured(3).trimmed();
97 if (after)
98 afterAssignments->append(qa);
99 else
100 assignments->append(qa);
101 } else {
102 qDebug()<<"regexp did not match";
103 }
104 ait.deleteArg();
105 } else if (ait.value() == QLatin1String("-o")) {
106 ignoreNext = true;
107 ait.deleteArg();
108 #if defined(Q_OS_WIN32)
109 } else if (ait.value() == QLatin1String("-win32")) {
110 #elif defined(Q_OS_MAC)
111 } else if (ait.value() == QLatin1String("-macx")) {
112 #elif defined(Q_OS_QNX6)
113 } else if (ait.value() == QLatin1String("-qnx6")) {
114 #else
115 } else if (ait.value() == QLatin1String("-unix")) {
116 #endif
117 ait.deleteArg();
118 }
119 }
120 }
121
122 void dumpQMakeAssignments(const QList<QMakeAssignment> &list)
123 {
124 foreach (const QMakeAssignment &qa, list) {
125 qCDebug(MakeFileParse::logging()) << " " << qa.variable << qa.op << qa.value;
126 }
127 }
128
129 QList<QMakeAssignment> MakeFileParse::parseAssignments(const QList<QMakeAssignment> &assignments)
130 {
131 bool foundSeparateDebugInfo = false;
132 bool foundForceDebugInfo = false;
133 QList<QMakeAssignment> filteredAssignments;
134 foreach (const QMakeAssignment &qa, assignments) {
135 if (qa.variable == QLatin1String("CONFIG")) {
136 QStringList values = qa.value.split(QLatin1Char(' '));
137 QStringList newValues;
138 foreach (const QString &value, values) {
139 if (value == QLatin1String("debug")) {
140 if (qa.op == QLatin1String("+=")) {
141 m_qmakeBuildConfig.explicitDebug = true;
142 m_qmakeBuildConfig.explicitRelease = false;
143 } else {
144 m_qmakeBuildConfig.explicitDebug = false;
145 m_qmakeBuildConfig.explicitRelease = true;
146 }
147 } else if (value == QLatin1String("release")) {
148 if (qa.op == QLatin1String("+=")) {
149 m_qmakeBuildConfig.explicitDebug = false;
150 m_qmakeBuildConfig.explicitRelease = true;
151 } else {
152 m_qmakeBuildConfig.explicitDebug = true;
153 m_qmakeBuildConfig.explicitRelease = false;
154 }
155 } else if (value == QLatin1String("debug_and_release")) {
156 if (qa.op == QLatin1String("+=")) {
157 m_qmakeBuildConfig.explicitBuildAll = true;
158 m_qmakeBuildConfig.explicitNoBuildAll = false;
159 } else {
160 m_qmakeBuildConfig.explicitBuildAll = false;
161 m_qmakeBuildConfig.explicitNoBuildAll = true;
162 }
163 } else if (value == QLatin1String("iphonesimulator")) {
164 if (qa.op == QLatin1String("+="))
165 m_config.osType = QMakeStepConfig::IphoneSimulator;
166 else
167 m_config.osType = QMakeStepConfig::NoOsType;
168 } else if (value == QLatin1String("iphoneos")) {
169 if (qa.op == QLatin1String("+="))
170 m_config.osType = QMakeStepConfig::IphoneOS;
171 else
172 m_config.osType = QMakeStepConfig::NoOsType;
173 } else if (value == QLatin1String("qml_debug")) {
174 if (qa.op == QLatin1String("+="))
175 m_config.linkQmlDebuggingQQ2 = TriState::Enabled;
176 else
177 m_config.linkQmlDebuggingQQ2 = TriState::Disabled;
178 } else if (value == QLatin1String("qtquickcompiler")) {
179 if (qa.op == QLatin1String("+="))
180 m_config.useQtQuickCompiler = TriState::Enabled;
181 else
182 m_config.useQtQuickCompiler = TriState::Disabled;
183 } else if (value == QLatin1String("force_debug_info")) {
184 if (qa.op == QLatin1String("+="))
185 foundForceDebugInfo = true;
186 else
187 foundForceDebugInfo = false;
188 } else if (value == QLatin1String("separate_debug_info")) {
189 if (qa.op == QLatin1String("+=")) {
190 foundSeparateDebugInfo = true;
191 m_config.separateDebugInfo = TriState::Enabled;
192 } else {
193 foundSeparateDebugInfo = false;
194 m_config.separateDebugInfo = TriState::Disabled;
195 }
196 } else {
197 newValues.append(value);
198 }
199 }
200 if (!newValues.isEmpty()) {
201 QMakeAssignment newQA = qa;
202 newQA.value = newValues.join(QLatin1Char(' '));
203 filteredAssignments.append(newQA);
204 }
205 } else {
206 filteredAssignments.append(qa);
207 }
208 }
209
210 if (foundForceDebugInfo && foundSeparateDebugInfo) {
211 m_config.separateDebugInfo = TriState::Enabled;
212 } else if (foundForceDebugInfo) {
213 // Found only force_debug_info, so readd it
214 QMakeAssignment newQA;
215 newQA.variable = QLatin1String("CONFIG");
216 newQA.op = QLatin1String("+=");
217 newQA.value = QLatin1String("force_debug_info");
218 filteredAssignments.append(newQA);
219 } else if (foundSeparateDebugInfo) {
220 // Found only separate_debug_info, so readd it
221 QMakeAssignment newQA;
222 newQA.variable = QLatin1String("CONFIG");
223 newQA.op = QLatin1String("+=");
224 newQA.value = QLatin1String("separate_debug_info");
225 filteredAssignments.append(newQA);
226 }
227 return filteredAssignments;
228 }
229
230 static FilePath findQMakeBinaryFromMakefile(const QString &makefile)
231 {
232 QFile fi(makefile);
233 if (fi.exists() && fi.open(QFile::ReadOnly)) {
234 QTextStream ts(&fi);
235 const QRegularExpression r1(QLatin1String("^QMAKE\\s*=(.*)$"));
236 while (!ts.atEnd()) {
237 QString line = ts.readLine();
238 const QRegularExpressionMatch match = r1.match(line);
239 if (match.hasMatch()) {
240 QFileInfo qmake(match.captured(1).trimmed());
241 QString qmakePath = qmake.filePath();
242 if (!QString::fromLatin1(QTC_HOST_EXE_SUFFIX).isEmpty()
243 && !qmakePath.endsWith(QLatin1String(QTC_HOST_EXE_SUFFIX))) {
244 qmakePath.append(QLatin1String(QTC_HOST_EXE_SUFFIX));
245 }
246 // Is qmake still installed?
247 QFileInfo fi(qmakePath);
248 if (fi.exists())
249 return FilePath::fromFileInfo(fi);
250 }
251 }
252 }
253 return FilePath();
254 }
255
256 MakeFileParse::MakeFileParse(const QString &makefile, Mode mode) : m_mode(mode)
257 {
258 qCDebug(logging()) << "Parsing makefile" << makefile;
259 if (!QFileInfo::exists(makefile)) {
260 qCDebug(logging()) << "**doesn't exist";
261 m_state = MakefileMissing;
262 return;
263 }
264
265 // Qt Version!
266 m_qmakePath = findQMakeBinaryFromMakefile(makefile);
267 qCDebug(logging()) << " qmake:" << m_qmakePath;
268
269 QString project = findQMakeLine(makefile, QLatin1String("# Project:")).trimmed();
270 if (project.isEmpty()) {
271 m_state = CouldNotParse;
272 qCDebug(logging()) << "**No Project line";
273 return;
274 }
275
276 project.remove(0, project.indexOf(QLatin1Char(':')) + 1);
277 project = project.trimmed();
278
279 // Src Pro file
280 m_srcProFile = QDir::cleanPath(QFileInfo(makefile).absoluteDir().filePath(project));
281 qCDebug(logging()) << " source .pro file:" << m_srcProFile;
282
283 QString command = findQMakeLine(makefile, QLatin1String("# Command:")).trimmed();
284 if (command.isEmpty()) {
285 m_state = CouldNotParse;
286 qCDebug(logging()) << "**No Command line found";
287 return;
288 }
289
290 command = trimLine(command);
291 parseCommandLine(command, project);
292
293 m_state = Okay;
294 }
295
296 MakeFileParse::MakefileState MakeFileParse::makeFileState() const
297 {
298 return m_state;
299 }
300
301 Utils::FilePath MakeFileParse::qmakePath() const
302 {
303 return m_qmakePath;
304 }
305
306 QString MakeFileParse::srcProFile() const
307 {
308 return m_srcProFile;
309 }
310
311 QMakeStepConfig MakeFileParse::config() const
312 {
313 return m_config;
314 }
315
316
317 QString MakeFileParse::unparsedArguments() const
318 {
319 return m_unparsedArguments;
320 }
321
322 BaseQtVersion::QmakeBuildConfigs MakeFileParse::effectiveBuildConfig(BaseQtVersion::QmakeBuildConfigs defaultBuildConfig) const
323 {
324 BaseQtVersion::QmakeBuildConfigs buildConfig = defaultBuildConfig;
325 if (m_qmakeBuildConfig.explicitDebug)
326 buildConfig = buildConfig | BaseQtVersion::DebugBuild;
327 else if (m_qmakeBuildConfig.explicitRelease)
328 buildConfig = buildConfig & ~BaseQtVersion::DebugBuild;
329 if (m_qmakeBuildConfig.explicitBuildAll)
330 buildConfig = buildConfig | BaseQtVersion::BuildAll;
331 else if (m_qmakeBuildConfig.explicitNoBuildAll)
332 buildConfig = buildConfig &~ BaseQtVersion::BuildAll;
333 return buildConfig;
334 }
335
336 const QLoggingCategory &MakeFileParse::logging()
337 {
338 static const QLoggingCategory category("qtc.qmakeprojectmanager.import", QtWarningMsg);
339 return category;
340 }
341
342 void MakeFileParse::parseCommandLine(const QString &command, const QString &project)
343 {
344
345 QList<QMakeAssignment> assignments;
346 QList<QMakeAssignment> afterAssignments;
347 // Split up args into assignments and other arguments, writes m_unparsedArguments
348 parseArgs(command, project, &assignments, &afterAssignments);
349 qCDebug(logging()) << " Initial assignments:";
350 dumpQMakeAssignments(assignments);
351
352 // Filter out CONFIG arguments we know into m_qmakeBuildConfig and m_config
353 const QList<QMakeAssignment> filteredAssignments = parseAssignments(assignments);
354 qCDebug(logging()) << " After parsing";
355 dumpQMakeAssignments(filteredAssignments);
356
357 qCDebug(logging()) << " Explicit Debug" << m_qmakeBuildConfig.explicitDebug;
358 qCDebug(logging()) << " Explicit Release" << m_qmakeBuildConfig.explicitRelease;
359 qCDebug(logging()) << " Explicit BuildAll" << m_qmakeBuildConfig.explicitBuildAll;
360 qCDebug(logging()) << " Explicit NoBuildAll" << m_qmakeBuildConfig.explicitNoBuildAll;
361 qCDebug(logging()) << " OsType" << m_config.osType;
362 qCDebug(logging()) << " LinkQmlDebuggingQQ2"
363 << (m_config.linkQmlDebuggingQQ2 == TriState::Enabled);
364 qCDebug(logging()) << " Qt Quick Compiler"
365 << (m_config.useQtQuickCompiler == TriState::Enabled);
366 qCDebug(logging()) << " Separate Debug Info"
367 << (m_config.separateDebugInfo == TriState::Enabled);
368
369 // Create command line of all unfiltered arguments
370 const QList<QMakeAssignment> &assignmentsToUse = m_mode == Mode::FilterKnownConfigValues
371 ? filteredAssignments : assignments;
372 foreach (const QMakeAssignment &qa, assignmentsToUse)
373 ProcessArgs::addArg(&m_unparsedArguments, qa.variable + qa.op + qa.value);
374 if (!afterAssignments.isEmpty()) {
375 ProcessArgs::addArg(&m_unparsedArguments, QLatin1String("-after"));
376 foreach (const QMakeAssignment &qa, afterAssignments)
377 ProcessArgs::addArg(&m_unparsedArguments, qa.variable + qa.op + qa.value);
378 }
379 }
380
381 } // Internal
382 } // QmakeProjectManager
383
384 // Unit tests:
385
386 #ifdef WITH_TESTS
387 # include <QTest>
388
389 # include "qmakeprojectmanagerplugin.h"
390
391 # include "projectexplorer/outputparser_test.h"
392
393 using namespace QmakeProjectManager::Internal;
394 using namespace ProjectExplorer;
395
396 void QmakeProjectManagerPlugin::testMakefileParser_data()
397 {
398 QTest::addColumn<QString>("command");
399 QTest::addColumn<QString>("project");
400 QTest::addColumn<QString>("unparsedArguments");
401 QTest::addColumn<int>("archConfig");
402 QTest::addColumn<int>("osType");
403 QTest::addColumn<bool>("linkQmlDebuggingQQ2");
404 QTest::addColumn<bool>("useQtQuickCompiler");
405 QTest::addColumn<bool>("separateDebugInfo");
406 QTest::addColumn<int>("effectiveBuildConfig");
407
408 QTest::newRow("Qt 5.7")
409 << QString::fromLatin1("-spec linux-g++ CONFIG+=debug CONFIG+=qml_debug -o Makefile ../untitled7/untitled7.pro")
410 << QString::fromLatin1("../untitled7/untitled7.pro")
411 << QString::fromLatin1("-spec linux-g++")
412 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
413 << true << false << false << 2;
414 QTest::newRow("Qt 5.7 extra1")
415 << QString::fromLatin1("SOMETHING=ELSE -spec linux-g++ CONFIG+=debug CONFIG+=qml_debug -o Makefile ../untitled7/untitled7.pro")
416 << QString::fromLatin1("../untitled7/untitled7.pro")
417 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
418 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
419 << true << false << false << 2;
420 QTest::newRow("Qt 5.7 extra2")
421 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE CONFIG+=debug CONFIG+=qml_debug -o Makefile ../untitled7/untitled7.pro")
422 << QString::fromLatin1("../untitled7/untitled7.pro")
423 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
424 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
425 << true << false << false << 2;
426 QTest::newRow("Qt 5.7 extra3")
427 << QString::fromLatin1("-spec linux-g++ CONFIG+=debug SOMETHING=ELSE CONFIG+=qml_debug -o Makefile ../untitled7/untitled7.pro")
428 << QString::fromLatin1("../untitled7/untitled7.pro")
429 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
430 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
431 << true << false << false << 2;
432 QTest::newRow("Qt 5.7 extra4")
433 << QString::fromLatin1("-spec linux-g++ CONFIG+=debug CONFIG+=qml_debug SOMETHING=ELSE -o Makefile ../untitled7/untitled7.pro")
434 << QString::fromLatin1("../untitled7/untitled7.pro")
435 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
436 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
437 << true << false << false << 2;
438 QTest::newRow("Qt 5.7 extra5")
439 << QString::fromLatin1("-spec linux-g++ CONFIG+=debug CONFIG+=qml_debug -o Makefile SOMETHING=ELSE ../untitled7/untitled7.pro")
440 << QString::fromLatin1("../untitled7/untitled7.pro")
441 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
442 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
443 << true << false << false << 2;
444 QTest::newRow("Qt 5.7 extra6")
445 << QString::fromLatin1("-spec linux-g++ CONFIG+=debug CONFIG+=qml_debug -o Makefile ../untitled7/untitled7.pro SOMETHING=ELSE")
446 << QString::fromLatin1("../untitled7/untitled7.pro")
447 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
448 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
449 << true << false << false << 2;
450 QTest::newRow("Qt 5.8")
451 << QString::fromLatin1("-o Makefile ../untitled7/untitled7.pro -spec linux-g++ CONFIG+=debug CONFIG+=qml_debug")
452 << QString::fromLatin1("../untitled7/untitled7.pro")
453 << QString::fromLatin1("-spec linux-g++")
454 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
455 << true << false << false << 2;
456 QTest::newRow("Qt 5.8 extra1")
457 << QString::fromLatin1("SOMETHING=ELSE -o Makefile ../untitled7/untitled7.pro -spec linux-g++ CONFIG+=debug CONFIG+=qml_debug")
458 << QString::fromLatin1("../untitled7/untitled7.pro")
459 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
460 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
461 << true << false << false << 2;
462 QTest::newRow("Qt 5.8 extra2")
463 << QString::fromLatin1("-o Makefile SOMETHING=ELSE ../untitled7/untitled7.pro -spec linux-g++ CONFIG+=debug CONFIG+=qml_debug")
464 << QString::fromLatin1("../untitled7/untitled7.pro")
465 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
466 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
467 << true << false << false << 2;
468 QTest::newRow("Qt 5.8 extra3")
469 << QString::fromLatin1("-o Makefile ../untitled7/untitled7.pro SOMETHING=ELSE -spec linux-g++ CONFIG+=debug CONFIG+=qml_debug")
470 << QString::fromLatin1("../untitled7/untitled7.pro")
471 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
472 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
473 << true << false << false << 2;
474 QTest::newRow("Qt 5.8 extra4")
475 << QString::fromLatin1("-o Makefile ../untitled7/untitled7.pro -spec linux-g++ SOMETHING=ELSE CONFIG+=debug CONFIG+=qml_debug")
476 << QString::fromLatin1("../untitled7/untitled7.pro")
477 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
478 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
479 << true << false << false << 2;
480 QTest::newRow("Qt 5.8 extra5")
481 << QString::fromLatin1("-o Makefile ../untitled7/untitled7.pro -spec linux-g++ CONFIG+=debug SOMETHING=ELSE CONFIG+=qml_debug")
482 << QString::fromLatin1("../untitled7/untitled7.pro")
483 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
484 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
485 << true << false << false << 2;
486 QTest::newRow("Qt 5.8 extra6")
487 << QString::fromLatin1("-o Makefile ../untitled7/untitled7.pro -spec linux-g++ CONFIG+=debug CONFIG+=qml_debug SOMETHING=ELSE")
488 << QString::fromLatin1("../untitled7/untitled7.pro")
489 << QString::fromLatin1("-spec linux-g++ SOMETHING=ELSE")
490 << static_cast<int>(QMakeStepConfig::NoArch) << static_cast<int>(QMakeStepConfig::NoOsType)
491 << true << false << false << 2;
492 }
493
494 void QmakeProjectManagerPlugin::testMakefileParser()
495 {
496 QFETCH(QString, command);
497 QFETCH(QString, project);
498 QFETCH(QString, unparsedArguments);
499 QFETCH(int, archConfig);
500 QFETCH(int, osType);
501 QFETCH(bool, linkQmlDebuggingQQ2);
502 QFETCH(bool, useQtQuickCompiler);
503 QFETCH(bool, separateDebugInfo);
504 QFETCH(int, effectiveBuildConfig);
505
506 MakeFileParse parser("/tmp/something", MakeFileParse::Mode::FilterKnownConfigValues);
507 parser.parseCommandLine(command, project);
508
509 QCOMPARE(Utils::ProcessArgs::splitArgs(parser.unparsedArguments()),
510 Utils::ProcessArgs::splitArgs(unparsedArguments));
511 QCOMPARE(parser.effectiveBuildConfig({}), effectiveBuildConfig);
512
513 const QMakeStepConfig qmsc = parser.config();
514 QCOMPARE(qmsc.osType, static_cast<QMakeStepConfig::OsType>(osType));
515 QCOMPARE(qmsc.linkQmlDebuggingQQ2 == TriState::Enabled, linkQmlDebuggingQQ2);
516 QCOMPARE(qmsc.useQtQuickCompiler == TriState::Enabled, useQtQuickCompiler);
517 QCOMPARE(qmsc.separateDebugInfo == TriState::Enabled, separateDebugInfo);
518 }
519 #endif
520