Skip to content
Snippets Groups Projects
qtversionmanager.cpp 46.1 KiB
Newer Older
    if (mkspecPath.isEmpty())
        mkspecPath = versionInfo().value("QT_INSTALL_DATA") + "/mkspecs/default";
    else
        mkspecPath = mkspecPath + "/default";
//     qDebug() << "default mkspec is located at" << mkspecPath;
con's avatar
con committed
#ifdef Q_OS_WIN
    QFile f2(mkspecPath + "/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) {
                    mkspec = temp.at(1).trimmed();
con's avatar
con committed
                }
con's avatar
con committed
            }
        }
        f2.close();
    }
con's avatar
con committed
#elif defined(Q_OS_MAC)
    QFile f2(mkspecPath + "/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++";
                        mkspec = "macx-g++";
                    } else {
                        //resolve mkspec link
                        QFileInfo f3(mkspecPath);
                        if (f3.isSymLink()) {
                            mkspec = f3.symLinkTarget();
con's avatar
con committed
                        }
                    }
                }
con's avatar
con committed
            }
        }
        f2.close();
    }
con's avatar
con committed
#else
    QFileInfo f2(mkspecPath);
    if (f2.isSymLink()) {
        mkspec = f2.symLinkTarget();
    }
con's avatar
con committed
#endif

dt's avatar
dt committed
    m_mkspecFullPath = mkspec;
    int index = mkspec.lastIndexOf('/');
hjk's avatar
hjk committed
    if (index == -1)
con's avatar
con committed
        index = mkspec.lastIndexOf('\\');
    QString mkspecDir = QDir(versionInfo().value("QT_INSTALL_DATA") + "/mkspecs/").canonicalPath();
Joerg Bornemann's avatar
Joerg Bornemann committed
    if (index >= 0 && QDir(mkspec.left(index)).canonicalPath() == mkspecDir)
con's avatar
con committed
        mkspec = mkspec.mid(index+1).trimmed();

    m_mkspec = mkspec;
    m_mkspecUpToDate = true;
//    qDebug()<<"mkspec for "<<versionInfo().value("QT_INSTALL_DATA")<<" is "<<mkspec;
con's avatar
con committed
}

void QtVersion::updateQMakeCXX() const
{
    if (m_qmakeCXXUpToDate)
        return;
    ProFileReader *reader = new ProFileReader();
    reader->setCumulative(false);
    reader->setParsePreAndPostFiles(false);
    reader->readProFile(mkspecPath() + "/qmake.conf");
    m_qmakeCXX = reader->value("QMAKE_CXX");
    delete reader;
    m_qmakeCXXUpToDate = true;
}

ProjectExplorer::ToolChain *QtVersion::createToolChain(ProjectExplorer::ToolChain::ToolChainType type) const
    ProjectExplorer::ToolChain *tempToolchain = 0;
    if (type == ProjectExplorer::ToolChain::MinGW) {
        QString qmake_cxx = qmakeCXX();
        ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
        //addToEnvironment(env);
        env.prependOrSetPath(mingwDirectory()+"/bin");
        qmake_cxx = env.searchInPath(qmake_cxx);
        tempToolchain = ProjectExplorer::ToolChain::createMinGWToolChain(qmake_cxx, mingwDirectory());
        //qDebug()<<"Mingw ToolChain";
    } else if(type == ProjectExplorer::ToolChain::MSVC) {
con's avatar
con committed
        tempToolchain = ProjectExplorer::ToolChain::createMSVCToolChain(msvcVersion(), isQt64Bit());
        //qDebug()<<"MSVC ToolChain ("<<version->msvcVersion()<<")";
    } else if(type == ProjectExplorer::ToolChain::WINCE) {
        tempToolchain = ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatform());
        //qDebug()<<"WinCE ToolChain ("<<version->msvcVersion()<<","<<version->wincePlatform()<<")";
    } else if(type == ProjectExplorer::ToolChain::GCC || type == ProjectExplorer::ToolChain::LinuxICC) {
        QString qmake_cxx = qmakeCXX();
        ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
        //addToEnvironment(env);
        qmake_cxx = env.searchInPath(qmake_cxx);
        if (qmake_cxx.isEmpty()) {
            // macx-xcode mkspec resets the value of QMAKE_CXX.
            // Unfortunately, we need a valid QMAKE_CXX to configure the parser.
            qmake_cxx = QLatin1String("cc");
        }
        tempToolchain = ProjectExplorer::ToolChain::createGccToolChain(qmake_cxx);
        //qDebug()<<"GCC ToolChain ("<<qmake_cxx<<")";
#ifdef QTCREATOR_WITH_S60
    } else if (type == ProjectExplorer::ToolChain::WINSCW) {
        tempToolchain = S60Manager::instance()->createWINSCWToolChain(this);
    } else if (type == ProjectExplorer::ToolChain::GCCE) {
        tempToolchain = S60Manager::instance()->createGCCEToolChain(this);
con's avatar
con committed
    } else if (type == ProjectExplorer::ToolChain::RVCT_ARMV5
               || type == ProjectExplorer::ToolChain::RVCT_ARMV6) {
        tempToolchain = S60Manager::instance()->createRVCTToolChain(this, type);
        qDebug()<<"Could not create ToolChain for"<<mkspec();
        qDebug()<<"Qt Creator doesn't know about the system includes, nor the systems defines.";
    }
    return tempToolchain;
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);
    }
    return QString::null;
}

