OSDN Git Service

1f497bbef55cf7b4d62cf80eaf674f7eb8935ce4
[qt-creator-jp/qt-creator-jp.git] / src / plugins / cmakeprojectmanager / cmakebuildconfiguration.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "cmakebuildconfiguration.h"
35
36 #include "cmakeopenprojectwizard.h"
37 #include "cmakeproject.h"
38 #include "cmaketarget.h"
39
40 #include <projectexplorer/projectexplorerconstants.h>
41 #include <projectexplorer/toolchainmanager.h>
42 #include <projectexplorer/buildsteplist.h>
43 #include <utils/qtcassert.h>
44
45 #include <QtGui/QInputDialog>
46
47 using namespace CMakeProjectManager;
48 using namespace Internal;
49
50 namespace {
51 const char * const CMAKE_BC_ID("CMakeProjectManager.CMakeBuildConfiguration");
52
53 const char * const TOOLCHAIN_KEY("CMakeProjectManager.CMakeBuildConfiguration.ToolChain");
54 const char * const BUILD_DIRECTORY_KEY("CMakeProjectManager.CMakeBuildConfiguration.BuildDirectory");
55 } // namespace
56
57 CMakeBuildConfiguration::CMakeBuildConfiguration(CMakeTarget *parent) :
58     BuildConfiguration(parent, QLatin1String(CMAKE_BC_ID))
59 {
60     m_buildDirectory = cmakeTarget()->defaultBuildDirectory();
61 }
62
63 CMakeBuildConfiguration::CMakeBuildConfiguration(CMakeTarget *parent, CMakeBuildConfiguration *source) :
64     BuildConfiguration(parent, source),
65     m_buildDirectory(source->m_buildDirectory),
66     m_msvcVersion(source->m_msvcVersion)
67 {
68     Q_ASSERT(parent);
69     cloneSteps(source);
70 }
71
72 QVariantMap CMakeBuildConfiguration::toMap() const
73 {
74     QVariantMap map(ProjectExplorer::BuildConfiguration::toMap());
75     map.insert(QLatin1String(TOOLCHAIN_KEY), toolChain() ? toolChain()->id() : QString());
76     map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory);
77     return map;
78 }
79
80 bool CMakeBuildConfiguration::fromMap(const QVariantMap &map)
81 {
82     if (!BuildConfiguration::fromMap(map))
83         return false;
84
85     setToolChain(ProjectExplorer::ToolChainManager::instance()->
86             findToolChain(map.value(QLatin1String(TOOLCHAIN_KEY)).toString()));
87
88     if (!toolChain()) {
89         // restoring from older versions?
90         QList<ProjectExplorer::ToolChain *> list = ProjectExplorer::ToolChainManager::instance()->toolChains();
91         if (!map.value("CMakeProjectManager.CMakeBuildConfiguration.MsvcVersion").toString().isEmpty()) {
92             foreach (ProjectExplorer::ToolChain *tc, list) {
93                 if (tc->id().startsWith(ProjectExplorer::Constants::MSVC_TOOLCHAIN_ID)) {
94                     setToolChain(tc);
95                     break;
96                 }
97             }
98         } else {
99 #ifdef Q_OS_WIN
100             QString toolChainId = ProjectExplorer::Constants::MINGW_TOOLCHAIN_ID;
101 #else
102             QString toolChainId = ProjectExplorer::Constants::GCC_TOOLCHAIN_ID;
103 #endif
104             foreach (ProjectExplorer::ToolChain *tc, list) {
105                 if (tc->id().startsWith(toolChainId)) {
106                     setToolChain(tc);
107                     break;
108                 }
109             }
110         }
111     }
112
113     m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY), cmakeTarget()->defaultBuildDirectory()).toString();
114
115     return true;
116 }
117
118 CMakeBuildConfiguration::~CMakeBuildConfiguration()
119 {
120 }
121
122 CMakeTarget *CMakeBuildConfiguration::cmakeTarget() const
123 {
124     return static_cast<CMakeTarget *>(target());
125 }
126
127 QString CMakeBuildConfiguration::buildDirectory() const
128 {
129     return m_buildDirectory;
130 }
131
132 void CMakeBuildConfiguration::setBuildDirectory(const QString &buildDirectory)
133 {
134     if (m_buildDirectory == buildDirectory)
135         return;
136     m_buildDirectory = buildDirectory;
137     emit buildDirectoryChanged();
138     emit environmentChanged();
139 }
140
141 ProjectExplorer::IOutputParser *CMakeBuildConfiguration::createOutputParser() const
142 {
143     if (toolChain())
144         return toolChain()->outputParser();
145     return 0;
146 }
147
148 Utils::Environment CMakeBuildConfiguration::baseEnvironment() const
149 {
150     Utils::Environment env = BuildConfiguration::baseEnvironment();
151     if (toolChain())
152         toolChain()->addToEnvironment(env);
153     return env;
154 }
155
156 /*!
157   \class CMakeBuildConfigurationFactory
158 */
159
160 CMakeBuildConfigurationFactory::CMakeBuildConfigurationFactory(QObject *parent) :
161     ProjectExplorer::IBuildConfigurationFactory(parent)
162 {
163 }
164
165 CMakeBuildConfigurationFactory::~CMakeBuildConfigurationFactory()
166 {
167 }
168
169 QStringList CMakeBuildConfigurationFactory::availableCreationIds(ProjectExplorer::Target *parent) const
170 {
171     if (!qobject_cast<CMakeTarget *>(parent))
172         return QStringList();
173     return QStringList() << QLatin1String(CMAKE_BC_ID);
174 }
175
176 QString CMakeBuildConfigurationFactory::displayNameForId(const QString &id) const
177 {
178     if (id == QLatin1String(CMAKE_BC_ID))
179         return tr("Build");
180     return QString();
181 }
182
183 bool CMakeBuildConfigurationFactory::canCreate(ProjectExplorer::Target *parent, const QString &id) const
184 {
185     if (!qobject_cast<CMakeTarget *>(parent))
186         return false;
187     if (id == QLatin1String(CMAKE_BC_ID))
188         return true;
189     return false;
190 }
191
192 CMakeBuildConfiguration *CMakeBuildConfigurationFactory::create(ProjectExplorer::Target *parent, const QString &id)
193 {
194     if (!canCreate(parent, id))
195         return 0;
196
197     CMakeTarget *cmtarget = static_cast<CMakeTarget *>(parent);
198     Q_ASSERT(cmtarget);
199
200     //TODO configuration name should be part of the cmakeopenprojectwizard
201     bool ok;
202     QString buildConfigurationName = QInputDialog::getText(0,
203                           tr("New Configuration"),
204                           tr("New configuration name:"),
205                           QLineEdit::Normal,
206                           QString(),
207                           &ok);
208     if (!ok || buildConfigurationName.isEmpty())
209         return 0;
210     CMakeBuildConfiguration *bc = new CMakeBuildConfiguration(cmtarget);
211     bc->setDisplayName(buildConfigurationName);
212
213     ProjectExplorer::BuildStepList *buildSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
214     ProjectExplorer::BuildStepList *cleanSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_CLEAN);
215
216     MakeStep *makeStep = new MakeStep(buildSteps);
217     buildSteps->insertStep(0, makeStep);
218
219     MakeStep *cleanMakeStep = new MakeStep(cleanSteps);
220     cleanSteps->insertStep(0, cleanMakeStep);
221     cleanMakeStep->setAdditionalArguments("clean");
222     cleanMakeStep->setClean(true);
223
224     CMakeOpenProjectWizard copw(cmtarget->cmakeProject()->projectManager(),
225                                 cmtarget->project()->projectDirectory(),
226                                 bc->buildDirectory(),
227                                 bc->environment());
228     if (copw.exec() != QDialog::Accepted) {
229         delete bc;
230         return 0;
231     }
232     bc->setToolChain(copw.toolChain());
233     cmtarget->addBuildConfiguration(bc); // this also makes the name unique
234
235     bc->setBuildDirectory(copw.buildDirectory());
236     cmtarget->cmakeProject()->parseCMakeLists();
237
238     // Default to all
239     if (cmtarget->cmakeProject()->hasBuildTarget("all"))
240         makeStep->setBuildTarget("all", true);
241
242     return bc;
243 }
244
245 bool CMakeBuildConfigurationFactory::canClone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source) const
246 {
247     return canCreate(parent, source->id());
248 }
249
250 CMakeBuildConfiguration *CMakeBuildConfigurationFactory::clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *source)
251 {
252     if (!canClone(parent, source))
253         return 0;
254     CMakeBuildConfiguration *old = static_cast<CMakeBuildConfiguration *>(source);
255     CMakeTarget *cmtarget(static_cast<CMakeTarget *>(parent));
256     return new CMakeBuildConfiguration(cmtarget, old);
257 }
258
259 bool CMakeBuildConfigurationFactory::canRestore(ProjectExplorer::Target *parent, const QVariantMap &map) const
260 {
261     QString id(ProjectExplorer::idFromMap(map));
262     return canCreate(parent, id);
263 }
264
265 CMakeBuildConfiguration *CMakeBuildConfigurationFactory::restore(ProjectExplorer::Target *parent, const QVariantMap &map)
266 {
267     if (!canRestore(parent, map))
268         return 0;
269     CMakeTarget *cmtarget(static_cast<CMakeTarget *>(parent));
270     CMakeBuildConfiguration *bc = new CMakeBuildConfiguration(cmtarget);
271     if (bc->fromMap(map))
272         return bc;
273     delete bc;
274     return 0;
275 }
276
277 ProjectExplorer::BuildConfiguration::BuildType CMakeBuildConfiguration::buildType() const
278 {
279     QString cmakeBuildType;
280     QFile cmakeCache(buildDirectory() + "/CMakeCache.txt");
281     if (cmakeCache.open(QIODevice::ReadOnly)) {
282         while (!cmakeCache.atEnd()) {
283             QString line = cmakeCache.readLine();
284             if (line.startsWith("CMAKE_BUILD_TYPE")) {
285                 if (int pos = line.indexOf('=')) {
286                     cmakeBuildType = line.mid(pos + 1).trimmed();
287                 }
288                 break;
289             }
290         }
291         cmakeCache.close();
292     }
293
294     // Cover all common CMake build types
295     if (cmakeBuildType.compare("Release", Qt::CaseInsensitive) == 0
296         || cmakeBuildType.compare("MinSizeRel", Qt::CaseInsensitive) == 0)
297     {
298         return Release;
299     } else if (cmakeBuildType.compare("Debug", Qt::CaseInsensitive) == 0
300                || cmakeBuildType.compare("debugfull", Qt::CaseInsensitive) == 0
301                || cmakeBuildType.compare("RelWithDebInfo", Qt::CaseInsensitive) == 0)
302     {
303         return Debug;
304     }
305
306     return Unknown;
307 }
308