Fixes: Move Buildparser to the projectexplorer, use in cmakeplugin

Details:  This enables us to parse the build errors correctly.
          The makesteps of the qt4project and cmakeproject have some
          code dupliaction, which could be refactored. And the code
          to find out the correct build parser could probably also
          be done better, but we are now parsing the build output for
          cmake.
This commit is contained in:
dt
2009-02-16 13:12:12 +01:00
parent 9cb615609c
commit c6a02170b9
17 changed files with 176 additions and 36 deletions

View File

@@ -40,6 +40,7 @@
#include "cmakestep.h"
#include "makestep.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <cpptools/cppmodelmanagerinterface.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
@@ -103,7 +104,7 @@ void CMakeProject::parseCMakeLists()
} else {
// TODO hmm?
}
if (newToolChain == m_toolChain) {
if (ProjectExplorer::ToolChain::equals(newToolChain, m_toolChain)) {
delete newToolChain;
newToolChain = 0;
} else {
@@ -158,6 +159,21 @@ void CMakeProject::parseCMakeLists()
}
}
QString CMakeProject::buildParser(const QString &buildConfiguration) const
{
if (!m_toolChain)
return QString::null;
if (m_toolChain->type() == ProjectExplorer::ToolChain::GCC
|| m_toolChain->type() == ProjectExplorer::ToolChain::LinuxICC
|| m_toolChain->type() == ProjectExplorer::ToolChain::MinGW) {
return ProjectExplorer::Constants::BUILD_PARSER_GCC;
} else if (m_toolChain->type() == ProjectExplorer::ToolChain::MSVC
|| m_toolChain->type() == ProjectExplorer::ToolChain::WINCE) {
return ProjectExplorer::Constants::BUILD_PARSER_MSVC;
}
return QString::null;
}
QStringList CMakeProject::targets() const
{
QStringList results;

View File

@@ -105,6 +105,7 @@ public:
MakeStep *makeStep() const;
CMakeStep *cmakeStep() const;
QStringList targets() const;
QString buildParser(const QString &buildConfiguration) const;
private:
void parseCMakeLists();

View File

@@ -34,6 +34,7 @@
#include "makestep.h"
#include "cmakeprojectconstants.h"
#include "cmakeproject.h"
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
#include <QtGui/QFormLayout>
@@ -42,6 +43,11 @@
#include <QtGui/QLineEdit>
#include <QtGui/QListWidget>
namespace {
bool debug = false;
}
using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
@@ -52,10 +58,42 @@ MakeStep::MakeStep(CMakeProject *pro)
MakeStep::~MakeStep()
{
delete m_buildParser;
m_buildParser = 0;
}
bool MakeStep::init(const QString &buildConfiguration)
{
// TODO figure out the correct build parser
delete m_buildParser;
m_buildParser = 0;
QString buildParser = m_pro->buildParser(buildConfiguration);
QList<ProjectExplorer::IBuildParserFactory *> buildParserFactories =
ExtensionSystem::PluginManager::instance()->getObjects<ProjectExplorer::IBuildParserFactory>();
foreach (ProjectExplorer::IBuildParserFactory * factory, buildParserFactories)
if (factory->canCreate(buildParser)) {
m_buildParser = factory->create(buildParser);
break;
}
if (m_buildParser) {
connect(m_buildParser, SIGNAL(addToOutputWindow(const QString &)),
this, SIGNAL(addToOutputWindow(const QString &)),
Qt::DirectConnection);
connect(m_buildParser, SIGNAL(addToTaskWindow(const QString &, int, int, const QString &)),
this, SLOT(slotAddToTaskWindow(const QString &, int, int, const QString &)),
Qt::DirectConnection);
connect(m_buildParser, SIGNAL(enterDirectory(const QString &)),
this, SLOT(addDirectory(const QString &)),
Qt::DirectConnection);
connect(m_buildParser, SIGNAL(leaveDirectory(const QString &)),
this, SLOT(removeDirectory(const QString &)),
Qt::DirectConnection);
}
m_openDirectories.clear();
addDirectory(m_pro->buildDirectory(buildConfiguration));
setEnabled(buildConfiguration, true);
setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration));
setCommand(buildConfiguration, "make"); // TODO give full path here?
@@ -89,6 +127,79 @@ bool MakeStep::immutable() const
return true;
}
void MakeStep::stdOut(const QString &line)
{
if (m_buildParser)
m_buildParser->stdOutput(line);
AbstractProcessStep::stdOut(line);
}
void MakeStep::stdError(const QString &line)
{
if (m_buildParser)
m_buildParser->stdError(line);
AbstractProcessStep::stdError(line);
}
void MakeStep::slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description)
{
QString filePath = fn;
if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) {
// We have no save way to decide which file in which subfolder
// is meant. Therefore we apply following heuristics:
// 1. Search for unique file in directories currently indicated as open by GNU make
// (Enter directory xxx, Leave directory xxx...) + current directory
// 3. Check if file is unique in whole project
// 4. Otherwise give up
filePath = filePath.trimmed();
QList<QFileInfo> possibleFiles;
foreach (const QString &dir, m_openDirectories) {
QFileInfo candidate(dir + QLatin1Char('/') + filePath);
if (debug)
qDebug() << "Checking path " << candidate.filePath();
if (candidate.exists()
&& !possibleFiles.contains(candidate)) {
if (debug)
qDebug() << candidate.filePath() << "exists!";
possibleFiles << candidate;
}
}
if (possibleFiles.count() == 0) {
if (debug)
qDebug() << "No success. Trying all files in project ...";
QString fileName = QFileInfo(filePath).fileName();
foreach (const QString &file, project()->files(ProjectExplorer::Project::AllFiles)) {
QFileInfo candidate(file);
if (candidate.fileName() == fileName) {
if (debug)
qDebug() << "Found " << file;
possibleFiles << candidate;
}
}
}
if (possibleFiles.count() == 1)
filePath = possibleFiles.first().filePath();
else
qWarning() << "Could not find absolute location of file " << filePath;
}
emit addToTaskWindow(filePath, type, linenumber, description);
}
void MakeStep::addDirectory(const QString &dir)
{
if (!m_openDirectories.contains(dir))
m_openDirectories.insert(dir);
}
void MakeStep::removeDirectory(const QString &dir)
{
if (m_openDirectories.contains(dir))
m_openDirectories.remove(dir);
}
CMakeProject *MakeStep::project() const
{
return m_pro;
@@ -154,7 +265,6 @@ void MakeBuildStepConfigWidget::init(const QString &buildConfiguration)
}
// and connect again
connect(m_targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
}
//

View File

@@ -64,8 +64,17 @@ public:
CMakeProject *project() const;
bool buildsTarget(const QString &buildConfiguration, const QString &target) const;
void setBuildTarget(const QString &buildConfiguration, const QString &target, bool on);
private slots:
void slotAddToTaskWindow(const QString & fn, int type, int linenumber, const QString & description);
void addDirectory(const QString &dir);
void removeDirectory(const QString &dir);
protected:
virtual void stdOut(const QString &line);
virtual void stdError(const QString &line);
private:
CMakeProject *m_pro;
ProjectExplorer::BuildParserInterface *m_buildParser;
QSet<QString> m_openDirectories;
};
class MakeBuildStepConfigWidget :public ProjectExplorer::BuildStepConfigWidget