cmakebuildconfiguration.cpp 9.52 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
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
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.
**
con's avatar
con committed
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at qt-info@nokia.com.
dt's avatar
dt committed
30
31
32
33
**
**************************************************************************/

#include "cmakebuildconfiguration.h"
34
35

#include "cmakeopenprojectwizard.h"
36
#include "cmakeproject.h"
37

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

49
#include <QInputDialog>
dt's avatar
dt committed
50

51
52
53
using namespace CMakeProjectManager;
using namespace Internal;

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

Tobias Hunger's avatar
Tobias Hunger committed
59
CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent) :
60
    BuildConfiguration(parent, Core::Id(CMAKE_BC_ID))
dt's avatar
dt committed
61
{
Tobias Hunger's avatar
Tobias Hunger committed
62
63
64
    CMakeProject *project = qobject_cast<CMakeProject *>(parent->project());
    if (project)
        m_buildDirectory = project->defaultBuildDirectory();
dt's avatar
dt committed
65
66
}

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

77
QVariantMap CMakeBuildConfiguration::toMap() const
dt's avatar
dt committed
78
{
79
80
81
82
83
84
85
    QVariantMap map(ProjectExplorer::BuildConfiguration::toMap());
    map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory);
    return map;
}

bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
{
86
87
88
    if (!BuildConfiguration::fromMap(map))
        return false;

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

91
    return true;
dt's avatar
dt committed
92
}
93

94
CMakeBuildConfiguration::~CMakeBuildConfiguration()
Tobias Hunger's avatar
Tobias Hunger committed
95
{ }
96

Tobias Hunger's avatar
Tobias Hunger committed
97
ProjectExplorer::BuildConfigWidget *CMakeBuildConfiguration::createConfigWidget()
dt's avatar
dt committed
98
{
Tobias Hunger's avatar
Tobias Hunger committed
99
    return new CMakeBuildSettingsWidget;
dt's avatar
dt committed
100
101
}

102
103
QString CMakeBuildConfiguration::buildDirectory() const
{
104
    return m_buildDirectory;
105
106
}

107
108
void CMakeBuildConfiguration::setBuildDirectory(const QString &buildDirectory)
{
dt's avatar
dt committed
109
    if (m_buildDirectory == buildDirectory)
110
        return;
dt's avatar
dt committed
111
    m_buildDirectory = buildDirectory;
112
    emit buildDirectoryChanged();
113
    emit environmentChanged();
114
}
115

116
117
ProjectExplorer::IOutputParser *CMakeBuildConfiguration::createOutputParser() const
{
118
119
120
121
122
123
    ProjectExplorer::IOutputParser *parserchain = new ProjectExplorer::GnuMakeParser;

    int versionId = QtSupport::QtProfileInformation::qtVersionId(target()->profile());
    if (versionId >= 0)
        parserchain->appendOutputParser(new QtSupport::QtParser);

Tobias Hunger's avatar
Tobias Hunger committed
124
125
    ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainProfileInformation::toolChain(target()->profile());
    if (tc)
126
127
        parserchain->appendOutputParser(tc->outputParser());
    return parserchain;
128
129
}

130
131
132
Utils::Environment CMakeBuildConfiguration::baseEnvironment() const
{
    Utils::Environment env = BuildConfiguration::baseEnvironment();
Tobias Hunger's avatar
Tobias Hunger committed
133
    target()->profile()->addToEnvironment(env);
134
135
136
    return env;
}

137
138
139
140
/*!
  \class CMakeBuildConfigurationFactory
*/

141
142
CMakeBuildConfigurationFactory::CMakeBuildConfigurationFactory(QObject *parent) :
    ProjectExplorer::IBuildConfigurationFactory(parent)
143
144
145
146
147
148
149
{
}

CMakeBuildConfigurationFactory::~CMakeBuildConfigurationFactory()
{
}

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