dt's avatar
dt committed
QString QtVersion::uicCommand() const
{
    if (!isValid())
        return QString::null;
    if (!m_uicCommand.isNull())
        return m_uicCommand;
#ifdef Q_OS_WIN
    const QStringList possibleCommands(QLatin1String("uic.exe"));
#else
dt's avatar
dt committed
    QStringList possibleCommands;
    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)
{
dt's avatar
dt committed
#ifdef Q_OS_WIN
    return QStringList(name + QLatin1String(".exe"));
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
#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);
dt's avatar
dt committed
#else
    return QStringList(name);
dt's avatar
dt committed
#endif
}

QString QtVersion::designerCommand() const
{
    if (!isValid())
        return QString::null;
    if (m_designerCommand.isNull())
        m_designerCommand = findQtBinary(possibleGuiBinaries(QLatin1String("designer")));
    return m_designerCommand;
}

QString QtVersion::linguistCommand() const
{
    if (!isValid())
        return QString::null;
    if (m_linguistCommand.isNull())
        m_linguistCommand = findQtBinary(possibleGuiBinaries(QLatin1String("linguist")));
    return m_linguistCommand;
QList<ProjectExplorer::ToolChain::ToolChainType> QtVersion::possibleToolChainTypes() const
con's avatar
con committed
{
    QList<ProjectExplorer::ToolChain::ToolChainType> toolChains;
con's avatar
con committed
    if (!isValid())
        return toolChains << ProjectExplorer::ToolChain::INVALID;
con's avatar
con committed
    const QString &spec = mkspec();
hjk's avatar
hjk committed
    if (spec.contains("win32-msvc") || spec.contains(QLatin1String("win32-icc")))
        toolChains << ProjectExplorer::ToolChain::MSVC;
    else if (spec.contains("win32-g++"))
        toolChains << ProjectExplorer::ToolChain::MinGW;
hjk's avatar
hjk committed
    else if (spec == QString::null)
        toolChains << ProjectExplorer::ToolChain::INVALID;
    else if (spec.contains("wince"))
        toolChains << ProjectExplorer::ToolChain::WINCE;
    else if (spec.contains("linux-icc"))
        toolChains << ProjectExplorer::ToolChain::LinuxICC;
#ifdef QTCREATOR_WITH_S60
    else if (spec.contains("symbian-abld"))
con's avatar
con committed
        toolChains << ProjectExplorer::ToolChain::GCCE
                << ProjectExplorer::ToolChain::RVCT_ARMV5
                << ProjectExplorer::ToolChain::RVCT_ARMV6
                << ProjectExplorer::ToolChain::WINSCW;
#endif
con's avatar
con committed
    else
        toolChains << ProjectExplorer::ToolChain::GCC;
    return toolChains;
}

ProjectExplorer::ToolChain::ToolChainType QtVersion::defaultToolchainType() const
{
    return possibleToolChainTypes().at(0);
con's avatar
con committed
}

con's avatar
con committed
#ifdef QTCREATOR_WITH_S60
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;
}
con's avatar
con committed
QString QtVersion::mingwDirectory() const
{
    return m_mingwDirectory;
}

