qmake 之 CONFIG 与 QT 乱谈

看qtcn论坛中经常有人忘记 QT+=network 等语句。随便写写吧,或许对他人有帮助。

写来写去,发现越写越乱,就这样吧,反正主要的内容很简单。 dbzhang800 20101116

从哪儿开始呢?

不妨先看个例子吧:

#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
qDebug()<<"hello qt!";
app.exec();
}

如何编译这个程序呢?我们知道,构建一个C++程序:无非是编译(包括编译预处理)、链接 这几步。

  • 编译时,我们需要让预处理器能找到我们的头文件(即:指定头文件路径)
  • 链接时,我们需要让链接器能找到我们需要的库

对这个程序来说呢,也就是,指定

头文件路径

$QTDIR/include

库文件

QtCore4.lib(或相应的其他形式)

答案就简单了(分别采用g++和msvc进行编译):

g++ main.cpp -Ie:\Qt\4.7.0\include -o main -Le:\Qt\4.7.0\lib -lQtCore4

cl main.cpp -ID:/Qt/4.7.0/include -Femain -link -LIBPATH:D:/Qt/4.7.0/lib QtCore4.lib

参数的含义可参考:

头文件 库文件

我们知道,在C++中,使用第三方库的过程,就是包含头文件、链接库文件的过程:

使用QString

需要 -lQtCore4

使用QWidget

需要 -lQtGui4

使用QFtp

需要 -lQtNetWork4

使用QWebView

需要 -lQtWebKit4

...

...

我们接下来先简单看一下Qt的头文件和库文件,然后看看qmake是如何处理的:为什么我们不需要在.pro文件内指定这些头文件路径和库文件

Qt头文件

估计不少对C、C++不是那么熟的同仁,会对Qt中的下面各种写法感到迷惑(比如我们要用到 QString 的头文件):

  • #include<QString>

  • #include<QtCore/QString>

  • #include<string.h>

  • #include<QtCore/string.h>

不过咱们都是学过C、C++的,都知道尖括号或双引号内就是一个头文件的文件名。所以理解起来应该没什么难度,转来转去无非是下面的几个文件:

  • $QTDIR/include/QtCore/QString

  • $QTDIR/include/QtCore/qstring.h

所以呢?当你

使用头文件

需要指定头文件路径

#include<QString>

$QTDIR/include/QtCore

#include<QtCore/QString>

$QTDIR/include

有些人喜欢用#include<QtCore>这种写法,这是头文件在哪儿呢?它的全路径是

$QTDIR/include/QtCore/QtCore

与此类似

使用头文件

需要指定头文件路径

#include<QtCore>

$QTDIR/include/QtCore

#include<QtGui>

$QTDIR/include/QtGui

#include<QtScript>

$QTDIR/include/QtScript

...

...

不清楚你注意到没?如果你坚持使用 #include<QtCore/QString> 这种写法,你只需要一个头文件路径,这就是$QTDIR/include

Qt库文件

和头文件比起来,库文件似乎就比较简单了。因为它们直接在下面的路径下

  • $QTDIR/lib

路径简单,可是库呢?

  • 动态库(共享库)、静态库(归档库)
  • 不同平台下有不同的后缀。 .dll, .so, .dylib, .lib, .a
  • 带调试信息,不带调试信息的库
  • windows下的动态库需要引导库

以windows下MSVC编译的Qt4为例:

  • 静态编译

    • $QTDIR/lib/QtCore.lib

    • $QTDIR/lib/QtCored.lib

  • 动态编译
    • $QTDIR/lib/QtCore4.lib

    • $QTDIR/lib/QtCore4.dll

    • $QTDIR/lib/QtCored4.lib

    • $QTDIR/lib/QtCored4.dll

qmake

用qmake管理我们前面的例子的话,我们只需要写一个简单 .pro 文件

CONFIG += console
QT -= gui
SOURCES += main.cpp

这样一来,qmake是如何知道需要哪些头文件和库文件的呢?

其实,这儿省略了两行代码(因为是默认值,所以可以不写,但对我们理解这个例子至关重要)

CONFIG += qt 
QT += core

那么这些东西如何和前面的东西联系起来呢?

首先

CONFIG += qt

将使得最终包含:

  • 头文件路径

    $QTDIR/include

    库文件路径

    $QTDIR/lib

其次

QT += core

将对Qt相关的路径进一步细化

  • 头文件路径中

    $QTDIR/include/QtCore

    链接需要的库

    QtCore4.lib

    编译预处理的宏

    QT_CORE_LIB

看,现在头文件路径和库文件都有了,而且,无论头文件写成 QString 还是 !QtCore/QString 都能被找到。

再次,由于在 .pro 文件内

  • CONFIG 中默认包含 qt
  • QT 中默认包含 core

这使得这点变得更加隐藏

QT

举个例子,如果我们在程序中用了

#include <QFtp>
...
QFtp xxx;
...

那么我们将需要

  • 指定头文件路径

    $QTDIR/include/QtNetwork

    指定要链接的库

    QtNetWork4.lib

这两个正是下面的语句所做的:

QT += network

  • 除此,该语句还定义宏 QT_NETWORK_LIB

哈哈哈,发现下面问题的答案了没:

  • 忘记了QT+=network这样的语句,为什么有的人遇到的编译错误,有的人遇到的是链接错误?

  • 因为没有头文件路径,编译时就会找不到头文件。(但如果写成 QtNetWork/QFtp ,则不会有这个问题。)
  • 因为没有指定链接库,即使头文件找到了,链接时也肯定会遇到问题的。(答案很明显吧)

如何启用一个模块

