OSDN Git Service

42047db5fcf5a1b43f99066a1cdc726120a929c9
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qt4projectmanager / qt-s60 / winscwtoolchain.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 "winscwtoolchain.h"
35
36 #include "qt4projectmanager/qt4projectmanagerconstants.h"
37 #include "qtversionmanager.h"
38
39 #include "ui_winscwtoolchainconfigwidget.h"
40 #include "winscwparser.h"
41
42 #include <projectexplorer/abi.h>
43 #include <projectexplorer/headerpath.h>
44 #include <utils/environment.h>
45
46 #include <QtCore/QDir>
47 #include <QtCore/QFileInfo>
48 #include <QtCore/QStringList>
49
50 namespace Qt4ProjectManager {
51 namespace Internal {
52
53 static const char winscwCompilerPathKeyC[] = "Qt4ProjectManager.Winscw.CompilerPath";
54 static const char winscwSystemIncludePathKeyC[] = "Qt4ProjectManager.Winscw.IncludePath";
55 static const char winscwSystemLibraryPathKeyC[] = "Qt4ProjectManager.Winscw.LibraryPath";
56
57 static const char *const WINSCW_DEFAULT_SYSTEM_INCLUDES[] = {
58     "/MSL/MSL_C/MSL_Common/Include",
59     "/MSL/MSL_C/MSL_Win32/Include",
60     "/MSL/MSL_CMSL_X86",
61     "/MSL/MSL_C++/MSL_Common/Include",
62     "/MSL/MSL_Extras/MSL_Common/Include",
63     "/MSL/MSL_Extras/MSL_Win32/Include",
64     "/Win32-x86 Support/Headers/Win32 SDK",
65     0
66 };
67
68 static const char *const WINSCW_DEFAULT_SYSTEM_LIBRARIES[] = {
69     "/Win32-x86 Support/Libraries/Win32 SDK",
70     "/Runtime/Runtime_x86/Runtime_Win32/Libs",
71     0
72 };
73
74 static QString winscwRoot(const QString &path)
75 {
76     if (path.isEmpty())
77         return QString();
78
79     QDir dir(path);
80     dir.cdUp();
81     dir.cdUp();
82     dir.cdUp();
83     dir.cd("Symbian_Support");
84     return dir.absolutePath();
85 }
86
87 static QString toNativePath(const QStringList &list)
88 {
89     return QDir::toNativeSeparators(list.join(QString(QLatin1Char(';'))));
90 }
91
92 static QStringList fromNativePath(const QString &list)
93 {
94     QString tmp = QDir::fromNativeSeparators(list);
95     return tmp.split(';');
96 }
97
98 static QStringList detectIncludesFor(const QString path)
99 {
100     QString root = winscwRoot(path);
101     QStringList result;
102     for (int i = 0; WINSCW_DEFAULT_SYSTEM_INCLUDES[i] != 0; ++i) {
103         QDir dir(root + QLatin1String(WINSCW_DEFAULT_SYSTEM_INCLUDES[i]));
104         if (dir.exists())
105             result.append(dir.absolutePath());
106     }
107     return result;
108 }
109
110 static QStringList detectLibrariesFor(const QString path)
111 {
112     QString root = winscwRoot(path);
113     QStringList result;
114     for (int i = 0; WINSCW_DEFAULT_SYSTEM_LIBRARIES[i] != 0; ++i) {
115         QDir dir(root + QLatin1String(WINSCW_DEFAULT_SYSTEM_LIBRARIES[i]));
116         if (dir.exists())
117             result.append(dir.absolutePath());
118     }
119     return result;
120 }
121
122 // --------------------------------------------------------------------------
123 // WinscwToolChain
124 // --------------------------------------------------------------------------
125
126 WinscwToolChain::WinscwToolChain(bool autodetected) :
127     ProjectExplorer::ToolChain(QLatin1String(Constants::WINSCW_TOOLCHAIN_ID), autodetected)
128 { }
129
130 WinscwToolChain::WinscwToolChain(const WinscwToolChain &tc) :
131     ProjectExplorer::ToolChain(tc),
132     m_systemIncludePathes(tc.m_systemIncludePathes),
133     m_systemLibraryPathes(tc.m_systemLibraryPathes),
134     m_compilerPath(tc.m_compilerPath)
135 { }
136
137 WinscwToolChain::~WinscwToolChain()
138 { }
139
140 QString WinscwToolChain::typeName() const
141 {
142     return WinscwToolChainFactory::tr("WINSCW");
143 }
144
145 ProjectExplorer::Abi WinscwToolChain::targetAbi() const
146 {
147     return ProjectExplorer::Abi(ProjectExplorer::Abi::ArmArchitecture, ProjectExplorer::Abi::SymbianOS,
148                                 ProjectExplorer::Abi::SymbianEmulatorFlavor,
149                                 ProjectExplorer::Abi::ElfFormat, false);
150 }
151
152 bool WinscwToolChain::isValid() const
153 {
154     if (m_compilerPath.isEmpty())
155         return false;
156
157     QFileInfo fi(m_compilerPath);
158     return fi.exists() && fi.isExecutable();
159 }
160
161 QByteArray WinscwToolChain::predefinedMacros() const
162 {
163     return QByteArray("#define __SYMBIAN32__\n");
164 }
165
166 QList<ProjectExplorer::HeaderPath> WinscwToolChain::systemHeaderPaths() const
167 {
168     QList<ProjectExplorer::HeaderPath> result;
169     foreach (const QString &value, m_systemIncludePathes)
170         result.append(ProjectExplorer::HeaderPath(value, ProjectExplorer::HeaderPath::GlobalHeaderPath));
171     return result;
172 }
173
174 void WinscwToolChain::addToEnvironment(Utils::Environment &env) const
175 {
176     if (!isValid())
177         return;
178
179     env.set(QLatin1String("MWCSYM2INCLUDES"), toNativePath(m_systemIncludePathes));
180     env.set(QLatin1String("MWSYM2LIBRARIES"), toNativePath(m_systemLibraryPathes));
181     env.set(QLatin1String("MWSYM2LIBRARYFILES"),
182             QLatin1String("MSL_All_MSE_Symbian_D.lib;gdi32.lib;user32.lib;kernel32.lib"));
183     env.prependOrSetPath(QFileInfo(m_compilerPath).absolutePath());
184 }
185
186 QString WinscwToolChain::makeCommand() const
187 {
188 #if defined Q_OS_WIN
189     return QLatin1String("make.exe");
190 #else
191     return QLatin1String("make");
192 #endif
193 }
194
195 QString WinscwToolChain::debuggerCommand() const
196 {
197     return QString();
198 }
199
200 QString WinscwToolChain::defaultMakeTarget() const
201 {
202     return QLatin1String("winscw");
203 }
204
205 ProjectExplorer::IOutputParser *WinscwToolChain::outputParser() const
206 {
207     return new WinscwParser;
208 }
209
210 bool WinscwToolChain::operator ==(const ProjectExplorer::ToolChain &tc) const
211 {
212     if (!ToolChain::operator ==(tc))
213         return false;
214
215     const WinscwToolChain *tcPtr = dynamic_cast<const WinscwToolChain *>(&tc);
216     Q_ASSERT(tcPtr);
217     return m_compilerPath == tcPtr->m_compilerPath
218             && m_systemIncludePathes == tcPtr->m_systemIncludePathes
219             && m_systemLibraryPathes == tcPtr->m_systemLibraryPathes;
220 }
221
222 ProjectExplorer::ToolChainConfigWidget *WinscwToolChain::configurationWidget()
223 {
224     return new WinscwToolChainConfigWidget(this);
225 }
226
227 ProjectExplorer::ToolChain *WinscwToolChain::clone() const
228 {
229     return new WinscwToolChain(*this);
230 }
231
232 QVariantMap WinscwToolChain::toMap() const
233 {
234     QVariantMap result = ToolChain::toMap();
235     result.insert(QLatin1String(winscwCompilerPathKeyC), m_compilerPath);
236     const QString semicolon = QString(QLatin1Char(';'));
237     result.insert(QLatin1String(winscwSystemIncludePathKeyC), m_systemIncludePathes.join(semicolon));
238     result.insert(QLatin1String(winscwSystemLibraryPathKeyC), m_systemLibraryPathes.join(semicolon));
239     return result;
240 }
241
242 bool WinscwToolChain::fromMap(const QVariantMap &data)
243 {
244     if (!ToolChain::fromMap(data))
245         return false;
246     m_compilerPath = data.value(QLatin1String(winscwCompilerPathKeyC)).toString();
247     const QChar semicolon = QLatin1Char(';');
248     m_systemIncludePathes = data.value(QLatin1String(winscwSystemIncludePathKeyC)).toString().split(semicolon);
249     m_systemLibraryPathes = data.value(QLatin1String(winscwSystemLibraryPathKeyC)).toString().split(semicolon);
250     return isValid();
251 }
252
253 void WinscwToolChain::setSystemIncludePathes(const QStringList &pathes)
254 {
255     if (m_systemIncludePathes == pathes)
256         return;
257     m_systemIncludePathes = pathes;
258     toolChainUpdated();
259 }
260
261 QStringList WinscwToolChain::systemIncludePathes() const
262 {
263     return m_systemIncludePathes;
264 }
265
266 void WinscwToolChain::setSystemLibraryPathes(const QStringList &pathes)
267 {
268     if (m_systemLibraryPathes == pathes)
269         return;
270     m_systemLibraryPathes = pathes;
271     toolChainUpdated();
272 }
273
274 QStringList WinscwToolChain::systemLibraryPathes() const
275 {
276     return m_systemLibraryPathes;
277 }
278
279 void WinscwToolChain::setCompilerPath(const QString &path)
280 {
281     if (m_compilerPath == path)
282         return;
283
284     m_compilerPath = path;
285     updateId(); // Will trigger topolChainUpdated()!
286 }
287
288 QString WinscwToolChain::compilerPath() const
289 {
290     return m_compilerPath;
291 }
292
293 void WinscwToolChain::updateId()
294 {
295     setId(QString::fromLatin1("%1:%2").arg(Constants::WINSCW_TOOLCHAIN_ID).arg(m_compilerPath));
296 }
297
298 // --------------------------------------------------------------------------
299 // ToolChainConfigWidget
300 // --------------------------------------------------------------------------
301
302 WinscwToolChainConfigWidget::WinscwToolChainConfigWidget(WinscwToolChain *tc) :
303     ProjectExplorer::ToolChainConfigWidget(tc),
304     m_ui(new Ui::WinscwToolChainConfigWidget)
305 {
306     m_ui->setupUi(this);
307
308     m_ui->compilerPath->setExpectedKind(Utils::PathChooser::ExistingCommand);
309     connect(m_ui->compilerPath, SIGNAL(changed(QString)),
310             this, SLOT(handleCompilerPathUpdate()));
311     connect(m_ui->includeEdit, SIGNAL(textChanged(QString)), this, SLOT(makeDirty()));
312     connect(m_ui->libraryEdit, SIGNAL(textChanged(QString)), this, SLOT(makeDirty()));
313
314     discard();
315 }
316
317 void WinscwToolChainConfigWidget::apply()
318 {
319     WinscwToolChain *tc = static_cast<WinscwToolChain *>(toolChain());
320     Q_ASSERT(tc);
321     tc->setCompilerPath(m_ui->compilerPath->path());
322     tc->setSystemIncludePathes(fromNativePath(m_ui->includeEdit->text()));
323     tc->setSystemLibraryPathes(fromNativePath(m_ui->libraryEdit->text()));
324 }
325
326 void WinscwToolChainConfigWidget::discard()
327 {
328     WinscwToolChain *tc = static_cast<WinscwToolChain *>(toolChain());
329     Q_ASSERT(tc);
330     m_ui->compilerPath->setPath(tc->compilerPath());
331     m_ui->includeEdit->setText(toNativePath(tc->systemIncludePathes()));
332     m_ui->libraryEdit->setText(toNativePath(tc->systemLibraryPathes()));
333 }
334
335 bool WinscwToolChainConfigWidget::isDirty() const
336 {
337     WinscwToolChain *tc = static_cast<WinscwToolChain *>(toolChain());
338     Q_ASSERT(tc);
339     return tc->compilerPath() != m_ui->compilerPath->path()
340             || tc->systemIncludePathes() != fromNativePath(m_ui->includeEdit->text())
341             || tc->systemLibraryPathes() != fromNativePath(m_ui->libraryEdit->text());
342 }
343
344 void WinscwToolChainConfigWidget::handleCompilerPathUpdate()
345 {
346     QString path = m_ui->compilerPath->path();
347     if (path.isEmpty())
348         return;
349     QFileInfo fi(path);
350     if (!fi.exists())
351         return;
352     m_ui->includeEdit->setText(toNativePath(detectIncludesFor(path)));
353     m_ui->libraryEdit->setText(toNativePath(detectLibrariesFor(path)));
354 }
355
356 void WinscwToolChainConfigWidget::makeDirty()
357 {
358     emit dirty(toolChain());
359 }
360
361 // --------------------------------------------------------------------------
362 // ToolChainFactory
363 // --------------------------------------------------------------------------
364
365 WinscwToolChainFactory::WinscwToolChainFactory() :
366     ProjectExplorer::ToolChainFactory()
367 { }
368
369 QString WinscwToolChainFactory::displayName() const
370 {
371     return tr("WINSCW");
372 }
373
374 QString WinscwToolChainFactory::id() const
375 {
376     return QLatin1String(Constants::WINSCW_TOOLCHAIN_ID);
377 }
378
379 QList<ProjectExplorer::ToolChain *> WinscwToolChainFactory::autoDetect()
380 {
381     QList<ProjectExplorer::ToolChain *> result;
382
383     // Compatibility to pre-2.2:
384     while (true) {
385         const QString path = QtVersionManager::instance()->popPendingMwcUpdate();
386         if (path.isNull())
387             break;
388
389         QFileInfo fi(path + QLatin1String("/x86Build/Symbian_Tools/Command_Line_Tools/mwwinrc.exe"));
390         if (fi.exists() && fi.isExecutable()) {
391             WinscwToolChain *tc = new WinscwToolChain(false);
392             tc->setCompilerPath(fi.absoluteFilePath());
393             tc->setDisplayName(tr("WINSCW from Qt version"));
394             result.append(tc);
395         }
396     }
397
398     QString cc = Utils::Environment::systemEnvironment().searchInPath(QLatin1String("mwwinrc"));
399     if (!cc.isEmpty()) {
400         WinscwToolChain *tc = new WinscwToolChain(true);
401         tc->setCompilerPath(cc);
402         tc->setSystemIncludePathes(detectIncludesFor(cc));
403         tc->setSystemLibraryPathes(detectLibrariesFor(cc));
404         result.append(tc);
405     }
406     return result;
407 }
408
409 bool WinscwToolChainFactory::canCreate()
410 {
411     return true;
412 }
413
414 ProjectExplorer::ToolChain *WinscwToolChainFactory::create()
415 {
416     return new WinscwToolChain(false);
417 }
418
419 bool WinscwToolChainFactory::canRestore(const QVariantMap &data)
420 {
421     return idFromMap(data).startsWith(QLatin1String(Constants::WINSCW_TOOLCHAIN_ID));
422 }
423
424 ProjectExplorer::ToolChain *WinscwToolChainFactory::restore(const QVariantMap &data)
425 {
426     WinscwToolChain *tc = new WinscwToolChain(false);
427     if (tc->fromMap(data))
428         return tc;
429
430     delete tc;
431     return 0;
432 }
433
434 } // namespace Internal
435 } // namespace Qt4ProjectManager