void QtVersion::setMingwDirectory(const QString &directory)
{
    m_mingwDirectory = directory;
}

QString QtVersion::msvcVersion() const
{
    return m_msvcVersion;
}

dt's avatar
dt committed
QString QtVersion::wincePlatform() const
{
//    qDebug()<<"QtVersion::wincePlatform returning"<<ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf");
dt's avatar
dt committed
    return ProjectExplorer::CeSdkHandler::platformName(mkspecPath() + "/qmake.conf");
}

con's avatar
con committed
void QtVersion::setMsvcVersion(const QString &version)
{
    m_msvcVersion = version;
}

void QtVersion::addToEnvironment(ProjectExplorer::Environment &env) const
con's avatar
con committed
{
    env.set("QTDIR", versionInfo().value("QT_INSTALL_DATA"));
con's avatar
con committed
    QString qtdirbin = versionInfo().value("QT_INSTALL_BINS");
dt's avatar
dt committed
    env.prependOrSetPath(qtdirbin);
con's avatar
con committed
}

int QtVersion::uniqueId() const
{
    return m_id;
}

int QtVersion::getUniqueId()
{
    return QtVersionManager::instance()->getUniqueId();
con's avatar
con committed
}

bool QtVersion::isValid() const
{
    return (!(m_id == -1 || m_qmakeCommand == QString::null || m_name == QString::null || mkspec() == QString::null) && !m_notInstalled);
con's avatar
con committed
}

QtVersion::QmakeBuildConfig QtVersion::defaultBuildConfig() const
{
    updateVersionInfo();
    QtVersion::QmakeBuildConfig result = QtVersion::QmakeBuildConfig(0);
    if (m_defaultConfigIsDebugAndRelease)
        result = QtVersion::BuildAll;
    if (m_defaultConfigIsDebug)
        result = QtVersion::QmakeBuildConfig(result | QtVersion::DebugBuild);
    return result;
}

bool QtVersion::hasDebuggingHelper() const
{
    return m_hasDebuggingHelper;
}

QString QtVersion::debuggingHelperLibrary() const
{
    QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
    if (qtInstallData.isEmpty())
        return QString::null;
    return DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(qtInstallData);
QStringList QtVersion::debuggingHelperLibraryLocations() const
{
    QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
    if (qtInstallData.isEmpty())
con's avatar
con committed
        return QStringList();
    return DebuggingHelperLibrary::debuggingHelperLibraryLocationsByInstallData(qtInstallData);
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"];
}

bool QtVersion::hasExamples() const
{
    updateVersionInfo();
    return m_hasExamples;
}

QString QtVersion::examplesPath() const
{
    updateVersionInfo();
    return m_versionInfo["QT_INSTALL_EXAMPLES"];
}
con's avatar
con committed
bool QtVersion::isQt64Bit() const
{
        const QString make = qmakeCommand();
Daniel Molkentin's avatar
Daniel Molkentin committed
//        qDebug() << make;
        bool isAmd64 = false;
#ifdef Q_OS_WIN32
#  ifdef __GNUC__   // MinGW lacking some definitions/winbase.h
#    define SCS_64BIT_BINARY 6
        DWORD binaryType = 0;
        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
    ProjectExplorer::ToolChain *tc = createToolChain(defaultToolchainType());
    if (!tc)
        return QApplication::tr("The Qt Version has no toolchain.");
    tc->addToEnvironment(env);
    QString directory = DebuggingHelperLibrary::copyDebuggingHelperLibrary(qtInstallData, &output);
    if (!directory.isEmpty())
        output += DebuggingHelperLibrary::buildDebuggingHelperLibrary(directory, tc->makeCommand(), qmakeCommand(), mkspec(), env);
    m_hasDebuggingHelper = !debuggingHelperLibrary().isEmpty();