diff --git a/projectmanagers/cmake/cmakebuilddirchooser.h b/projectmanagers/cmake/cmakebuilddirchooser.h --- a/projectmanagers/cmake/cmakebuilddirchooser.h +++ b/projectmanagers/cmake/cmakebuilddirchooser.h @@ -38,11 +38,11 @@ { Q_OBJECT public: - enum StatusType - { - BuildDirCreated = 1, - CorrectProject = 2, - BuildFolderEmpty = 4, + enum StatusType + { + BuildDirCreated = 1, + CorrectProject = 2, + BuildFolderEmpty = 4, HaveCMake = 8, CorrectBuildDir = 16, DirAlreadyCreated = 32 //Error message in case it's already configured @@ -69,9 +69,14 @@ private slots: void updated(); + private: + void buildDirVariables(const KDevelop::Path& buildDir, + QString& srcDir, + QString& installDir, + QString& buildType); + QStringList m_alreadyUsed; - static QString buildDirProject(const KDevelop::Path &buildDir); QStringList extraArgumentsHistory() const; Ui::CMakeBuildDirChooser* m_chooserUi; diff --git a/projectmanagers/cmake/cmakebuilddirchooser.cpp b/projectmanagers/cmake/cmakebuilddirchooser.cpp --- a/projectmanagers/cmake/cmakebuilddirchooser.cpp +++ b/projectmanagers/cmake/cmakebuilddirchooser.cpp @@ -102,114 +102,127 @@ update(); } -QString CMakeBuildDirChooser::buildDirProject(const Path &srcDir) +void CMakeBuildDirChooser::buildDirVariables( + const KDevelop::Path& buildDir, + QString& srcDir, + QString& installDir, + QString& buildType) { - const Path cachePath(srcDir, "CMakeCache.txt"); + static const QString srcLine = QStringLiteral("CMAKE_HOME_DIRECTORY:INTERNAL="); + static const QString installLine = QStringLiteral("CMAKE_INSTALL_PREFIX:PATH="); + static const QString buildLine = QStringLiteral("CMAKE_BUILD_TYPE:STRING="); + + const Path cachePath(buildDir, "CMakeCache.txt"); QFile file(cachePath.toLocalFile()); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - { + srcDir.clear(); + installDir.clear(); + buildType.clear(); + + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qCWarning(CMAKE) << "Something really strange happened reading" << cachePath; - return QString(); + return; } - QString ret; - bool correct=false; - const QString pLine="CMAKE_HOME_DIRECTORY:INTERNAL="; - while (!correct && !file.atEnd()) - { + int cnt = 0; + while (cnt != 3 && !file.atEnd()) { // note: CMakeCache.txt is UTF8-encoded, also see bug 329305 QString line = QString::fromUtf8(file.readLine().trimmed()); - if(line.startsWith(pLine)) - { - correct=true; - ret=line.mid(pLine.count()); + + if (line.startsWith(srcLine)) { + srcDir = line.mid(srcLine.count()); + ++cnt; + } + + if (line.startsWith(installLine)) { + installDir = line.mid(installLine.count()); + ++cnt; + } + + if (line.startsWith(buildLine)) { + buildType = line.mid(buildLine.count()); + ++cnt; } } - qCDebug(CMAKE) << "The source directory for " << file.fileName() << "is" << ret; - return ret; + + qCDebug(CMAKE) << "The source directory for " << file.fileName() << "is" << srcDir; + qCDebug(CMAKE) << "The install directory for " << file.fileName() << "is" << installDir; + qCDebug(CMAKE) << "The build type for " << file.fileName() << "is" << buildType; } void CMakeBuildDirChooser::updated() { - bool haveCMake=QFile::exists(m_chooserUi->cmakeBin->url().toLocalFile()); + bool haveCMake = QFile::exists(m_chooserUi->cmakeBin->url().toLocalFile()); StatusTypes st; - if( haveCMake ) st |= HaveCMake; + if (haveCMake) + st |= HaveCMake; m_chooserUi->buildFolder->setEnabled(haveCMake); m_chooserUi->installPrefix->setEnabled(haveCMake); m_chooserUi->buildType->setEnabled(haveCMake); // m_chooserUi->generator->setEnabled(haveCMake); - if(!haveCMake) - { + if (!haveCMake) { setStatus(i18n("You need to select a cmake binary."), false); return; } Path chosenBuildFolder(m_chooserUi->buildFolder->url()); bool emptyUrl = chosenBuildFolder.isEmpty(); - if( emptyUrl ) st |= BuildFolderEmpty; + if (emptyUrl) + st |= BuildFolderEmpty; - bool dirEmpty = false, dirExists= false, dirRelative = false; + bool dirEmpty = false; + bool dirExists = false; + bool dirRelative = false; QString srcDir; - if(!emptyUrl) - { + QString installDir; + QString buildType; + + if (!emptyUrl) { QDir d(chosenBuildFolder.toLocalFile()); dirExists = d.exists(); dirEmpty = dirExists && d.count()<=2; dirRelative = d.isRelative(); - if(!dirEmpty && dirExists && !dirRelative) - { - bool hasCache=QFile::exists(Path(chosenBuildFolder, "CMakeCache.txt").toLocalFile()); - if(hasCache) - { - QString proposed=m_srcFolder.toLocalFile(); - - srcDir = buildDirProject(chosenBuildFolder); - if(!srcDir.isEmpty()) - { - if(QDir(srcDir).canonicalPath()==QDir(proposed).canonicalPath()) - { - st |= CorrectBuildDir | BuildDirCreated; - } - } - else - { + + if (!dirEmpty && dirExists && !dirRelative) { + bool hasCache = QFile::exists(Path(chosenBuildFolder, "CMakeCache.txt").toLocalFile()); + if (hasCache) { + QString proposed = m_srcFolder.toLocalFile(); + + buildDirVariables(chosenBuildFolder, srcDir, installDir, buildType); + + if (!srcDir.isEmpty()) { + if (QDir(srcDir).canonicalPath() == QDir(proposed).canonicalPath()) + st |= CorrectBuildDir | BuildDirCreated; + } else qCWarning(CMAKE) << "maybe you are trying a damaged CMakeCache.txt file. Proper: "; - } + + if (!installDir.isEmpty() && QDir(installDir).exists()) + m_chooserUi->installPrefix->setUrl(QUrl::fromLocalFile(installDir)); + + m_chooserUi->buildType->setCurrentText(buildType); } } - if(m_alreadyUsed.contains(chosenBuildFolder.toLocalFile())) { - st=DirAlreadyCreated; - } - } - else - { + if (m_alreadyUsed.contains(chosenBuildFolder.toLocalFile())) + st = DirAlreadyCreated; + } else { setStatus(i18n("You need to specify a build directory."), false); return; } - - if(st & (BuildDirCreated | CorrectBuildDir)) - { + if (st & (BuildDirCreated | CorrectBuildDir)) { setStatus(i18n("Using an already created build directory."), true); m_chooserUi->installPrefix->setEnabled(false); m_chooserUi->buildType->setEnabled(false); - } - else - { + } else { bool correct = (dirEmpty || !dirExists) && !(st & DirAlreadyCreated) && !dirRelative; - - if(correct) - { + if (correct) { st |= CorrectBuildDir; setStatus(i18n("Creating a new build directory."), true); - } - else - { - //Useful to explain what's going wrong - if(st & DirAlreadyCreated) + } else { + // Useful to explain what's going wrong + if (st & DirAlreadyCreated) setStatus(i18n("Build directory already configured."), false); else if (!srcDir.isEmpty()) setStatus(i18n("This build directory is for %1, "