浅谈 qmake 之 shadow build(就是将源码路径和构建路径分开)
译:用CMake构建Qt项目
作者: Johan Thelin 译者:赖敬文
原链接:http://developer.qt.nokia.com/quarterly/view/using_cmake_to_build_qt_projects
翻译来源:http://blog.csdn.net/jingwenlai_scut
QtSDK中已经包含了QMake用于处理跨平台的编译问题。然而,还存在其它编译工具,比如autotools,SCons和CMake.这些工具满足不同的需求,比如外部依赖。
当KDE项目从使用Qt3升级到使用Qt4时,整个项目将构建工具从autotools转而使用CMake.这使得CMake在Qt开发世界中在用户数以及功能支持和质量上占有了特殊的位置。从开发过程来看,QtCreator从1.1开始支持CMake (从1.3开始支持Microsoft的开发工具集).
1.一个基本的例子
在本文中我们将只关注CMake本身,并且指出如何将它与Qt结合起来。首先,我们看一个简单但典型的基于CMake的项目。从下面的列表可以看出,这个工程包括一些源代码及文本文件。
$ ls
CMakeLists.txt
hellowindow.cpp
hellowindow.h
main.cpp
最基本的,CMakeLists.txt文件将QMake需要使用到的工程文件替换了。如果需要编译这个工程,可以创建一个build目录,并在其内使用cmake及make来编译。
$ mkdir build
$ cd build
$ cmake .. && make
创建一个build目录的原因是我们想达到”out-of-source”编译的目的,即我们可以把编译过程中产生的中间文件与源代码隔离开来。当然,用qmake也可以做到这一点,但是需要做额外的一些步骤,但CMake可以很容易得做到这一点。
CMake 正在编译一个基本的项目
CMake中使用的参数代表指CMakeLists.txt文件所在的目录。这个CMakeLists.txt文件控制了整个编译的过程。为了更彻底地理解它,我们用以下这个图来看看整个编译的流程。下面这张图表明用户编写的文件(源代码,头文件,.ui文件,.qrc文件)在编译过程中是如何被Qt的工具进行处理,并整合到整个编译流程中的。因为qmake是用于处理这个流程的,它隐藏了这个流程中的很多细节。
Qt编译系统
当使用CMake的时候,这些中间过程必须要显式地进行处理。这也就是说,在头文件中如果有使用Q_OBJECT宏的话,则这个文件需要被moc进行处理,.ui文件也必须要由uic处理,.qrc文件需要由rcc程序处理。
在上面的例子中,我们简化了这些步骤,我们只需要处理包含了Q_OBJECT宏的头文件。也就是说,我们需要用moc对helloworld.h文件进行处理。与此工程相对应的CMakeLists.txt文件如下:
PROJECT(helloworld)
FIND_PACKAGE(Qt4 REQUIRED)
上述两句的意思指定义此工程为helloworld,并且让cmake自动去寻找Qt4,下面,我们需要用SET命令把需要定义的头文件与cpp文件等串起来.
SET(helloworld_SOURCES main.cpp hellowindow.cpp)
SET(helloworld_HEADERS hellowindow.h)
为了调用moc程序,需要使用 QT4_WRAP_CPP宏。 定义如下:
QT4_WRAP_CPP(helloworld_HEADERS_MOC ${helloworld_HEADERS})
这一步的作用实际上与在命令行中使用
$moc –o helloworld_moc.h helloworld.h
是类似的,上述的helloworld_HEADERS_MOC只是为了后续使用而取的名字。
为了编译这个Qt工程,需要包含Qt的库文件目录并且包含一些定义:
INCLUDE(${QT_USE_FILE})
ADD_DEFINITIONS(${QT_DEFINITIONS})
最后,CMake需要知道最终应用程序的名字以及加入链接库来生成它。这个在cmake中可以很方便地使用ADD_EXECUTABLE 和 TARGET_LINK_LIBRARIES. 因此,在CMakeLists.txt中加入如下:
ADD_EXECUTABLE(helloworld ${helloworld_SOURCES}
${helloworld_HEADERS_MOC})
TARGET_LINK_LIBRARIES(helloworld ${QT_LIBRARIES})
重新回顾上述CMakeLists.txt, 你会觉得相对于qmake来说,要多写一些配置,这实际上已经大大简化了,因为cmake并不是如qmake一样专为Qt而使用。
2.加入更多的Qt元素
从上面的最基本的例子继续,我们再在加入资源文件及UI文件。在上述的例子中增加了hellowindow.ui及images.qrc文件,相应的CMakeLists.txt增加以下的内容:
SET(helloworld_SOURCES main.cpp hellowindow.cpp)
SET(helloworld_HEADERS hellowindow.h)
SET(helloworld_FORMS hellowindow.ui)
SET(helloworld_RESOURCES images.qrc)
.qrc文件及.ui文件通过宏 QT4_WRAP_UI 和 QT4_ADD_RESOURCES进行处理。这些宏与QT4_WRAP_CPP的宏的作用是一样的,实际上都是在编译过程中调用相应的应用程序对其进行处理。即针对.qrc文件通过调用rcc程序对其处理,对.ui文件通过调用uic程序对其处理。对CMakeLists.txt增加内容如下:
QT4_WRAP_CPP(helloworld_HEADERS_MOC ${helloworld_HEADERS})
QT4_WRAP_UI(helloworld_FORMS_HEADERS ${helloworld_FORMS})
QT4_ADD_RESOURCES(helloworld_RESOURCES_RCC ${helloworld_RESOURCES})
同样地,这些中间生成的文件在最终生成应用程序的时候需要用到,因此,add_executable修改如下:
ADD_EXECUTABLE(helloworld ${helloworld_SOURCES}
${helloworld_HEADERS_MOC}
${helloworld_FORMS_HEADERS}
${helloworld_RESOURCES_RCC})
在编译之前,还有一个问题要处理,如上所述,我们要进行的是在源代码之外 的编译,因此,这些生成的中间文件都会在build目录下,这样的话,编译器则不能定位由uic程序产生的诸如ui_hellowindow.h等文件。所以,我们需要把build目录添加到包含目录中,如下:
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
加入这一行之后,所以中间生成的文件都会被包含在include路径中。
3.更多Qt 模块
目前为止,我们均只依赖于QtCore和QtGui模块。如果需要引用其它模块,cmake需要显式地开启它。通过set命令将特定的模块设置为TRUE则可。例如,如果要在程序中使用OpenGL的支持,则需要在CMakeLists.txt中使用如下这一行:
SET(QT_USE_QTOPENGL TRUE)
其它较常用的模块包括:
QT_USE_QTNETWORK
QT_USE_QTOPENGL
QT_USE_QTSQL
QT_USE_QTXML
QT_USE_QTSVG
QT_USE_QTTEST
QT_USE_QTDBUS
QT_USE_QTSCRIPT
QT_USE_QTWEBKIT
QT_USE_QTXMLPATTERNS
QT_USE_PHONON
此外,还有其它的宏可以用,具体地可参见cmake/share/Modules/FindQt4.cmake
4.获益与复杂性的平衡
如上可以看到,使用cmake并不如qmake轻松,但是cmake提供了更多的功能。最显著的获益是cmake支持”out-of-source”编译,这可能会更改使用习惯,但是这样做使得对源代码的版本跟踪变得更加方便。
同样地,使用cmake的另外一个好处是不只是针对Qt,cmake使得添加额外的库的支持变得更加容易,比如,针对不同的平台,链接不同的库或者是将Qt与其它库一起使用以构建较大型的程序,此时cmake的优势开始显现。
其它的强大的功能是具有了在一次设置的过程中产生不同版本的应用程序的能力,也就是说,针对一个单一的配置文件,可以产生多种不同的编译过程。
Cmake与qmake之间的选择其实很简单,对于只使用Qt的项目,qmake是个很好的先把。而当编译的需求超过了qmake的处理能力或者使用qmake配置变得很复杂时,cmake可以替代它。
http://blog.csdn.net/u013243710/article/details/36005539
浅谈 qmake 之 shadow build(就是将源码路径和构建路径分开)的更多相关文章
- 浅谈 qmake 之 shadow build(将源码路径和构建路径分开,一套源码要分别用msvc2008、msvc2008、mingw分别编译又不互相干扰)
shadow build shadow build 是什么东西?就是将源码路径和构建路径分开(也就是生成的makefile文件和其他产物都不放到源码路径),以此来保证源码路径的清洁. 这不是qmake ...
- 浅谈 qmake 之 shadow build
shadow build shadow build 是什么东西?就是将源码路径和构建路径分开(也就是生成的makefile文件和其他产物都不放到源码路径),以此来保证源码路径的清洁. 这不是qmake ...
- 浅谈MySQL Capabilities --从调研PHP mysqlnd源码细节角度认识
今天一起来研究下MySQL Capabilities,这个非常重要,如果大家有想法自己动手实现一个MySQL客户端或者Proxy工具,那么就得先了解一下这块,正好PHP 5.3以上版本由于官方为了规避 ...
- 浅谈qmake之pro、pri、prf、prl文件
浅谈qmake之pro.pri.prf.prl文件 转载自:http://blog.csdn.net/dbzhang800/article/details/6348432 尽管每次和cmake对比起来 ...
- 浅谈 qmake 之 pro、pri、prf、prl文件
尽管每次和cmake对比起来,我们总是说 qmake 简单.功能少.但是qmake仍然是一个非常复杂的东西,我想大多人应该和我一样吧: 不是太清楚CONFIG等变量到底如何起作用的 用过的qmake内 ...
- 在Mac OS 下 build Tesseract4.0 源码并在命令行中使用
作者电脑:Mac Mini 系统信息:OS X EI Capitan 10.11.6 Tesseract4.0github地址:https://github.com/tesseract-ocr/tes ...
- 浅谈Linux(Centos7.4)环境下NTP服务器的构建
一.软件环境 1.操作系统版本 [root@Geeklp201 etc]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core ...
- pom配置项目build jar 包含源码的配置
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> ...
- 从ApacheTomcat架构谈面试到源码编译环境v10.0.12
概述 开启博客分享已近三个月,感谢所有花时间精力和小编一路学习和成长的伙伴们,有你们的支持,我们继续再接再厉 **本人博客网站 **IT小神 www.itxiaoshen.com 定义 Tomcat官 ...
随机推荐
- 创业不要在IT业内创(市场太小,而且都喜欢自己折腾、没有花钱的习惯)
精神是好的.但是,我看了你的产品和网站:你选的创业方向基本是死路一条,我劝你该放弃就放弃.我判断你的思路还局限在IT行业内,创业不要在IT业内创,要走出去,睁开眼看看别人的世界,自己体会.我不是打击你 ...
- 【Xamarin挖墙脚系列:IOS现有的设备SDK /OS/硬件一览】
附件下载: http://pan.baidu.com/s/1o7rsrUE
- Lisp之根源
原文:http://www.paulgraham.com/rootsoflisp.html 约翰麦卡锡于1960年发表了一篇非凡的论文,他在这篇论文中对编程的贡献有如 欧几里德对几何的贡献.1 他向我 ...
- POJ 2579 Fiber Network(状态压缩+Floyd)
Fiber Network Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3328 Accepted: 1532 Des ...
- HDOJ-1012 u Calculate e(水)
http://acm.hdu.edu.cn/showproblem.php?pid=1012 简单套公式 # include <stdio.h> double Factorial(doub ...
- Python IDE的选择和安装
安装好Python后我们需要选择合适自己的IDE进行学习,虽然利用python默认的编辑器,或者直接文档编辑也可以进行基础的学习,但总归不是太方便,能够开发python项目的IDE很多,如sublim ...
- 深入浅出:重温JAVA中接口与抽象的区别
抽象类:声明一个抽象类,就是在类的声明开头.在Class关键字的前面使用关键字abstract 下面定义一个抽象类,代码如下: abstract class A{ abstract void call ...
- Linux shell 的 test 命令用法详解
基本格式:test expression expression为test命令构造的表达式.这里expression是test命令可以理解的任何有效表达式,该简化格式将是读者可能会踫见的最常用格式返回值 ...
- .net如何后台批量删除
button_Click(Sender sender,Event e){foreach (DataListItem item in DataList1.Items){CheckBox cbox=(Ch ...
- JQ 更改li 颜色
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...