当前位置: 首页 > news >正文

浅谈 qmake 之 pro、pri、prf、prl文件

尽管每次和cmake对比起来,我们总是说 qmake 简单、功能少。但是qmake仍然是一个非常复杂的东西,我想大多人应该和我一样吧:

  • 不是太清楚CONFIG等变量到底如何起作用的
  • 用过的qmake内置变量和函数不超过20个
  • 看Qt Creator源码或者QtSolution等库中自己使用的 *.pro 文件就想看天书一样

本文只能抓住一条线,简单介绍一下 *.pro、*.pri、*.prf、*.prl等四种文件:干嘛用的,如何用的

*.pro

qmake 的工程(project)文件,这个大家肯定都非常熟悉了。那我就不费话了,上例子:

这是一个典型的Qt示例程序的.pro文件(propriprfprl.pro):

TEMPLATE = app
CONFIG += QT
QT += core gui

TARGET = propriprfprl

SOURCES += main.cpp/
        widget.cpp
HEADERS  += widget.h
FORMS    += widget.ui
  • 前面3行是qmake的默认值,我们都可以省略
  • TARGET 这行指定工程名,我们也可以省略

*.pri

i 是什么东西?包含(include)的首字母。类似于C、C++中的头文件吧,反正就是我们可以吧 *.pro 文件内的一部分单独放到一个 *.pri 文件内,然后包含进来。

接前面的例子,我们将源文件的设置独立出来,放到propriprfprl.pri文件内:

SOURCES += main.cpp/
        widget.cpp
HEADERS  += widget.h
FORMS    += widget.ui

这时,我们的 propriprfprl.pro 文件就可以简化为:

TEMPLATE = app
CONFIG += QT
QT += core gui

TARGET = propriprfprl
include(propriprfprl.pri)
  • 这有什么用呢?对我们这个例子来说,确实没什么用,反而多了一个文件,更麻烦了。
  • 可是,如果一个大点的项目,含有多个*.pro文件呢,这些pro需要有些共同的设置或需要的文件,这时就很有必要了。

*.prf

f又是神马东东?特性(feature)的首字符

  • 和pri文件类似,该文件也是要被包含进pro文件的
  • 只是:它更隐蔽
  • 你经常和它打交道,可能却一直视而不见

我们这个例子中其实已经用到了,这就是

CONFIG+=QT

当我们在CONFIG中指定一个东西时,qmake就会尝试去加载相应的feature文件:

  • Qt安装目录下的 mkspecs/features/qt.prf
  • features 文件的文件名必须小写
  • qmake 去哪些目录下搜索features文件呢?
    • manual中有介绍,此处略
    • 暂时只知道前面提到的 $$QTDIR/mkspecs/features 就可以了

写一个自己的features文件:propriprfprl.prf

win32:CONFIG += console
  • 为win32的程序添加控制台,有点多次一举哈。
  • 将该文件放置到我们前面提到的目录中

然后在pro文件内添加

CONFIG += propriprfprl

看到和 CONFIG += console 同样的效果了吧?

注:我们也可以使用 load命令来加载prf文件,比如前面的命令可以认为等价于

load(propriprfprl)

*.prl

l 这个东西容易理解,链接(link)的首字符。主要和生成与使用静态库密切相关(动态库也可以有该文件,去Qt安装目录下的lib目录下看看即可)。

  • 生成静态库时,我们需要使用下列配置(进而生成和库文件同名的 *.prl 文件)
CONFIG += create_prl
  • 当工程的TEMPLATE为app时,会自动添加如下指令(找库文件的时候,会尝试找相应的 *.prl 文件)
CONFIG += link_pri

那么该文件有什么用处呢?举一个大家可能熟悉的例子QextSerialPort1.2这个库(windows下的情况):

  • 编译时,需要 setupapi.lib advapi32.lib user32.lib 这几个库文件
  • 编译成静态库以后,它本身是不包含这3个库文件信息的
  • 于是,当我们使用这个 QextSerialPort 静态库,还是需要指定 这几个库文件

如果有prl文件呢,该文件就会包含依赖信息了,我们看一下:

QMAKE_PRL_BUILD_DIR = E:/dbzhang800-qextserialport/buildlib
QMAKE_PRO_INPUT = buildlib.pro
QMAKE_PRL_TARGET = qextserialport-1.2
QMAKE_PRL_CONFIG = include_source_dir incredibuild_xge lex yacc warn_on uic resources incremental_off windows release ReleaseBuild Release build_pass qt warn_on release incremental flat link_prl precompile_header autogen_precompile_source copy_dir_files debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe stl exceptions rtti mmx 3dnow sse sse2 release ReleaseBuild Release build_pass qt qextserialport-buildlib create_prl qextserialport-uselib qextserialport-static static debug_and_release build_all release ReleaseBuild Release build_pass no_autoqmake staticlib static moc thread
QMAKE_PRL_LIBS = setupapi.lib advapi32.lib user32.lib d://Qt//4.7.0//lib//QtGui4.lib d://Qt//4.7.0//lib//QtCore4.lib 

参考

  • qmake manual:qmake-advanced-usage.html
  • qmake manual:qmake-variable-reference.html
  • http://www.qtcentre.org/wiki/index.php?title=Undocumented_qmake

相关文章:

  • android实现点击两次返回键实现退出功能
  • Qt共享内存的使用
  • Qt for android 弹出Detected problems with app native libraries (please consult log for detail): 解决方案
  • qml去掉标题栏后实现窗口拖动
  • Qt for android 在安卓上面运行app启动闪黑屏的解决方法
  • Qt 中文及字符混合加密,双重加密解密
  • Qt 实时监控网络状态
  • VNISEdit工具打包QT程序
  • Linux安装python3.6
  • Qt如何输出日志输出文件(最全最新的框架方法,包含Qt4和Qt5)
  • GCC 7.3.0编译安装
  • add-apt-repository: command not found
  • Ubuntu12.04升级C++11标准
  • ubuntu中安装lua5.3
  • ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • android 一些 utils
  • gitlab-ci配置详解(一)
  • Javascript Math对象和Date对象常用方法详解
  • JavaScript创建对象的四种方式
  • Java的Interrupt与线程中断
  • Markdown 语法简单说明
  • redis学习笔记(三):列表、集合、有序集合
  • Redis字符串类型内部编码剖析
  • 对超线程几个不同角度的解释
  • 分布式熔断降级平台aegis
  • 解析带emoji和链接的聊天系统消息
  • 类orAPI - 收藏集 - 掘金
  • 前端技术周刊 2019-01-14:客户端存储
  • 手机端车牌号码键盘的vue组件
  • 算法-图和图算法
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 优化 Vue 项目编译文件大小
  • 智能合约开发环境搭建及Hello World合约
  • k8s使用glusterfs实现动态持久化存储
  • Prometheus VS InfluxDB
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (Note)C++中的继承方式
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (转)VC++中ondraw在什么时候调用的
  • (转)创业家杂志:UCWEB天使第一步
  • (转)重识new
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .gitattributes 文件
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .NET 读取 JSON格式的数据