先附一篇参考链接

然后给cmake的官网帮助地址:https://cmake.org/cmake/help/v3.10/index.html

可以在上面找到所有的cmake命令的解释,cmake命令共分成4类

  • Scripting Commands 脚本命令
  • 项目命令
  • CTest Commands
  • Deprecated Commands 不推荐使用的命令

说一下QT建立工程的过程

cMakelist加入opencv_库文件

后面在编译选项的时候要选择cmake,它一开始默认是qmake,如果使用的是qmake,那么工程生成的是.pro的配置文件,所以这里要选择cmake,会生成cmakelist.txt的配置文件

cmake_minimum_required(VERSION 2.8)

project(test)
add_executable(${PROJECT_NAME} "main.cpp")

set(CMAKE_CXX_STANDARD 11)
find_package(OpenCV 4.4.0 REQUIRED)
target_link_libraries(test ${OpenCV_LIBS})

解释:

在项目新建完成之后,第1-3行是默认生成的。

1:版本要求指定 cmake 的最小版本

2:工程名设置项目名称

3:把项目名和执行主函数 放一块 执行//相当于生成可执行文件

这3个是cmake的最低配置要求

4:配置设置设置变量

set共有3个作用

1.普通变量

set(<variable> <value>... [PARENT_SCOPE])

设置变量<variable> 的值为 <value>

如果后面增加了 PARENT_SCOPE 选项的话, 表示 在上层作用域/目录 设置<variable> 的值为 <value>, 但是当前作用域/目录 该<variable> 的值不变。

2. 设置缓存条目

set(<variable> <value>... CACHE <type> <docstring> [FORCE])

设置给定的缓存变量<variable> 的值为 <value>.

由于缓存项旨在提供用户可设置的值,因此默认情况下不会覆盖现有缓存项。使用FORCE选项覆盖现有条目。

3.设置环境变量

set(ENV{<variable>} [<value>])

设置环境变量<variable>的值为<value>. 后面使用 $ENV{<variable>} 可以获取该值.

5:额外需要库

find_packag()是一个搜包命令,能够将第三方的开源库一整个直接导入进来。

根据cmake官方文档可以知道,find_package()有Module模式(基本用法,basic signature)和Config模式(full signature,完全用法),其中Module模式是基础,Config模式则更复杂高级些。

区分Module模式和Config模式

Module模式也就是基础用法(Basic Signature,这里Signature表示“用法”,而不是“签名”),Config模式也就是高级用法(Full Signature)

也就是说,只有这3种情况下才是Config模式:

  • find_package()中指定CONFIG关键字
  • find_package()中指定NO_MODULE关键字
  • find_package()中使用了不在"basic signature"(也就是Module模式下所有支持的配置)关键字

Module模式下find_package()的用法

find_package(<package> [version] [EXACT] [QUIET] [MODULE]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS components...]
             [NO_POLICY_SCOPE])

versionEXACT: 都是可选的,version指定的是版本,如果指定就必须检查找到的包的版本是否和version兼容。如果指定EXACT则表示必须完全匹配的版本而不是兼容版本就可以。

QUIET 可选字段,表示如果查找失败,不会在屏幕进行输出(但是如果指定了REQUIRED字段,则QUIET无效,仍然会输出查找失败提示语)。

MODULE 可选字段。前面提到说“如果Module模式查找失败则回退到Config模式进行查找”,但是假如设定了MODULE选项,那么就只在Module模式查找,如果Module模式下查找失败并不回落到Config模式查找。

REQUIRED可选字段。表示一定要找到包,找不到的话就立即停掉整个cmake。而如果不指定REQUIRED则cmake会继续执行。

COMPONENTScomponents:可选字段,表示查找的包中必须要找到的组件(components),如果有任何一个找不到就算失败,类似于REQUIRED,导致cmake停止执行。

OPTIONAL_COMPONENTScomponents:可选的模块,找不到也不会让cmake停止执行。

Module模式查找顺序
Module模式下是要查找到名为Find<PackageName>.cmake的文件。

先在CMAKE_MODULE_PATH变量对应的路径中查找。如果路径为空,或者路径中查找失败,则在cmake module directory(cmake安装时的Modules目录,比如/usr/local/share/cmake/Modules)查找。

后面还有configure模式下的用法,参考链接:https://www.jianshu.com/p/39fc5e548310

6:链接 所需要的库(工程名和库名) 特别容易出错

add_library(common STATIC util.cpp) # 生成静态库
add_library(common SHARED util.cpp) # 生成动态库或共享库

add_library 默认生成是静态库,通过以上命令生成文件名字,

  • 在 Linux 下是:
    demo
    libcommon.a
    libcommon.so
  • 在 Windows 下是:
    demo.exe
    common.lib
    common.dll

1.add_library该指令的主要作用就是将指定的源文件生成链接文件,然后添加到工程中去

//Normal Libraries
add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            source1 [source2 ...])

//Imported Libraries
add_library(<name> <SHARED|STATIC|MODULE|OBJECT|UNKNOWN> IMPORTED
            [GLOBAL])

//Object Libraries
add_library(<name> OBJECT <src>...)

//Alias Libraries
add_library(<name> ALIAS <target>)

//Interface Libraries
add_library(<name> INTERFACE [IMPORTED [GLOBAL]])

其中<name>表示库文件的名字,该库文件会根据命令里列出的源文件来创建。而STATIC、SHARED和MODULE的作用是指定生成的库文件的类型。STATIC库是目标文件的归档文件,在链接其它目标的时候使用。SHARED库会被动态链接(动态链接库),在运行时会被加载。MODULE库是一种不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数。默认状态下,库文件将会在于源文件目录树的构建目录树的位置被创建,该命令也会在这里被调用。

而语法中的source1 source2分别表示各个源文件。

 

2.link_directories     设置链接库搜索目录

link_directories(directory1 directory2 ...)

该指令的作用主要是指定要链接的库文件的路径,该指令有时候不一定需要。因为find_package和find_library指令可以得到库文件的绝对路径。不过你自己写的动态库文件放在自己新建的目录下时,可以用该指令指定该目录的路径以便工程能够找到。

 

3.target_link_libraries 设置 target 需要链接的库

该指令的作用为将目标文件与库文件进行链接。

target_link_libraries(<target> [item1] [item2] [...]
                      [[debug|optimized|general] <item>] ...)

上述指令中的<target>是指通过add_executable()和add_library()指令生成已经创建的目标文件。而[item]表示库文件没有后缀的名字。默认情况下,库依赖项是传递的。当这个目标链接到另一个目标时,链接到这个目标的库也会出现在另一个目标的连接线上。这个传递的接口存储在interface_link_libraries的目标属性中,可以通过设置该属性直接重写传递接口。

 

至此,完成整个工程项目的配置,如果有报错的情况,请根据错误信息百度解决

 

 

最后给一个参考链接,也是对于cmake语法的介绍,这个比较完整,我上面所述的是针对本次工程配置所需的语法使用介绍