qmakestep.cpp 16.3 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
con's avatar
con committed
5
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
con's avatar
con committed
9
** No Commercial Usage
10
**
con's avatar
con committed
11
12
13
14
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
15
**
16
** GNU Lesser General Public License Usage
17
**
18
19
20
21
22
23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
**
con's avatar
con committed
25
26
27
28
29
30
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
con's avatar
con committed
31
**
32
**************************************************************************/
hjk's avatar
hjk committed
33

con's avatar
con committed
34
#include "qmakestep.h"
hjk's avatar
hjk committed
35

36
#include "projectexplorer/projectexplorerconstants.h"
37
#include <proparser/profileevaluator.h>
Tobias Hunger's avatar
Tobias Hunger committed
38
39
#include "qmakeparser.h"
#include "qt4buildconfiguration.h"
con's avatar
con committed
40
41
42
#include "qt4project.h"
#include "qt4projectmanagerconstants.h"
#include "qt4projectmanager.h"
Tobias Hunger's avatar
Tobias Hunger committed
43
#include "qt4target.h"
44
#include "qtversionmanager.h"
con's avatar
con committed
45

Tobias Hunger's avatar
Tobias Hunger committed
46
47
#include <projectexplorer/buildsteplist.h>

con's avatar
con committed
48
#include <coreplugin/icore.h>
hjk's avatar
hjk committed
49
#include <utils/qtcassert.h>
50
#include <utils/qtcprocess.h>
con's avatar
con committed
51

Tobias Hunger's avatar
Tobias Hunger committed
52
53
#include <QtCore/QDir>
#include <QtCore/QFile>
con's avatar
con committed
54
55
56
57
58

using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;
using namespace ProjectExplorer;

59
60
61
62
namespace {
const char * const QMAKE_BS_ID("QtProjectManager.QMakeBuildStep");

const char * const QMAKE_ARGUMENTS_KEY("QtProjectManager.QMakeBuildStep.QMakeArguments");
63
const char * const QMAKE_FORCED_KEY("QtProjectManager.QMakeBuildStep.QMakeForced");
64
65
}

Tobias Hunger's avatar
Tobias Hunger committed
66
67
QMakeStep::QMakeStep(BuildStepList *bsl) :
    AbstractProcessStep(bsl, QLatin1String(QMAKE_BS_ID)),
68
    m_forced(false)
con's avatar
con committed
69
{
70
    ctor();
con's avatar
con committed
71
72
}

Tobias Hunger's avatar
Tobias Hunger committed
73
74
QMakeStep::QMakeStep(BuildStepList *bsl, const QString &id) :
    AbstractProcessStep(bsl, id),
75
76
77
78
79
    m_forced(false)
{
    ctor();
}

Tobias Hunger's avatar
Tobias Hunger committed
80
81
QMakeStep::QMakeStep(BuildStepList *bsl, QMakeStep *bs) :
    AbstractProcessStep(bsl, bs),
82
    m_forced(bs->m_forced),
dt's avatar
dt committed
83
    m_userArgs(bs->m_userArgs)
84
{
85
86
87
88
89
    ctor();
}

void QMakeStep::ctor()
{
90
91
    //: QMakeStep default display name
    setDefaultDisplayName(tr("qmake"));
92
93
}

con's avatar
con committed
94
95
96
97
QMakeStep::~QMakeStep()
{
}

dt's avatar
dt committed
98
99
100
101
102
Qt4BuildConfiguration *QMakeStep::qt4BuildConfiguration() const
{
    return static_cast<Qt4BuildConfiguration *>(buildConfiguration());
}

