Qt Creator源码分析系列——HostOsInfo类

该篇文章内容主要集中Qt Creator HostOsInfo部分代码的分析。从分析插件中的coreplugin中的HostOsInfo模块开始,项目文件在路径\qt-creator-master\qt-creator-master\src\utils\utils-lib\下。

从hostosinfo.h引入的头文件看起:

#include "utils_global.h"
#include "osspecificaspects.h"
#include <QString>

utils_global.h内容如下所示,如果定义了UTILS_LIBRARY,则将QTCREATOR_UTILS_EXPORT定义为Q_DECL_EXPORT。如果定义了QTCREATOR_UTILS_STATIC_LIB,则将QTCREATOR_UTILS_EXPORT定义为空(单个文件进行手动测试)。否则,将QTCREATOR_UTILS_EXPORT定义为Q_DECL_IMPORT。只是用于设置编译输出方式的。

#pragma once
#include <qglobal.h>
#if defined(UTILS_LIBRARY)
#  define QTCREATOR_UTILS_EXPORT Q_DECL_EXPORT
#elif  defined(QTCREATOR_UTILS_STATIC_LIB) // Abuse single files for manual tests
#  define QTCREATOR_UTILS_EXPORT
#else
#  define QTCREATOR_UTILS_EXPORT Q_DECL_IMPORT
#endif

osspecificaspects.h

因为是windows平台,这里QTC_WIN_EXE_SUFFIX定义为".exe"。Utils命名空间里有代表操作系统类型的枚举类型。

#pragma once
#include <QString>
#include <algorithm>
#define QTC_WIN_EXE_SUFFIX ".exe"
namespace Utils {
// Add more as needed.
enum OsType { OsTypeWindows, OsTypeLinux, OsTypeMac, OsTypeOtherUnix, OsTypeOther };
namespace OsSpecificAspects {
// 如果操作系统类型是Windows,则在形参executable后加上后缀.exe
inline QString withExecutableSuffix(OsType osType, const QString &executable)
{
    QString finalName = executable;
    if (osType == OsTypeWindows)
        finalName += QLatin1String(QTC_WIN_EXE_SUFFIX);
    return finalName;
}
// 如果是Windows或者Mac平台则是Qt::CaseInsensitive(大小写不敏感)
inline Qt::CaseSensitivity fileNameCaseSensitivity(OsType osType)
{
    return osType == OsTypeWindows || osType == OsTypeMac ? Qt::CaseInsensitive : Qt::CaseSensitive;
}
inline Qt::CaseSensitivity envVarCaseSensitivity(OsType osType)
{
    return fileNameCaseSensitivity(osType);
}
// 路径分隔符  windows平台是; 其它平台是:
inline QChar pathListSeparator(OsType osType)
{
    return QLatin1Char(osType == OsTypeWindows ? ';' : ':');
}
// 键盘修改器 如果是Mac平台,则是Qt::MetaModifier 其他是Qt::ControlModifier
inline Qt::KeyboardModifier controlModifier(OsType osType)
{
    return osType == OsTypeMac ? Qt::MetaModifier : Qt::ControlModifier;
}
// 将Windows下的pathName中的/都替换为\\
inline QString pathWithNativeSeparators(OsType osType, const QString &pathName)
{
    if (osType == OsTypeWindows) {
        const int pos = pathName.indexOf('/');
        if (pos >= 0) {
            QString n = pathName;
            std::replace(std::begin(n) + pos, std::end(n), '/', '\\');
            return n;
        }
    }
    return pathName;
}
} // namespace OsSpecificAspects
} // namespace Utils

HostOsInfo类

HostOsInfo类包含了返回操作系统类型的hostOs函数、返回CPU架构的hostArchitecture函数

namespace Utils {
class QTCREATOR_UTILS_EXPORT HostOsInfo
{
public:
	// 这里的OsType就是上面介绍的枚举类型
    static constexpr OsType hostOs()
    {
#if defined(Q_OS_WIN)
        return OsTypeWindows;
#elif defined(Q_OS_LINUX)
        return OsTypeLinux;
#elif defined(Q_OS_MAC)
        return OsTypeMac;
#elif defined(Q_OS_UNIX)
        return OsTypeOtherUnix;
#else
        return OsTypeOther;
#endif
    }

