///
/// Returns all arguments
/// That is: possbile subpath
/// spec
/// config arguemnts
/// moreArguments
/// user arguments
QString QMakeStep::allArguments(bool shorted)
{
    QmakeBuildConfiguration *bc = qmakeBuildConfiguration();
    QStringList arguments;
    if (bc->subNodeBuild())
        arguments << bc->subNodeBuild()->path().toUserOutput();
    else if (shorted)
        arguments << project()->projectFilePath().fileName();
    else
        arguments << project()->projectFilePath().toUserOutput();

    arguments << QLatin1String("-r");
    bool userProvidedMkspec = false;
    for (QtcProcess::ConstArgIterator ait(m_userArgs); ait.next(); ) {
        if (ait.value() == QLatin1String("-spec")) {
            if (ait.next()) {
                userProvidedMkspec = true;
                break;
            }
        }
    }
    FileName specArg = mkspec();
    if (!userProvidedMkspec && !specArg.isEmpty())
        arguments << QLatin1String("-spec") << specArg.toUserOutput();

    // Find out what flags we pass on to qmake
    arguments << bc->configCommandLineArguments();

    arguments << deducedArguments().toArguments();

    QString args = QtcProcess::joinArgs(arguments);
    // User arguments
    QtcProcess::addArgs(&args, m_userArgs);
    return args;
}
Exemple #2
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);
}
Exemple #3
0
bool QMakeStep::init(QList<const BuildStep *> &earlierSteps)
{
    if (m_commandFuture)
        return false;

    QmakeBuildConfiguration *qmakeBc = qmakeBuildConfiguration();
    const BaseQtVersion *qtVersion = QtKitInformation::qtVersion(target()->kit());

    if (!qtVersion)
        return false;

    QString workingDirectory;

    if (qmakeBc->subNodeBuild())
        workingDirectory = qmakeBc->subNodeBuild()->buildDir();
    else
        workingDirectory = qmakeBc->buildDirectory().toString();

    m_qmakeExecutable = qtVersion->qmakeCommand().toString();
    m_qmakeArguments = allArguments(qtVersion);
    m_runMakeQmake = (qtVersion->qtVersion() >= QtVersionNumber(5, 0 ,0));
    if (m_runMakeQmake) {
        m_makeExecutable = makeCommand();
        if (m_makeExecutable.isEmpty())
            return false;
    } else {
        m_makeExecutable.clear();
    }

    QString makefile = workingDirectory;

    if (qmakeBc->subNodeBuild()) {
        if (!qmakeBc->subNodeBuild()->makefile().isEmpty())
            makefile.append(qmakeBc->subNodeBuild()->makefile());
        else
            makefile.append(QLatin1String("/Makefile"));
    } else if (!qmakeBc->makefile().isEmpty()) {
        makefile.append(QLatin1Char('/'));
        makefile.append(qmakeBc->makefile());
    } else {
        makefile.append(QLatin1String("/Makefile"));
    }

    // Check whether we need to run qmake
    bool makefileOutDated = (qmakeBc->compareToImportFrom(makefile) != QmakeBuildConfiguration::MakefileMatches);
    if (m_forced || makefileOutDated)
        m_needToRunQMake = true;
    m_forced = false;

    ProcessParameters *pp = processParameters();
    pp->setMacroExpander(qmakeBc->macroExpander());
    pp->setWorkingDirectory(workingDirectory);
    pp->setEnvironment(qmakeBc->environment());

    setOutputParser(new QMakeParser);

    QmakeProFileNode *node = static_cast<QmakeProject *>(qmakeBc->target()->project())->rootProjectNode();
    if (qmakeBc->subNodeBuild())
        node = qmakeBc->subNodeBuild();
    QString proFile = node->filePath().toString();

    QList<ProjectExplorer::Task> tasks = qtVersion->reportIssues(proFile, workingDirectory);
    Utils::sort(tasks);

    if (!tasks.isEmpty()) {
        bool canContinue = true;
        foreach (const ProjectExplorer::Task &t, tasks) {
            addTask(t);
            if (t.type == Task::Error)
                canContinue = false;
        }