dt's avatar
dt committed
103
104
105
106
107
108
109
///
/// Returns all arguments
/// That is: possbile subpath
/// spec
/// config arguemnts
/// moreArguments
/// user arguments
110
QString QMakeStep::allArguments(bool shorted)
con's avatar
con committed
111
{
112
    QString additonalArguments = m_userArgs;
dt's avatar
dt committed
113
    Qt4BuildConfiguration *bc = qt4BuildConfiguration();
con's avatar
con committed
114
    QStringList arguments;
115
    if (bc->subNodeBuild())
116
        arguments << QDir::toNativeSeparators(bc->subNodeBuild()->path());
117
118
119
    else if (shorted)
        arguments << QDir::toNativeSeparators(QFileInfo(
                buildConfiguration()->target()->project()->file()->fileName()).fileName());
120
    else
121
        arguments << QDir::toNativeSeparators(buildConfiguration()->target()->project()->file()->fileName());
con's avatar
con committed
122
123
    arguments << "-r";

124
125
126
127
128
    for (Utils::QtcProcess::ArgIterator ait(&additonalArguments); ait.next(); )
        if (ait.value() == QLatin1String("-spec"))
            goto haveSpec;
    arguments << "-spec" << bc->qtVersion()->mkspec();
  haveSpec:
129

dt's avatar
dt committed
130
    // Find out what flags we pass on to qmake
131
    arguments << bc->configCommandLineArguments();
dt's avatar
dt committed
132

133
134
    arguments << moreArguments();

135
136
137
    QString args = Utils::QtcProcess::joinArgs(arguments);
    Utils::QtcProcess::addArgs(&args, additonalArguments);
    return args;
dt's avatar
dt committed
138
139
}

dt's avatar
dt committed
140
141
142
143
///
/// moreArguments,
/// -unix for Maemo
/// -after OBJECTS_DIR, MOC_DIR, UI_DIR, RCC_DIR
144
/// QMAKE_VAR_QMLJSDEBUGGER_PATH
dt's avatar
dt committed
145
146
147
148
QStringList QMakeStep::moreArguments()
{
    Qt4BuildConfiguration *bc = qt4BuildConfiguration();
    QStringList arguments;
149
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
150
    const ProjectExplorer::ToolChainType type = bc->toolChainType();
151
152
    if (type == ProjectExplorer::ToolChain_GCC_MAEMO5
            || type == ProjectExplorer::ToolChain_GCC_HARMATTAN) {
ck's avatar
ck committed
153
        arguments << QLatin1String("-unix");
154
    }
ck's avatar
ck committed
155
#endif
156
    if (!bc->qtVersion()->supportsShadowBuilds()) {
157
158
159
160
161
162
        // We have a target which does not allow shadow building.
        // But we really don't want to have the build artefacts in the source dir
        // so we try to hack around it, to make the common cases work.
        // This is a HACK, remove once the symbian make generator supports
        // shadow building
        arguments << QLatin1String("-after")
163
164
165
166
                  << QLatin1String("OBJECTS_DIR=obj")
                  << QLatin1String("MOC_DIR=moc")
                  << QLatin1String("UI_DIR=ui")
                  << QLatin1String("RCC_DIR=rcc");
167
    }
ck's avatar
ck committed
168

169
    // Do not turn debugger path into native path separators: Qmake does not like that!
170
    arguments << QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH) + QLatin1Char('=') +
171
            Core::ICore::instance()->resourcePath() + QLatin1String("/qml/qmljsdebugger");
con's avatar
con committed
172
173
174
    return arguments;
}

