qmake运行时依赖的配置文件集 qmake.conf、.qmake.conf、.qmake.stash、.qmake.super、.qmake.cache文件

qmake.conf是qmake根据.pro文件生成makefile时默认依赖的qmake language语法的配置文件之一。生成makefile所依赖的配置文件在makefile中有展现,下面是Makefile中描述的Makefile生成规则(qmake生成Makefile并不需要显示写出这些依赖文件,qmake内部能自己定位和解析到):
参考:qmake 与 配置文件

qmake.conf文件是qt用于存放系统平台和编译器相关默认值的配置文件。后续的qt_lib_*.prl配置文件中对qmake.conf中定义的全局变量有所依赖。qt为所支持的各种系统平台和对应编译器附加了相关的配置文件,其位置在QtInstallDIr/Qt5.12.0\5.12.0\msvc2015_64\mkspecs中。
 

windows台式机系统的默认配置​​​​​​

 这里的每一个文件夹代表一个qt所支持的目标系统平台+编译器组合,比如windows台式机+msvc的目标系统相关的默认配置所在路径为win32_msvc。windows uwpx64+msvc2015的目标系统的配置路径为winrt-x64-msvc2015。
qmake.conf体系文件的作用包括对qmake的内置变量初始化、部分属性初始化等等操作。

QMAKESPEC

qmake requires a platform and compiler description file which contains many default values used to generate appropriate Makefiles. The standard Qt distribution comes with many of these files, located in the mkspecs subdirectory of the Qt installation.

The QMAKESPEC environment variable can contain any of the following:

  • A complete path to a directory containing a qmake.conf file. In this case qmake will open the qmake.conf file from within that directory. If the file does not exist, qmake will exit with an error.
  • The name of a platform-compiler combination. In this case, qmake will search in the directory specified by the mkspecs subdirectory of the data path specified when Qt was compiled (see QLibraryInfo::DataPath).

Note: The QMAKESPEC path will be automatically added to the generated Makefile after the contents of the INCLUDEPATH system variable.


.qmake.conf 是对qmake.conf的一个补充,一般用来设置内置变量或者全局的自定义变量等等,其加载时机在qmake.conf之前,意义是避免用户修改QtInstallDir\Qt5.12.0\5.12.0\msvc2015_64\mkspecs中的qmake.conf文件,让用户将关键改动放到.qmake.conf中,增加配置的灵活性,方便用户根据具体工程具体环境做一些配置而不去更改qmake.conf。
工程有需要的,应该在工程路径下最顶层的.pro同级的路径下自己添加.qmake.conf。qt源码中对.qmake.conf有一个辅助查找路径的功能。
.qmake.super,.qmake.cache,.qmake.stash是qmake通过脚本的cache()函数进行生成的。用于缓存变量信息之类的。这三个文件在加载系统配置前就会独立创建一个QMakeEvaluator对其单独加载解析一遍,获取到存在其中的XQMAKESPEC、QMAKESPEC、QMAKEPATH、QMAKEFEATURES这四个变量的值(如果存在的话)。然后加载完系统配置(loadSpecInternal())之后再对.qmake.super,.qmake.cache,.qmake.stash进行一遍加载。参考:qmake 与 配置文件 

qmake.conf、.qmake.conf及系列qmake language写的配置文件,目的是在qmake进行解析的前在为qmake配置环境相关参数去生成正确的makefile。配置文件中的配置选项在qmake生成Makefile的时候基本融入Makefile中了,比如.pro中的DEFINES会被对等加入Makefile中的DEFINES中,所有这些工程配置文件存在与否基本不会影响后面的jom的make中的编译过程(makefile中有生成makefile的规则对这些配置文件有所依赖,这是对make的唯一影响),对后续的程序运行也不会造成任何影响。需要注意的是qt.conf不是qmake中的配置文件,而是编译出的程序的配置文件,与exe在同目录下,它是程序运行时需要依赖的配置文件。参考:qt获取qt.conf 中内容过程 

在qt src的工程代码中,经常看到.pro中有load(qt_tools)这条语句,它表示qmake在loadSpec之前,根据是否有.qmake.conf来设置qmake language中的_QMAKE_CONF_变量值,在qt_tool.prf中调用的qt_build_paths.prf会依赖变量_QMAKE_CONF_。qt_build_paths.prf的目的是为了 辅助qmake在构建路径中生成与源码路径下同样结构的目录的过程 而设置所必须的全局变量。

qt_build_paths.prf的作用
#qt_build_paths.prf
#  W A R N I N G
#  -------------
#
# This file is not part of the Qt API.  It exists purely as an
# implementation detail.  It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#

# Find the module's source root dir.
isEmpty(_QMAKE_CONF_): error("Project has no top-level .qmake.conf file.")
MODULE_BASE_INDIR = $$dirname(_QMAKE_CONF_)
REAL_MODULE_BASE_OUTDIR = $$shadowed($$MODULE_BASE_INDIR)
MODULE_BASE_OUTDIR = $$REAL_MODULE_BASE_OUTDIR
!isEmpty(MODULE_BASE_DIR): MODULE_SYNCQT_DIR = $$MODULE_BASE_DIR    # compat for webkit
isEmpty(MODULE_SYNCQT_DIR): MODULE_SYNCQT_DIR = $$MODULE_BASE_INDIR
isEmpty(MODULE_QMAKE_OUTDIR): MODULE_QMAKE_OUTDIR = $$MODULE_BASE_OUTDIR

exists($$MODULE_BASE_INDIR/.git): \
    CONFIG += git_build

