ToolChain: Refactor toolchain support

Refactor ToolChains in Qt Creator:

 * Allow for several toolchains of the same type
 * Be smarter wrt. guessing what kind of output a toolchain
   produces. This allows us to eventually handle e.g. embedded
   linux setups way better than before.
 * Be smarter wrt. guessing what kind of environment a Qt version
   needs.
 * Improve auto-detection of toolchains a bit
 * Decide on which debugger to use based on the kind of output
   produced by the compiler.
 * Add options page to configure toolchains
 * Remove toolchain related options from the Qt version dialog

Reviewed-by: dt
This commit is contained in:
Tobias Hunger
2011-02-01 18:36:00 +01:00
parent be31c80b02
commit 8d0c477245
112 changed files with 6498 additions and 3687 deletions

View File

@@ -38,7 +38,7 @@
#include "cmaketarget.h"
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
#include <projectexplorer/buildsteplist.h>
#include <utils/qtcassert.h>
@@ -50,7 +50,7 @@ using namespace Internal;
namespace {
const char * const CMAKE_BC_ID("CMakeProjectManager.CMakeBuildConfiguration");
const char * const MSVC_VERSION_KEY("CMakeProjectManager.CMakeBuildConfiguration.MsvcVersion");
const char * const TOOLCHAIN_KEY("CMakeProjectManager.CMakeBuildConfiguration.ToolChain");
const char * const BUILD_DIRECTORY_KEY("CMakeProjectManager.CMakeBuildConfiguration.BuildDirectory");
} // namespace
@@ -74,7 +74,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(CMakeTarget *parent, CMakeBuild
QVariantMap CMakeBuildConfiguration::toMap() const
{
QVariantMap map(ProjectExplorer::BuildConfiguration::toMap());
map.insert(QLatin1String(MSVC_VERSION_KEY), m_msvcVersion);
map.insert(QLatin1String(TOOLCHAIN_KEY), m_toolChain ? m_toolChain->id() : QString());
map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory);
return map;
}
@@ -84,7 +84,8 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
if (!BuildConfiguration::fromMap(map))
return false;
m_msvcVersion = map.value(QLatin1String(MSVC_VERSION_KEY)).toString();
m_toolChain = ProjectExplorer::ToolChainManager::instance()->
findToolChain(map.value(QLatin1String(TOOLCHAIN_KEY)).toString());
m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), cmakeTarget()->defaultBuildDirectory()).toString();
return true;
@@ -105,41 +106,6 @@ QString CMakeBuildConfiguration::buildDirectory() const
return m_buildDirectory;
}
ProjectExplorer::ToolChainType CMakeBuildConfiguration::toolChainType() const
{
if (m_toolChain)
return m_toolChain->type();
return ProjectExplorer::ToolChain_UNKNOWN;
}
ProjectExplorer::ToolChain *CMakeBuildConfiguration::toolChain() const
{
updateToolChain();
return m_toolChain;
}
void CMakeBuildConfiguration::updateToolChain() const
{
ProjectExplorer::ToolChain *newToolChain = 0;
if (msvcVersion().isEmpty()) {
#ifdef Q_OS_WIN
newToolChain = ProjectExplorer::ToolChain::createMinGWToolChain("gcc", QString());
#else
newToolChain = ProjectExplorer::ToolChain::createGccToolChain("gcc");
#endif
} else { // msvc
newToolChain = ProjectExplorer::ToolChain::createMSVCToolChain(m_msvcVersion, false);
}
if (ProjectExplorer::ToolChain::equals(newToolChain, m_toolChain)) {
delete newToolChain;
newToolChain = 0;
} else {
delete m_toolChain;
m_toolChain = newToolChain;
}
}
void CMakeBuildConfiguration::setBuildDirectory(const QString &buildDirectory)
{
if (m_buildDirectory == buildDirectory)
@@ -149,21 +115,6 @@ void CMakeBuildConfiguration::setBuildDirectory(const QString &buildDirectory)
emit environmentChanged();
}
QString CMakeBuildConfiguration::msvcVersion() const
{
return m_msvcVersion;
}
void CMakeBuildConfiguration::setMsvcVersion(const QString &msvcVersion)
{
if (m_msvcVersion == msvcVersion)
return;
m_msvcVersion = msvcVersion;
updateToolChain();
emit msvcVersionChanged();
}
ProjectExplorer::IOutputParser *CMakeBuildConfiguration::createOutputParser() const
{
if (m_toolChain)
@@ -255,10 +206,10 @@ CMakeBuildConfiguration *CMakeBuildConfigurationFactory::create(ProjectExplorer:
delete bc;
return 0;
}
bc->setToolChain(copw.toolChain());
cmtarget->addBuildConfiguration(bc); // this also makes the name unique
bc->setBuildDirectory(copw.buildDirectory());
bc->setMsvcVersion(copw.msvcVersion());
cmtarget->cmakeProject()->parseCMakeLists();
// Default to all

View File

@@ -35,7 +35,7 @@
#define CMAKEBUILDCONFIGURATION_H
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/toolchaintype.h>
#include <projectexplorer/abi.h>
namespace ProjectExplorer {
class ToolChain;
@@ -60,23 +60,14 @@ public:
virtual QString buildDirectory() const;
ProjectExplorer::ToolChainType toolChainType() const;
ProjectExplorer::ToolChain *toolChain() const;
void setBuildDirectory(const QString &buildDirectory);
QString msvcVersion() const;
void setMsvcVersion(const QString &msvcVersion);
QVariantMap toMap() const;
ProjectExplorer::IOutputParser *createOutputParser() const;
Utils::Environment baseEnvironment() const;
signals:
void msvcVersionChanged();
protected:
CMakeBuildConfiguration(CMakeTarget *parent, CMakeBuildConfiguration *source);
virtual bool fromMap(const QVariantMap &map);

View File

@@ -44,7 +44,7 @@
#include "cmakeprojectmanager.h"
#include <utils/pathchooser.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
#include <QtGui/QVBoxLayout>
#include <QtGui/QFormLayout>
@@ -72,7 +72,8 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const
: m_cmakeManager(cmakeManager),
m_sourceDirectory(sourceDirectory),
m_creatingCbpFiles(false),
m_environment(env)
m_environment(env),
m_toolChain(0)
{
int startid;
if (hasInSourceBuild()) {
@@ -106,7 +107,8 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const
: m_cmakeManager(cmakeManager),
m_sourceDirectory(sourceDirectory),
m_creatingCbpFiles(true),
m_environment(env)
m_environment(env),
m_toolChain(0)
{
CMakeRunPage::Mode rmode;
@@ -126,7 +128,8 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const
: m_cmakeManager(cmakeManager),
m_sourceDirectory(sourceDirectory),
m_creatingCbpFiles(true),
m_environment(env)
m_environment(env),
m_toolChain(0)
{
m_buildDirectory = oldBuildDirectory;
addPage(new ShadowBuildPage(this, true));
@@ -196,16 +199,6 @@ void CMakeOpenProjectWizard::setBuildDirectory(const QString &directory)
m_buildDirectory = directory;
}
QString CMakeOpenProjectWizard::msvcVersion() const
{
return m_msvcVersion;
}
void CMakeOpenProjectWizard::setMsvcVersion(const QString &version)
{
m_msvcVersion = version;
}
QString CMakeOpenProjectWizard::arguments() const
{
return m_arguments;
@@ -216,6 +209,17 @@ void CMakeOpenProjectWizard::setArguments(const QString &args)
m_arguments = args;
}
ProjectExplorer::ToolChain *CMakeOpenProjectWizard::toolChain() const
{
return m_toolChain;
}
void CMakeOpenProjectWizard::setToolChain(ProjectExplorer::ToolChain *tc)
{
m_toolChain = tc;
}
Utils::Environment CMakeOpenProjectWizard::environment() const
{
return m_environment;
@@ -236,7 +240,6 @@ InSourceBuildPage::InSourceBuildPage(CMakeOpenProjectWizard *cmakeWizard)
setTitle(tr("Build Location"));
}
ShadowBuildPage::ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard, bool change)
: QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard)
{
@@ -378,9 +381,8 @@ void CMakeRunPage::initializePage()
m_descriptionLabel->setText(tr("Refreshing cbp file in %1.").arg(m_buildDirectory));
}
if (m_cmakeWizard->cmakeManager()->hasCodeBlocksMsvcGenerator()) {
m_generatorComboBox->setVisible(true);
// Try to find out generator from CMakeCache file, if it exists
QString cachedGenerator;
// Try to find out generator from CMakeCachhe file, if it exists
QFile fi(m_buildDirectory + "/CMakeCache.txt");
if (fi.exists()) {
@@ -398,67 +400,66 @@ void CMakeRunPage::initializePage()
}
}
}
m_generatorComboBox->setVisible(true);
m_generatorComboBox->clear();
// Find out whether we have multiple msvc versions
QStringList msvcVersions = ProjectExplorer::ToolChain::availableMSVCVersions();
if (msvcVersions.isEmpty()) {
} else if (msvcVersions.count() == 1) {
m_generatorComboBox->addItem(tr("NMake Generator"), msvcVersions.first());
} else {
foreach (const QString &msvcVersion, msvcVersions)
m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(msvcVersion), msvcVersion);
}
if (cachedGenerator == "NMake Makefiles" && !msvcVersions.isEmpty()) {
m_generatorComboBox->setCurrentIndex(0);
m_cmakeWizard->setMsvcVersion(msvcVersions.first());
}
m_generatorComboBox->addItem(tr("MinGW Generator"), "mingw");
if (cachedGenerator == "MinGW Makefiles") {
m_generatorComboBox->setCurrentIndex(m_generatorComboBox->count() - 1);
m_cmakeWizard->setMsvcVersion("");
QList<ProjectExplorer::ToolChain *> tcs =
ProjectExplorer::ToolChainManager::instance()->findToolChains(ProjectExplorer::Abi::hostAbi());
foreach (ProjectExplorer::ToolChain *tc, tcs) {
ProjectExplorer::Abi targetAbi = tc->targetAbi();
QVariant tcVariant = qVariantFromValue(static_cast<void *>(tc));
if (targetAbi.os() == ProjectExplorer::Abi::Windows) {
if (targetAbi.osFlavor() == ProjectExplorer::Abi::Windows_msvc)
m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(tc->displayName()), tcVariant);
else if (targetAbi.osFlavor() == ProjectExplorer::Abi::Windows_msys)
m_generatorComboBox->addItem(tr("MinGW Generator (%1)").arg(tc->displayName()), tcVariant);
else
continue;
}
}
} else {
// No new enough cmake, simply hide the combo box
m_generatorComboBox->setVisible(false);
QList<ProjectExplorer::ToolChain *> tcs =
ProjectExplorer::ToolChainManager::instance()->findToolChains(ProjectExplorer::Abi::hostAbi());
if (tcs.isEmpty())
return;
m_cmakeWizard->setToolChain(tcs.at(0));
}
}
void CMakeRunPage::runCMake()
{
int index = m_generatorComboBox->currentIndex();
ProjectExplorer::ToolChain *tc = 0;
if (index >= 0) {
tc = static_cast<ProjectExplorer::ToolChain *>(m_generatorComboBox->itemData(index).value<void *>());
if (!tc)
return;
m_cmakeWizard->setToolChain(tc);
} else {
tc = m_cmakeWizard->toolChain();
}
Q_ASSERT(tc);
m_runCMake->setEnabled(false);
m_argumentsLineEdit->setEnabled(false);
m_generatorComboBox->setEnabled(false);
CMakeManager *cmakeManager = m_cmakeWizard->cmakeManager();
#ifdef Q_OS_WIN
m_cmakeWizard->setMsvcVersion(QString());
QString generator = QLatin1String("-GCodeBlocks - MinGW Makefiles");
if (m_generatorComboBox->isVisible()) {
// the combobox is shown, check which generator is selected
int index = m_generatorComboBox->currentIndex();
if (index != -1) {
QString version = m_generatorComboBox->itemData(index).toString();
if (version != "mingw") {
generator = "-GCodeBlocks - NMake Makefiles";
m_cmakeWizard->setMsvcVersion(version);
} else {
m_cmakeWizard->setMsvcVersion("");
}
}
}
#else // Q_OS_WIN
QString generator = QLatin1String("-GCodeBlocks - Unix Makefiles");
#endif
Utils::Environment env = m_cmakeWizard->environment();
if (!m_cmakeWizard->msvcVersion().isEmpty()) {
// Add the environment of that msvc version to environment
ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChain::createMSVCToolChain(m_cmakeWizard->msvcVersion(), false);
tc->addToEnvironment(env);
delete tc;
if (tc->targetAbi().os() == ProjectExplorer::Abi::Windows) {
if (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::Windows_msvc)
generator = QLatin1String("-GCodeBlocks - NMake Makefiles");
else
generator = QLatin1String("-GCodeBlocks - MinGW Makefiles");
}
Utils::Environment env = m_cmakeWizard->environment();
tc->addToEnvironment(env);
if (m_cmakeExecutable) {
// We asked the user for the cmake executable
m_cmakeWizard->cmakeManager()->setCMakeExecutable(m_cmakeExecutable->path());
@@ -475,6 +476,7 @@ void CMakeRunPage::runCMake()
} else {
m_runCMake->setEnabled(true);
m_argumentsLineEdit->setEnabled(true);
m_generatorComboBox->setEnabled(true);
m_output->appendPlainText(tr("No valid CMake executable specified."));
}
}
@@ -515,6 +517,8 @@ void CMakeRunPage::cmakeFinished()
{
m_runCMake->setEnabled(true);
m_argumentsLineEdit->setEnabled(true);
m_generatorComboBox->setEnabled(true);
if (m_cmakeProcess->exitCode() != 0) {
m_exitCodeLabel->setVisible(true);
m_exitCodeLabel->setText(tr("CMake exited with errors. Please check cmake output."));
@@ -542,4 +546,3 @@ bool CMakeRunPage::isComplete() const
{
return m_complete;
}

View File

@@ -48,6 +48,10 @@ namespace Utils {
class PathChooser;
}
namespace ProjectExplorer {
class ToolChain;
}
namespace CMakeProjectManager {
namespace Internal {
@@ -87,10 +91,11 @@ public:
CMakeManager *cmakeManager() const;
QString arguments() const;
void setArguments(const QString &args);
ProjectExplorer::ToolChain *toolChain() const;
void setToolChain(ProjectExplorer::ToolChain *);
Utils::Environment environment() const;
QString msvcVersion() const;
void setMsvcVersion(const QString &version);
bool existsUpToDateXmlFile() const;
private:
void init();
bool hasInSourceBuild() const;
@@ -98,9 +103,9 @@ private:
QString m_buildDirectory;
QString m_sourceDirectory;
QString m_arguments;
QString m_msvcVersion;
bool m_creatingCbpFiles;
Utils::Environment m_environment;
ProjectExplorer::ToolChain *m_toolChain;
};
class InSourceBuildPage : public QWizardPage

View File

@@ -169,7 +169,6 @@ void CMakeProject::changeActiveBuildConfiguration(ProjectExplorer::BuildConfigur
mode,
cmakebc->environment());
copw.exec();
cmakebc->setMsvcVersion(copw.msvcVersion());
}
// reparse
parseCMakeLists();
@@ -282,6 +281,9 @@ bool CMakeProject::parseCMakeLists()
//qDebug()<<"Updating CodeModel";
createUiCodeModelSupport();
if (!activeBC->toolChain())
return true;
QStringList allIncludePaths;
QStringList allFrameworkPaths;
QList<ProjectExplorer::HeaderPath> allHeaderPaths = activeBC->toolChain()->systemHeaderPaths();
@@ -527,9 +529,9 @@ bool CMakeProject::fromMap(const QVariantMap &map)
CMakeBuildConfiguration *bc =
static_cast<CMakeBuildConfiguration *>(t->buildConfigurations().at(0));
bc->setMsvcVersion(copw.msvcVersion());
if (!copw.buildDirectory().isEmpty())
bc->setBuildDirectory(copw.buildDirectory());
bc->setToolChain(copw.toolChain());
addTarget(t);
} else {
@@ -554,7 +556,7 @@ bool CMakeProject::fromMap(const QVariantMap &map)
activeBC->environment());
if (copw.exec() != QDialog::Accepted)
return false;
activeBC->setMsvcVersion(copw.msvcVersion());
activeBC->setToolChain(copw.toolChain());
}
}

View File

@@ -299,14 +299,6 @@ void CMakeRunConfiguration::setUserEnvironmentChanges(const QList<Utils::Environ
}
}
ProjectExplorer::ToolChainType CMakeRunConfiguration::toolChainType() const
{
CMakeBuildConfiguration *bc = activeBuildConfiguration();
if (!bc)
return ProjectExplorer::ToolChain_UNKNOWN;
return bc->toolChainType();
}
void CMakeRunConfiguration::setEnabled(bool b)
{
if (m_enabled == b)

View File

@@ -37,6 +37,7 @@
#include <projectexplorer/applicationrunconfiguration.h>
#include <projectexplorer/persistentsettings.h>
#include <projectexplorer/environmentwidget.h>
#include <projectexplorer/toolchain.h>
#include <utils/environment.h>
#include <utils/pathchooser.h>
#include <utils/detailswidget.h>
@@ -83,7 +84,6 @@ public:
QString dumperLibrary() const;
QStringList dumperLibraryLocations() const;
ProjectExplorer::ToolChainType toolChainType() const;
QVariantMap toMap() const;