当启用一个模块时,我们

  • 要么是修改 CONFIG 变量
  • 要么是细化 QT 变量
  • 而有的模块,两者均可。

修改QT

这是最常规的,QtCore、QtGui、QtNetWork 等等

  • 使用Core模块

    QT += core

    使用Gui模块

    QT += gui

    使用NetWork模块

    QT+=network

修改CONFIG

比如 QAxContainer 模块

CONFIG += qaxcontainer两者均可

比如 QtTest 模块:

我们可以使用

CONFIG += qtestlib

也可以使用

QT += testlib

两者的区别是,后者会定义 QT_TESTLIB_LIB 这样宏(同QT+= core gui等效果一样),前者则不会定义这个宏。

Qt *.pro编写一般规则的更多相关文章

  1. 【整理】QT .pro文件中的变量说明

    注释 以"#"开始的行,直到结束 模板变量 告诉qmake生成哪种makefile TEMPLATE = app 其中 app - 表示该工程建立一个应用程序的makefile.这 ...

  2. QT .pro文件中的变量说明

      https://blog.csdn.net/tanou3212/article/details/79942840 TEMPLATE:定义了工程的编译模式 赋值方式为:TEMPLATE=app (1 ...

  3. 《玩转Django2.0》读书笔记-编写URL规则

    <玩转Django2.0>读书笔记-编写URL规则 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. URL(Uniform Resource Locator,统一资源定位 ...

  4. Linux防火墙基础与编写防火墙规则

    Iptables采用了表和链的分层结构,每个规则表相当于内核空间的一个容器,根据规则集的不同用途划分为默认的四个表,raw表,mangle表,nat表,filter表,每个表容器内包括不同的规则链,根 ...

  5. 03 编写URL规则

    3-1 URL编写规则 # 在每个App中设置独立的静态资源和模板文件并添加一个空白内容的urls.py文件. # 当程序收到用户请求的时候,首先在根目录的urls.py查找该URL属于哪个APP,然 ...

  6. 利用Eric+Qt Designer编写倒计时时钟

    [前言]前几日通过编写命令行通讯录,掌握了Python的基本语法结构,于是开始向更高水平冲击,利用Eric与Qt Designer 编写一个带界面的小程序.本次实操中也确实遇到了不少问题,通过学习也都 ...

  7. Qt Pro文件与Qt模块启用

    看qt论坛中经常有人忘记 QT+=network 等语句.随便写写吧,或许对他人有帮助. 一.从哪开始呢 不妨先看个例子吧: #include <QtCore/QCoreApplication& ...

  8. Prometheus 编写告警规则案例

    Prometheus 编写告警规则案例 注:确保alertmanager配置完毕! 1.创建编辑文件:vim /usr/local/prometheus/rules/node.yml # groups ...

  9. Cluster基础(一):配置iSCSI服务、编写udev规则、配置并访问NFS共享、部署Multipath多路径环境

    一.配置iSCSI服务 目标: 本案例要求先搭建好一台iSCSI服务器,并将整个磁盘共享给客户端: 虚拟机添加新的磁盘 将新添加的磁盘分区并创建两个逻辑卷 逻辑卷名称分别为:/dev/myvg/isc ...

随机推荐

  1. NYOJ--1237最大岛屿

    最大岛屿 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 神秘的海洋,惊险的探险之路,打捞海底宝藏,激烈的海战,海盗劫富等等.加勒比海盗,你知道吧?杰克船长驾驶着自己的的 ...

  2. java获取Json和http状态码

    最近再做接口自动化测试,其中有几个方法比较重要 1.获取http状态码 /* * 返回接口状态码 * */ public static String getHttpCode(String url) { ...

  3. iOS开发之——制作framework静态库教程

    环境: 硬件:macbook air 系统:OSX EI Capitan 版本:10.11.3 xcode : Version 7.2.1 (7C1002) 最近在做ios的静态库(据说framewo ...

  4. jQuery时间轴插件:jQuery Timelinr

    前言 这是一款可用于展示历史和计划的时间轴插件,尤其比较适合一些网站展示发展历程.大事件等场景.该插件基于jQuery,可以滑动切换.水平和垂直滚动.支持键盘方向键.经过扩展后可以支持鼠标滚轮事件. ...

  5. 获取WIN10技术预览版

    说明 这是一款预发行软件 在进行商业发行之前,我们可能会对 Windows Technical Preview 进行大量修改. Microsoft 不对此处提供的信息作任何明示或默示的担保. 有些产品 ...

  6. JMeter学习(十九)JMeter测试MongoDB

    JMeter测试MongoDB性能有两种方式,一种是利用JMeter直接进行测试MongoDB,还有一种是写Java代码方式测试MongoDB性能. 第一种方法 1.编写Java代码,内容如下: pa ...

  7. [转]Source Insight使用小技巧小结

    Source Insight是一款强大的代码查看工具,本身支持扩展性很好.下面我们就介绍2个扩展用例. 1.快速打开当前文件所在的目录,这个功能类似于eclipse的easyshell插件,就是能快速 ...

  8. 关于eclipse入门开发c/c++文章推荐

    1. 关于编译说明. http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/ 2. 关于快捷键与代码阅读 http://www.cn ...

  9. 用于json的 .ashx 小细节

    public void ProcessRequest(HttpContext context) { switch (action) { case "attribute_field_valid ...

  10. 委托--delegate

    委托,跟类很相似,能够定义对象,但是区别是 1,委托必须有关键字delegate. 2,委托有类型修饰符,比如void,string,int.修饰符取决于他的方法返回类型. 3,委托没有方法实现. d ...