    enum HostArchitecture { HostArchitectureX86, HostArchitectureAMD64, HostArchitectureItanium, HostArchitectureArm, HostArchitectureUnknown };
    static HostArchitecture hostArchitecture();

    static constexpr bool isWindowsHost() { return hostOs() == OsTypeWindows; }
    static constexpr bool isLinuxHost() { return hostOs() == OsTypeLinux; }
    static constexpr bool isMacHost() { return hostOs() == OsTypeMac; }
    static constexpr bool isAnyUnixHost()
    {
#ifdef Q_OS_UNIX
        return true;
#else
        return false;
#endif
    }

    static QString withExecutableSuffix(const QString &executable)
    {
        return OsSpecificAspects::withExecutableSuffix(hostOs(), executable);
    }

    static void setOverrideFileNameCaseSensitivity(Qt::CaseSensitivity sensitivity);
    static void unsetOverrideFileNameCaseSensitivity();
	// 文件名大小写敏感检查 
    static Qt::CaseSensitivity fileNameCaseSensitivity()
    {
        return m_useOverrideFileNameCaseSensitivity
                ? m_overrideFileNameCaseSensitivity
                : OsSpecificAspects::fileNameCaseSensitivity(hostOs());
    }

    static QChar pathListSeparator()
    {
        return OsSpecificAspects::pathListSeparator(hostOs());
    }

    static Qt::KeyboardModifier controlModifier()
    {
        return OsSpecificAspects::controlModifier(hostOs());
    }

    static bool canCreateOpenGLContext(QString *errorMessage);

private:
    static Qt::CaseSensitivity m_overrideFileNameCaseSensitivity;
    static bool m_useOverrideFileNameCaseSensitivity;
};

} // namespace Utils
#include "hostosinfo.h"
#include <QCoreApplication>

#if !defined(QT_NO_OPENGL) && defined(QT_GUI_LIB)
#include <QOpenGLContext>
#endif

#ifdef Q_OS_WIN
#include <qt_windows.h>
#endif

using namespace Utils;

//对静态函数进行初始化设置
Qt::CaseSensitivity HostOsInfo::m_overrideFileNameCaseSensitivity = Qt::CaseSensitive;
bool HostOsInfo::m_useOverrideFileNameCaseSensitivity = false;

void HostOsInfo::setOverrideFileNameCaseSensitivity(Qt::CaseSensitivity sensitivity)
{
    m_useOverrideFileNameCaseSensitivity = true;
    m_overrideFileNameCaseSensitivity = sensitivity;
}
void HostOsInfo::unsetOverrideFileNameCaseSensitivity()
{
    m_useOverrideFileNameCaseSensitivity = false;
}

#ifdef Q_OS_WIN
static WORD hostProcessorArchitecture()
{
    SYSTEM_INFO info;
    GetNativeSystemInfo(&info); // 该函数在C:\Qt\Tools\mingw530_32\i686-w64-mingw32\include的sysinfoapi.h中
    return info.wProcessorArchitecture;
}
#endif

HostOsInfo::HostArchitecture HostOsInfo::hostArchitecture()
{
#ifdef Q_OS_WIN
    static const WORD processorArchitecture = hostProcessorArchitecture();
    switch (processorArchitecture) {
    case PROCESSOR_ARCHITECTURE_AMD64: // 处于winnt.h中
        return HostOsInfo::HostArchitectureAMD64;
    case PROCESSOR_ARCHITECTURE_INTEL:
        return HostOsInfo::HostArchitectureX86;
    case PROCESSOR_ARCHITECTURE_IA64:
        return HostOsInfo::HostArchitectureItanium;
    case PROCESSOR_ARCHITECTURE_ARM:
        return HostOsInfo::HostArchitectureArm;
    default:
        return HostOsInfo::HostArchitectureUnknown;
    }
#else
    return HostOsInfo::HostArchitectureUnknown;
#endif
}
//检查能否使用OpenGL
bool HostOsInfo::canCreateOpenGLContext(QString *errorMessage)
{
#if defined(QT_NO_OPENGL) || !defined(QT_GUI_LIB)
    Q_UNUSED(errorMessage)
    return false;
#else
    static const bool canCreate = QOpenGLContext().create();
    if (!canCreate)
        *errorMessage = QCoreApplication::translate("Utils::HostOsInfo", "Cannot create OpenGL context.");
    return canCreate;
#endif
}
发布了134 篇原创文章 · 获赞 141 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/asmartkiller/article/details/104400542