Newer
Older
if (value == "debug") {
if (qa.op == "+=")
result = result | QtVersion::DebugBuild;
result = result & ~QtVersion::DebugBuild;
} else if (value == "release") {
if (qa.op == "+=")
result = result & ~QtVersion::DebugBuild;
result = result | QtVersion::DebugBuild;
} else if (value == "debug_and_release") {
if (qa.op == "+=")
result = result | QtVersion::BuildAll;
result = result & ~QtVersion::BuildAll;
} else {
newValues.append(value);
QMakeAssignment newQA = qa;
newQA.value = newValues.join(" ");
if (!newValues.isEmpty())
assignments->append(newQA);
} else {
assignments->append(qa);
}
}
return result;
}
void QtVersion::updateVersionInfo() const
{
if (m_versionInfoUpToDate)
return;
// extract data from qmake executable
m_versionInfo.clear();
m_notInstalled = false;
m_hasExamples = false;
m_hasDocumentation = false;
if (qmake.exists() && qmake.isExecutable()) {
static const char * const variables[] = {
"QT_INSTALL_DATA",
"QT_INSTALL_LIBS",
"QT_INSTALL_HEADERS",
"QT_INSTALL_DEMOS",
"QT_INSTALL_EXAMPLES",
"QT_INSTALL_CONFIGURATION",
"QT_INSTALL_TRANSLATIONS",
"QT_INSTALL_PLUGINS",
"QT_INSTALL_BINS",
"QT_INSTALL_DOCS",
};
QStringList args;
for (uint i = 0; i < sizeof variables / sizeof variables[0]; ++i)
args << "-query" << variables[i];
QProcess process;
process.start(qmake.absoluteFilePath(), args, QIODevice::ReadOnly);
if (process.waitForFinished(2000)) {
QByteArray output = process.readAllStandardOutput();
QTextStream stream(&output);
while (!stream.atEnd()) {
const QString line = stream.readLine();
const int index = line.indexOf(QLatin1Char(':'));
if (index != -1) {
QString value = QDir::fromNativeSeparators(line.mid(index+1));
if (value != "**Unknown**")
m_versionInfo.insert(line.left(index), value);
}
if (m_versionInfo.contains("QT_INSTALL_DATA")) {
QString qtInstallData = m_versionInfo.value("QT_INSTALL_DATA");
m_versionInfo.insert("QMAKE_MKSPECS", QDir::cleanPath(qtInstallData+"/mkspecs"));
if (!qtInstallData.isEmpty())
m_hasDebuggingHelper = !DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(qtInstallData).isEmpty();
// Now check for a qt that is configured with a prefix but not installed
if (m_versionInfo.contains("QT_INSTALL_BINS")) {
QFileInfo fi(m_versionInfo.value("QT_INSTALL_BINS"));
if (!fi.exists())
m_notInstalled = true;
}
if (m_versionInfo.contains("QT_INSTALL_HEADERS")){
QFileInfo fi(m_versionInfo.value("QT_INSTALL_HEADERS"));
if (!fi.exists())
m_notInstalled = true;
}
if (m_versionInfo.contains("QT_INSTALL_DOCS")){
QFileInfo fi(m_versionInfo.value("QT_INSTALL_DOCS"));
if (fi.exists())
m_hasDocumentation = true;
}
if (m_versionInfo.contains("QT_INSTALL_EXAMPLES")){
QFileInfo fi(m_versionInfo.value("QT_INSTALL_EXAMPLES"));
if (fi.exists())
m_hasExamples = true;
}
if (m_versionInfo.contains("QT_INSTALL_DEMOS")){
QFileInfo fi(m_versionInfo.value("QT_INSTALL_DEMOS"));
if (fi.exists())
m_hasDemos = true;
}
QString QtVersion::findQtBinary(const QStringList &possibleCommands) const
{
const QString qtdirbin = versionInfo().value(QLatin1String("QT_INSTALL_BINS")) + QLatin1Char('/');
foreach (const QString &possibleCommand, possibleCommands) {
const QString fullPath = qtdirbin + possibleCommand;
if (QFileInfo(fullPath).isFile())
return QDir::cleanPath(fullPath);
}
QString QtVersion::uicCommand() const
{
if (!isValid())
if (!m_uicCommand.isNull())
return m_uicCommand;
#ifdef Q_OS_WIN
const QStringList possibleCommands(QLatin1String("uic.exe"));
#else
possibleCommands << QLatin1String("uic-qt4") << QLatin1String("uic4") << QLatin1String("uic");
#endif
m_uicCommand = findQtBinary(possibleCommands);
return m_uicCommand;
}
// Return a list of GUI binary names
// 'foo', 'foo.exe', 'Foo.app/Contents/MacOS/Foo'
static inline QStringList possibleGuiBinaries(const QString &name)
{
return QStringList(name + QLatin1String(".exe"));
#elif defined(Q_OS_MAC) // 'Foo.app/Contents/MacOS/Foo'
QString upCaseName = name;
upCaseName[0] = upCaseName.at(0).toUpper();
QString macBinary = upCaseName;
macBinary += QLatin1String(".app/Contents/MacOS/");
macBinary += upCaseName;
return QStringList(macBinary);
return QStringList(name);
}
QString QtVersion::designerCommand() const
{
if (!isValid())
if (m_designerCommand.isNull())
m_designerCommand = findQtBinary(possibleGuiBinaries(QLatin1String("designer")));
return m_designerCommand;
}
QString QtVersion::linguistCommand() const
{
if (!isValid())
if (m_linguistCommand.isNull())
m_linguistCommand = findQtBinary(possibleGuiBinaries(QLatin1String("linguist")));
return m_linguistCommand;
bool QtVersion::supportsTargetId(const QString &id) const
{
updateToolChainAndMkspec();
return m_targetIds.contains(id);
}
QSet<QString> QtVersion::supportedTargetIds() const
{
updateToolChainAndMkspec();
return m_targetIds;
bool QtVersion::supportsMobileTarget() const
{
return supportsTargetId(Constants::S60_DEVICE_TARGET_ID) ||
supportsTargetId(Constants::S60_EMULATOR_TARGET_ID) ||
supportsTargetId(Constants::MAEMO_DEVICE_TARGET_ID) ||
supportsTargetId(Constants::QT_SIMULATOR_TARGET_ID);
QList<QSharedPointer<ProjectExplorer::ToolChain> > QtVersion::toolChains() const
return m_toolChains;
}
ProjectExplorer::ToolChain *QtVersion::toolChain(ProjectExplorer::ToolChain::ToolChainType type) const
{
foreach(const QSharedPointer<ProjectExplorer::ToolChain> &tcptr, toolChains())
if (tcptr->type() == type)
return tcptr.data();
return 0;
}
QList<ProjectExplorer::ToolChain::ToolChainType> QtVersion::possibleToolChainTypes() const
QList<ProjectExplorer::ToolChain::ToolChainType> types;
foreach(const QSharedPointer<ProjectExplorer::ToolChain> &tc, toolChains())
types << tc->type();
return types;
}
// if none, then it's INVALID everywhere this function is called
typedef QSharedPointer<ProjectExplorer::ToolChain> ToolChainPtr;
if (m_toolChainUpToDate)
return;
if (!isValid()) {
m_targetIds.insert(Constants::DESKTOP_TARGET_ID);
// no .qmake.cache so look at the default mkspec
QString baseMkspecDir = versionInfo().value("QMAKE_MKSPECS");
if (baseMkspecDir.isEmpty())
baseMkspecDir = versionInfo().value("QT_INSTALL_DATA") + "/mkspecs";
#ifdef Q_OS_WIN
baseMkspecDir = baseMkspecDir.toLower();
#endif
QString mkspecFullPath = baseMkspecDir + "/default";
// qDebug() << "default mkspec is located at" << mkspecFullPath;
#ifdef Q_OS_WIN
QFile f2(mkspecFullPath + "/qmake.conf");
if (f2.exists() && f2.open(QIODevice::ReadOnly)) {
while (!f2.atEnd()) {
QByteArray line = f2.readLine();
if (line.startsWith("QMAKESPEC_ORIGINAL")) {
const QList<QByteArray> &temp = line.split('=');
if (temp.size() == 2) {
QString possibleFullPath = temp.at(1).trimmed();
// We sometimes get a mix of different slash styles here...
possibleFullPath = possibleFullPath.replace('\\', '/');
if (QFileInfo(possibleFullPath).exists()) // Only if the path exists
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
}
break;
}
}
f2.close();
}
#elif defined(Q_OS_MAC)
QFile f2(mkspecFullPath + "/qmake.conf");
if (f2.exists() && f2.open(QIODevice::ReadOnly)) {
while (!f2.atEnd()) {
QByteArray line = f2.readLine();
if (line.startsWith("MAKEFILE_GENERATOR")) {
const QList<QByteArray> &temp = line.split('=');
if (temp.size() == 2) {
const QByteArray &value = temp.at(1);
if (value.contains("XCODE")) {
// we don't want to generate xcode projects...
// qDebug() << "default mkspec is xcode, falling back to g++";
mkspecFullPath = baseMkspecDir + "/macx-g++";
}
//resolve mkspec link
QFileInfo f3(mkspecFullPath);
while (f3.isSymLink()) {
mkspecFullPath = f3.symLinkTarget();
f3.setFile(mkspecFullPath);
}
}
break;
}
}
f2.close();
}
#else
QFileInfo f2(mkspecFullPath);
while (f2.isSymLink()) {
mkspecFullPath = f2.symLinkTarget();
f2.setFile(mkspecFullPath);
}
#endif
#ifdef Q_OS_WIN
#endif
m_mkspecFullPath = mkspecFullPath;
QString mkspec = m_mkspecFullPath;
if (mkspec.startsWith(baseMkspecDir)) {
mkspec = mkspec.mid(baseMkspecDir.length() + 1);
} else {
QString sourceMkSpecPath = sourcePath() + "/mkspecs";
if (mkspec.startsWith(sourceMkSpecPath)) {
mkspec = mkspec.mid(sourceMkSpecPath.length() + 1);
} else {
// Do nothing
}
}
m_mkspec = mkspec;
// qDebug()<<"mkspec for "<<qmakeCommand()<<" is "<<m_mkspec<<m_mkspecFullPath;
ProFileOption option;
option.properties = versionInfo();
ProMessageHandler msgHandler(true);
ProFileCacheManager::instance()->incRefCount();
ProFileParser parser(ProFileCacheManager::instance()->cache(), &msgHandler);
ProFileEvaluator evaluator(&option, &parser, &msgHandler);
if (ProFile *pro = parser.parsedProFile(m_mkspecFullPath + "/qmake.conf")) {
evaluator.setCumulative(false);
evaluator.accept(pro, ProFileEvaluator::LoadProOnly);
pro->deref();
}
QString qmakeCXX = evaluator.values("QMAKE_CXX").join(" ");
QString makefileGenerator = evaluator.value("MAKEFILE_GENERATOR");
QString ce_sdk = evaluator.values("CE_SDK").join(QLatin1String(" "));
QString ce_arch = evaluator.value("CE_ARCH");
QString qt_arch = evaluator.value("QT_ARCH");
if (!ce_sdk.isEmpty() && !ce_arch.isEmpty()) {
QString wincePlatformName = ce_sdk + " (" + ce_arch + QLatin1Char(')');
m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatformName));
m_targetIds.insert(Constants::DESKTOP_TARGET_ID);
} else if (makefileGenerator == QLatin1String("SYMBIAN_ABLD") ||
makefileGenerator == QLatin1String("SYMBIAN_SBSV2") ||
makefileGenerator == QLatin1String("SYMBIAN_UNIX")) {
if (S60Manager *s60mgr = S60Manager::instance()) {
m_targetIds.insert(QLatin1String(Constants::S60_DEVICE_TARGET_ID));
m_toolChains << ToolChainPtr(s60mgr->createGCCEToolChain(this));
if (S60Manager::hasRvctCompiler())
m_toolChains << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5))
<< ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6));
if (!mwcDirectory().isEmpty()) {
m_toolChains << ToolChainPtr(s60mgr->createWINSCWToolChain(this));
m_targetIds.insert(QLatin1String(Constants::S60_EMULATOR_TARGET_ID));
if (S60Manager::hasRvctCompiler())
m_toolChains << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC));
m_toolChains << ToolChainPtr(s60mgr->createGCCE_GnuPocToolChain(this));
m_targetIds.insert(QLatin1String(Constants::S60_DEVICE_TARGET_ID));
} else if (qt_arch.startsWith(QLatin1String("arm"))
&& MaemoManager::instance().isValidMaemoQtVersion(this)) {
m_toolChains << ToolChainPtr(MaemoManager::instance().maemoToolChain(this));
m_targetIds.insert(QLatin1String(Constants::MAEMO_DEVICE_TARGET_ID));
} else if (qmakeCXX == "cl" || qmakeCXX == "icl") {
// TODO proper support for intel cl. Detect matching VC version unless set.
if (m_msvcVersion.isEmpty())
m_msvcVersion = ProjectExplorer::MSVCToolChain::findInstallationByMkSpec(isQt64Bit(), mkspec).name;
ProjectExplorer::ToolChain::createMSVCToolChain(m_msvcVersion, isQt64Bit()));
m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
} else if (qmakeCXX == "g++" && makefileGenerator == "MINGW") {
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
//addToEnvironment(env);
env.prependOrSetPath(mingwDirectory() + "/bin");
qmakeCXX = env.searchInPath(qmakeCXX);
ProjectExplorer::ToolChain::createMinGWToolChain(qmakeCXX, mingwDirectory()));
m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
} else if (qmakeCXX.contains("g++")) { // All g++ variants are treated as desktop g++
// we should try to do a better job, but for now that's good enough
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
//addToEnvironment(env);
m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createGccToolChain(qmakeCXX));
m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
} else if (qmakeCXX == QLatin1String("icpc")) {
m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createLinuxIccToolChain());
m_targetIds.insert(QLatin1String(Constants::DESKTOP_TARGET_ID));
if (m_toolChains.isEmpty()) {
qDebug()<<"Could not create ToolChain for"<<m_mkspecFullPath<<qmakeCXX;
qDebug()<<"Qt Creator doesn't know about the system includes, nor the systems defines.";
}
QStringList configValues = evaluator.values("CONFIG");
m_defaultConfigIsDebugAndRelease = false;
foreach(const QString &value, configValues) {
if (value == "debug")
m_defaultConfigIsDebug = true;
else if (value == "release")
m_defaultConfigIsDebug = false;
else if (value == "build_all")
m_defaultConfigIsDebugAndRelease = true;
}
// Is this actually a simulator Qt?
if (configValues.contains(QLatin1String("simulator"))) {
m_targetIds.clear();
m_targetIds.insert(QLatin1String(Constants::QT_SIMULATOR_TARGET_ID));
}
ProFileCacheManager::instance()->decRefCount();
m_toolChainUpToDate = true;
QString QtVersion::mwcDirectory() const
{
return m_mwcDirectory;
}
void QtVersion::setMwcDirectory(const QString &directory)
{
m_mwcDirectory = directory;
QString QtVersion::s60SDKDirectory() const
{
return m_s60SDKDirectory;
}
void QtVersion::setS60SDKDirectory(const QString &directory)
{
m_s60SDKDirectory = directory;
QString QtVersion::gcceDirectory() const
{
return m_gcceDirectory;
}
void QtVersion::setGcceDirectory(const QString &directory)
{
m_gcceDirectory = directory;
QString QtVersion::mingwDirectory() const
{
return m_mingwDirectory;
}
void QtVersion::setMingwDirectory(const QString &directory)
{
m_mingwDirectory = directory;
m_toolChainUpToDate = false;
}
QString QtVersion::msvcVersion() const
{
return m_msvcVersion;
}
void QtVersion::setMsvcVersion(const QString &version)
{
m_msvcVersion = version;
m_toolChainUpToDate = false;
void QtVersion::addToEnvironment(ProjectExplorer::Environment &env) const
env.set("QTDIR", QDir::toNativeSeparators(versionInfo().value("QT_INSTALL_DATA")));
env.prependOrSetPath(versionInfo().value("QT_INSTALL_BINS"));
}
int QtVersion::uniqueId() const
{
return m_id;
}
int QtVersion::getUniqueId()
{
return QtVersionManager::instance()->getUniqueId();
&& !qmakeCommand().isEmpty()
&& !displayName().isEmpty()
&& !m_notInstalled
&& m_versionInfo.contains("QT_INSTALL_BINS");
}
QString QtVersion::invalidReason() const
{
if (isValid())
return QString();
return QCoreApplication::translate("QtVersion", "No qmake path set");
return QCoreApplication::translate("QtVersion", "Qt version has no name");
return QCoreApplication::translate("QtVersion", "Qt version is not properly installed, please run make install");
if (!m_versionInfo.contains("QT_INSTALL_BINS"))
return QCoreApplication::translate("QtVersion",
"Could not determine the path to the binaries of the Qt installation, maybe the qmake path is wrong?");
QtVersion::QmakeBuildConfigs QtVersion::defaultBuildConfig() const
QtVersion::QmakeBuildConfigs result = QtVersion::QmakeBuildConfig(0);
if (m_defaultConfigIsDebugAndRelease)
result = QtVersion::BuildAll;
if (m_defaultConfigIsDebug)
result = result | QtVersion::DebugBuild;
bool QtVersion::hasDebuggingHelper() const
{
return m_hasDebuggingHelper;
}
QString QtVersion::debuggingHelperLibrary() const
{
QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
if (qtInstallData.isEmpty())
return DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(qtInstallData);
QStringList QtVersion::debuggingHelperLibraryLocations() const
{
QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
if (qtInstallData.isEmpty())
return DebuggingHelperLibrary::debuggingHelperLibraryLocationsByInstallData(qtInstallData);
bool QtVersion::supportsBinaryDebuggingHelper() const
{
QList<ProjectExplorer::ToolChain::ToolChainType> types = possibleToolChainTypes();
if (types.contains(ProjectExplorer::ToolChain::GCC)
|| types.contains(ProjectExplorer::ToolChain::LINUX_ICC)
|| types.contains(ProjectExplorer::ToolChain::MSVC)
|| types.contains(ProjectExplorer::ToolChain::WINCE)
|| types.contains(ProjectExplorer::ToolChain::GCC_MAEMO)
|| types.contains(ProjectExplorer::ToolChain::OTHER)
|| types.contains(ProjectExplorer::ToolChain::UNKNOWN))
return true;
return false;
}
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
bool QtVersion::hasDocumentation() const
{
updateVersionInfo();
return m_hasDocumentation;
}
QString QtVersion::documentationPath() const
{
updateVersionInfo();
return m_versionInfo["QT_INSTALL_DOCS"];
}
bool QtVersion::hasDemos() const
{
updateVersionInfo();
return m_hasDemos;
}
QString QtVersion::demosPath() const
{
updateVersionInfo();
return m_versionInfo["QT_INSTALL_DEMOS"];
}
QString QtVersion::headerInstallPath() const
{
updateVersionInfo();
return m_versionInfo["QT_INSTALL_HEADERS"];
}
bool QtVersion::hasExamples() const
{
updateVersionInfo();
return m_hasExamples;
}
QString QtVersion::examplesPath() const
{
updateVersionInfo();
return m_versionInfo["QT_INSTALL_EXAMPLES"];
}
{
const QString make = qmakeCommand();
bool isAmd64 = false;
#ifdef Q_OS_WIN32
# ifdef __GNUC__ // MinGW lacking some definitions/winbase.h
# define SCS_64BIT_BINARY 6
# endif
bool success = GetBinaryTypeW(reinterpret_cast<const TCHAR*>(make.utf16()), &binaryType) != 0;
if (success && binaryType == SCS_64BIT_BINARY)
isAmd64=true;
// qDebug() << "isAmd64:" << isAmd64 << binaryType;
return isAmd64;
#else
Q_UNUSED(isAmd64)
return false;
QString QtVersion::buildDebuggingHelperLibrary()
{
QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
if (qtInstallData.isEmpty())
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
addToEnvironment(env);
// TODO: the debugging helper doesn't comply to actual tool chain yet
QList<QSharedPointer<ProjectExplorer::ToolChain> > alltc = toolChains();
ProjectExplorer::ToolChain *tc = alltc.isEmpty() ? 0 : alltc.first().data();
return QCoreApplication::translate("QtVersion", "The Qt Version has no toolchain.");
QString output;
QString directory = DebuggingHelperLibrary::copyDebuggingHelperLibrary(qtInstallData, &output);
if (!directory.isEmpty()) {
output += DebuggingHelperLibrary::buildDebuggingHelperLibrary(directory, tc->makeCommand(),
qmakeCommand(), mkspec(), env,
(tc->type() == ToolChain::GCC_MAEMO ? QLatin1String("-unix") : QLatin1String("")));
}