/**************************************************************************** ** ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of Qt Creator. ** ** 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 Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** 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. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ #include "qt4buildconfiguration.h" #include "qt4project.h" #include "qt4projectconfigwidget.h" #include "qt4projectmanagerconstants.h" #include "qt4nodes.h" #include "qmakestep.h" #include "makestep.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; using namespace ProjectExplorer; namespace { const char * const QT4_BC_ID("Qt4ProjectManager.Qt4BuildConfiguration"); const char * const USE_SHADOW_BUILD_KEY("Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild"); const char * const BUILD_DIRECTORY_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory"); const char * const BUILD_CONFIGURATION_KEY("Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration"); enum { debug = 0 }; } Qt4BuildConfiguration::Qt4BuildConfiguration(Target *target) : BuildConfiguration(target, Core::Id(QT4_BC_ID)), m_shadowBuild(true), m_isEnabled(false), m_qmakeBuildConfiguration(0), m_subNodeBuild(0), m_fileNodeBuild(0) { ctor(); } Qt4BuildConfiguration::Qt4BuildConfiguration(Target *target, const Core::Id id) : BuildConfiguration(target, id), m_shadowBuild(true), m_isEnabled(false), m_qmakeBuildConfiguration(0), m_subNodeBuild(0), m_fileNodeBuild(0) { ctor(); } Qt4BuildConfiguration::Qt4BuildConfiguration(Target *target, Qt4BuildConfiguration *source) : BuildConfiguration(target, source), m_shadowBuild(source->m_shadowBuild), m_isEnabled(false), m_buildDirectory(source->m_buildDirectory), m_qmakeBuildConfiguration(source->m_qmakeBuildConfiguration), m_subNodeBuild(0), // temporary value, so not copied m_fileNodeBuild(0) { cloneSteps(source); ctor(); } Qt4BuildConfiguration::~Qt4BuildConfiguration() { } QVariantMap Qt4BuildConfiguration::toMap() const { QVariantMap map(BuildConfiguration::toMap()); map.insert(QLatin1String(USE_SHADOW_BUILD_KEY), m_shadowBuild); map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory); map.insert(QLatin1String(BUILD_CONFIGURATION_KEY), int(m_qmakeBuildConfiguration)); return map; } bool Qt4BuildConfiguration::fromMap(const QVariantMap &map) { if (!BuildConfiguration::fromMap(map)) return false; m_shadowBuild = map.value(QLatin1String(USE_SHADOW_BUILD_KEY), true).toBool(); m_qmakeBuildConfiguration = QtSupport::BaseQtVersion::QmakeBuildConfigs(map.value(QLatin1String(BUILD_CONFIGURATION_KEY)).toInt()); m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), defaultShadowBuildDirectory()).toString(); m_lastEmmitedBuildDirectory = buildDirectory(); m_qtVersionSupportsShadowBuilds = supportsShadowBuilds(); return true; } void Qt4BuildConfiguration::ctor() { connect(this, SIGNAL(environmentChanged()), this, SLOT(emitBuildDirectoryChanged())); connect(this, SIGNAL(environmentChanged()), this, SLOT(emitProFileEvaluateNeeded())); connect(target(), SIGNAL(kitChanged()), this, SLOT(kitChanged())); } void Qt4BuildConfiguration::kitChanged() { emitProFileEvaluateNeeded(); emit environmentChanged(); emitBuildDirectoryChanged(); } void Qt4BuildConfiguration::emitBuildDirectoryChanged() { // We also emit buildDirectoryChanged if the the Qt version's supportShadowBuild changed if (buildDirectory() != m_lastEmmitedBuildDirectory || supportsShadowBuilds() != m_qtVersionSupportsShadowBuilds) { m_lastEmmitedBuildDirectory = buildDirectory(); m_qtVersionSupportsShadowBuilds = supportsShadowBuilds(); emit buildDirectoryChanged(); } } Utils::Environment Qt4BuildConfiguration::baseEnvironment() const { Utils::Environment env = BuildConfiguration::baseEnvironment(); return env; } BuildConfigWidget *Qt4BuildConfiguration::createConfigWidget() { return new Qt4ProjectConfigWidget(target()); } QString Qt4BuildConfiguration::defaultShadowBuildDirectory() const { // todo displayName isn't ideal return Qt4Project::shadowBuildDirectory(target()->project()->document()->fileName(), target()->kit(), displayName()); } /// returns the unexpanded build directory QString Qt4BuildConfiguration::rawBuildDirectory() const { QString workingDirectory; if (m_shadowBuild) { if (!m_buildDirectory.isEmpty()) workingDirectory = m_buildDirectory; else workingDirectory = defaultShadowBuildDirectory(); } if (workingDirectory.isEmpty()) workingDirectory = target()->project()->projectDirectory(); return workingDirectory; } /// returns the build directory QString Qt4BuildConfiguration::buildDirectory() const { QString path = QDir::cleanPath(environment().expandVariables(rawBuildDirectory())); return QDir::cleanPath(QDir(target()->project()->projectDirectory()).absoluteFilePath(path)); } bool Qt4BuildConfiguration::supportsShadowBuilds() { QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); return !version || version->supportsShadowBuilds(); } /// If only a sub tree should be build this function returns which sub node /// should be build /// \see Qt4BuildConfiguration::setSubNodeBuild Qt4ProjectManager::Qt4ProFileNode *Qt4BuildConfiguration::subNodeBuild() const { return m_subNodeBuild; } /// A sub node build on builds a sub node of the project /// That is triggered by a right click in the project explorer tree /// The sub node to be build is set via this function immediately before /// calling BuildManager::buildProject( BuildConfiguration * ) /// and reset immediately afterwards /// That is m_subNodesBuild is set only temporarly void Qt4BuildConfiguration::setSubNodeBuild(Qt4ProjectManager::Qt4ProFileNode *node) { m_subNodeBuild = node; } FileNode *Qt4BuildConfiguration::fileNodeBuild() const { return m_fileNodeBuild; } void Qt4BuildConfiguration::setFileNodeBuild(FileNode *node) { m_fileNodeBuild = node; } /// returns whether this is a shadow build configuration or not /// note, even if shadowBuild() returns true, it might be using the /// source directory as the shadow build directory, thus it /// still is a in-source build bool Qt4BuildConfiguration::shadowBuild() const { return m_shadowBuild; } /// returns the shadow build directory if set /// \note buildDirectory() is probably the function you want to call QString Qt4BuildConfiguration::shadowBuildDirectory() const { if (m_buildDirectory.isEmpty()) return defaultShadowBuildDirectory(); return m_buildDirectory; } void Qt4BuildConfiguration::setShadowBuildAndDirectory(bool shadowBuild, const QString &buildDirectory) { QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); QString directoryToSet = buildDirectory; bool toSet = (shadowBuild && version && version->isValid() && version->supportsShadowBuilds()); if (m_shadowBuild == toSet && m_buildDirectory == directoryToSet) return; m_shadowBuild = toSet; m_buildDirectory = directoryToSet; emit environmentChanged(); emitBuildDirectoryChanged(); emitProFileEvaluateNeeded(); } QString Qt4BuildConfiguration::defaultMakeTarget() const { ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(target()->kit()); QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); if (!tc || !version) return QString(); return tc->defaultMakeTarget(); } QString Qt4BuildConfiguration::makefile() const { return static_cast(target()->project())->rootQt4ProjectNode()->makefile(); } QtSupport::BaseQtVersion::QmakeBuildConfigs Qt4BuildConfiguration::qmakeBuildConfiguration() const { return m_qmakeBuildConfiguration; } void Qt4BuildConfiguration::setQMakeBuildConfiguration(QtSupport::BaseQtVersion::QmakeBuildConfigs config) { if (m_qmakeBuildConfiguration == config) return; m_qmakeBuildConfiguration = config; emit qmakeBuildConfigurationChanged(); emitBuildDirectoryChanged(); emitProFileEvaluateNeeded(); } void Qt4BuildConfiguration::emitProFileEvaluateNeeded() { Target *t = target(); Project *p = t->project(); if (t->activeBuildConfiguration() == this && p->activeTarget() == t) static_cast(p)->scheduleAsyncUpdate(); } void Qt4BuildConfiguration::emitQMakeBuildConfigurationChanged() { emit qmakeBuildConfigurationChanged(); } QStringList Qt4BuildConfiguration::configCommandLineArguments() const { QStringList result; QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); QtSupport::BaseQtVersion::QmakeBuildConfigs defaultBuildConfiguration = version ? version->defaultBuildConfig() : (QtSupport::BaseQtVersion::DebugBuild | QtSupport::BaseQtVersion::BuildAll); QtSupport::BaseQtVersion::QmakeBuildConfigs userBuildConfiguration = m_qmakeBuildConfiguration; if ((defaultBuildConfiguration & QtSupport::BaseQtVersion::BuildAll) && !(userBuildConfiguration & QtSupport::BaseQtVersion::BuildAll)) result << QLatin1String("CONFIG-=debug_and_release"); if (!(defaultBuildConfiguration & QtSupport::BaseQtVersion::BuildAll) && (userBuildConfiguration & QtSupport::BaseQtVersion::BuildAll)) result << QLatin1String("CONFIG+=debug_and_release"); if ((defaultBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild) && !(userBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild)) result << QLatin1String("CONFIG+=release"); if (!(defaultBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild) && (userBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild)) result << QLatin1String("CONFIG+=debug"); return result; } QMakeStep *Qt4BuildConfiguration::qmakeStep() const { QMakeStep *qs = 0; BuildStepList *bsl = stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD)); Q_ASSERT(bsl); for (int i = 0; i < bsl->count(); ++i) if ((qs = qobject_cast(bsl->at(i))) != 0) return qs; return 0; } MakeStep *Qt4BuildConfiguration::makeStep() const { MakeStep *ms = 0; BuildStepList *bsl = stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD)); Q_ASSERT(bsl); for (int i = 0; i < bsl->count(); ++i) if ((ms = qobject_cast(bsl->at(i))) != 0) return ms; return 0; } // returns true if both are equal Qt4BuildConfiguration::MakefileState Qt4BuildConfiguration::compareToImportFrom(const QString &makefile) { QMakeStep *qs = qmakeStep(); if (QFileInfo(makefile).exists() && qs) { Utils::FileName qmakePath = QtSupport::QtVersionManager::findQMakeBinaryFromMakefile(makefile); QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); if (!version) return MakefileForWrongProject; if (version->qmakeCommand() == qmakePath) { // same qtversion QPair result = QtSupport::QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig()); if (qmakeBuildConfiguration() == result.first) { // The qmake Build Configuration are the same, // now compare arguments lists // we have to compare without the spec/platform cmd argument // and compare that on its own QString workingDirectory = QFileInfo(makefile).absolutePath(); QStringList actualArgs; QString userArgs = qs->userArguments(); // This copies the settings from userArgs to actualArgs (minus some we // are not interested in), splitting them up into individual strings: extractSpecFromArguments(&userArgs, workingDirectory, version, &actualArgs); actualArgs = qs->deducedArguments() + actualArgs + qs->deducedArgumentsAfter(); Utils::FileName actualSpec = qs->mkspec(); QString qmakeArgs = result.second; QStringList parsedArgs; Utils::FileName parsedSpec = extractSpecFromArguments(&qmakeArgs, workingDirectory, version, &parsedArgs); if (debug) { qDebug()<<"Actual args:"<mkspec(); if ((actualSpec == version->mkspec() || actualSpec == Utils::FileName::fromString(QLatin1String("default"))) && (parsedSpec == version->mkspec() || parsedSpec == Utils::FileName::fromString(QLatin1String("default")) || parsedSpec.isEmpty())) return MakefileMatches; } return MakefileIncompatible; } else { if (debug) qDebug()<<"different qmake buildconfigurations buildconfiguration:"<qmakeCommand().toString() << " Makefile:"<< qmakePath.toString(); return MakefileForWrongProject; } } return MakefileMissing; } bool Qt4BuildConfiguration::removeQMLInspectorFromArguments(QString *args) { bool removedArgument = false; for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) { const QString arg = ait.value(); if (arg.contains(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH)) || arg.contains(QLatin1String(Constants::QMAKEVAR_QUICK1_DEBUG)) || arg.contains(QLatin1String(Constants::QMAKEVAR_QUICK2_DEBUG))) { ait.deleteArg(); removedArgument = true; } } return removedArgument; } Utils::FileName Qt4BuildConfiguration::extractSpecFromArguments(QString *args, const QString &directory, const QtSupport::BaseQtVersion *version, QStringList *outArgs) { Utils::FileName parsedSpec; bool ignoreNext = false; bool nextIsSpec = false; for (Utils::QtcProcess::ArgIterator ait(args); ait.next(); ) { if (ignoreNext) { ignoreNext = false; ait.deleteArg(); } else if (nextIsSpec) { nextIsSpec = false; parsedSpec = Utils::FileName::fromUserInput(ait.value()); ait.deleteArg(); } else if (ait.value() == QLatin1String("-spec") || ait.value() == QLatin1String("-platform")) { nextIsSpec = true; ait.deleteArg(); } else if (ait.value() == QLatin1String("-cache")) { // We ignore -cache, because qmake contained a bug that it didn't // mention the -cache in the Makefile. // That means changing the -cache option in the additional arguments // does not automatically rerun qmake. Alas, we could try more // intelligent matching for -cache, but i guess people rarely // do use that. ignoreNext = true; ait.deleteArg(); } else if (outArgs && ait.isSimple()) { outArgs->append(ait.value()); } } if (parsedSpec.isEmpty()) return Utils::FileName(); Utils::FileName baseMkspecDir = Utils::FileName::fromUserInput( version->qmakeProperty("QT_HOST_DATA") + QLatin1String("/mkspecs")); baseMkspecDir = Utils::FileName::fromString(baseMkspecDir.toFileInfo().canonicalFilePath()); // if the path is relative it can be // relative to the working directory (as found in the Makefiles) // or relatively to the mkspec directory // if it is the former we need to get the canonical form // for the other one we don't need to do anything if (parsedSpec.toFileInfo().isRelative()) { if (QFileInfo(directory + QLatin1Char('/') + parsedSpec.toString()).exists()) { parsedSpec = Utils::FileName::fromUserInput(directory + QLatin1Char('/') + parsedSpec.toString()); } else { parsedSpec = Utils::FileName::fromUserInput(baseMkspecDir.toString() + QLatin1Char('/') + parsedSpec.toString()); } } QFileInfo f2 = parsedSpec.toFileInfo(); while (f2.isSymLink()) { parsedSpec = Utils::FileName::fromString(f2.symLinkTarget()); f2.setFile(parsedSpec.toString()); } if (parsedSpec.isChildOf(baseMkspecDir)) { parsedSpec = parsedSpec.relativeChildPath(baseMkspecDir); } else { Utils::FileName sourceMkSpecPath = Utils::FileName::fromString(version->sourcePath().toString() + QLatin1String("/mkspecs")); if (parsedSpec.isChildOf(sourceMkSpecPath)) { parsedSpec = parsedSpec.relativeChildPath(sourceMkSpecPath); } } return parsedSpec; } ProjectExplorer::IOutputParser *Qt4BuildConfiguration::createOutputParser() const { ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit()); return tc ? tc->outputParser() : 0; } bool Qt4BuildConfiguration::isEnabled() const { return m_isEnabled; } QString Qt4BuildConfiguration::disabledReason() const { if (!m_isEnabled) return tr("Parsing the .pro file"); return QString(); } void Qt4BuildConfiguration::setEnabled(bool enabled) { if (m_isEnabled == enabled) return; m_isEnabled = enabled; emit enabledChanged(); } /*! \class Qt4BuildConfigurationFactory */ Qt4BuildConfigurationFactory::Qt4BuildConfigurationFactory(QObject *parent) : ProjectExplorer::IBuildConfigurationFactory(parent) { update(); QtSupport::QtVersionManager *vm = QtSupport::QtVersionManager::instance(); connect(vm, SIGNAL(qtVersionsChanged(QList,QList,QList)), this, SLOT(update())); } Qt4BuildConfigurationFactory::~Qt4BuildConfigurationFactory() { } void Qt4BuildConfigurationFactory::update() { emit availableCreationIdsChanged(); } bool Qt4BuildConfigurationFactory::canHandle(const Target *t) const { if (!t->project()->supportsKit(t->kit())) return false; return qobject_cast(t->project()); } QList Qt4BuildConfigurationFactory::availableCreationIds(const Target *parent) const { if (!canHandle(parent)) return QList(); return QList() << Core::Id(QT4_BC_ID); } QString Qt4BuildConfigurationFactory::displayNameForId(const Core::Id id) const { if (id == QT4_BC_ID) return tr("Qmake based build"); return QString(); } bool Qt4BuildConfigurationFactory::canCreate(const Target *parent, const Core::Id id) const { if (!canHandle(parent)) return false; return id == QT4_BC_ID; } BuildConfiguration *Qt4BuildConfigurationFactory::create(ProjectExplorer::Target *parent, const Core::Id id, const QString &name) { if (!canCreate(parent, id)) return 0; QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(parent->kit()); Q_ASSERT(version); bool ok = true; QString buildConfigurationName = name; if (buildConfigurationName.isEmpty()) buildConfigurationName = QInputDialog::getText(0, tr("New Configuration"), tr("New configuration name:"), QLineEdit::Normal, version->displayName(), &ok); buildConfigurationName = buildConfigurationName.trimmed(); if (!ok || buildConfigurationName.isEmpty()) return 0; //: Debug build configuration. We recommend not translating it. QString defaultFirstName = tr("%1 Debug").arg(version->displayName()); QString customFirstName; if (buildConfigurationName != version->displayName()) customFirstName = tr("%1 Debug").arg(buildConfigurationName); //: Release build configuration. We recommend not translating it. QString defaultSecondName = tr("%1 Release").arg(version->displayName()); QString customSecondName; if (buildConfigurationName != version->displayName()) customSecondName = tr("%1 Release").arg(buildConfigurationName); BuildConfiguration *bc = Qt4BuildConfiguration::setup(parent, defaultFirstName, customFirstName, version->defaultBuildConfig(), QString(), QString(), false); parent->addBuildConfiguration( Qt4BuildConfiguration::setup(parent, defaultSecondName, customSecondName, (version->defaultBuildConfig() ^ QtSupport::BaseQtVersion::DebugBuild), QString(), QString(), false)); return bc; } bool Qt4BuildConfigurationFactory::canClone(const Target *parent, ProjectExplorer::BuildConfiguration *source) const { return canHandle(parent) && qobject_cast(source); } BuildConfiguration *Qt4BuildConfigurationFactory::clone(Target *parent, BuildConfiguration *source) { if (!canClone(parent, source)) return 0; Qt4BuildConfiguration *oldbc(static_cast(source)); return new Qt4BuildConfiguration(parent, oldbc); } bool Qt4BuildConfigurationFactory::canRestore(const Target *parent, const QVariantMap &map) const { if (!canHandle(parent)) return false; return ProjectExplorer::idFromMap(map) == QT4_BC_ID; } BuildConfiguration *Qt4BuildConfigurationFactory::restore(Target *parent, const QVariantMap &map) { if (!canRestore(parent, map)) return 0; Qt4BuildConfiguration *bc = new Qt4BuildConfiguration(parent); if (bc->fromMap(map)) return bc; delete bc; return 0; } QList Qt4BuildConfigurationFactory::availableBuildConfigurations(const ProjectExplorer::Kit *k, const QString &proFilePath) { QList infoList; QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k); if (!version || !version->isValid()) return infoList; QtSupport::BaseQtVersion::QmakeBuildConfigs config = version->defaultBuildConfig() | QtSupport::BaseQtVersion::DebugBuild; BuildConfigurationInfo info = BuildConfigurationInfo(config, QString(), QString(), false); info.directory = Qt4Project::shadowBuildDirectory(proFilePath, k, buildConfigurationDisplayName(info)); infoList.append(info); info.buildConfig = config ^ QtSupport::BaseQtVersion::DebugBuild; info.directory = Qt4Project::shadowBuildDirectory(proFilePath, k, buildConfigurationDisplayName(info)); infoList.append(info); return infoList; } // Return name of a build configuration. QString Qt4BuildConfigurationFactory::buildConfigurationDisplayName(const BuildConfigurationInfo &info) { return (info.buildConfig & QtSupport::BaseQtVersion::DebugBuild) ? //: Name of a debug build configuration to created by a project wizard. We recommend not translating it. tr("Debug") : //: Name of a release build configuration to be created by a project wizard. We recommend not translating it. tr("Release"); } BuildConfiguration::BuildType Qt4BuildConfiguration::buildType() const { if (qmakeBuildConfiguration() & QtSupport::BaseQtVersion::DebugBuild) return Debug; else return Release; } Qt4BuildConfiguration *Qt4BuildConfiguration::setup(Target *t, QString defaultDisplayName, QString displayName, QtSupport::BaseQtVersion::QmakeBuildConfigs qmakeBuildConfiguration, QString additionalArguments, QString directory, bool importing) { bool debug = qmakeBuildConfiguration & QtSupport::BaseQtVersion::DebugBuild; // Add the buildconfiguration Qt4BuildConfiguration *bc = new Qt4BuildConfiguration(t); bc->setDefaultDisplayName(defaultDisplayName); bc->setDisplayName(displayName); ProjectExplorer::BuildStepList *buildSteps = bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD)); ProjectExplorer::BuildStepList *cleanSteps = bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_CLEAN)); Q_ASSERT(buildSteps); Q_ASSERT(cleanSteps); QMakeStep *qmakeStep = new QMakeStep(buildSteps); buildSteps->insertStep(0, qmakeStep); MakeStep *makeStep = new MakeStep(buildSteps); buildSteps->insertStep(1, makeStep); MakeStep* cleanStep = new MakeStep(cleanSteps); cleanStep->setClean(true); cleanStep->setUserArguments(QLatin1String("clean")); cleanSteps->insertStep(0, cleanStep); bool enableQmlDebugger = Qt4BuildConfiguration::removeQMLInspectorFromArguments(&additionalArguments); if (!additionalArguments.isEmpty()) qmakeStep->setUserArguments(additionalArguments); if (importing) qmakeStep->setLinkQmlDebuggingLibrary(enableQmlDebugger); // set some options for qmake and make if (qmakeBuildConfiguration & QtSupport::BaseQtVersion::BuildAll) // debug_and_release => explicit targets makeStep->setUserArguments(debug ? QLatin1String("debug") : QLatin1String("release")); bc->setQMakeBuildConfiguration(qmakeBuildConfiguration); if (!directory.isEmpty()) bc->setShadowBuildAndDirectory(directory != t->project()->projectDirectory(), directory); return bc; }