175
bool QMakeStep::init()
con's avatar
con committed
176
{
dt's avatar
dt committed
177
    Qt4BuildConfiguration *qt4bc = qt4BuildConfiguration();
178
    const QtVersion *qtVersion = qt4bc->qtVersion();
con's avatar
con committed
179

180
    QString args = allArguments();
181
    QString workingDirectory;
182

183
184
185
186
    if (qt4bc->subNodeBuild())
        workingDirectory = qt4bc->subNodeBuild()->buildDir();
    else
        workingDirectory = qt4bc->buildDirectory();
con's avatar
con committed
187
188
189

    QString program = qtVersion->qmakeCommand();

Tobias Hunger's avatar
Tobias Hunger committed
190
    // Check whether we need to run qmake
191
    m_needToRunQMake = true;
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
    QString makefile = workingDirectory;

    if (qt4bc->subNodeBuild()) {
        if (!qt4bc->subNodeBuild()->makefile().isEmpty()) {
            makefile.append(qt4bc->subNodeBuild()->makefile());
        } else {
            makefile.append("/Makefile");
        }
    } else if (!qt4bc->makefile().isEmpty()) {
        makefile.append(qt4bc->makefile());
    } else {
        makefile.append("/Makefile");
    }

    if (QFileInfo(makefile).exists()) {
        QString qmakePath = QtVersionManager::findQMakeBinaryFromMakefile(makefile);
208
        if (qtVersion->qmakeCommand() == qmakePath) {
209
            m_needToRunQMake = !qt4bc->compareToImportFrom(makefile);
dt's avatar
dt committed
210
        }
con's avatar
con committed
211
212
213
214
    }

    if (m_forced) {
        m_forced = false;
215
        m_needToRunQMake = true;
con's avatar
con committed
216
217
    }

218
    setEnabled(m_needToRunQMake);
219
220
221
222
223
224
    ProcessParameters *pp = processParameters();
    pp->setMacroExpander(qt4bc->macroExpander());
    pp->setWorkingDirectory(workingDirectory);
    pp->setCommand(program);
    pp->setArguments(args);
    pp->setEnvironment(qt4bc->environment());
225

Tobias Hunger's avatar
Tobias Hunger committed
226
    setOutputParser(new QMakeParser);
dt's avatar
dt committed
227

dt's avatar
dt committed
228
229
230
231
232
    Qt4ProFileNode *node = qt4bc->qt4Target()->qt4Project()->rootProjectNode();
    if (qt4bc->subNodeBuild())
        node = qt4bc->subNodeBuild();
    QString proFile = node->path();

233
    m_tasks = qt4BuildConfiguration()->qtVersion()->reportIssues(proFile, workingDirectory);
dt's avatar
dt committed
234
    m_scriptTemplate = node->projectType() == ScriptTemplate;
dt's avatar
dt committed
235

Tobias Hunger's avatar
Tobias Hunger committed
236
    return AbstractProcessStep::init();
con's avatar
con committed
237
238
239
240
}

void QMakeStep::run(QFutureInterface<bool> &fi)
{
dt's avatar
dt committed
241
    if (m_scriptTemplate) {
con's avatar
con committed
242
243
244
        fi.reportResult(true);
        return;
    }
245

246
    // Warn on common error conditions:
dt's avatar
dt committed
247

248
    bool canContinue = true;
dt's avatar
dt committed
249
    foreach (const ProjectExplorer::Task &t, m_tasks) {
250
251
252
253
254
        addTask(t);
        if (t.type == Task::Error)
            canContinue = false;
    }
    if (!canContinue) {
255
        emit addOutput(tr("Configuration is faulty, please check the Build Issues view for details."), BuildStep::MessageOutput);
256
257
        fi.reportResult(false);
        return;
258
259
    }

260
    if (!m_needToRunQMake) {
261
        emit addOutput(tr("Configuration unchanged, skipping qmake step."), BuildStep::MessageOutput);
con's avatar
con committed
262
263
264
        fi.reportResult(true);
        return;
    }
265

Tobias Hunger's avatar
Tobias Hunger committed
266
    AbstractProcessStep::run(fi);
con's avatar
con committed
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
}

void QMakeStep::setForced(bool b)
{
    m_forced = b;
}

bool QMakeStep::forced()
{
    return m_forced;
}

ProjectExplorer::BuildStepConfigWidget *QMakeStep::createConfigWidget()
{
    return new QMakeStepConfigWidget(this);
}

bool QMakeStep::immutable() const
{
dt's avatar
dt committed
286
    return false;
con's avatar
con committed
287
288
289
290
291
292
293
294
}

void QMakeStep::processStartupFailed()
{
    m_forced = true;
    AbstractProcessStep::processStartupFailed();
}

295
bool QMakeStep::processSucceeded(int exitCode, QProcess::ExitStatus status)
con's avatar
con committed
296
{
297
    bool result = AbstractProcessStep::processSucceeded(exitCode, status);
con's avatar
con committed
298
299
    if (!result)
        m_forced = true;
300
    qt4BuildConfiguration()->emitBuildDirectoryInitialized();
con's avatar
con committed
301
302
303
    return result;
}