!force_independent {
    # If the module is not built independently, everything ends up in qtbase.
    # This is the case in non-prefix builds, except for selected modules.
    MODULE_BASE_OUTDIR = $$[QT_HOST_PREFIX]
    MODULE_QMAKE_OUTDIR = $$[QT_HOST_PREFIX]
}

qmake 源码中对 qmake language中的_QMAKE_CONF_变量赋值逻辑。(_QMAKE_CONF_赋值是在加载make.conf之前,而make.conf加载是在解析.pro之前)

//QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\qmake\library\qmakeevaluator.cpp
bool QMakeEvaluator::prepareProject(const QString &inDir){//获取.qmake.super,.qmake.conf,.qmake.cache,.qmake.stack的信息
    QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
    QString superdir;
    if (m_option->do_cache) {
        QString conffile;
        QString cachefile = m_option->cachefile;
        if (cachefile.isEmpty())  { //find it as it has not been specified
            if (m_outputDir.isEmpty())
                goto no_cache;
            superdir = m_outputDir;
            forever {
                QString superfile = superdir + QLatin1String("/.qmake.super");
                if (m_vfs->exists(superfile, flags)) {
                    m_superfile = QDir::cleanPath(superfile);
                    break;
                }
                QFileInfo qdfi(superdir);
                if (qdfi.isRoot()) {
                    superdir.clear();
                    break;
                }
                superdir = qdfi.path();
            }
            QString sdir = inDir;
            QString dir = m_outputDir;
            forever {
                conffile = sdir + QLatin1String("/.qmake.conf");
                if (!m_vfs->exists(conffile, flags))
                    conffile.clear();
                cachefile = dir + QLatin1String("/.qmake.cache");
                if (!m_vfs->exists(cachefile, flags))
                    cachefile.clear();
                if (!conffile.isEmpty() || !cachefile.isEmpty()) {
                    if (dir != sdir)
                        m_sourceRoot = sdir;
                    m_buildRoot = dir;
                    break;
                }
                if (dir == superdir)
                    goto no_cache;
                QFileInfo qsdfi(sdir);
                QFileInfo qdfi(dir);
                if (qsdfi.isRoot() || qdfi.isRoot())
                    goto no_cache;
                sdir = qsdfi.path();
                dir = qdfi.path();
            }
        } else {
            m_buildRoot = QFileInfo(cachefile).path();
        }
        m_conffile = QDir::cleanPath(conffile);
        m_cachefile = QDir::cleanPath(cachefile);
    }
  no_cache:

    QString dir = m_outputDir;
    forever {
        QString stashfile = dir + QLatin1String("/.qmake.stash");
        if (dir == (!superdir.isEmpty() ? superdir : m_buildRoot) || m_vfs->exists(stashfile, flags)) {
            m_stashfile = QDir::cleanPath(stashfile);
            break;
        }
        QFileInfo qdfi(dir);
        if (qdfi.isRoot())
            break;
        dir = qdfi.path();
    }

    return true;
}
......
bool QMakeEvaluator::loadSpecInternal()  //加载QtInstallDIr\Qt5.12.0\5.12.0\msvc2015_64\mkspecs下的spec.prf和qmake.conf
{
    if (evaluateFeatureFile(QLatin1String("spec_pre.prf")) != ReturnTrue)
        return false;
    QString spec = m_qmakespec + QLatin1String("/qmake.conf");
    if (evaluateFile(spec, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue) {
        evalError(fL1S("Could not read qmake configuration file %1.").arg(spec));
        return false;
    }
    
.......
bool QMakeEvaluator::loadSpec()  //先加载.qmake.super,.qmake.conf,.qmake.cache。然后加载spec_pre.prf和qmake.conf
{
......
    if (!m_superfile.isEmpty() && evaluator.evaluateFile(
      m_superfile, QMakeHandler::EvalConfigFile, LoadProOnly|LoadHidden) != ReturnTrue) {
        return false;
     }
    if (!m_conffile.isEmpty() && evaluator.evaluateFile(
        m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly|LoadHidden) != ReturnTrue)             
    {
        return false;
    }
    if (!m_cachefile.isEmpty() && evaluator.evaluateFile(
        m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly|LoadHidden) != ReturnTrue) 
    {
        return false;
    }
......
    if (!loadSpecInternal())
        return false;
    if (!m_conffile.isEmpty()) {
        valuesRef(ProKey("_QMAKE_CONF_")) << ProString(m_conffile);
        if (evaluateFile(
                m_conffile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
            return false;
    }
    if (!m_cachefile.isEmpty()) {
        valuesRef(ProKey("_QMAKE_CACHE_")) << ProString(m_cachefile);
        if (evaluateFile(
                m_cachefile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
            return false;
    }
    QMakeVfs::VfsFlags flags = (m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact);
    if (!m_stashfile.isEmpty() && m_vfs->exists(m_stashfile, flags)) {
        valuesRef(ProKey("_QMAKE_STASH_")) << ProString(m_stashfile);
        if (evaluateFile(
                m_stashfile, QMakeHandler::EvalConfigFile, LoadProOnly) != ReturnTrue)
            return false;
    }

....
}

QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
        ProFile *pro, QMakeHandler::EvalFileType type, LoadFlags flags) //解析pro文件
{
    .....
    bool ok = baseEval->loadSpec(); //加载环境配置
    ....
    m_handler->doneWithEval(currentProFile()); //解析pro文件
}

qmake命令行参数 - 百度文库

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值