由于工作需要,最近打算统一将所有C/C++项目都改成使用cmake编译。传统后台业务问题不大,但是有些牵涉到跨平台的Qt项目还是折腾了一阵。下面对这段时间的收获做一个总结,也希望帮助看到本文的朋友少走弯路。特此声明,以下配置均为Qt5.6.3 MinGW 4.9.2 32位版本。

1. 基本配置项

1.1 moc ui和rcc编译开关

SET(CMAKE_AUTOMOC ON)
SET(CMAKE_AUTOUIC ON)
SET(CMAKE_AUTORCC ON)

1.2 启用C++11标准

* 如果在.h文件中直接对参数初始化或使用了nullptr等,请务必配置这一项

SET(CMAKE_CXX_STANDARD 11)

1.3 包含所有.h文件

* 有些只编写了.h文件,例如常量声明,结构体声明等,请务必配置这一项

SET(CMAKE_INCLUDE_CURRENT_DIR ON)

1.4 查找Qt模块

* 首先是CMAKE_PREFIX_PATH,对应各个模块的cmake文件路径,其次FIND_PACKAGE才能生效

SET(CMAKE_PREFIX_PATH <PREFIX_PATH>/lib/cmake)
FIND_PACKAGE(Qt5 COMPONENTS Core Xml Sql Gui Widgets REQUIRED)

1.5 引入外部头文件和动态链接库

* 我习惯在src的同级目录使用include和lib路径来保存依赖,这样让整个系统看起来更整洁

INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/../include)
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/../lib)

1.6 统一配置各目录层级的.cpp

* 网上有很多做法是每一个目录编写独立的CMakeLists.txt,但是个人感觉没有单一CMakeLists.txt文件配置方便,特别是如果各个目录间存在依赖的情况下更容易出错

AUX_SOURCE_DIRECTORY(./<mod_1> mod_1_src_list)
AUX_SOURCE_DIRECTORY(./<mod_2> mod_2_src_list)
AUX_SOURCE_DIRECTORY(. src_list)

1.7 指定最终编译产物的输出路径

* 和使用include和lib作为外部依赖路径类似,我也习惯在src的同级目录分别创建bin和out用来存放最终的编译产物

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../out)

1.8 区分release和debug生成的动态库

* 有时候为了方便调试,我们需要让debug版本的动态以d结尾

SET(CMAKE_DEBUG_POSTFIX d)

1.9 QDebug在release下依然可以输出函数名和行号

* 主要是为了保证日志数据有效

ADD_DEFINITIONS(-DQT_MESSAGELOGCONTEXT)

1.10 添加链接库

TARGET_LINK_LIBRARIES(${target} Qt5::Sql Qt5::Gui <lib>)

1.11 输出

ADD_EXECUTABLE(${target} ${SRC_LIST})
ADD_LIBRARY(${target} SHARED ${SRC_LIST})

1.12 根据release和debug分目录数据产物

* 主要是针对动态库产物的输出,分不同的目录更适合大型项目的统编

SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/../debug)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/../release)

1.13 添加自定义的宏

* 可以在项目中通过条件编译的方式选择不同的配置

OPTION(C_MODE "Use Customize Mode" ON)
IF(C_MODE)
# 其他指令
ENDIF()

改变代码的编译过程

// 在cmakelists.txt中定义
ADD_DEFINITIONS(-DTEST_DEBUG) // 配置源码中的条件编译
#ifdef TEST_DEBUG
...
...
#else
...
#endif

debug调试

ADD_DEFINITIONS("-Wall -g")

1.14 添加指定文件

* 一般来说,一个.cpp文件都会有一个.h来对应。编译的时候我们只需要告诉编译器所有的.cpp文件即可。例如:ADD_EXECUTABLE(sth ${cpp})。但是有时候,我们会定义一些结构体或常量,并将他们集中声明在一个.h文件里。

FILE(GLOB HEADER_FILES "*.h")
FILE(GLOB SOURCE_FILES "*.cpp")

1.15 安装与复制

* 当我们需要在编译完成以后执行copy或install的时候

FILE(COPY ${HEADER_FILES} DESTINATION ${PROJECT_SOURCE_DIR}/../include/${target})

INSTALL(TARGETS mylib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION libstatic)

2. 注意事项

2.1 如果是使用MinGW编译windows下的动态库不需要添加导出类的宏

2.2 LINK_DIRECTORIES 指令必须放在ADD_指令前

2.3 对多级目录的项目使用cmake做统编,每一个层级的编译应该使用动态库的方式

2.4 如果你使用的是QtCreator,自定义宏的方式可能不生效,但这并不是cmake的问题

3. Windows下如何使用cmake和gcc

3.1 安装MinGW Installation Manager和CMake的windows安装包,安装gcc编译工具链(mingw32-gcc, mingw32-gcc-g++, mingw32-make ...缺少的依赖可以从MinGW Installation Manager里面安装)

3.2 配置环境变量

