Qmake VS Cmake

Qmake VS Cmake用cmake构建Qt工程(对比qmake进行学习)cmakevsqmakeqmake是为Qt量身打造的,使用起来非常方便cmake使用上不如qmake简单直接,但复杂换来的是强大的功能内置的out-ofsource构建。(目前QtCreator为qmake也默认启用了该功能。参考:浅谈qmake之sha

大家好,又见面了,我是你们的朋友全栈君。

用 cmake 构建Qt工程(对比qmake进行学习)

cmake vs qmake

  • qmake 是为 Qt 量身打造的,使用起来非常方便
  • cmake 使用上不如qmake简单直接,但复杂换来的是强大的功能
    • 内置的 out-of source 构建。(目前QtCreator为qmake也默认启用了该功能。参考:浅谈 qmake 之 shadow build

    • 为各种平台和场景提供条件编译
    • 可处理多个可执行文件情况,和很好配合 QtTest 工作

如何选择?

Using CMake to Build Qt Projects 一文中说:

  • 对简单的Qt工程,采用 qmake
  • 对复杂度超过 qmake 处理能力的,采用 cmake

尽管如此,如果简单Qt的工程都不知道怎么用 cmake 构建,复杂的工程,就更不知道如何使用 cmake 了。还是从简单的学起吧

简单的 Qt 程序

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

如果不使用构建工具,直接调用编译器来编译的话,只需要类似这样的一条命令:

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

指定头文件目录,以及需要链接的库

qmake

qmake 需要一个 .pro 文件:

CONFIG += qt
QT -= gui
SOURCES += main.cpp
  • 因为我们需要 Qt的库和头文件,所以需要 CONFIG += qt 

    • 这是默认项,可直接去掉该行
  • 启用qt后,可以通过 QT -= gui 来进一步细调我们需要的模块
    • 默认是 core gui。我们不需要gui模块,故去掉。

cmake

cmake 需要一个 CMakeLists.txt 文件:

PROJECT(example)
FIND_PACKAGE(Qt4 REQUIRED)
SET(QT_DONT_USE_QTGUI TRUE)
INCLUDE(${ QT_USE_FILE})
ADD_EXECUTABLE(example main.cpp)
TARGET_LINK_LIBRARIES(example ${ QT_LIBRARIES})

  • FIND_PACKAGE 来启用 Qt4
  • 默认使用了core 和 gui,故手动禁用 QTGUI
    • 这两行可以直接使用 FIND_PACKAGE(Qt4 COMPONENTS QtCore REQUIRED),未指定的模块将被禁用

  • 包含一个CMake为Qt提供的配置文件,${QT_USE_FILE}变量是一个文件名
  • 添加可执行程序目标
  • 链接到 Qt 的库

复杂一点

考虑一个常规Qt程序:

  • main.cpp
  • mainwindows.ui
  • mainwindows.h
  • mainwindows.cpp

如果手动编译的话:

  • mainwindow.ui 需要使用 uic 预处理

uic mainwindow.ui -o ui_mainwindow.h
  • mainwindow.h 需要 moc 预处理

moc mainwindow.h -o moc_mainwindow.cpp
  • 调用编译器进行编译

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

qmake

使用 qmake 的的话,一个简单的 pro 文件

TARGET = example
TEMPLATE = app
SOURCES += main.cpp mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui

HEADERS 中的文件是否需要 moc 进行预处理,qmake 运行时会根据其是否含有Q_OBJECT自动判断。

这也是为什么 很多人添加Q_OBJECT宏后不重新运行qmake会出错误的原因。

cmake

看看相应的 cmake 的 CMakeLists.txt 文件

PROJECT(example)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
FIND_PACKAGE(Qt4 REQUIRED)
INCLUDE(${ QT_USE_FILE})
INCLUDE_DIRECTORIES(${ CMAKE_CURRENT_BINARY_DIR})
QT4_WRAP_CPP(example_MOCS mainwindow.h)
QT4_WRAP_UI(example_UIS mainwindow.ui)
ADD_EXECUTABLE(example main.cpp mainwindow.cpp ${ example_MOCS})
TARGET_LINK_LIBRARIES(example ${ QT_LIBRARIES})

  • 需要 moc 的文件,用 QT4_WRAP_CPP 处理
    • 生成的文件放入变量 example_MOCS 中,最后一块链接到可执行程序
  • 需要 uic 的文件,用 QT4_WRAP_UI 处理

Windows

因为windows下链接时分为 console 和 windows 两个子系统,所以windows下有些问题需要特殊处理。

用 qmake 时:

  • 默认是 windows 子系统
  • 可以通过 CONFIG += console 使用 console 子系统

用 cmake 是:

  • 默认是 console 子系统
  • 使用 windows 子系统需要

SET(QT_USE_QTMAIN TRUE)
ADD_EXECUTABLE(example WIN32 main.cpp mainwindow.cpp ${example_MOCS})

前者启用 qtmain.lib 库来提供windows下的 WinMain 入口函数。后者链接 windows 子系统

再复杂一点

  • main.cpp
  • mainwindows.ui
  • mainwindows.h
  • mainwindows.cpp
  • main.qrc
  • main.rc

前面已经用到了Qt的 moc 和 uic,这次增加了资源系统 需要用 rcc

rcc main.qrc -o qrc_main.cpp

同时,使用了windows下的资源文件 .rc (比如给程序添加图标)

  • MVSC 中使用 rc.exe 对 .rc 文件进行处理
  • MinGW 中使用 windres.exe 处理 .rc 文件

qmake

TARGET = example
TEMPLATE = lib
HEADERS = mainwindow.h widget.h
SOURCES = main.cpp widget.cpp mainwindow.cpp
RESOURCES = main.qrc
RC_FILE = main.rc

cmake

PROJECT(example)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
FIND_PACKAGE(Qt4 REQUIRED)
SET(QT_USE_QTMAIN TRUE)
INCLUDE(${ QT_USE_FILE})
INCLUDE_DIRECTORIES(${ CMAKE_CURRENT_BINARY_DIR})

if(MINGW)
set(CMAKE_RC_COMPILER_INIT windres)
ENABLE_LANGUAGE(RC)
SET(CMAKE_RC_COMPILE_OBJECT
"<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
endif(MINGW)

SET(example_SRCS main.cpp mainwindow.cpp widget.cpp res/main.rc)
SET(example_MOC_SRCS mainwindow.h widget.h)
QT4_WRAP_CPP(example_MOCS ${example_MOC_SRCS})
QT4_ADD_RESOURCES(example_RCC_SRCS main.qrc)
SET(example_SRCS ${ example_SRCS} ${ example_MOCS} ${ example_RCC_SRCS})

ADD_EXECUTABLE(example WIN32 main.cpp mainwindow.cpp ${ example_SRCS})
TARGET_LINK_LIBRARIES(example ${ QT_LIBRARIES})

  • 对Qt的资源文件,使用 QT4_ADD_RESOURCES 来调用rcc进行预处理
  • 对 Windows 资源文件,直接和源文件一样,添加到列表中即可。只是:
    • MinGW 下仅仅这么做还不行,上面的 MinGW 块用来修复这个问题

Debug 与 Release

qmake

使用 qmake 时,可以在 pro 文件内分别为两种模式设置不同的选项。

使用时,可以直接 make release 或 make debug 来编译不同的版本

cmake

不同于 qmake,由于 cmake 采用 out-of-source 方式。故:

  • 建立debug release两目录,分别在其中执行cmake -DCMAKE_BUILD_TYPE=Debug(或Release)
  • 需要编译不同版本时进入不同目录执行make

对生成 msvc 工程的情况, CMAKE_BUILD_TYPE 不起作用。生成工程后使用IDE自带的模式选择。

参考

trackback: http://hi.baidu.com/cyclone/blog/item/41651d95d86028187bf480eb.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/144217.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • String头文件_string头文件的作用

    String头文件_string头文件的作用首先说string的头文件1、<string>包装了std的C++头文件2、<string.h>旧的C头文件3、<cstring.h>旧C头文件的std版本,切记,这不是cstring的头文件详见effectivec++的第49条再说cstring的头文件注:VC9编译环境下1、<atlstr.h&g…

    2022年9月13日
    0
  • 520表白季,教你用matlab画动态心形曲线图,可自动保存GIF格式图片,送给女朋友,她们一定会惊讶,赶紧收藏!!!

    520表白季,教你用matlab画动态心形曲线图,可自动保存GIF格式图片,送给女朋友,她们一定会惊讶,赶紧收藏!!!昨天发表了一篇用python教你画心形图表白的文章:想要表白的看这里,教你用python画不同类型的心形图虏获芳心,值得收藏!!里面详细介绍了各种心形图的画法以及最终的表白神器,值得点赞收藏!!同样matlab也可以实现相同的功能并且还可以做得更好,今天就用教你用matlab画动态心形曲线图,不信请看下面:虏获芳心matlab画动态心形曲线图matlab画动态心形曲线图(基础版)matlab画3D心形图备注matlab画动态心形曲线图利用数学上的格式f(x)=x^2^/^3+e/3*(π-x^2

    2022年10月17日
    0
  • sbc 通信_ipc进程间通信

    sbc 通信_ipc进程间通信SBC在企业IP通信系统中的应用刘航2008/05/04  摘要:本文针对企业IP通信系统建设实施的两大问题:终端接入安全和IP多媒体业务NAT穿越,介绍了基于SBC(SessionBorderController,会话边界控制器)的解决方案,并提出了利用SBC辅助实现IP录音的一种新应用模式。  关键词:IP通信、SBC、NAT穿越、安全、IP录音一、引言

    2022年9月12日
    0
  • vue项目刷新当前页面的方法

    vue项目刷新当前页面的方法尝试了几种刷新页面的方法,比如1、浏览器直接刷新(会出现短暂的白页面现象)2、设置一个空白页面,需要刷新的时候跳转到空页面再从空页面跳回来(些许麻烦)3、使用provide/inject(目前觉得最实用,主讲此方法)…

    2022年8月31日
    0
  • linux tar 解压命令总结

    linux tar 解压命令总结把常用的tar解压命令总结下,当作备忘:tar-c:建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时可选的。-z:有gzip属性的-j:有bz2属性的-Z:有compress属性的

    2022年5月12日
    42
  • 视觉slam与激光slam_适马fpl 视频

    视觉slam与激光slam_适马fpl 视频SLAM(同步定位与地图构建),是指运动物体根据传感器的信息,一边计算自身位置,一边构建环境地图的过程,解决机器人等在未知环境下运动时的定位与地图构建问题。目前,SLAM的主要应用于机器人、无人机、无人驾驶、AR、VR等领域。其用途包括传感器自身的定位,以及后续的路径规划、运动性能、场景理解。SLAM按照传感器来分,分为视觉SLAM(VSLAM)和激光SLAM,视觉SLAM基于摄像

    2022年8月23日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号