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); }
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; }