304
void QMakeStep::setUserArguments(const QString &arguments)
305
{
306
307
    if (m_userArgs == arguments)
        return;
dt's avatar
dt committed
308
    m_userArgs = arguments;
309

310
    emit userArgumentsChanged();
311
312

    qt4BuildConfiguration()->emitQMakeBuildConfigurationChanged();
313
314
315
316
317
318
    qt4BuildConfiguration()->emitProFileEvaluteNeeded();
}

QStringList QMakeStep::parserArguments()
{
    QStringList result;
319
320
321
322
323
324
    for (Utils::QtcProcess::ConstArgIterator ait(allArguments()); ait.next(); ) {
        const QString &arg = ait.value();
        if (arg.contains(QLatin1Char('='))) {
            result << arg;
        } else {
            for (int i = 0; i < ProFileOption::modeMapSize; ++i) {
325
326
                // Workaround: Apple GCC does not like ProFileOption::modeMap[i], because the array's bounds are not known
                if (QLatin1String((&ProFileOption::modeMap[0] + i)->qmakeOption) == arg) {
327
328
329
330
331
332
                    result << arg;
                    break;
                }
            }
        }
    }
333
    return result;
334
335
}

336
QString QMakeStep::userArguments()
337
{
dt's avatar
dt committed
338
    return m_userArgs;
339
340
}

341
QVariantMap QMakeStep::toMap() const
342
{
343
344
    QVariantMap map(AbstractProcessStep::toMap());
    map.insert(QLatin1String(QMAKE_ARGUMENTS_KEY), m_userArgs);
345
    map.insert(QLatin1String(QMAKE_FORCED_KEY), m_forced);
346
    return map;
347
348
}

349
bool QMakeStep::fromMap(const QVariantMap &map)
350
{
351
    m_userArgs = map.value(QLatin1String(QMAKE_ARGUMENTS_KEY)).toString();
352
    m_forced = map.value(QLatin1String(QMAKE_FORCED_KEY), false).toBool();
353
    return BuildStep::fromMap(map);
354
355
}

356
357
358
359
////
// QMakeStepConfigWidget
////

con's avatar
con committed
360
QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step)
361
    : BuildStepConfigWidget(), m_step(step), m_ignoreChange(false)
con's avatar
con committed
362
363
364
{
    m_ui.setupUi(this);
    connect(m_ui.qmakeAdditonalArgumentsLineEdit, SIGNAL(textEdited(const QString&)),
365
366
367
            this, SLOT(qmakeArgumentsLineEdited()));
    connect(m_ui.buildConfigurationComboBox, SIGNAL(currentIndexChanged(int)),
            this, SLOT(buildConfigurationSelected()));
368
369
    connect(step, SIGNAL(userArgumentsChanged()),
            this, SLOT(userArgumentsChanged()));
370
    connect(step->qt4BuildConfiguration(), SIGNAL(qtVersionChanged()),
371
            this, SLOT(qtVersionChanged()));
372
373
374
375
376
377
    connect(step->qt4BuildConfiguration(), SIGNAL(qmakeBuildConfigurationChanged()),
            this, SLOT(qmakeBuildConfigChanged()));
}

void QMakeStepConfigWidget::init()
{
378
    m_ui.qmakeAdditonalArgumentsLineEdit->setText(m_step->userArguments());
379
380
381
382
383

    qmakeBuildConfigChanged();

    updateSummaryLabel();
    updateEffectiveQMakeCall();
con's avatar
con committed
384
385
}

dt's avatar
dt committed
386
387
388
389
390
QString QMakeStepConfigWidget::summaryText() const
{
    return m_summaryText;
}

391
392
393
394
395
QString QMakeStepConfigWidget::displayName() const
{
    return m_step->displayName();
}

396
void QMakeStepConfigWidget::qtVersionChanged()
397
{
398
    updateSummaryLabel();
dt's avatar
dt committed
399
    updateEffectiveQMakeCall();
400
401
}

