Ejemplo n.º 1
0
void QnxToolChain::addToEnvironment(Utils::Environment &env) const
{
    if (env.value(QLatin1String("QNX_HOST")).isEmpty()
            || env.value(QLatin1String("QNX_TARGET")).isEmpty())
        setQnxEnvironment(env, QnxUtils::qnxEnvironment(m_ndkPath));

    GccToolChain::addToEnvironment(env);
}
Ejemplo n.º 2
0
void SymbianQtVersion::addToEnvironment(const ProjectExplorer::Profile *p, Utils::Environment &env) const
{
    BaseQtVersion::addToEnvironment(p, env);
    // Generic Symbian environment:
    QString epocRootPath = ProjectExplorer::SysRootProfileInformation::sysRoot(p).toString();
    QDir epocDir(epocRootPath);

    // Clean up epoc root path for the environment:
    if (!epocRootPath.endsWith(QLatin1Char('/')))
        epocRootPath.append(QLatin1Char('/'));
    if (!isBuildWithSymbianSbsV2()) {
#ifdef Q_OS_WIN
        if (epocRootPath.count() > 2
                && epocRootPath.at(0).toLower() >= QLatin1Char('a')
                && epocRootPath.at(0).toLower() <= QLatin1Char('z')
                && epocRootPath.at(1) == QLatin1Char(':')) {
            epocRootPath = epocRootPath.mid(2);
        }
#endif
    }
    env.set(QLatin1String("EPOCROOT"), QDir::toNativeSeparators(epocRootPath));

    env.prependOrSetPath(epocDir.filePath(QLatin1String("epoc32/tools"))); // e.g. make.exe
    // Windows only:
    if (ProjectExplorer::Abi::hostAbi().os() == ProjectExplorer::Abi::WindowsOS) {
        QString winDir = QLatin1String(qgetenv("WINDIR"));
        if (!winDir.isEmpty())
            env.prependOrSetPath(QDir(winDir).filePath(QLatin1String("system32")));

        if (epocDir.exists(QLatin1String("epoc32/gcc/bin")))
            env.prependOrSetPath(epocDir.filePath(QLatin1String("epoc32/gcc/bin"))); // e.g. cpp.exe, *NOT* gcc.exe
        // Find perl in the special Symbian flavour:
        if (epocDir.exists(QLatin1String("../../tools/perl/bin"))) {
            epocDir.cd(QLatin1String("../../tools/perl/bin"));
            env.prependOrSetPath(epocDir.absolutePath());
        } else {
            env.prependOrSetPath(epocDir.filePath(QLatin1String("perl/bin")));
        }
    }

    // SBSv2:
    if (isBuildWithSymbianSbsV2()) {
        QString sbsHome(env.value(QLatin1String("SBS_HOME")));
        QString sbsConfig = sbsV2Directory();
        if (!sbsConfig.isEmpty()) {
            env.prependOrSetPath(sbsConfig);
            // SBS_HOME is the path minus the trailing /bin:
            env.set(QLatin1String("SBS_HOME"),
                    QDir::toNativeSeparators(sbsConfig.left(sbsConfig.count() - 4))); // We need this for Qt 4.6.3 compatibility
        } else if (!sbsHome.isEmpty()) {
            env.prependOrSetPath(sbsHome + QLatin1String("/bin"));
        }
    }
}
Ejemplo n.º 3
0
ProjectExplorer::ToolChain *RvctToolChainFactory::create()
{
    RvctToolChain *tc = new RvctToolChain(false);
    Utils::Environment env = Utils::Environment::systemEnvironment();
    if (env.hasKey(QLatin1String(RVCT_LICENSE_KEY))) {
        tc->setEnvironmentChanges(QList<Utils::EnvironmentItem>()
                                  << Utils::EnvironmentItem(QLatin1String(RVCT_LICENSE_KEY),
                                                            env.value(QLatin1String(RVCT_LICENSE_KEY))));
    }
    tc->setDisplayName(tr("RVCT"));
    return tc;
}
Ejemplo n.º 4
0
void MakeStepConfigWidget::updateDetails()
{
    ToolChain *tc
            = ToolChainKitInformation::toolChain(m_makeStep->target()->kit());
    QmakeBuildConfiguration *bc = m_makeStep->qmakeBuildConfiguration();
    if (!bc)
        bc = qobject_cast<QmakeBuildConfiguration *>(m_makeStep->target()->activeBuildConfiguration());

    if (tc && bc)
        m_ui->makeLabel->setText(tr("Override %1:").arg(QDir::toNativeSeparators(tc->makeCommand(bc->environment()))));
    else
        m_ui->makeLabel->setText(tr("Make:"));

    if (!tc) {
        setSummaryText(tr("<b>Make:</b> %1").arg(ProjectExplorer::ToolChainKitInformation::msgNoToolChainInTarget()));
        return;
    }
    if (!bc) {
        setSummaryText(tr("<b>Make:</b> No Qt build configuration."));
        return;
    }

    ProcessParameters param;
    param.setMacroExpander(bc->macroExpander());
    param.setWorkingDirectory(bc->buildDirectory().toString());
    QString makeCmd = tc->makeCommand(bc->environment());
    if (!m_makeStep->makeCommand().isEmpty())
        makeCmd = m_makeStep->makeCommand();
    param.setCommand(makeCmd);

    QString args = m_makeStep->userArguments();

    Utils::Environment env = bc->environment();
    Utils::Environment::setupEnglishOutput(&env);
    // We prepend "L" to the MAKEFLAGS, so that nmake / jom are less verbose
    // FIXME doing this without the user having a way to override this is rather bad
    if (tc && m_makeStep->makeCommand().isEmpty()) {
        if (tc->targetAbi().os() == Abi::WindowsOS
                && tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor) {
            const QString makeFlags = QLatin1String("MAKEFLAGS");
            env.set(makeFlags, QLatin1Char('L') + env.value(makeFlags));
        }
    }
    param.setArguments(args);
    param.setEnvironment(env);

    if (param.commandMissing())
        setSummaryText(tr("<b>Make:</b> %1 not found in the environment.").arg(makeCmd)); // Override display text
    else
        setSummaryText(param.summaryInWorkdir(displayName()));
}
Ejemplo n.º 5
0
bool MakeStep::init()
{
    CMakeBuildConfiguration *bc = cmakeBuildConfiguration();
    if (!bc)
        bc = targetsActiveBuildConfiguration();

    if (!bc)
        emit addTask(Task::buildConfigurationMissingTask());

    ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit());
    if (!tc)
        emit addTask(Task::compilerMissingTask());

    if (!bc || !tc) {
        emitFaultyConfigurationMessage();
        return false;
    }

    m_useNinja = bc->useNinja();

    QString arguments = Utils::QtcProcess::joinArgs(m_buildTargets);
    Utils::QtcProcess::addArgs(&arguments, additionalArguments());

    setIgnoreReturnValue(m_clean);

    ProcessParameters *pp = processParameters();
    pp->setMacroExpander(bc->macroExpander());
    Utils::Environment env = bc->environment();
    // Force output to english for the parsers. Do this here and not in the toolchain's
    // addToEnvironment() to not screw up the users run environment.
    env.set(QLatin1String("LC_ALL"), QLatin1String("C"));
    if (m_useNinja && !env.value(QLatin1String("NINJA_STATUS")).startsWith(m_ninjaProgressString))
        env.set(QLatin1String("NINJA_STATUS"), m_ninjaProgressString + QLatin1String("%o/sec] "));
    pp->setEnvironment(env);
    pp->setWorkingDirectory(bc->buildDirectory().toString());
    pp->setCommand(makeCommand(tc, bc->environment()));
    pp->setArguments(arguments);
    pp->resolveAll();

    setOutputParser(new CMakeParser());
    IOutputParser *parser = target()->kit()->createOutputParser();
    if (parser)
        appendOutputParser(parser);
    outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());

    return AbstractProcessStep::init();
}
static void prependOrSetQtEnvironment(Utils::Environment &env,
                                     const QString &key,
                                     const QString &value,
                                     bool &updated)
{
    const QString currentValue = env.value(key);
    const QString newValue = value + QLatin1String(":$") + key;
    if (!currentValue.isEmpty()) {
        if (currentValue == newValue)
            return;
        else
            env.unset(key);
    }

    env.prependOrSet(key, newValue);
    updated = true;
}
Ejemplo n.º 7
0
// Windows: Expand the delayed evaluation references returned by the
// SDK setup scripts: "PATH=!Path!;foo". Some values might expand
// to empty and should not be added
static QString winExpandDelayedEnvReferences(QString in, const Utils::Environment &env)
{
    const QChar exclamationMark = QLatin1Char('!');
    for (int pos = 0; pos < in.size(); ) {
        // Replace "!REF!" by its value in process environment
        pos = in.indexOf(exclamationMark, pos);
        if (pos == -1)
            break;
        const int nextPos = in.indexOf(exclamationMark, pos + 1);
        if (nextPos == -1)
            break;
        const QString var = in.mid(pos + 1, nextPos - pos - 1);
        const QString replacement = env.value(var.toUpper());
        in.replace(pos, nextPos + 1 - pos, replacement);
        pos += replacement.size();
    }
    return in;
}
Ejemplo n.º 8
0
bool MakeStep::init(QList<const BuildStep *> &earlierSteps)
{
    QmakeBuildConfiguration *bc = qmakeBuildConfiguration();
    if (!bc)
        bc = qobject_cast<QmakeBuildConfiguration *>(target()->activeBuildConfiguration());
    if (!bc)
        emit addTask(Task::buildConfigurationMissingTask());

    ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit());
    if (!tc)
        emit addTask(Task::compilerMissingTask());

    if (!bc || !tc) {
        emitFaultyConfigurationMessage();
        return false;
    }

    ProcessParameters *pp = processParameters();
    pp->setMacroExpander(bc->macroExpander());

    QString workingDirectory;
    if (bc->subNodeBuild())
        workingDirectory = bc->subNodeBuild()->buildDir();
    else
        workingDirectory = bc->buildDirectory().toString();
    pp->setWorkingDirectory(workingDirectory);

    pp->setCommand(effectiveMakeCommand());

    // If we are cleaning, then make can fail with a error code, but that doesn't mean
    // we should stop the clean queue
    // That is mostly so that rebuild works on a already clean project
    setIgnoreReturnValue(m_clean);

    QString args;

    QmakeProjectManager::QmakeProFileNode *subNode = bc->subNodeBuild();
    if (subNode) {
        QString makefile = subNode->makefile();
        if (makefile.isEmpty())
            makefile = QLatin1String("Makefile");
        // Use Makefile.Debug and Makefile.Release
        // for file builds, since the rules for that are
        // only in those files.
        if (subNode->isDebugAndRelease() && bc->fileNodeBuild()) {
            if (bc->buildType() == QmakeBuildConfiguration::Debug)
                makefile += QLatin1String(".Debug");
            else
                makefile += QLatin1String(".Release");
        }
        if (makefile != QLatin1String("Makefile")) {
            Utils::QtcProcess::addArg(&args, QLatin1String("-f"));
            Utils::QtcProcess::addArg(&args, makefile);
        }
        m_makeFileToCheck = QDir(workingDirectory).filePath(makefile);
    } else {
        if (!bc->makefile().isEmpty()) {
            Utils::QtcProcess::addArg(&args, QLatin1String("-f"));
            Utils::QtcProcess::addArg(&args, bc->makefile());
            m_makeFileToCheck = QDir(workingDirectory).filePath(bc->makefile());
        } else {
            m_makeFileToCheck = QDir(workingDirectory).filePath(QLatin1String("Makefile"));
        }
    }

    Utils::QtcProcess::addArgs(&args, m_userArgs);
    if (bc->fileNodeBuild() && subNode) {
        QString objectsDir = subNode->objectsDirectory();
        if (objectsDir.isEmpty()) {
            objectsDir = subNode->buildDir(bc);
            if (subNode->isDebugAndRelease()) {
                if (bc->buildType() == QmakeBuildConfiguration::Debug)
                    objectsDir += QLatin1String("/debug");
                else
                    objectsDir += QLatin1String("/release");
            }
        }
        QString relObjectsDir = QDir(pp->workingDirectory()).relativeFilePath(objectsDir);
        if (relObjectsDir == QLatin1String("."))
            relObjectsDir.clear();
        if (!relObjectsDir.isEmpty())
            relObjectsDir += QLatin1Char('/');
        QString objectFile = relObjectsDir +
                bc->fileNodeBuild()->filePath().toFileInfo().baseName() +
                subNode->objectExtension();
        Utils::QtcProcess::addArg(&args, objectFile);
    }
    Utils::Environment env = bc->environment();
    Utils::Environment::setupEnglishOutput(&env);
    // We also prepend "L" to the MAKEFLAGS, so that nmake / jom are less verbose
    if (tc && makeCommand().isEmpty()) {
        if (tc->targetAbi().os() == Abi::WindowsOS
                && tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor) {
            const QString makeFlags = QLatin1String("MAKEFLAGS");
            env.set(makeFlags, QLatin1Char('L') + env.value(makeFlags));
        }
    }

    pp->setEnvironment(env);
    pp->setArguments(args);
    pp->resolveAll();

    setOutputParser(new ProjectExplorer::GnuMakeParser());
    if (tc && tc->targetAbi().os() == Abi::MacOS)
        appendOutputParser(new XcodebuildParser);
    IOutputParser *parser = target()->kit()->createOutputParser();
    if (parser)
        appendOutputParser(parser);
    outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
    appendOutputParser(new QMakeParser); // make may cause qmake to be run, add last to make sure
                                         // it has a low priority.

    m_scriptTarget = (static_cast<QmakeProject *>(bc->target()->project())->rootProjectNode()->projectType() == ScriptTemplate);

    return AbstractProcessStep::init(earlierSteps);
}
Ejemplo n.º 9
0
bool MakeStep::init()
{
    Qt4BuildConfiguration *bc = qt4BuildConfiguration();
    if (!bc)
        bc = qobject_cast<Qt4BuildConfiguration *>(target()->activeBuildConfiguration());

    m_tasks.clear();
    if (!bc) {
        m_tasks.append(ProjectExplorer::Task(ProjectExplorer::Task::Error,
                                             tr("Qt Creator needs a build configuration set up to build. Configure a tool chain in Project mode."),
                                             Utils::FileName(), -1,
                                             Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)));
        return false;
    }

    ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainProfileInformation::toolChain(target()->profile());
    if (!tc) {
        m_tasks.append(ProjectExplorer::Task(ProjectExplorer::Task::Error,
                                             tr("Qt Creator needs a tool chain set up to build. Configure a tool chain the profile options."),
                                             Utils::FileName(), -1,
                                             Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)));
        return false;
    }

    ProjectExplorer::ProcessParameters *pp = processParameters();
    pp->setMacroExpander(bc->macroExpander());

    QString workingDirectory;
    if (bc->subNodeBuild())
        workingDirectory = bc->subNodeBuild()->buildDir();
    else
        workingDirectory = bc->buildDirectory();
    pp->setWorkingDirectory(workingDirectory);

    QString makeCmd = tc->makeCommand();
    if (!m_makeCmd.isEmpty())
        makeCmd = m_makeCmd;
    pp->setCommand(makeCmd);

    // If we are cleaning, then make can fail with a error code, but that doesn't mean
    // we should stop the clean queue
    // That is mostly so that rebuild works on a already clean project
    setIgnoreReturnValue(m_clean);

    QString args;

    Qt4ProjectManager::Qt4ProFileNode *subNode = bc->subNodeBuild();
    if (subNode) {
        QString makefile = subNode->makefile();
        if (makefile.isEmpty())
            makefile = QLatin1String("Makefile");
        if (subNode->isDebugAndRelease()) {
            if (bc->buildType() == Qt4BuildConfiguration::Debug)
                makefile += QLatin1String(".Debug");
            else
                makefile += QLatin1String(".Release");
        }
        if (makefile != QLatin1String("Makefile")) {
            Utils::QtcProcess::addArg(&args, QLatin1String("-f"));
            Utils::QtcProcess::addArg(&args, makefile);
        }
        m_makeFileToCheck = QDir(workingDirectory).filePath(makefile);
    } else {
        if (!bc->makefile().isEmpty()) {
            Utils::QtcProcess::addArg(&args, QLatin1String("-f"));
            Utils::QtcProcess::addArg(&args, bc->makefile());
            m_makeFileToCheck = QDir(workingDirectory).filePath(bc->makefile());
        } else {
            m_makeFileToCheck = QDir(workingDirectory).filePath(QLatin1String("Makefile"));
        }
    }

    Utils::QtcProcess::addArgs(&args, m_userArgs);

    if (!isClean()) {
        if (!bc->defaultMakeTarget().isEmpty())
            Utils::QtcProcess::addArg(&args, bc->defaultMakeTarget());
    }

    if (bc->fileNodeBuild() && subNode) {
        QString objectsDir = subNode->objectsDirectory();
        if (objectsDir.isEmpty()) {
            objectsDir = subNode->buildDir(bc);
            if (subNode->isDebugAndRelease()) {
                if (bc->buildType() == Qt4BuildConfiguration::Debug)
                    objectsDir += QLatin1String("/debug");
                else
                    objectsDir += QLatin1String("/release");
            }
        }
        QString relObjectsDir = QDir(pp->workingDirectory()).relativeFilePath(objectsDir);
        if (!relObjectsDir.isEmpty())
            relObjectsDir += QLatin1Char('/');
        QString objectFile = relObjectsDir +
                QFileInfo(bc->fileNodeBuild()->path()).baseName() +
                subNode->objectExtension();
        Utils::QtcProcess::addArg(&args, objectFile);
    }
    Utils::Environment env = bc->environment();
    // Force output to english for the parsers. Do this here and not in the toolchain's
    // addToEnvironment() to not screw up the users run environment.
    env.set(QLatin1String("LC_ALL"), QLatin1String("C"));
    // -w option enables "Enter"/"Leaving directory" messages, which we need for detecting the
    // absolute file path
    // doing this without the user having a way to override this is rather bad
    // so we only do it for unix and if the user didn't override the make command
    // but for now this is the least invasive change
    // We also prepend "L" to the MAKEFLAGS, so that nmake / jom are less verbose
    if (tc && m_makeCmd.isEmpty()) {
        if (tc->targetAbi().binaryFormat() != ProjectExplorer::Abi::PEFormat )
            Utils::QtcProcess::addArg(&args, QLatin1String("-w"));
        if (tc->targetAbi().os() == ProjectExplorer::Abi::WindowsOS
                && tc->targetAbi().osFlavor() != ProjectExplorer::Abi::WindowsMSysFlavor) {
            const QString makeFlags = QLatin1String("MAKEFLAGS");
            env.set(makeFlags, QLatin1Char('L') + env.value(makeFlags));
        }
    }

    pp->setEnvironment(env);
    pp->setArguments(args);

    ProjectExplorer::IOutputParser *parser = 0;
    QtSupport::BaseQtVersion *version = QtSupport::QtProfileInformation::qtVersion(target()->profile());
    if (version)
        parser = version->createOutputParser();
    if (parser)
        parser->appendOutputParser(new QtSupport::QtParser);
    else
        parser = new QtSupport::QtParser;
    if (tc)
        parser->appendOutputParser(tc->outputParser());

    parser->setWorkingDirectory(workingDirectory);

    setOutputParser(parser);

    m_scriptTarget = (static_cast<Qt4Project *>(bc->target()->project())->rootQt4ProjectNode()->projectType() == ScriptTemplate);

    return AbstractProcessStep::init();
}
Ejemplo n.º 10
0
bool MakeStep::init()
{
    Qt4BuildConfiguration *bc = qt4BuildConfiguration();
    if (!bc)
        bc = qobject_cast<Qt4BuildConfiguration *>(target()->activeBuildConfiguration());

    m_tasks.clear();
    ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit());
    if (!tc) {
        m_tasks.append(Task(Task::Error, tr("Qt Creator needs a compiler set up to build. Configure a compiler in the kit options."),
                            Utils::FileName(), -1,
                            Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)));
        return true; // otherwise the tasks will not get reported
    }

    ProcessParameters *pp = processParameters();
    pp->setMacroExpander(bc->macroExpander());

    QString workingDirectory;
    if (bc->subNodeBuild())
        workingDirectory = bc->subNodeBuild()->buildDir();
    else
        workingDirectory = bc->buildDirectory();
    pp->setWorkingDirectory(workingDirectory);

    QString makeCmd = tc->makeCommand(bc->environment());
    if (!m_makeCmd.isEmpty())
        makeCmd = m_makeCmd;
    pp->setCommand(makeCmd);

    // If we are cleaning, then make can fail with a error code, but that doesn't mean
    // we should stop the clean queue
    // That is mostly so that rebuild works on a already clean project
    setIgnoreReturnValue(m_clean);

    QString args;

    Qt4ProjectManager::Qt4ProFileNode *subNode = bc->subNodeBuild();
    if (subNode) {
        QString makefile = subNode->makefile();
        if (makefile.isEmpty())
            makefile = QLatin1String("Makefile");
        // Use Makefile.Debug and Makefile.Release
        // for file builds, since the rules for that are
        // only in those files.
        if (subNode->isDebugAndRelease() && bc->fileNodeBuild()) {
            if (bc->buildType() == Qt4BuildConfiguration::Debug)
                makefile += QLatin1String(".Debug");
            else
                makefile += QLatin1String(".Release");
        }
        if (makefile != QLatin1String("Makefile")) {
            Utils::QtcProcess::addArg(&args, QLatin1String("-f"));
            Utils::QtcProcess::addArg(&args, makefile);
        }
        m_makeFileToCheck = QDir(workingDirectory).filePath(makefile);
    } else {
        if (!bc->makefile().isEmpty()) {
            Utils::QtcProcess::addArg(&args, QLatin1String("-f"));
            Utils::QtcProcess::addArg(&args, bc->makefile());
            m_makeFileToCheck = QDir(workingDirectory).filePath(bc->makefile());
        } else {
            m_makeFileToCheck = QDir(workingDirectory).filePath(QLatin1String("Makefile"));
        }
    }

    Utils::QtcProcess::addArgs(&args, m_userArgs);
    if (bc->fileNodeBuild() && subNode) {
        QString objectsDir = subNode->objectsDirectory();
        if (objectsDir.isEmpty()) {
            objectsDir = subNode->buildDir(bc);
            if (subNode->isDebugAndRelease()) {
                if (bc->buildType() == Qt4BuildConfiguration::Debug)
                    objectsDir += QLatin1String("/debug");
                else
                    objectsDir += QLatin1String("/release");
            }
        }
        QString relObjectsDir = QDir(pp->workingDirectory()).relativeFilePath(objectsDir);
        if (!relObjectsDir.isEmpty())
            relObjectsDir += QLatin1Char('/');
        QString objectFile = relObjectsDir +
                QFileInfo(bc->fileNodeBuild()->path()).baseName() +
                subNode->objectExtension();
        Utils::QtcProcess::addArg(&args, objectFile);
    }
    Utils::Environment env = bc->environment();
    // We also prepend "L" to the MAKEFLAGS, so that nmake / jom are less verbose
    if (tc && m_makeCmd.isEmpty()) {
        if (tc->targetAbi().os() == Abi::WindowsOS
                && tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor) {
            const QString makeFlags = QLatin1String("MAKEFLAGS");
            env.set(makeFlags, QLatin1Char('L') + env.value(makeFlags));
        }
    }

    pp->setEnvironment(env);
    pp->setArguments(args);
    pp->resolveAll();

    setOutputParser(new ProjectExplorer::GnuMakeParser());
    IOutputParser *parser = target()->kit()->createOutputParser();
    if (parser)
        appendOutputParser(parser);
    outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());
    appendOutputParser(new QMakeParser); // make may cause qmake to be run, add last to make sure
                                         // it has a low priority.

    m_scriptTarget = (static_cast<Qt4Project *>(bc->target()->project())->rootQt4ProjectNode()->projectType() == ScriptTemplate);

    return AbstractProcessStep::init();
}
Ejemplo n.º 11
0
bool MakeStep::init(QList<const BuildStep *> &earlierSteps)
{
    CMakeBuildConfiguration *bc = cmakeBuildConfiguration();
    if (!bc)
        bc = targetsActiveBuildConfiguration();

    if (!bc)
        emit addTask(Task::buildConfigurationMissingTask());

    ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit());
    if (!tc)
        emit addTask(Task::compilerMissingTask());

    if (!bc || !tc) {
        emitFaultyConfigurationMessage();
        return false;
    }

    m_useNinja = bc->useNinja();

    QString arguments;
    if (m_addRunConfigurationArgument) {
        CMakeRunConfiguration* rc = targetsActiveRunConfiguration();
        if (!rc) {
            emit addTask(Task(Task::Error,
                              QCoreApplication::translate("ProjectExplorer::Task",
                                        "You asked to build the current Run Configurations build target only, "
                                        "but the current Run Configuration is not associated with a build target. "
                                        "Please update the Make Step in your build settings."),
                            Utils::FileName(), -1,
                            ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM));
            emitFaultyConfigurationMessage();
            return false;
        }
        if (!rc->title().isEmpty())
            Utils::QtcProcess::addArg(&arguments, rc->title());
    }
    Utils::QtcProcess::addArgs(&arguments, m_buildTargets);
    Utils::QtcProcess::addArgs(&arguments, additionalArguments());

    setIgnoreReturnValue(m_clean);

    ProcessParameters *pp = processParameters();
    pp->setMacroExpander(bc->macroExpander());
    Utils::Environment env = bc->environment();
    // Force output to english for the parsers. Do this here and not in the toolchain's
    // addToEnvironment() to not screw up the users run environment.
    env.set(QLatin1String("LC_ALL"), QLatin1String("C"));
    if (m_useNinja && !env.value(QLatin1String("NINJA_STATUS")).startsWith(m_ninjaProgressString))
        env.set(QLatin1String("NINJA_STATUS"), m_ninjaProgressString + QLatin1String("%o/sec] "));
    pp->setEnvironment(env);
    pp->setWorkingDirectory(bc->buildDirectory().toString());
    pp->setCommand(makeCommand(tc, bc->environment()));
    pp->setArguments(arguments);
    pp->resolveAll();

    setOutputParser(new CMakeParser());
    IOutputParser *parser = target()->kit()->createOutputParser();
    if (parser)
        appendOutputParser(parser);
    outputParser()->setWorkingDirectory(pp->effectiveWorkingDirectory());

    return AbstractProcessStep::init(earlierSteps);
}