cmakebuildconfiguration.cpp 9.26 KB
Newer Older
dt's avatar
dt committed
1 2 3 4
/**************************************************************************
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
dt's avatar
dt committed
6
**
Eike Ziller's avatar
Eike Ziller committed
7
** Contact: http://www.qt-project.org/
dt's avatar
dt committed
8 9 10 11
**
**
** GNU Lesser General Public License Usage
**
hjk's avatar
hjk committed
12 13 14 15 16 17
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
dt's avatar
dt committed
18
**
con's avatar
con committed
19
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
20
** rights. These rights are described in the Nokia Qt LGPL Exception
con's avatar
con committed
21 22
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
23 24 25 26 27
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
dt's avatar
dt committed
28 29 30 31
**
**************************************************************************/

#include "cmakebuildconfiguration.h"
32 33

#include "cmakeopenprojectwizard.h"
34
#include "cmakeproject.h"
35

Tobias Hunger's avatar
Tobias Hunger committed
36
#include <projectexplorer/buildsteplist.h>
37 38
#include <projectexplorer/gnumakeparser.h>
#include <projectexplorer/ioutputparser.h>
Tobias Hunger's avatar
Tobias Hunger committed
39
#include <projectexplorer/kitinformation.h>
Tobias Hunger's avatar
Tobias Hunger committed
40 41
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
42 43
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtparser.h>
Tobias Hunger's avatar
Tobias Hunger committed
44
#include <qtsupport/qtkitinformation.h>
45 46
#include <utils/qtcassert.h>

47
#include <QInputDialog>
dt's avatar
dt committed
48

49 50 51
using namespace CMakeProjectManager;
using namespace Internal;

52
namespace {
53 54
const char CMAKE_BC_ID[] = "CMakeProjectManager.CMakeBuildConfiguration";
const char BUILD_DIRECTORY_KEY[] = "CMakeProjectManager.CMakeBuildConfiguration.BuildDirectory";
Tobias Hunger's avatar
Tobias Hunger committed
55
} // namespace
56

Daniel Teske's avatar
Daniel Teske committed
57
CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent) :
58
    BuildConfiguration(parent, Core::Id(CMAKE_BC_ID))
dt's avatar
dt committed
59
{
Daniel Teske's avatar
Daniel Teske committed
60
    m_buildDirectory = static_cast<CMakeProject *>(parent->project())->defaultBuildDirectory();
dt's avatar
dt committed
61 62
}

Tobias Hunger's avatar
Tobias Hunger committed
63 64
CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent,
                                                 CMakeBuildConfiguration *source) :
Tobias Hunger's avatar
Tobias Hunger committed
65
    BuildConfiguration(parent, source),
dt's avatar
dt committed
66 67 68
    m_buildDirectory(source->m_buildDirectory),
    m_msvcVersion(source->m_msvcVersion)
{
Tobias Hunger's avatar
Tobias Hunger committed
69
    Q_ASSERT(parent);
70
    cloneSteps(source);
dt's avatar
dt committed
71 72
}

73
QVariantMap CMakeBuildConfiguration::toMap() const
dt's avatar
dt committed
74
{
75 76 77 78 79 80 81
    QVariantMap map(ProjectExplorer::BuildConfiguration::toMap());
    map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory);
    return map;
}

bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
{
82 83 84
    if (!BuildConfiguration::fromMap(map))
        return false;

Tobias Hunger's avatar
Tobias Hunger committed
85
    m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY)).toString();
86

87
    return true;
dt's avatar
dt committed
88
}
89

90
CMakeBuildConfiguration::~CMakeBuildConfiguration()
Tobias Hunger's avatar
Tobias Hunger committed
91
{ }
92

Tobias Hunger's avatar
Tobias Hunger committed
93
ProjectExplorer::BuildConfigWidget *CMakeBuildConfiguration::createConfigWidget()
dt's avatar
dt committed
94
{
Tobias Hunger's avatar
Tobias Hunger committed
95
    return new CMakeBuildSettingsWidget;
dt's avatar
dt committed
96 97
}

98 99
QString CMakeBuildConfiguration::buildDirectory() const
{
100
    return m_buildDirectory;
101 102
}

