CMake实践记录

作为一门比shell的语法还x疼的“语言”,不动动笔杆子真不行。

以下基本以flameshot 为例来学习。

覆盖掉CMakeCache中缓存的option

不推荐使用option(OPTION_NAME "Option description" OPTION_STATE),因为更改option状态时会被CMakeCache里的旧Option状态覆盖,且对subdirectory内的CMakeLists.txt作用效果不好。

推荐做法:set(OPTION_NAME OPTION_STATE CACHE OPTION_TYPE "Option description" FORCE)

  • OPTION_NAME:option名称。
  • OPTION_STATE:option状态,一般为ONOFF,推荐使用全大写。
  • CACHE:表示写入到CMakeCache里。
  • FORCE:表示强制覆盖CMakeCache里的值。

CMakeLists.txt内添加编译时变量

语法:add_compile_options("...")

例如MSVC开启强制utf-8:

1
2
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")

题外话,对应的在QMake内开启的方法为在.pro内添加:

1
2
3
win32-msvc* {
  QMAKE_CXXFLAGS += /utf-8
}

添加宏(MARCO)

语法:add_definitions(-DMARCO_NAME) 相当于编译时有了宏MARCO_NAME。

那么如何把宏去掉呢?

remove_definitions(-DMARCO_NAME)

include、output、link的顺序

include_directories,然后add_excutable,再add_subdirectories,最后target_link_libraries

CMake使用Qt5库

需要按以下几步走。

打开额外Compiler开关

1
2
3
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

分别编译Qt的元对象系统(信号槽,或者说使用了Q_OBJECT宏的地方)、Qt的资源文件*.qrc和Qt的UI文件*.ui

设定CMake的Modules

在尽量开头的位置设置CMAKE_PREFIX_PATH到Qt自带的cmake目录,如:

set(CMAKE_PATH_PREFIX /opt/Qt5.15.2/5.15.2/gcc_64/lib/cmake)

实际操作过程中推荐这样写:

set(CMAKE_PATH_PREFIX ${QT_CMAKE_PATH})

并在执行cmakeexport下:

export QT_CMAKE_PATH=/opt/Qt5.15.2/5.15.2/gcc_64/lib/cmake

(Windows下,使用QtCreator不需要export,如果用命令行的话使用git的bash,有export

检查Qt库(CMake modules)的安装情况

以使用QtCore、QtGui、QtWidgets为例,设定了CMAKE_PATH_PREFIX后:

find_package(Qt5 CONFIG REQUIRED Core Gui Widgets)

PS:似乎还有一种语法:

find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)

链接Qt动态库

基本在最后位置:

target_link_libraries(${BIN_NAME} Qt5::Core Qt5::Gui Qt5::Widgets)

上面的语句默认链接debug版本的动态库,若要链接release版本,增加optimized

target_link_libraries(${BIN_NAME} optimized Qt5::Core Qt5::Gui Qt5::Widgets)

包含子目录

  1. 在上层目录中,首先add_executable(BIN_NAME),之后add_subdirectories(sub_dir)
  2. 在子目录sub_dir中,target_sources(BIN_NAME srcfile1 srcfile2 ...)

target_sources的用法

target_sources不仅是添加源文件,同样可以添加*.qrc*.ui(前提是相关Compiler已打开)。

区分系统平台

立即推:

1
2
3
4
5
6
7
8
9
if(WIN32)
# do something...
elif(UNIX)
# do something...
elif(APPLE)
# do someting...
else()
# 醒醒吧
endif()

QtCreator中could not load cache的解决方法

可怜的qtc,bug满身,对Qml而言是,对CMake更是。

现在还坚持用qtc的原因只有方便看文档和上色丰富简单又好看了吧。

清除-重新构建后总是报错:could not load cache怎么办?

找到左边项目-CMake-Re-configure with Initial Parameters,点一下即可重新编译。

Windows平台rc文件的使用

使用target_sources添加即可。

注意:编码格式在设置了UTF-8以后无比不要用UTF-8-BOM,否则在编译时会报错。

关于*.rc文件的格式,参考flameshot.rc

Windows平台关闭控制台

使用WIN32参数:

add_executable(KeyContainer WIN32)

解决Cannot find source file: main.cpp

目录结构如下:

1
2
3
4
5
6
├─CMakeLists.txt
└─src
    │─CMakeLists.txt
    └─core
        │─CMakeLists.txt
        │─main.cpp

CMakeLists一层一层add_subdirectory。

add_executable时报错:Cannot find source file: main.cpp。

意外发现将CMake最低要求版本cmake_minimum_required设置到>=3.13,qtc默认给的是3.5。

题外话:直接在文件夹里cmake .没有这个报错,所以……彩鸡qtc。

署名 - 非商业性使用 - 禁止演绎 4.0