157
QString CMakeBuildConfigurationFactory::displayNameForId(const Core::Id id) const
158
{
159
    if (id == Core::Id(CMAKE_BC_ID))
160
161
        return tr("Build");
    return QString();
162
163
}

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

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

Tobias Hunger's avatar
Tobias Hunger committed
178
179
180
181
182
183
184
185
186
187
188
189
190
    CMakeProject *project = qobject_cast<CMakeProject *>(parent->project());
    if (!project)
        return 0;

    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();
191
    if (!ok || buildConfigurationName.isEmpty())
192
        return 0;
Tobias Hunger's avatar
Tobias Hunger committed
193
194

    CMakeBuildConfiguration *bc = new CMakeBuildConfiguration(parent);
195
196
    bc->setDisplayName(buildConfigurationName);

Tobias Hunger's avatar
Tobias Hunger committed
197
198
    ProjectExplorer::BuildStepList *buildSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
    ProjectExplorer::BuildStepList *cleanSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN);
199

Tobias Hunger's avatar
Tobias Hunger committed
200
201
202
203
204
    MakeStep *makeStep = new MakeStep(buildSteps);
    buildSteps->insertStep(0, makeStep);

    MakeStep *cleanMakeStep = new MakeStep(cleanSteps);
    cleanSteps->insertStep(0, cleanMakeStep);
205
    cleanMakeStep->setAdditionalArguments("clean");
206
207
    cleanMakeStep->setClean(true);

Tobias Hunger's avatar
Tobias Hunger committed
208
209
    CMakeOpenProjectWizard copw(project->projectManager(),
                                project->projectDirectory(),
210
211
212
213
                                bc->buildDirectory(),
                                bc->environment());
    if (copw.exec() != QDialog::Accepted) {
        delete bc;
214
        return 0;
215
216
217
218
219
    }

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

    // Default to all
Tobias Hunger's avatar
Tobias Hunger committed
220
    if (project->hasBuildTarget("all"))
221
        makeStep->setBuildTarget("all", true);
222

223
224
225
    return bc;
}

Tobias Hunger's avatar
Tobias Hunger committed
226
bool CMakeBuildConfigurationFactory::canClone(const ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const
227
228
229
230
{
    return canCreate(parent, source->id());
}

Tobias Hunger's avatar
Tobias Hunger committed
231
CMakeBuildConfiguration *CMakeBuildConfigurationFactory::clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source)
232
{
233
234
    if (!canClone(parent, source))
        return 0;
235
    CMakeBuildConfiguration *old = static_cast<CMakeBuildConfiguration *>(source);
Tobias Hunger's avatar
Tobias Hunger committed
236
    return new CMakeBuildConfiguration(parent, old);
237
238
}

Tobias Hunger's avatar
Tobias Hunger committed
239
bool CMakeBuildConfigurationFactory::canRestore(const ProjectExplorer::Target *parent, const QVariantMap &map) const
240
{
241
    return canCreate(parent, ProjectExplorer::idFromMap(map));
242
243
}

Tobias Hunger's avatar
Tobias Hunger committed
244
CMakeBuildConfiguration *CMakeBuildConfigurationFactory::restore(ProjectExplorer::Target *parent, const QVariantMap &map)
245
246
247
{
    if (!canRestore(parent, map))
        return 0;
Tobias Hunger's avatar
Tobias Hunger committed
248
    CMakeBuildConfiguration *bc = new CMakeBuildConfiguration(parent);
249
250
251
252
    if (bc->fromMap(map))
        return bc;
    delete bc;
    return 0;
253
}
254

Tobias Hunger's avatar
Tobias Hunger committed
255
256
257
258
259
260
261
bool CMakeBuildConfigurationFactory::canHandle(const ProjectExplorer::Target *t) const
{
    if (!t->project()->supportsProfile(t->profile()))
        return false;
    return qobject_cast<CMakeProject *>(t->project());
}

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
287
288
289
290
291
292
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;
}