103 104
void CMakeBuildConfiguration::setBuildDirectory(const QString &buildDirectory)
{
dt's avatar
dt committed
105
    if (m_buildDirectory == buildDirectory)
106
        return;
dt's avatar
dt committed
107
    m_buildDirectory = buildDirectory;
108
    emit buildDirectoryChanged();
109
    emit environmentChanged();
110
}
111

112 113
ProjectExplorer::IOutputParser *CMakeBuildConfiguration::createOutputParser() const
{
114 115
    ProjectExplorer::IOutputParser *parserchain = new ProjectExplorer::GnuMakeParser;

Tobias Hunger's avatar
Tobias Hunger committed
116
    int versionId = QtSupport::QtKitInformation::qtVersionId(target()->kit());
117 118 119
    if (versionId >= 0)
        parserchain->appendOutputParser(new QtSupport::QtParser);

Tobias Hunger's avatar
Tobias Hunger committed
120
    ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(target()->kit());
Tobias Hunger's avatar
Tobias Hunger committed
121
    if (tc)
122 123
        parserchain->appendOutputParser(tc->outputParser());
    return parserchain;
124 125
}

126 127 128
Utils::Environment CMakeBuildConfiguration::baseEnvironment() const
{
    Utils::Environment env = BuildConfiguration::baseEnvironment();
Tobias Hunger's avatar
Tobias Hunger committed
129
    target()->kit()->addToEnvironment(env);
130 131 132
    return env;
}

133 134 135 136
/*!
  \class CMakeBuildConfigurationFactory
*/

137 138
CMakeBuildConfigurationFactory::CMakeBuildConfigurationFactory(QObject *parent) :
    ProjectExplorer::IBuildConfigurationFactory(parent)
139 140 141 142 143 144 145
{
}

CMakeBuildConfigurationFactory::~CMakeBuildConfigurationFactory()
{
}

Tobias Hunger's avatar
Tobias Hunger committed
146
QList<Core::Id> CMakeBuildConfigurationFactory::availableCreationIds(const ProjectExplorer::Target *parent) const
147
{
Tobias Hunger's avatar
Tobias Hunger committed
148
    if (!canHandle(parent))
149 150
        return QList<Core::Id>();
    return QList<Core::Id>() << Core::Id(CMAKE_BC_ID);
151 152
}

153
QString CMakeBuildConfigurationFactory::displayNameForId(const Core::Id id) const
154
{
155
    if (id == CMAKE_BC_ID)
156 157
        return tr("Build");
    return QString();
158 159
}

Tobias Hunger's avatar
Tobias Hunger committed
160
bool CMakeBuildConfigurationFactory::canCreate(const ProjectExplorer::Target *parent, const Core::Id id) const
161
{
Tobias Hunger's avatar
Tobias Hunger committed
162
    if (!canHandle(parent))
163
        return false;
164
    if (id == CMAKE_BC_ID)
165 166 167 168
        return true;
    return false;
}

Tobias Hunger's avatar
Tobias Hunger committed
169
CMakeBuildConfiguration *CMakeBuildConfigurationFactory::create(ProjectExplorer::Target *parent, const Core::Id id, const QString &name)
170 171 172 173
{
    if (!canCreate(parent, id))
        return 0;

174
    CMakeProject *project = static_cast<CMakeProject *>(parent->project());
Tobias Hunger's avatar
Tobias Hunger committed
175 176 177 178 179 180 181 182 183 184

    bool ok = true;
    QString buildConfigurationName = name;
    if (buildConfigurationName.isEmpty())
        buildConfigurationName = QInputDialog::getText(0,
                                                       tr("New Configuration"),
                                                       tr("New configuration name:"),
                                                       QLineEdit::Normal,
                                                       QString(), &ok);
    buildConfigurationName = buildConfigurationName.trimmed();
185
    if (!ok || buildConfigurationName.isEmpty())
186
        return 0;
Tobias Hunger's avatar
Tobias Hunger committed
187

Daniel Teske's avatar
Daniel Teske committed
188
    CMakeBuildConfiguration *bc = new CMakeBuildConfiguration(parent);
189 190
    bc->setDisplayName(buildConfigurationName);

Tobias Hunger's avatar
Tobias Hunger committed
191 192
    ProjectExplorer::BuildStepList *buildSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
    ProjectExplorer::BuildStepList *cleanSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN);
193

