diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index d18e3e8fd35750a73b6239c265921ddeebd98248..9080f440c3b32f00b176c26383a9618fea234a7f 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -32,6 +32,7 @@ #include "cmakeopenprojectwizard.h" #include "cmakeproject.h" +#include "cmakeprojectconstants.h" #include <projectexplorer/buildsteplist.h> #include <projectexplorer/gnumakeparser.h> @@ -50,12 +51,11 @@ using namespace CMakeProjectManager; using namespace Internal; namespace { -const char CMAKE_BC_ID[] = "CMakeProjectManager.CMakeBuildConfiguration"; const char BUILD_DIRECTORY_KEY[] = "CMakeProjectManager.CMakeBuildConfiguration.BuildDirectory"; } // namespace CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent) : - BuildConfiguration(parent, Core::Id(CMAKE_BC_ID)), m_useNinja(false) + BuildConfiguration(parent, Core::Id(Constants::CMAKE_BC_ID)), m_useNinja(false) { m_buildDirectory = static_cast<CMakeProject *>(parent->project())->defaultBuildDirectory(); } @@ -161,12 +161,12 @@ QList<Core::Id> CMakeBuildConfigurationFactory::availableCreationIds(const Proje { if (!canHandle(parent)) return QList<Core::Id>(); - return QList<Core::Id>() << Core::Id(CMAKE_BC_ID); + return QList<Core::Id>() << Core::Id(Constants::CMAKE_BC_ID); } QString CMakeBuildConfigurationFactory::displayNameForId(const Core::Id id) const { - if (id == CMAKE_BC_ID) + if (id == Constants::CMAKE_BC_ID) return tr("Build"); return QString(); } @@ -175,7 +175,7 @@ bool CMakeBuildConfigurationFactory::canCreate(const ProjectExplorer::Target *pa { if (!canHandle(parent)) return false; - if (id == CMAKE_BC_ID) + if (id == Constants::CMAKE_BC_ID) return true; return false; } @@ -199,6 +199,17 @@ CMakeBuildConfiguration *CMakeBuildConfigurationFactory::create(ProjectExplorer: if (!ok || buildConfigurationName.isEmpty()) return 0; + CMakeOpenProjectWizard::BuildInfo info; + info.sourceDirectory = project->projectDirectory(); + info.environment = Utils::Environment::systemEnvironment(); + info.buildDirectory = project->defaultBuildDirectory(); + info.kit = parent->kit(); + info.useNinja = false; // This is ignored anyway + + CMakeOpenProjectWizard copw(project->projectManager(), CMakeOpenProjectWizard::ChangeDirectory, info); + if (copw.exec() != QDialog::Accepted) + return 0; + CMakeBuildConfiguration *bc = new CMakeBuildConfiguration(parent); bc->setDisplayName(buildConfigurationName); @@ -213,16 +224,8 @@ CMakeBuildConfiguration *CMakeBuildConfigurationFactory::create(ProjectExplorer: cleanMakeStep->setAdditionalArguments("clean"); cleanMakeStep->setClean(true); - CMakeOpenProjectWizard copw(project->projectManager(), - project->projectDirectory(), - bc->buildDirectory(), - bc); - if (copw.exec() != QDialog::Accepted) { - delete bc; - return 0; - } - bc->setBuildDirectory(copw.buildDirectory()); + bc->setUseNinja(copw.useNinja()); // Default to all if (project->hasBuildTarget("all")) diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp index de16775854567dc94647a33f67a6efbfadc33a3d..6ad1d0a7cb5fe4e5693467c84f8c1b6dba373f92 100644 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.cpp @@ -49,6 +49,7 @@ #include <QDateTime> #include <QSettings> #include <QStringList> +#include <QApplication> using namespace CMakeProjectManager; using namespace CMakeProjectManager::Internal; @@ -67,17 +68,21 @@ using namespace CMakeProjectManager::Internal; namespace CMakeProjectManager { namespace Internal { - class GeneratorInfo { public: - GeneratorInfo() - : m_kit(0), m_isNinja(false) {} - explicit GeneratorInfo(ProjectExplorer::Kit *kit, bool ninja = false) - : m_kit(kit), m_isNinja(ninja) {} + enum Ninja { NoNinja, OfferNinja, ForceNinja }; + static QList<GeneratorInfo> generatorInfosFor(ProjectExplorer::Kit *k, Ninja n, bool hasCodeBlocks); + + GeneratorInfo(); + explicit GeneratorInfo(ProjectExplorer::Kit *kit, bool ninja = false); + + ProjectExplorer::Kit *kit() const; + bool isNinja() const; - ProjectExplorer::Kit *kit() const { return m_kit; } - bool isNinja() const { return m_isNinja; } + QString displayName() const; + QString generatorArgument() const; + QString generator() const; private: ProjectExplorer::Kit *m_kit; @@ -89,12 +94,121 @@ namespace Internal { Q_DECLARE_METATYPE(CMakeProjectManager::Internal::GeneratorInfo); +GeneratorInfo::GeneratorInfo() + : m_kit(0), m_isNinja(false) +{} + +GeneratorInfo::GeneratorInfo(ProjectExplorer::Kit *kit, bool ninja) + : m_kit(kit), m_isNinja(ninja) +{} + +ProjectExplorer::Kit *GeneratorInfo::kit() const +{ + return m_kit; +} + +bool GeneratorInfo::isNinja() const { + return m_isNinja; +} + +QString GeneratorInfo::generator() const +{ + if (!m_kit) + return QString(); + ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(m_kit); + ProjectExplorer::Abi targetAbi = tc->targetAbi(); + if (m_isNinja) { + return QLatin1String("Ninja"); + } else if (targetAbi.os() == ProjectExplorer::Abi::WindowsOS) { + if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2005Flavor + || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2008Flavor + || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2010Flavor + || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2012Flavor) { + return QLatin1String("NMake Makefiles"); + } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { +#ifdef Q_OS_WIN + return QLatin1String("MinGW Makefiles"); +#else + return QLatin1String("Unix Makefiles"); +#endif + } + } + return QLatin1String("Unix Makefiles"); +} -CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, CMakeBuildConfiguration *bc) +QString GeneratorInfo::generatorArgument() const +{ + QString tmp = generator(); + if (tmp.isEmpty()) + return tmp; + return QLatin1String("-GCodeBlocks - ") + tmp; +} + +QString GeneratorInfo::displayName() const +{ + if (!m_kit) + return QString(); + if (m_isNinja) + return QApplication::tr("Ninja (%1)").arg(m_kit->displayName()); + ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(m_kit); + ProjectExplorer::Abi targetAbi = tc->targetAbi(); + if (targetAbi.os() == ProjectExplorer::Abi::WindowsOS) { + if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2005Flavor + || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2008Flavor + || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2010Flavor + || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2012Flavor) { + return QApplication::tr("NMake Generator (%1)").arg(m_kit->displayName()); + } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { +#ifdef Q_OS_WIN + return QApplication::tr("MinGW Generator (%1)").arg(m_kit->displayName()); +#else + return QApplication::tr("Unix Generator (%1)").arg(m_kit->displayName()); +#endif + } + } else { + // Non windows + return QApplication::tr("Unix Generator (%1)").arg(m_kit->displayName()); + } + return QString(); +} + +QList<GeneratorInfo> GeneratorInfo::generatorInfosFor(ProjectExplorer::Kit *k, Ninja n, bool hasCodeBlocks) +{ + QList<GeneratorInfo> results; + ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k); + ProjectExplorer::Abi targetAbi = tc->targetAbi(); + if (n != ForceNinja) { + if (targetAbi.os() == ProjectExplorer::Abi::WindowsOS) { + if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2005Flavor + || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2008Flavor + || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2010Flavor + || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2012Flavor) { + if (hasCodeBlocks) + results << GeneratorInfo(k); + } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { + results << GeneratorInfo(k); + } + } else { + // Non windows + results << GeneratorInfo(k); + } + } + if (n != NoNinja) + results << GeneratorInfo(k, true); + return results; +} + +////////////// +/// CMakeOpenProjectWizard +////////////// + +CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, Utils::Environment env) : m_cmakeManager(cmakeManager), m_sourceDirectory(sourceDirectory), m_creatingCbpFiles(false), - m_buildConfiguration(bc) + m_environment(env), + m_useNinja(false), + m_kit(0) { int startid; if (hasInSourceBuild()) { @@ -120,37 +234,31 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const init(); } -CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, - const QString &buildDirectory, CMakeOpenProjectWizard::Mode mode, - CMakeBuildConfiguration *bc) +CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, CMakeOpenProjectWizard::Mode mode, + const BuildInfo &info) : m_cmakeManager(cmakeManager), - m_sourceDirectory(sourceDirectory), + m_sourceDirectory(info.sourceDirectory), m_creatingCbpFiles(true), - m_buildConfiguration(bc) + m_environment(info.environment), + m_useNinja(info.useNinja), + m_kit(info.kit) { - CMakeRunPage::Mode rmode; if (mode == CMakeOpenProjectWizard::NeedToCreate) rmode = CMakeRunPage::Recreate; else if (mode == CMakeOpenProjectWizard::WantToUpdate) rmode = CMakeRunPage::WantToUpdate; - else + else if (mode == CMakeOpenProjectWizard::NeedToUpdate) rmode = CMakeRunPage::NeedToUpdate; - addPage(new CMakeRunPage(this, rmode, buildDirectory)); - init(); -} + else + rmode = CMakeRunPage::ChangeDirectory; -CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, - const QString &oldBuildDirectory, - CMakeBuildConfiguration *bc) - : m_cmakeManager(cmakeManager), - m_sourceDirectory(sourceDirectory), - m_creatingCbpFiles(true), - m_buildConfiguration(bc) -{ - m_buildDirectory = oldBuildDirectory; - addPage(new ShadowBuildPage(this, true)); - addPage(new CMakeRunPage(this, CMakeRunPage::ChangeDirectory)); + if (mode == CMakeOpenProjectWizard::ChangeDirectory) { + m_buildDirectory = info.buildDirectory; + addPage(new ShadowBuildPage(this, true)); + } + + addPage(new CMakeRunPage(this, rmode, info.buildDirectory)); init(); } @@ -216,6 +324,16 @@ void CMakeOpenProjectWizard::setBuildDirectory(const QString &directory) m_buildDirectory = directory; } +bool CMakeOpenProjectWizard::useNinja() const +{ + return m_useNinja; +} + +void CMakeOpenProjectWizard::setUseNinja(bool b) +{ + m_useNinja = b; +} + QString CMakeOpenProjectWizard::arguments() const { return m_arguments; @@ -228,12 +346,17 @@ void CMakeOpenProjectWizard::setArguments(const QString &args) Utils::Environment CMakeOpenProjectWizard::environment() const { - return m_buildConfiguration->environment(); + return m_environment; +} + +ProjectExplorer::Kit *CMakeOpenProjectWizard::kit() const +{ + return m_kit; } -CMakeBuildConfiguration *CMakeOpenProjectWizard::buildConfiguration() const +void CMakeOpenProjectWizard::setKit(ProjectExplorer::Kit *kit) { - return m_buildConfiguration; + m_kit = kit; } InSourceBuildPage::InSourceBuildPage(CMakeOpenProjectWizard *cmakeWizard) @@ -284,6 +407,7 @@ CMakeRunPage::CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard, Mode mode, const : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard), m_complete(false), + m_optionalCMake(false), m_mode(mode), m_buildDirectory(buildDirectory) { @@ -366,17 +490,41 @@ void CMakeRunPage::initWidgets() setMinimumSize(600, 400); } +QString CMakeRunPage::cachedGeneratorFromFile(const QString &cache) +{ + QFile fi(cache); + if (fi.exists()) { + // Cache exists, then read it... + if (fi.open(QIODevice::ReadOnly | QIODevice::Text)) { + while (!fi.atEnd()) { + QString line = fi.readLine(); + if (line.startsWith("CMAKE_GENERATOR:INTERNAL=")) { + int splitpos = line.indexOf('='); + if (splitpos != -1) { + QString cachedGenerator = line.mid(splitpos + 1).trimmed(); + if (!cachedGenerator.isEmpty()) + return cachedGenerator; + } + } + } + } + } + return QString(); +} + void CMakeRunPage::initializePage() { if (m_mode == Initial) { - m_complete = m_cmakeWizard->existsUpToDateXmlFile(); + bool upToDateXmlFile = m_cmakeWizard->existsUpToDateXmlFile();; m_buildDirectory = m_cmakeWizard->buildDirectory(); - if (m_cmakeWizard->existsUpToDateXmlFile()) { + if (upToDateXmlFile) { m_descriptionLabel->setText( tr("The directory %1 already contains a cbp file, which is recent enough. " - "You can pass special arguments or change the used tool chain here and rerun CMake. " + "You can pass special arguments and rerun CMake. " "Or simply finish the wizard directly.").arg(m_buildDirectory)); + m_optionalCMake = true; + m_complete = true; } else { m_descriptionLabel->setText( tr("The directory %1 does not contain a cbp file. Qt Creator needs to create this file by running CMake. " @@ -404,71 +552,64 @@ void CMakeRunPage::initializePage() m_descriptionLabel->setText(tr("Refreshing cbp file in %1.").arg(m_buildDirectory)); } - - // Try figuring out generator and toolchain from CMakeCache.txt - QString cachedGenerator; - QString cmakeCxxCompiler; - QFile fi(m_buildDirectory + "/CMakeCache.txt"); - if (fi.exists()) { - // Cache exists, then read it... - if (fi.open(QIODevice::ReadOnly | QIODevice::Text)) { - while (!fi.atEnd()) { - QString line = fi.readLine(); - if (line.startsWith("CMAKE_GENERATOR:INTERNAL=")) { - int splitpos = line.indexOf('='); - if (splitpos != -1) - cachedGenerator = line.mid(splitpos + 1).trimmed(); - } - if (line.startsWith("CMAKE_CXX_COMPILER:FILEPATH=")) { - int splitpos = line.indexOf("="); - if (splitpos != -1) - cmakeCxxCompiler = line.mid(splitpos +1).trimmed(); - } - if (!cachedGenerator.isEmpty() && !cmakeCxxCompiler.isEmpty()) - break; - } - } - } - // Build the list of generators/toolchains we want to offer - // restrict toolchains based on CMAKE_CXX_COMPILER ? - Q_UNUSED(cmakeCxxCompiler); m_generatorComboBox->clear(); - bool hasCodeBlocksGenerator = m_cmakeWizard->cmakeManager()->hasCodeBlocksMsvcGenerator(); - QList<ProjectExplorer::Kit *> kitList = - ProjectExplorer::KitManager::instance()->kits(); + bool hasCodeBlocksGenerator = m_cmakeWizard->cmakeManager()->hasCodeBlocksMsvcGenerator(); + bool hasNinjaGenerator = m_cmakeWizard->cmakeManager()->hasCodeBlocksNinjaGenerator(); - foreach (ProjectExplorer::Kit *k, kitList) { - ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k); - if (!tc) - continue; - ProjectExplorer::Abi targetAbi = tc->targetAbi(); - if (targetAbi.os() == ProjectExplorer::Abi::WindowsOS) { - if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2005Flavor - || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2008Flavor - || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2010Flavor - || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2012Flavor) { - if (hasCodeBlocksGenerator && (cachedGenerator.isEmpty() || cachedGenerator == "NMake Makefiles")) - m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(k->displayName()), qVariantFromValue(GeneratorInfo(k))); - } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { -#ifdef Q_OS_WIN - if (cachedGenerator.isEmpty() || cachedGenerator == "MinGW Makefiles") - m_generatorComboBox->addItem(tr("MinGW Generator (%1)").arg(k->displayName()), qVariantFromValue(GeneratorInfo(k))); -#else - if (cachedGenerator.isEmpty() || cachedGenerator == "Unix Makefiles") - m_generatorComboBox->addItem(tr("Unix Generator (%1)").arg(k->displayName()), qVariantFromValue(GeneratorInfo(k))); -#endif - } - } else { - // Non windows - if (cachedGenerator.isEmpty() || cachedGenerator == "Unix Makefiles") - m_generatorComboBox->addItem(tr("Unix Generator (%1)").arg(k->displayName()), qVariantFromValue(GeneratorInfo(k))); + if (m_mode == Initial) { + // Try figuring out generator and toolchain from CMakeCache.txt + QString cachedGenerator = cachedGeneratorFromFile(m_buildDirectory + "/CMakeCache.txt"); + + m_generatorComboBox->show(); + QList<ProjectExplorer::Kit *> kitList = + ProjectExplorer::KitManager::instance()->kits(); + + foreach (ProjectExplorer::Kit *k, kitList) { + ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k); + if (!tc) + continue; + QList<GeneratorInfo> infos = GeneratorInfo::generatorInfosFor(k, + hasNinjaGenerator ? GeneratorInfo::OfferNinja : GeneratorInfo::NoNinja, + hasCodeBlocksGenerator); + + foreach (const GeneratorInfo &info, infos) + if (cachedGenerator.isEmpty() || info.generator() == cachedGenerator) + m_generatorComboBox->addItem(info.displayName(), qVariantFromValue(info)); + } + } else { + // Note: We don't compare the actually cached generator to what is set in the buildconfiguration + // We assume that the buildconfiguration is correct + GeneratorInfo::Ninja ninja; + if (m_mode == CMakeRunPage::NeedToUpdate || m_mode == CMakeRunPage::WantToUpdate) { + ninja = m_cmakeWizard->useNinja() ? GeneratorInfo::ForceNinja : GeneratorInfo::NoNinja; + } else { // Recreate, ChangeDirectory + // Note: ReCreate is technically just a removed .cbp file, we assume the cache + // got removed too. If the cache still exists the error message from cmake should + // be a good hint to change the generator + ninja = hasNinjaGenerator ? GeneratorInfo::OfferNinja : GeneratorInfo::NoNinja; } - if (m_cmakeWizard->cmakeManager()->hasCodeBlocksNinjaGenerator() && - (cachedGenerator.isEmpty() || cachedGenerator == "Ninja")) - m_generatorComboBox->addItem(tr("Ninja (%1)").arg(k->displayName()), qVariantFromValue(GeneratorInfo(k, true))); + + QList<GeneratorInfo> infos = GeneratorInfo::generatorInfosFor(m_cmakeWizard->kit(), + ninja, + true); + foreach (const GeneratorInfo &info, infos) + m_generatorComboBox->addItem(info.displayName(), qVariantFromValue(info)); + } +} + +bool CMakeRunPage::validatePage() +{ + if (m_optionalCMake) { + int index = m_generatorComboBox->currentIndex(); + if (index == -1) + return false; + GeneratorInfo generatorInfo = m_generatorComboBox->itemData(index).value<GeneratorInfo>(); + m_cmakeWizard->setKit(generatorInfo.kit()); + m_cmakeWizard->setUseNinja(generatorInfo.isNinja()); } + return QWizardPage::validatePage(); } void CMakeRunPage::runCMake() @@ -477,54 +618,39 @@ void CMakeRunPage::runCMake() // We asked the user for the cmake executable m_cmakeWizard->cmakeManager()->setCMakeExecutable(m_cmakeExecutable->path()); + m_optionalCMake = false; + m_complete = false; + + Utils::Environment env = m_cmakeWizard->environment(); int index = m_generatorComboBox->currentIndex(); - ProjectExplorer::Kit *k = 0; - GeneratorInfo generatorInfo; - if (index >= 0) { - generatorInfo = m_generatorComboBox->itemData(index).value<GeneratorInfo>(); - k = generatorInfo.kit(); - } - if (!k) { + if (index == -1) { m_output->appendPlainText(tr("No generator selected.")); return; } + GeneratorInfo generatorInfo = m_generatorComboBox->itemData(index).value<GeneratorInfo>(); + m_cmakeWizard->setKit(generatorInfo.kit()); + m_cmakeWizard->setUseNinja(generatorInfo.isNinja()); - ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k); + // If mode is initial the user chooses the kit, otherwise it's already choosen + // and the environment already contains the kit + if (m_mode == Initial) + generatorInfo.kit()->addToEnvironment(env); m_runCMake->setEnabled(false); m_argumentsLineEdit->setEnabled(false); m_generatorComboBox->setEnabled(false); - CMakeManager *cmakeManager = m_cmakeWizard->cmakeManager(); - - QString generator = QLatin1String("-GCodeBlocks - Unix Makefiles"); - if (generatorInfo.isNinja()) { - m_cmakeWizard->buildConfiguration()->setUseNinja(true); - generator = "-GCodeBlocks - Ninja"; - } else if (tc->targetAbi().os() == ProjectExplorer::Abi::WindowsOS) { - m_cmakeWizard->buildConfiguration()->setUseNinja(false); - if (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { -#ifdef Q_OS_WIN - generator = QLatin1String("-GCodeBlocks - MinGW Makefiles"); -#else - generator = QLatin1String("-GCodeBlocks - Unix Makefiles"); -#endif - } else { - generator = QLatin1String("-GCodeBlocks - NMake Makefiles"); - } - } - - Utils::Environment env = m_cmakeWizard->environment(); - tc->addToEnvironment(env); m_output->clear(); + CMakeManager *cmakeManager = m_cmakeWizard->cmakeManager(); if (m_cmakeWizard->cmakeManager()->isCMakeExecutableValid()) { m_cmakeProcess = new Utils::QtcProcess(); connect(m_cmakeProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(cmakeReadyReadStandardOutput())); connect(m_cmakeProcess, SIGNAL(readyReadStandardError()), this, SLOT(cmakeReadyReadStandardError())); connect(m_cmakeProcess, SIGNAL(finished(int)), this, SLOT(cmakeFinished())); - cmakeManager->createXmlFile(m_cmakeProcess, m_argumentsLineEdit->text(), m_cmakeWizard->sourceDirectory(), m_buildDirectory, env, generator); + cmakeManager->createXmlFile(m_cmakeProcess, m_argumentsLineEdit->text(), m_cmakeWizard->sourceDirectory(), + m_buildDirectory, env, generatorInfo.generatorArgument()); } else { m_runCMake->setEnabled(true); m_argumentsLineEdit->setEnabled(true); diff --git a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h index 9b2c629259ac24d5eb0e535259f008af3e519a9e..dd013da7bcb70b9fd2d27a5cac399223bc7505da 100644 --- a/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h +++ b/src/plugins/cmakeprojectmanager/cmakeopenprojectwizard.h @@ -31,9 +31,13 @@ #ifndef CMAKEOPENPROJECTWIZARD_H #define CMAKEOPENPROJECTWIZARD_H +#include "cmakebuildconfiguration.h" + #include <utils/environment.h> #include <utils/wizard.h> #include <utils/qtcprocess.h> +#include <projectexplorer/target.h> +#include <projectexplorer/project.h> #include <QPushButton> #include <QComboBox> @@ -47,14 +51,13 @@ class PathChooser; } namespace ProjectExplorer { -class ToolChain; +class Kit; } namespace CMakeProjectManager { namespace Internal { class CMakeManager; -class CMakeBuildConfiguration; class CMakeOpenProjectWizard : public Utils::Wizard { @@ -70,28 +73,52 @@ public: Nothing, NeedToCreate, NeedToUpdate, - WantToUpdate + WantToUpdate, + ChangeDirectory + }; + + class BuildInfo + { + public: + BuildInfo() + {} + + BuildInfo(CMakeBuildConfiguration *bc) + : sourceDirectory(bc->target()->project()->projectDirectory()) + , buildDirectory(bc->buildDirectory()) + , environment(bc->environment()) + , useNinja(bc->useNinja()) + , kit(bc->target()->kit()) + {} + + QString sourceDirectory; + QString buildDirectory; + Utils::Environment environment; + bool useNinja; + ProjectExplorer::Kit *kit; }; - // used at importing a project without a .user file - CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, CMakeBuildConfiguration *bc); + /// used at importing a project without a .user file + CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, Utils::Environment env); + /// used to update if we have already a .user file /// recreates or updates the cbp file - CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const QString &buildDirectory, Mode mode, CMakeBuildConfiguration *bc); - /// used to change the build directory of one buildconfiguration - /// shows a page for selecting a directory - /// then the run cmake page - CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const QString &oldBuildDirectory, CMakeBuildConfiguration *bc); + /// Also used to change the build directory of one buildconfiguration or create a new buildconfiguration + CMakeOpenProjectWizard(CMakeManager *cmakeManager, Mode mode, const BuildInfo &info); + virtual int nextId() const; QString buildDirectory() const; QString sourceDirectory() const; void setBuildDirectory(const QString &directory); + bool useNinja() const; + void setUseNinja(bool b); CMakeManager *cmakeManager() const; QString arguments() const; void setArguments(const QString &args); Utils::Environment environment() const; - CMakeBuildConfiguration *buildConfiguration() const; + ProjectExplorer::Kit *kit() const; + void setKit(ProjectExplorer::Kit *kit); bool existsUpToDateXmlFile() const; private: @@ -102,7 +129,9 @@ private: QString m_sourceDirectory; QString m_arguments; bool m_creatingCbpFiles; - CMakeBuildConfiguration *m_buildConfiguration; + Utils::Environment m_environment; + bool m_useNinja; + ProjectExplorer::Kit *m_kit; }; class InSourceBuildPage : public QWizardPage @@ -134,6 +163,7 @@ public: explicit CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard, Mode mode = Initial, const QString &buildDirectory = QString()); virtual void initializePage(); + virtual bool validatePage(); virtual void cleanupPage(); virtual bool isComplete() const; private slots: @@ -143,6 +173,7 @@ private slots: void cmakeReadyReadStandardError(); private: void initWidgets(); + QString cachedGeneratorFromFile(const QString &cache); CMakeOpenProjectWizard *m_cmakeWizard; QPlainTextEdit *m_output; QPushButton *m_runCMake; @@ -153,6 +184,7 @@ private: QLabel *m_descriptionLabel; QLabel *m_exitCodeLabel; bool m_complete; + bool m_optionalCMake; Mode m_mode; QString m_buildDirectory; }; diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index e33c7deef48e3dd3f69cf30a3aea6d85e456f0f0..5d551ea6cb5599168766950c17876c394ef93b1b 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -49,6 +49,7 @@ #include <projectexplorer/kitmanager.h> #include <projectexplorer/toolchain.h> #include <projectexplorer/target.h> +#include <projectexplorer/deployconfiguration.h> #include <qtsupport/customexecutablerunconfiguration.h> #include <cpptools/ModelManagerInterface.h> #include <extensionsystem/pluginmanager.h> @@ -145,8 +146,6 @@ void CMakeProject::changeActiveBuildConfiguration(ProjectExplorer::BuildConfigur CMakeBuildConfiguration *cmakebc = static_cast<CMakeBuildConfiguration *>(bc); // Pop up a dialog asking the user to rerun cmake - QFileInfo sourceFileInfo(m_fileName); - QString cbpFile = CMakeManager::findCbpFile(QDir(bc->buildDirectory())); QFileInfo cbpFileFi(cbpFile); CMakeOpenProjectWizard::Mode mode = CMakeOpenProjectWizard::Nothing; @@ -162,13 +161,12 @@ void CMakeProject::changeActiveBuildConfiguration(ProjectExplorer::BuildConfigur } if (mode != CMakeOpenProjectWizard::Nothing) { - CMakeOpenProjectWizard copw(m_manager, - sourceFileInfo.absolutePath(), - cmakebc->buildDirectory(), - mode, - cmakebc); - copw.exec(); + CMakeOpenProjectWizard copw(m_manager, mode, + CMakeOpenProjectWizard::BuildInfo(cmakebc)); + if (copw.exec() == QDialog::Accepted) + cmakebc->setUseNinja(copw.useNinja()); // NeedToCreate can change the Ninja setting } + // reparse parseCMakeLists(); } @@ -190,7 +188,7 @@ void CMakeProject::changeBuildDirectory(CMakeBuildConfiguration *bc, const QStri QString CMakeProject::defaultBuildDirectory() const { - return projectDirectory() + QLatin1String("/qtcreator-build"); + return projectDirectory() + QLatin1String("-build"); } bool CMakeProject::parseCMakeLists() @@ -531,33 +529,59 @@ bool CMakeProject::fromMap(const QVariantMap &map) if (!Project::fromMap(map)) return false; - Kit *defaultKit = KitManager::instance()->defaultKit(); - if (!activeTarget() && defaultKit) - addTarget(createTarget(defaultKit)); - - // We have a user file, but we could still be missing the cbp file - // or simply run createXml with the saved settings - QFileInfo sourceFileInfo(m_fileName); - CMakeBuildConfiguration *activeBC = qobject_cast<CMakeBuildConfiguration *>(activeTarget()->activeBuildConfiguration()); - if (!activeBC) - return false; - QString cbpFile = CMakeManager::findCbpFile(QDir(activeBC->buildDirectory())); - QFileInfo cbpFileFi(cbpFile); - - CMakeOpenProjectWizard::Mode mode = CMakeOpenProjectWizard::Nothing; - if (!cbpFileFi.exists()) - mode = CMakeOpenProjectWizard::NeedToCreate; - else if (cbpFileFi.lastModified() < sourceFileInfo.lastModified()) - mode = CMakeOpenProjectWizard::NeedToUpdate; - - if (mode != CMakeOpenProjectWizard::Nothing) { - CMakeOpenProjectWizard copw(m_manager, - sourceFileInfo.absolutePath(), - activeBC->buildDirectory(), - mode, - activeBC); + bool hasUserFile = activeTarget(); + if (!hasUserFile) { + CMakeOpenProjectWizard copw(m_manager, projectDirectory(), Utils::Environment::systemEnvironment()); if (copw.exec() != QDialog::Accepted) return false; + Kit *k = copw.kit(); + Target *t = new Target(this, k); + CMakeBuildConfiguration *bc(new CMakeBuildConfiguration(t)); + bc->setDefaultDisplayName("all"); + bc->setUseNinja(copw.useNinja()); + bc->setBuildDirectory(copw.buildDirectory()); + ProjectExplorer::BuildStepList *buildSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); + ProjectExplorer::BuildStepList *cleanSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN); + + // Now create a standard build configuration + buildSteps->insertStep(0, new MakeStep(buildSteps)); + + MakeStep *cleanMakeStep = new MakeStep(cleanSteps); + cleanSteps->insertStep(0, cleanMakeStep); + cleanMakeStep->setAdditionalArguments("clean"); + cleanMakeStep->setClean(true); + + t->addBuildConfiguration(bc); + + DeployConfigurationFactory *fac = ExtensionSystem::PluginManager::instance()->getObject<DeployConfigurationFactory>(); + ProjectExplorer::DeployConfiguration *dc = fac->create(t, ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID); + t->addDeployConfiguration(dc); + + addTarget(t); + } else { + // We have a user file, but we could still be missing the cbp file + // or simply run createXml with the saved settings + QFileInfo sourceFileInfo(m_fileName); + CMakeBuildConfiguration *activeBC = qobject_cast<CMakeBuildConfiguration *>(activeTarget()->activeBuildConfiguration()); + if (!activeBC) + return false; + QString cbpFile = CMakeManager::findCbpFile(QDir(activeBC->buildDirectory())); + QFileInfo cbpFileFi(cbpFile); + + CMakeOpenProjectWizard::Mode mode = CMakeOpenProjectWizard::Nothing; + if (!cbpFileFi.exists()) + mode = CMakeOpenProjectWizard::NeedToCreate; + else if (cbpFileFi.lastModified() < sourceFileInfo.lastModified()) + mode = CMakeOpenProjectWizard::NeedToUpdate; + + if (mode != CMakeOpenProjectWizard::Nothing) { + CMakeOpenProjectWizard copw(m_manager, mode, + CMakeOpenProjectWizard::BuildInfo(activeBC)); + if (copw.exec() != QDialog::Accepted) + return false; + else + activeBC->setUseNinja(copw.useNinja()); + } } m_watcher = new QFileSystemWatcher(this); @@ -565,17 +589,13 @@ bool CMakeProject::fromMap(const QVariantMap &map) parseCMakeLists(); - if (hasBuildTarget("all")) { + if (!hasUserFile && hasBuildTarget("all")) { MakeStep *makeStep = qobject_cast<MakeStep *>( activeTarget()->activeBuildConfiguration()->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD)->at(0)); Q_ASSERT(makeStep); makeStep->setBuildTarget("all", true); } - foreach (Target *t, targets()) - connect(t, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)), - this, SLOT(changeActiveBuildConfiguration(ProjectExplorer::BuildConfiguration*))); - connect(Core::EditorManager::instance(), SIGNAL(editorAboutToClose(Core::IEditor*)), this, SLOT(editorAboutToClose(Core::IEditor*))); @@ -588,6 +608,22 @@ bool CMakeProject::fromMap(const QVariantMap &map) return true; } +bool CMakeProject::setupTarget(Target *t) +{ + CMakeBuildConfigurationFactory *factory + = ExtensionSystem::PluginManager::instance()->getObject<CMakeBuildConfigurationFactory>(); + CMakeBuildConfiguration *bc = factory->create(t, Constants::CMAKE_BC_ID, QLatin1String("all")); + if (!bc) + return false; + + t->addBuildConfiguration(bc); + + DeployConfigurationFactory *fac = ExtensionSystem::PluginManager::instance()->getObject<DeployConfigurationFactory>(); + ProjectExplorer::DeployConfiguration *dc = fac->create(t, ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID); + t->addDeployConfiguration(dc); + return true; +} + CMakeBuildTarget CMakeProject::buildTargetForTitle(const QString &title) { foreach (const CMakeBuildTarget &ct, m_buildTargets) @@ -903,25 +939,21 @@ void CMakeBuildSettingsWidget::init(BuildConfiguration *bc) void CMakeBuildSettingsWidget::openChangeBuildDirectoryDialog() { CMakeProject *project = static_cast<CMakeProject *>(m_buildConfiguration->target()->project()); - CMakeOpenProjectWizard copw(project->projectManager(), - project->projectDirectory(), - m_buildConfiguration->buildDirectory(), - m_buildConfiguration); + CMakeOpenProjectWizard copw(project->projectManager(), CMakeOpenProjectWizard::ChangeDirectory, + CMakeOpenProjectWizard::BuildInfo(m_buildConfiguration)); if (copw.exec() == QDialog::Accepted) { project->changeBuildDirectory(m_buildConfiguration, copw.buildDirectory()); + m_buildConfiguration->setUseNinja(copw.useNinja()); m_pathLineEdit->setText(m_buildConfiguration->buildDirectory()); } } void CMakeBuildSettingsWidget::runCMake() { - // TODO skip build directory CMakeProject *project = static_cast<CMakeProject *>(m_buildConfiguration->target()->project()); CMakeOpenProjectWizard copw(project->projectManager(), - project->projectDirectory(), - m_buildConfiguration->buildDirectory(), CMakeOpenProjectWizard::WantToUpdate, - m_buildConfiguration); + CMakeOpenProjectWizard::BuildInfo(m_buildConfiguration)); if (copw.exec() == QDialog::Accepted) project->parseCMakeLists(); } diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index 717d577b07c0f7dfe0b835489fa4ffc4fb908882..bebb747ebf8a357165c7bf64998d3b73ccbd179a 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -110,6 +110,7 @@ signals: protected: bool fromMap(const QVariantMap &map); + bool setupTarget(ProjectExplorer::Target *t); // called by CMakeBuildSettingsWidget void changeBuildDirectory(CMakeBuildConfiguration *bc, const QString &newBuildDirectory); diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h index 2e6db191d1994cc5c442fe0b0abd77295e2ea945..8ce6c946fa848063a4a08e34f6873f45471dacb0 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h @@ -45,6 +45,9 @@ const char RUNCMAKECONTEXTMENU[] = "CMakeProject.RunCMakeContextMenu"; // Project const char CMAKEPROJECT_ID[] = "CMakeProjectManager.CMakeProject"; +// Buildconfiguration +const char CMAKE_BC_ID[] = "CMakeProjectManager.CMakeBuildConfiguration"; + // Menu const char M_CONTEXT[] = "CMakeEditor.ContextMenu"; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index 98ee2ea382268ebb444dcc9aabd467a7ebdd3c9f..8e562737443bf846b8cf666c93ca6fe7f87aec74 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -119,11 +119,8 @@ void CMakeManager::runCMake(ProjectExplorer::Project *project) CMakeBuildConfiguration *bc = static_cast<CMakeBuildConfiguration *>(cmakeProject->activeTarget()->activeBuildConfiguration()); - CMakeOpenProjectWizard copw(this, - cmakeProject->projectDirectory(), - bc->buildDirectory(), - CMakeOpenProjectWizard::WantToUpdate, - bc); + CMakeOpenProjectWizard copw(this, CMakeOpenProjectWizard::WantToUpdate, + CMakeOpenProjectWizard::BuildInfo(bc)); if (copw.exec() == QDialog::Accepted) cmakeProject->parseCMakeLists(); } diff --git a/src/plugins/cmakeprojectmanager/makestep.cpp b/src/plugins/cmakeprojectmanager/makestep.cpp index 7c9bcd4b40f17275240ccdd1fcc9ff76e7dd8be2..cd173e298bfec9226411d5c845f3a43170ba10c7 100644 --- a/src/plugins/cmakeprojectmanager/makestep.cpp +++ b/src/plugins/cmakeprojectmanager/makestep.cpp @@ -93,20 +93,21 @@ MakeStep::MakeStep(BuildStepList *bsl, MakeStep *bs) : void MakeStep::ctor() { m_percentProgress = QRegExp("^\\[\\s*(\\d*)%\\]"); - m_useNinja = false; m_ninjaProgress = QRegExp ("^\\[\\s*(\\d*)/\\s*(\\d*)"); m_ninjaProgressString = QLatin1String("[%s/%t "); // ninja: [33/100 //: Default display name for the cmake make step. setDefaultDisplayName(tr("Make")); - BuildConfiguration *bc = cmakeBuildConfiguration(); + CMakeBuildConfiguration *bc = cmakeBuildConfiguration(); if (bc) { + m_useNinja = bc->useNinja(); m_activeConfiguration = 0; connect(bc, SIGNAL(useNinjaChanged(bool)), this, SLOT(setUseNinja(bool))); } else { // That means the step is in the deploylist, so we listen to the active build config // changed signal and react to the activeBuildConfigurationChanged() signal of the buildconfiguration m_activeConfiguration = targetsActiveBuildConfiguration(); + m_useNinja = m_activeConfiguration->useNinja(); connect (target(), SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)), this, SLOT(activeBuildConfigurationChanged())); activeBuildConfigurationChanged(); diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 0fd4265785da252878020edff53e8b2b2d0d180e..8f148f65bedcc3051ae01c0ce1cfd90131d74cbe 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -250,11 +250,21 @@ Target *Project::createTarget(Kit *k) return 0; Target *t = new Target(this, k); - t->createDefaultSetup(); - + if (!setupTarget(t)) { + delete t; + return 0; + } return t; } +bool Project::setupTarget(Target *t) +{ + t->updateDefaultBuildConfigurations(); + t->updateDefaultDeployConfigurations(); + t->updateDefaultRunConfigurations(); + return true; +} + Target *Project::restoreTarget(const QVariantMap &data) { Core::Id id = idFromMap(data); diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index 7cec2182a9c8580d21455778d02435167f4e8750..5210783735642fab0259618531d1cf1389efa1a3 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -147,6 +147,7 @@ signals: protected: virtual bool fromMap(const QVariantMap &map); + virtual bool setupTarget(Target *t); virtual void setProjectContext(Core::Context context); virtual void setProjectLanguage(Core::Context language); diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp index 155cbb32bb5035d9c481147d0af1506d212ef63c..acd77850006c37eede616180084cf4750b017690 100644 --- a/src/plugins/projectexplorer/target.cpp +++ b/src/plugins/projectexplorer/target.cpp @@ -515,13 +515,6 @@ QVariantMap Target::toMap() const return map; } -void Target::createDefaultSetup() -{ - updateDefaultBuildConfigurations(); - updateDefaultDeployConfigurations(); - updateDefaultRunConfigurations(); -} - void Target::updateDefaultBuildConfigurations() { IBuildConfigurationFactory *bcFactory = IBuildConfigurationFactory::find(this); diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h index 98a874c15755e82c78957f4878fc1f4d34f6291b..0d45484f2812798169c2db2512bebae262d33613 100644 --- a/src/plugins/projectexplorer/target.h +++ b/src/plugins/projectexplorer/target.h @@ -113,7 +113,6 @@ public: QVariantMap toMap() const; - void createDefaultSetup(); void updateDefaultBuildConfigurations(); void updateDefaultDeployConfigurations(); void updateDefaultRunConfigurations();