402
void QMakeStepConfigWidget::qmakeBuildConfigChanged()
dt's avatar
dt committed
403
{
404
405
    Qt4BuildConfiguration *bc = m_step->qt4BuildConfiguration();
    bool debug = bc->qmakeBuildConfiguration() & QtVersion::DebugBuild;
Tobias Hunger's avatar
Tobias Hunger committed
406
407
408
    int index = debug ? 0 : 1;
    if (bc->qmakeBuildConfiguration() & QtVersion::BuildAll)
        index = 2;
409
    m_ignoreChange = true;
Tobias Hunger's avatar
Tobias Hunger committed
410
411
    m_ui.buildConfigurationComboBox->setCurrentIndex(index);

412
413
414
415
    m_ignoreChange = false;
    updateSummaryLabel();
    updateEffectiveQMakeCall();
}
dt's avatar
dt committed
416

417
418
419
420
void QMakeStepConfigWidget::userArgumentsChanged()
{
    if (m_ignoreChange)
        return;
421
    m_ui.qmakeAdditonalArgumentsLineEdit->setText(m_step->userArguments());
422
423
    updateSummaryLabel();
    updateEffectiveQMakeCall();
dt's avatar
dt committed
424
425
}

426
void QMakeStepConfigWidget::qmakeArgumentsLineEdited()
con's avatar
con committed
427
{
428
    m_ignoreChange = true;
429
    m_step->setUserArguments(m_ui.qmakeAdditonalArgumentsLineEdit->text());
430
    m_ignoreChange = false;
431

432
    updateSummaryLabel();
433
    updateEffectiveQMakeCall();
con's avatar
con committed
434
435
}

436
void QMakeStepConfigWidget::buildConfigurationSelected()
con's avatar
con committed
437
{
438
439
440
441
    if (m_ignoreChange)
        return;
    Qt4BuildConfiguration *bc = m_step->qt4BuildConfiguration();
    QtVersion::QmakeBuildConfigs buildConfiguration = bc->qmakeBuildConfiguration();
Tobias Hunger's avatar
Tobias Hunger committed
442
443
444
445
446
447
448
449
450
451
    switch (m_ui.buildConfigurationComboBox->currentIndex()) {
    case 0:
        buildConfiguration = QtVersion::DebugBuild;
        break;
    case 1:
        buildConfiguration = 0;
        break;
    case 2:
        buildConfiguration = QtVersion::BuildAll;
        break;
con's avatar
con committed
452
    }
Tobias Hunger's avatar
Tobias Hunger committed
453

454
455
456
    m_ignoreChange = true;
    bc->setQMakeBuildConfiguration(buildConfiguration);
    m_ignoreChange = false;
con's avatar
con committed
457

458
459
    updateSummaryLabel();
    updateEffectiveQMakeCall();
con's avatar
con committed
460
461
}

462
void QMakeStepConfigWidget::updateSummaryLabel()
463
{
464
465
466
    Qt4BuildConfiguration *qt4bc = m_step->qt4BuildConfiguration();
    const QtVersion *qtVersion = qt4bc->qtVersion();
    if (!qtVersion) {
Friedemann Kleint's avatar
Friedemann Kleint committed
467
        m_summaryText = tr("<b>qmake:</b> No Qt version set. Cannot run qmake.");
468
        emit updateSummary();
469
        return;
470
471
472
    }

    // We don't want the full path to the .pro file
473
    QString args = m_step->allArguments(true);
474
475
    // And we only use the .pro filename not the full path
    QString program = QFileInfo(qtVersion->qmakeCommand()).fileName();
476
    m_summaryText = tr("<b>qmake:</b> %1 %2").arg(program, args);
477
    emit updateSummary();
478

479
480
481
482
}

void QMakeStepConfigWidget::updateEffectiveQMakeCall()
{
dt's avatar
dt committed
483
    Qt4BuildConfiguration *qt4bc = m_step->qt4BuildConfiguration();
484
    const QtVersion *qtVersion = qt4bc->qtVersion();
Tobias Hunger's avatar
Tobias Hunger committed
485
    QString program = QFileInfo(qtVersion->qmakeCommand()).fileName();
486
    m_ui.qmakeArgumentsEdit->setPlainText(program + QLatin1Char(' ') + m_step->allArguments());
con's avatar
con committed
487
488
}