Tobias Hunger's avatar
Tobias Hunger committed
194 195 196 197 198
    MakeStep *makeStep = new MakeStep(buildSteps);
    buildSteps->insertStep(0, makeStep);

    MakeStep *cleanMakeStep = new MakeStep(cleanSteps);
    cleanSteps->insertStep(0, cleanMakeStep);
199
    cleanMakeStep->setAdditionalArguments("clean");
200 201
    cleanMakeStep->setClean(true);

Tobias Hunger's avatar
Tobias Hunger committed
202 203
    CMakeOpenProjectWizard copw(project->projectManager(),
                                project->projectDirectory(),
204 205 206 207
                                bc->buildDirectory(),
                                bc->environment());
    if (copw.exec() != QDialog::Accepted) {
        delete bc;
208
        return 0;
209 210 211 212 213
    }

    bc->setBuildDirectory(copw.buildDirectory());

    // Default to all
Tobias Hunger's avatar
Tobias Hunger committed
214
    if (project->hasBuildTarget("all"))
215
        makeStep->setBuildTarget("all", true);
216

217 218 219
    return bc;
}

Tobias Hunger's avatar
Tobias Hunger committed
220
bool CMakeBuildConfigurationFactory::canClone(const ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const
221 222 223 224
{
    return canCreate(parent, source->id());
}

Tobias Hunger's avatar
Tobias Hunger committed
225
CMakeBuildConfiguration *CMakeBuildConfigurationFactory::clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source)
226
{
227 228
    if (!canClone(parent, source))
        return 0;
229
    CMakeBuildConfiguration *old = static_cast<CMakeBuildConfiguration *>(source);
Tobias Hunger's avatar
Tobias Hunger committed
230
    return new CMakeBuildConfiguration(parent, old);
231 232
}

Tobias Hunger's avatar
Tobias Hunger committed
233
bool CMakeBuildConfigurationFactory::canRestore(const ProjectExplorer::Target *parent, const QVariantMap &map) const
234
{
235
    return canCreate(parent, ProjectExplorer::idFromMap(map));
236 237
}

Tobias Hunger's avatar
Tobias Hunger committed
238
CMakeBuildConfiguration *CMakeBuildConfigurationFactory::restore(ProjectExplorer::Target *parent, const QVariantMap &map)
239 240 241
{
    if (!canRestore(parent, map))
        return 0;
Tobias Hunger's avatar
Tobias Hunger committed
242
    CMakeBuildConfiguration *bc = new CMakeBuildConfiguration(parent);
243 244 245 246
    if (bc->fromMap(map))
        return bc;
    delete bc;
    return 0;
247
}
248

Tobias Hunger's avatar
Tobias Hunger committed
249 250
bool CMakeBuildConfigurationFactory::canHandle(const ProjectExplorer::Target *t) const
{
Tobias Hunger's avatar
Tobias Hunger committed
251
    if (!t->project()->supportsKit(t->kit()))
Tobias Hunger's avatar
Tobias Hunger committed
252 253 254 255
        return false;
    return qobject_cast<CMakeProject *>(t->project());
}

256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
ProjectExplorer::BuildConfiguration::BuildType CMakeBuildConfiguration::buildType() const
{
    QString cmakeBuildType;
    QFile cmakeCache(buildDirectory() + "/CMakeCache.txt");
    if (cmakeCache.open(QIODevice::ReadOnly)) {
        while (!cmakeCache.atEnd()) {
            QString line = cmakeCache.readLine();
            if (line.startsWith("CMAKE_BUILD_TYPE")) {
                if (int pos = line.indexOf('=')) {
                    cmakeBuildType = line.mid(pos + 1).trimmed();
                }
                break;
            }
        }
        cmakeCache.close();
    }

    // Cover all common CMake build types
    if (cmakeBuildType.compare("Release", Qt::CaseInsensitive) == 0
        || cmakeBuildType.compare("MinSizeRel", Qt::CaseInsensitive) == 0)
    {
        return Release;
    } else if (cmakeBuildType.compare("Debug", Qt::CaseInsensitive) == 0
               || cmakeBuildType.compare("debugfull", Qt::CaseInsensitive) == 0
               || cmakeBuildType.compare("RelWithDebInfo", Qt::CaseInsensitive) == 0)
    {
        return Debug;
    }

    return Unknown;
}