*3.3 mingw32-make.exe 复制后重命名为 cmake.exe

3.4 指定编译方案:cmake -G   "MinGW Makefiles" . (如果编译器为vs的话使用"NMake Makefiles")

3.5 make 完成编译

*3.6 因为mingw已经不再更新,建议使用mingw-w64代替

Qt构建cmake工程方法总结的更多相关文章

  1. 【经验分享】win10 cmake 构建 Tengine 工程

      欢迎关注我的公众号 [极智视界],回复001获取Google编程规范   O_o   >_<   o_O   O_o   ~_~   o_O   本教程详细记录了在 win10 环境中 ...

  2. cmake使用方法详解

    cmake 简介 CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性 ...

  3. CMake 使用方法(转)

    CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的 ...

  4. 转:CMake 使用方法

    CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的 ...

  5. CMake 使用方法

    CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的 ...

  6. CMake 使用方法 & CMakeList.txt<转>

    CMake 使用方法 & CMakeList.txt cmake 简介 CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的make ...

  7. Qt程序打包发布方法(使用官方提供的windeployqt工具)

    Qt程序打包发布方法(使用官方提供的windeployqt工具) 转自:http://tieba.baidu.com/p/3730103947?qq-pf-to=pcqq.group Qt 官方开发环 ...

  8. 构建编译TVM方法

    构建编译TVM方法 本文提供如何在各种系统上构建和安装TVM包的说明.它包括两个步骤: 1.     首先从C代码构建共享库( libtvm.so for linux, libtvm.dylib fo ...

  9. 使用BLADE构建c++工程管理

    使用BLADE构建c++工程管理 字数764 阅读2753 评论2 喜欢4 一. c++工程依赖管理 之前在百度一直使用comake2构建c++项目,十分方便.免去了手写Makefile的痛苦,很多项 ...

  10. 解析Qt中QThread使用方法

    本文讲述的是在Qt中QThread使用方法,QThread似乎是很难的一个东西,特别是信号和槽,有非常多的人(尽管使用者本人往往不知道)在用不恰当(甚至错误)的方式在使用QThread,随便用goog ...

随机推荐

  1. SQL 注入漏洞详解 - Union 注入

    1)漏洞简介 SQL 注入简介 SQL 注入 即是指 Web 应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在 Web 应用程序中事先定义好的查询语句的结尾上添加额外的 SQL 语句,在 ...

  2. STM32开发环境配置记录——关于PlatformIO + VSCode + CubeMX的集成环境配置

    前言 ​ 为什么配置这样的一个环境呢?鄙人受够了Keil5那个简陋的工作环境了,实在是用不下去,调试上很容易跟CubeMX的代码产生不协调导致调试--发布代码不一致造成的一系列问题.CubeIDE虽说 ...

  3. Scratch全套Q版三国人物角色素材包免费下载

    全新Q版三国人物角色素材包,内含142张细腻可爱的Q版风格图片,涵盖三国名将.士兵.场景等丰富元素,为scratch爱好者提供多样选择,适合各类三国主题创作. 免费下载:www.xiaohujing. ...

  4. adb对安卓app进行抓包(ip连接设备)

    adb对安卓app进行抓包(ip连接设备) 一,首先将安卓设备的开发者模式打开,提示允许adb调试 二,自己的笔记本要和安卓设备在同一个网段下(同连一个WiFi就可以了) 三,在笔记本上根据ip来连接 ...

  5. 对比python学julia(第三章:游戏编程)--(第四节)捕鱼达人(5)

    4.3.    编程实现 (续上) 3. 实现射击捕鱼 在第 3 个阶段,将按照"编程思路"中介绍的射击捕鱼的算法进行编程,实现让玩家操控大炮射击捕鱼.在"bydr&qu ...

  6. MapGIS路网数据发布

    准备 1.MapGIS 10 桌面版(我用的10.5.6.10) 2.路网的shp文件 数据导入 1.创建要素集,如果已有要素集可以不用创建: 2.导入路网要素类,选择准备好的shp文件后导入即可: ...

  7. 【转载】 【树莓派】为Ubuntu Mate for ARM 更换中国软件源

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/wr132/article/details ...

  8. Jax计算框架的NamedSharding的reshape —— namedsharding-gives-a-way-to-express-shardings-with-names

    官方文档参考: https://jax.readthedocs.io/en/latest/notebooks/Distributed_arrays_and_automatic_parallelizat ...

  9. AI实践者师生夏令营讲座视频:南京大学Lamda实验室(周志华 团队)讲座视频 —— 强化学习的局限性与展望

    视频地址: 周志华团队与Intel团队的讲座视频--强化学习的局限性与未来展望 视频链接地址: https://bizwebcast.smarket.com.cn/b975d6d9969a42cba9 ...

  10. 【转载】sun的rpc ——rpcbind(nfs文件系统中的rpc)

    原文地址: https://blog.csdn.net/wangpeng138375/article/details/8169071 ================================= ...