dt's avatar
dt committed
489
490
491
492
////
// QMakeStepFactory
////

493
494
QMakeStepFactory::QMakeStepFactory(QObject *parent) :
    ProjectExplorer::IBuildStepFactory(parent)
dt's avatar
dt committed
495
496
497
498
499
500
501
{
}

QMakeStepFactory::~QMakeStepFactory()
{
}

Tobias Hunger's avatar
Tobias Hunger committed
502
bool QMakeStepFactory::canCreate(BuildStepList *parent, const QString &id) const
dt's avatar
dt committed
503
{
Tobias Hunger's avatar
Tobias Hunger committed
504
    if (parent->id() != QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_BUILD))
505
        return false;
Tobias Hunger's avatar
Tobias Hunger committed
506
    if (!qobject_cast<Qt4BuildConfiguration *>(parent->parent()))
507
508
        return false;
    return (id == QLatin1String(QMAKE_BS_ID));
dt's avatar
dt committed
509
510
}

Tobias Hunger's avatar
Tobias Hunger committed
511
ProjectExplorer::BuildStep *QMakeStepFactory::create(BuildStepList *parent, const QString &id)
dt's avatar
dt committed
512
{
Tobias Hunger's avatar
Tobias Hunger committed
513
    if (!canCreate(parent, id))
514
        return 0;
Tobias Hunger's avatar
Tobias Hunger committed
515
    return new QMakeStep(parent);
516
517
}

Tobias Hunger's avatar
Tobias Hunger committed
518
bool QMakeStepFactory::canClone(BuildStepList *parent, BuildStep *source) const
519
{
Tobias Hunger's avatar
Tobias Hunger committed
520
    return canCreate(parent, source->id());
dt's avatar
dt committed
521
522
}

Tobias Hunger's avatar
Tobias Hunger committed
523
ProjectExplorer::BuildStep *QMakeStepFactory::clone(BuildStepList *parent, ProjectExplorer::BuildStep *source)
dt's avatar
dt committed
524
{
Tobias Hunger's avatar
Tobias Hunger committed
525
    if (!canClone(parent, source))
526
        return 0;
Tobias Hunger's avatar
Tobias Hunger committed
527
    return new QMakeStep(parent, qobject_cast<QMakeStep *>(source));
dt's avatar
dt committed
528
529
}

Tobias Hunger's avatar
Tobias Hunger committed
530
bool QMakeStepFactory::canRestore(BuildStepList *parent, const QVariantMap &map) const
531
532
{
    QString id(ProjectExplorer::idFromMap(map));
Tobias Hunger's avatar
Tobias Hunger committed
533
    return canCreate(parent, id);
534
535
}

Tobias Hunger's avatar
Tobias Hunger committed
536
ProjectExplorer::BuildStep *QMakeStepFactory::restore(BuildStepList *parent, const QVariantMap &map)
dt's avatar
dt committed
537
{
Tobias Hunger's avatar
Tobias Hunger committed
538
    if (!canRestore(parent, map))
539
        return 0;
Tobias Hunger's avatar
Tobias Hunger committed
540
    QMakeStep *bs = new QMakeStep(parent);
541
542
543
544
    if (bs->fromMap(map))
        return bs;
    delete bs;
    return 0;
dt's avatar
dt committed
545
546
}

Tobias Hunger's avatar
Tobias Hunger committed
547
QStringList QMakeStepFactory::availableCreationIds(ProjectExplorer::BuildStepList *parent) const
548
{
Tobias Hunger's avatar
Tobias Hunger committed
549
550
    if (parent->id() == QLatin1String(ProjectExplorer::Constants::BUILDSTEPS_BUILD))
        if (Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(parent->parent()))
551
552
            if (!bc->qmakeStep())
                return QStringList() << QLatin1String(QMAKE_BS_ID);
553
554
    return QStringList();
}
dt's avatar
dt committed
555

556
557
558
QString QMakeStepFactory::displayNameForId(const QString &id) const
{
    if (id == QLatin1String(QMAKE_BS_ID))
559
        return tr("qmake");
560
561
    return QString();
}