捋完了CMake下的Debug与Release,同事突然问我一句,qmake下面的Debug与Release是怎么配置的,发现第一时间竟然想不起来了...
注:从cmake3.0开始,qmake已经没有多少优势了,Qt6自身也已经使用cmake构建,新的项目没必要再使用qmake。
本文内容:
qmake && make
:默认是release。但如果.pro内添加了CONFIG+=debug
,那么结果是debug。qmake CONFIG+=debug && make
:构建结果一定是 debugqmake CONFIG+=release && make
:构建结果一定是 release-
如果.pro内添加了
CONFIG+=debug_and_release
(不管是Windows下自动添加,还是Linux下你手动添加)qmake && make debug
:构建结果是 debugqmake && make release
:构建结果是 release
-
CONFIG += debug release debug release debug
:要好好理解 CONFIG(debug, debug|release)
:很有用/很常用/也很晦涩难懂build_pass
:是否有用看是否关注了
qmake使用
qmake的使用很简单,创建工程文件 xxxx.pro后,直接
qmake
make
就行了。
但是这编译出的程序是 debug 版本 还是 release ??
-
不严谨答案:release
-
严谨答案:不一定。
取决于在.pro内配置
-
在 xxxx.pro文件内添加
CONFIG += release
上面编译出来的就是 release -
在 xxxx.pro文件内添加
CONFIG += debug
上面编译出来的就是 debug
注意:这个是很反直觉的。如果类似语句可以多次添加(即使你没加,其他pri/prf/prl中也可能会加),此时,需要看谁在最后(如下,编译出来会是 release):
CONFIG += release
CONFIG += debug
CONFIG += debug release debug
CONFIG += release
所有的难以理解,都是从这个多次添加的用法开始的。命令行参数中的
CONFIG+=
也在干这个事情。
也可以命令行参数指定
除了可以在.pro内指定外,还可以使用qmake的命令行参数
如下命令,编译出来是debug:
qmake CONFIG+=debug
make
如下命令,编译出来是release:
qmake CONFIG+=release
make
还可以指定make的target
当在工程文件.pro内使用 debug_and_release
选项(这是 Windows 下的默认选项)。那么Makefile会支持两个target,这样,就不用在乎qmake指定什么了...
构建debug版本:
qmake
make debug
构建release版本:
qmake
make release
当然,你也可以这么写(反正make后面的 target 说了算)
qmake CONFIG+=debug
make release
去掉make后面的target,才轮到CONFIG+=debug
说了算
qmake CONFIG+=debug
make
qmake 之 CONFIG(debug, debug|release)
这个怪异的写法,是在解决一个很很常规的问题。
问题起源
在 Qt 编程中,10多年前,多数人用的都是 qmake,并编写相应pro文件。
实际中经常需要对 debug 与 release 两种编译模式 设置不同的选项,比方说链接不同库
遇到该问题,简单看看qmake的manual,不少人都会写出类似下面的内容:
debug {
LIBS += -L../lib1 -lhellod
}
release {
LIBS += -L../lib2 -lhello
}
很不幸,这么做通常不能正常工作。
如果打开看生成的makefile文件,会发现 无论是debug还是release,上面的两个语句都会同时起作用。也就是说,上面相当于
LIBS += -L../lib1 -lhellod -L../lib2 -lhello
原因
这是很违反直觉的,因为CONFIG可以同时定义 debug 和 release,但只有一个处于active(当两个互斥的值出现时,最后设置的处于active状态)
比如:
CONFIG = debug
CONFIG += release
这种情况下,release处于active状态,但,debug 和 release 都能通过上面的测试。
如何解决?
CONFIG(debug, debug|release) {
LIBS += -L../lib1 -lhellod
} else {
LIBS += -L../lib2 -lhello
}
或
CONFIG(debug, debug|release):LIBS += -L../lib1 -lhellod
CONFIG(release, debug|release):LIBS += -L../lib2 -lhello
那么,CONFIG(debug, debug|release)
这种语法是什么含义呢?
两个参数,前者是要判断的active的选项,后者是互斥的选项的一个集合。
什么叫active,也就是,最后一个给CONFIG添加的时debug还是release,下面例子:
CONFIG = debug release debug debug
CONFIG += debug
CONFIG += release
激活的是release
build_pass
qmake中反直觉的事情很多,build_pass
算一个。
当在工程文件.pro内使用 debug_and_release
选项(这是 Windows 下的默认选项)时,工程的.pro文件实际上会被处理三次:
- 一次生成:Makefile
- 一次生成: Makefile.Debug
- 还一次: Makefile.Release
例如:
build_pass: message("build pass")
else: message("non build pass")
message("Hello dbzhang800!")
运行qmake x.pro
,结果如下:
Project MESSAGE: non build pass
Project MESSAGE: Hello dbzhang800!
Project MESSAGE: build pass
Project MESSAGE: Hello dbzhang800!
Project MESSAGE: build pass
Project MESSAGE: Hello dbzhang800!
配合debug和release
pro文件内容:
build_pass: message("build pass")
else: message("non build pass")
CONFIG(debug, debug|release) {
message("debug")
} else {
message("release")
}
- 直接运行
qmake
,结果:
Project MESSAGE: non build pass
Project MESSAGE: release
Project MESSAGE: build pass
Project MESSAGE: release
Project MESSAGE: build pass
Project MESSAGE: debug
此时打开Makefile文件:
MAKEFILE = Makefile
first: release
...
- 直接运行
qmake CONFIG+=debug
,结果:
Project MESSAGE: non build pass
Project MESSAGE: debug
Project MESSAGE: build pass
Project MESSAGE: debug
Project MESSAGE: build pass
Project MESSAGE: release
此时打开Makefile文件:
MAKEFILE = Makefile
first: debug
...
参考
个人2010年前后在百度空间和CSDN中写过多篇qmake相关的blog,但是百度空间关闭后,很多记录找不回来了。本文是基于早期留存的记录片段进行整理而成。
由于不想重新查找资料并去一一核实,所以不贴参考链接了。