forked from qt-creator/qt-creator
Fixes: Add ToolChain classes.
Details: These classes replace a number of classes with differing interfaces by just one class. The design isn't quite perfect, but a lot better than what it used to be. Also moved the ToolChain classes to the projectexplorerm so that eventually the cmake plugin can also use them.
This commit is contained in:
326
src/plugins/projectexplorer/toolchain.cpp
Normal file
326
src/plugins/projectexplorer/toolchain.cpp
Normal file
@@ -0,0 +1,326 @@
|
||||
#include "toolchain.h"
|
||||
#include "cesdkhandler.h"
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QTemporaryFile>
|
||||
#include <QtCore/QString>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace ProjectExplorer::Internal;
|
||||
|
||||
bool ToolChain::equals(ToolChain *a, ToolChain *b)
|
||||
{
|
||||
if (a == b)
|
||||
return true;
|
||||
if (a == 0 || b == 0)
|
||||
return false;
|
||||
if (a->type() == b->type())
|
||||
a->equals(b);
|
||||
}
|
||||
|
||||
ToolChain::ToolChain()
|
||||
{
|
||||
}
|
||||
|
||||
ToolChain::~ToolChain()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ToolChain *ToolChain::createGccToolChain(const QString &gcc)
|
||||
{
|
||||
return new GccToolChain(gcc);
|
||||
}
|
||||
|
||||
ToolChain *ToolChain::createMinGWToolChain(const QString &gcc, const QString &mingwPath)
|
||||
{
|
||||
return new MinGWToolChain(gcc, mingwPath);
|
||||
}
|
||||
|
||||
ToolChain *ToolChain::createMSVCToolChain(const QString &name)
|
||||
{
|
||||
return new MSVCToolChain(name);
|
||||
}
|
||||
|
||||
ToolChain *ToolChain::createWinCEToolChain(const QString &name, const QString &platform)
|
||||
{
|
||||
return new WinCEToolChain(name, platform);
|
||||
}
|
||||
|
||||
QStringList ToolChain::availableMSVCVersions()
|
||||
{
|
||||
QSettings registry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7",
|
||||
QSettings::NativeFormat);
|
||||
QStringList versions = registry.allKeys();
|
||||
return versions;
|
||||
}
|
||||
|
||||
GccToolChain::GccToolChain(const QString &gcc)
|
||||
: m_gcc(gcc)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ToolChain::ToolChainType GccToolChain::type() const
|
||||
{
|
||||
return ToolChain::GCC;
|
||||
}
|
||||
|
||||
QByteArray GccToolChain::predefinedMacros()
|
||||
{
|
||||
if (m_predefinedMacros.isEmpty()) {
|
||||
QStringList arguments;
|
||||
arguments << QLatin1String("-xc++")
|
||||
<< QLatin1String("-E")
|
||||
<< QLatin1String("-dM")
|
||||
<< QLatin1String("-");
|
||||
|
||||
QProcess cpp;
|
||||
cpp.start(m_gcc, arguments);
|
||||
cpp.closeWriteChannel();
|
||||
cpp.waitForFinished();
|
||||
m_predefinedMacros = cpp.readAllStandardOutput();
|
||||
}
|
||||
return m_predefinedMacros;
|
||||
}
|
||||
|
||||
QList<HeaderPath> GccToolChain::systemHeaderPaths()
|
||||
{
|
||||
if (m_systemHeaderPaths.isEmpty()) {
|
||||
QStringList arguments;
|
||||
arguments << QLatin1String("-xc++")
|
||||
<< QLatin1String("-E")
|
||||
<< QLatin1String("-v")
|
||||
<< QLatin1String("-");
|
||||
|
||||
QProcess cpp;
|
||||
cpp.setReadChannelMode(QProcess::MergedChannels);
|
||||
cpp.start(m_gcc, arguments);
|
||||
cpp.closeWriteChannel();
|
||||
cpp.waitForFinished();
|
||||
|
||||
QByteArray line;
|
||||
while (cpp.canReadLine()) {
|
||||
line = cpp.readLine();
|
||||
if (line.startsWith("#include"))
|
||||
break;
|
||||
}
|
||||
|
||||
if (! line.isEmpty() && line.startsWith("#include")) {
|
||||
HeaderPath::Kind kind = HeaderPath::UserHeaderPath;
|
||||
while (cpp.canReadLine()) {
|
||||
line = cpp.readLine();
|
||||
if (line.startsWith("#include")) {
|
||||
kind = HeaderPath::GlobalHeaderPath;
|
||||
} else if (! line.isEmpty() && QChar(line.at(0)).isSpace()) {
|
||||
HeaderPath::Kind thisHeaderKind = kind;
|
||||
|
||||
line = line.trimmed();
|
||||
if (line.endsWith('\n'))
|
||||
line.chop(1);
|
||||
|
||||
int index = line.indexOf(" (framework directory)");
|
||||
if (index != -1) {
|
||||
line = line.left(index);
|
||||
thisHeaderKind = HeaderPath::FrameworkHeaderPath;
|
||||
}
|
||||
|
||||
m_systemHeaderPaths.append(HeaderPath(QFile::decodeName(line), thisHeaderKind));
|
||||
} else if (line.startsWith("End of search list.")) {
|
||||
break;
|
||||
} else {
|
||||
qWarning() << "ignore line:" << line;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_systemHeaderPaths;
|
||||
}
|
||||
|
||||
void GccToolChain::addToEnvironment(ProjectExplorer::Environment &env)
|
||||
{
|
||||
Q_UNUSED(env)
|
||||
}
|
||||
|
||||
bool GccToolChain::equals(ToolChain *other) const
|
||||
{
|
||||
return (m_gcc == static_cast<GccToolChain *>(other)->m_gcc);
|
||||
}
|
||||
|
||||
MinGWToolChain::MinGWToolChain(const QString &gcc, const QString &mingwPath)
|
||||
: GccToolChain(gcc), m_mingwPath(mingwPath)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ToolChain::ToolChainType MinGWToolChain::type() const
|
||||
{
|
||||
return ToolChain::MinGW;
|
||||
}
|
||||
|
||||
bool MinGWToolChain::equals(ToolChain *other) const
|
||||
{
|
||||
MinGWToolChain *o = static_cast<MinGWToolChain *>(other);
|
||||
return (m_mingwPath == o->m_mingwPath && this->GccToolChain::equals(other));
|
||||
}
|
||||
|
||||
void MinGWToolChain::addToEnvironment(ProjectExplorer::Environment &env)
|
||||
{
|
||||
QString binDir = m_mingwPath + "/bin";
|
||||
if (QFileInfo(binDir).exists())
|
||||
env.prependOrSetPath(binDir);
|
||||
}
|
||||
|
||||
|
||||
MSVCToolChain::MSVCToolChain(const QString &name)
|
||||
: m_name(name), m_valuesSet(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ToolChain::ToolChainType MSVCToolChain::type() const
|
||||
{
|
||||
return ToolChain::MSVC;
|
||||
}
|
||||
|
||||
bool MSVCToolChain::equals(ToolChain *other) const
|
||||
{
|
||||
MSVCToolChain *o = static_cast<MSVCToolChain *>(other);
|
||||
return (m_name == o->m_name);
|
||||
}
|
||||
|
||||
QByteArray MSVCToolChain::predefinedMacros()
|
||||
{
|
||||
return "#define __WIN32__\n"
|
||||
"#define __WIN32\n"
|
||||
"#define _WIN32\n"
|
||||
"#define WIN32\n"
|
||||
"#define __WINNT__\n"
|
||||
"#define __WINNT\n"
|
||||
"#define WINNT\n"
|
||||
"#define _X86_\n"
|
||||
"#define __MSVCRT__\n";
|
||||
}
|
||||
|
||||
QList<HeaderPath> MSVCToolChain::systemHeaderPaths()
|
||||
{
|
||||
//TODO fix this code
|
||||
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
|
||||
addToEnvironment(env);
|
||||
#ifdef QTCREATOR_WITH_MSVC_INCLUDES
|
||||
return env.value("INCLUDE").split(QLatin1Char(';'));
|
||||
#endif
|
||||
return QList<HeaderPath>();
|
||||
}
|
||||
|
||||
void MSVCToolChain::addToEnvironment(ProjectExplorer::Environment &env)
|
||||
{
|
||||
if (!m_valuesSet) {
|
||||
QSettings registry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7",
|
||||
QSettings::NativeFormat);
|
||||
QString path = registry.value(m_name).toString();
|
||||
ProjectExplorer::Environment oldEnv(env);
|
||||
QString desc;
|
||||
QString varsbat = path + "Common7\\Tools\\vsvars32.bat";
|
||||
if (QFileInfo(varsbat).exists()) {
|
||||
QTemporaryFile tf(QDir::tempPath() + "\\XXXXXX.bat");
|
||||
if (!tf.open())
|
||||
return;
|
||||
QString filename = tf.fileName();
|
||||
tf.write("call \"" + varsbat.toLocal8Bit()+"\"\r\n");
|
||||
tf.write(("set > \"" + QDir::tempPath() + "\\qtcreator-msvc-environment.txt\"\r\n").toLocal8Bit());
|
||||
tf.flush();
|
||||
tf.waitForBytesWritten(30000);
|
||||
|
||||
QProcess run;
|
||||
QString cmdPath = env.searchInPath("cmd");
|
||||
run.start(cmdPath, QStringList()<<"/c"<<filename);
|
||||
run.waitForFinished();
|
||||
tf.close();
|
||||
|
||||
QFile vars(QDir::tempPath() + "\\qtcreator-msvc-environment.txt");
|
||||
if (vars.exists() && vars.open(QIODevice::ReadOnly)) {
|
||||
while (!vars.atEnd()) {
|
||||
QByteArray line = vars.readLine();
|
||||
QString line2 = QString::fromLocal8Bit(line);
|
||||
line2 = line2.trimmed();
|
||||
QRegExp regexp("(\\w*)=(.*)");
|
||||
if (regexp.exactMatch(line2)) {
|
||||
QString variable = regexp.cap(1);
|
||||
QString value = regexp.cap(2);
|
||||
value.replace('%' + variable + '%', oldEnv.value(variable));
|
||||
m_values.append(QPair<QString, QString>(variable, value));
|
||||
|
||||
}
|
||||
}
|
||||
vars.close();
|
||||
vars.remove();
|
||||
}
|
||||
}
|
||||
m_valuesSet = true;
|
||||
}
|
||||
|
||||
QList< QPair<QString, QString> >::const_iterator it, end;
|
||||
end = m_values.constEnd();
|
||||
for (it = m_values.constBegin(); it != end; ++it) {
|
||||
env.set((*it).first, (*it).second);
|
||||
qDebug()<<"variable:"<<(*it).first<<"value:"<<(*it).second;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WinCEToolChain::WinCEToolChain(const QString &name, const QString &platform)
|
||||
: MSVCToolChain(name), m_platform(platform)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ToolChain::ToolChainType WinCEToolChain::type() const
|
||||
{
|
||||
return ToolChain::WINCE;
|
||||
}
|
||||
|
||||
bool WinCEToolChain::equals(ToolChain *other) const
|
||||
{
|
||||
WinCEToolChain *o = static_cast<WinCEToolChain *>(other);
|
||||
return (m_platform == o->m_platform && this->MSVCToolChain::equals(other));
|
||||
}
|
||||
|
||||
QByteArray WinCEToolChain::predefinedMacros()
|
||||
{
|
||||
//TODO
|
||||
return MSVCToolChain::predefinedMacros();
|
||||
}
|
||||
|
||||
QList<HeaderPath> WinCEToolChain::systemHeaderPaths()
|
||||
{
|
||||
//TODO fix this code
|
||||
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
|
||||
addToEnvironment(env);
|
||||
#ifdef QTCREATOR_WITH_MSVC_INCLUDES
|
||||
return env.value("INCLUDE").split(QLatin1Char(';'));
|
||||
#endif
|
||||
}
|
||||
|
||||
void WinCEToolChain::addToEnvironment(ProjectExplorer::Environment &env)
|
||||
{
|
||||
MSVCToolChain::addToEnvironment(env);
|
||||
QSettings registry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7",
|
||||
QSettings::NativeFormat);
|
||||
QString path = registry.value(m_name).toString();
|
||||
// Find MSVC path
|
||||
|
||||
path += "/";
|
||||
|
||||
// qDebug()<<"MSVC path"<<msvcPath;
|
||||
// qDebug()<<"looking for platform name in"<< path() + "/mkspecs/" + mkspec() +"/qmake.conf";
|
||||
// Find Platform name
|
||||
// qDebug()<<"Platform Name"<<platformName;
|
||||
|
||||
CeSdkHandler cesdkhandler;
|
||||
cesdkhandler.parse(path);
|
||||
cesdkhandler.find(m_platform).addToEnvironment(env);
|
||||
}
|
||||
Reference in New Issue
Block a user