cmake

注释行

CMake使用#进行行注释。可以放在任何位置。

# 这是一个 CMakeLists.txt 文件
cmake_minimum_required(VERSION 3.0.0)
注释块

CMake使用#[[ ]]形式进行块注释

#[[ 这是一个 CMakeLists.txt 文件。
这是一个 CMakeLists.txt 文件
这是一个 CMakeLists.txt 文件]]
cmake_minimum_required(VERSION 3.0.0)
cmake_minimum_required

指定使用的 cmake 的最低版本(可选,非必须,如果不加可能会有警告)

project

定义工程名称,并可指定工程的版本、工程描述、web 主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。

# PROJECT 指令的语法是:
project(<PROJECT-NAME> [<language-name>...])
project(<PROJECT-NAME>
       [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
       [DESCRIPTION <project-description-string>]
       [HOMEPAGE_URL <url-string>]
       [LANGUAGES <language-name>...])
add_executable

定义工程会生成一个可执行程序

add_executable(可执行程序名 源文件名称)
  • 这里的可执行程序名和project中的项目名没有任何关系

  • 源文件名可以是一个也可以是多个,如有多个可用空格或;间隔

# 样式1
add_executable(app add.c div.c main.c mult.c sub.c)
# 样式2
add_executable(app add.c;div.c;main.c;mult.c;sub.c)
set

定义变量

# SET 指令的语法是:
# [] 中的参数为可选项, 如不需要可以不写
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
  • VAR:变量名
  • VALUE:变量值
# 方式1: 各个源文件之间使用空格间隔
# set(SRC_LIST add.c  div.c   main.c  mult.c  sub.c)

# 方式2: 各个源文件之间使用分号 ; 间隔
set(SRC_LIST add.c;div.c;main.c;mult.c;sub.c)
add_executable(app  ${SRC_LIST})
list
# 追加(拼接)
list(APPEND SRC_1 ${SRC_1} ${SRC_2} ${TEMP})
# 移除 main.cpp
list(REMOVE_ITEM SRC_1 ${PROJECT_SOURCE_DIR}/main.cpp)
#获取 list 的长度。
list(LENGTH <list> <output variable>)
#读取列表中指定索引的的元素,可以指定多个索引
list(GET <list> <element index> [<element index> ...] <output variable>)
#将列表中的元素用连接符(字符串)连接起来组成一个字符串
list (JOIN <list> <glue> <output variable>)
#查找列表是否存在指定的元素,若果未找到,返回 - 1
list(FIND <list> <value> <output variable>)
#将元素追加到列表中
list (APPEND <list> [<element> ...])
#在 list 中指定的位置插入若干元素
list(INSERT <list> <element_index> <element> [<element> ...])
#将元素插入到列表的 0 索引位置
list (PREPEND <list> [<element> ...])
#将列表中最后元素移除
list (POP_BACK <list> [<out-var>...])
#将列表中第一个元素移除
list (POP_FRONT <list> [<out-var>...])
#将指定的元素从列表中移除
list (REMOVE_ITEM <list> <value> [<value> ...])
#将指定索引的元素从列表中移除
list (REMOVE_AT <list> <index> [<index> ...])
#移除列表中的重复元素
list (REMOVE_DUPLICATES <list>)
#列表翻转
list(REVERSE <list>)
#列表排序
list (SORT <list> [COMPARE <compare>] [CASE <case>] [ORDER <order>])
  • COMPARE:指定排序方法。有如下几种值可选:
  • STRING: 按照字母顺序进行排序,为默认的排序方法
  • FILE_BASENAME:如果是一系列路径名,会使用 basename 进行排序
  • NATURAL:使用自然数顺序排序
  • CASE:指明是否大小写敏感。有如下几种值可选:
  • SENSITIVE: 按照大小写敏感的方式进行排序,为默认值
  • INSENSITIVE:按照大小写不敏感方式进行排序
  • ORDER:指明排序的顺序。有如下几种值可选:
  • ASCENDING: 按照升序排列,为默认值
  • DESCENDING:按照降序排列
指定使用的C++标准
g++ *.cpp -std=c++11 -o app
#增加-std=c++11
set(CMAKE_CXX_STANDARD 11)
#增加-std=c++14
set(CMAKE_CXX_STANDARD 14)
#增加-std=c++17
set(CMAKE_CXX_STANDARD 17)
#增加-std=c++11
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=11
#增加-std=c++14
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=14
#增加-std=c++17
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=17
指定输出的路径

在 CMake 中指定可执行程序输出的路径,也对应一个宏,叫做 EXECUTABLE_OUTPUT_PATH,它的值还是通过 set 命令进行设置:

set(HOME /home/robin/Linux/Sort)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
  • 第一行:定义一个变量用于存储一个绝对路径
  • 第二行:将拼接好的路径值设置给 EXECUTABLE_OUTPUT_PATH
    • 如果这个路径中的子目录不存在,会自动生成,无需自己手动创建
aux_source_directory

在 CMake 中使用 aux_source_directory 命令可以查找某个路径下的所有源文件,命令格式为:

aux_source_directory(< dir > < variable >)

PROJECT_SOURCE_DIRCMAKE_CURRENT_SOURCE_DIR这个宏代表CMakeList.txt文件所在路径

  • dir:要搜索的目录
  • variable:将从dir目录下搜索到的源文件列表存储到变量中
cmake_minimum_required(VERSION 3.0)
project(CALC)
 
# 搜索 src 目录下的源文件
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src SRC_LIST)
add_executable(app  ${SRC_LIST})
file
file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型)
  • GLOB: 将指定目录下搜索到的满足条件的所有文件名生成一个列表,并将其存储到变量中。
  • GLOB_RECURSE:递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中。

搜索当前目录的 src 目录下所有的源文件,并存储到变量中

file(GLOB MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
file(GLOB MAIN_HEAD ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
  • CMAKE_CURRENT_SOURCE_DIR 宏表示当前访问的 CMakeLists.txt 文件所在的路径。

  • 关于要搜索的文件路径和类型可加双引号,也可不加:

  • file(GLOB MAIN_HEAD "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h")
    
制作静态库
add_library(库名称 STATIC 源文件1 [源文件2] ...) 
  • 在 Linux 中,静态库名字分为三部分:lib+ 库名字 +.a,此处只需要指定出库的名字就可以了,另外两部分在生成该文件的时候会自动填充。

  • 在 Windows 中虽然库名和 Linux 格式不同,但也只需指定出名字即可。

add_library(calc STATIC ${SRC_LIST})

这样最终就会生成对应的静态库文件 libcalc.a

制作动态库
add_library(库名称 SHARED 源文件1 [源文件2] ...) 
  • 在 Linux 中,动态库名字分为三部分:lib+ 库名字 +.so,此处只需要指定出库的名字就可以了,另外两部分在生成该文件的时候会自动填充。

  • 在 Windows 中虽然库名和 Linux 格式不同,但也只需指定出名字即可。

add_library(calc SHARED ${SRC_LIST})

这样最终就会生成对应的动态库文件 libcalc.so

LIBRARY_OUTPUT_PATH
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
链接静态库
link_libraries(<static lib> [<static lib>...])
  • 参数 1:指定出要链接的静态库的名字
  • 可以是全名 libxxx.a
  • 也可以是掐头(lib)去尾(.a)之后的名字 xxx
  • 参数 2-N:要链接的其它静态库的名字
link_directories(<lib path>)
链接动态库
target_link_libraries(
    <target> 
    <PRIVATE|PUBLIC|INTERFACE> <item>... 
    [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
  • target:指定要加载动态库的文件的名字

    • 该文件可能是一个源文件
    • 该文件可能是一个动态库文件
    • 该文件可能是一个可执行文件
  • PRIVATE|PUBLIC|INTERFACE:动态库的访问权限,默认为 PUBLIC

    • 如果各个动态库之间没有依赖关系,无需做任何设置,三者没有没有区别,一般无需指定,使用默认的 PUBLIC 即可。

    • 动态库的链接具有传递性,如果动态库 A 链接了动态库 B、C,动态库 D 链接了动态库 A,此时动态库 D 相当于也链接了动态库 B、C,并可以使用动态库 B、C 中定义的方法

target_link_libraries(A B C)
target_link_libraries(D A)


- `PUBLIC`:在 `public` 后面的库会被 Link 到前面的 target 中,并且里面的符号也会被导出,提供给第三方使用。
- `PRIVATE`:在 `private` 后面的库仅被 link 到前面的 target 中,并且终结掉,第三方不能感知你调了啥库
- `INTERFACE`:在 `interface` 后面引入的库不会被链接到前面的 target 中,只会导出符号。

动态库的链接和静态库是完全不同的:

静态库会在生成可执行程序的链接阶段被打包到可执行程序中,所以可执行程序启动,静态库就被加载到内存中了。
动态库在生成可执行程序的链接阶段不会被打包到可执行程序中,当可执行程序被启动并且调用了动态库中的函数的时候,动态库才会被加载到内存
因此,在 cmake 中指定要链接的动态库的时候,应该将命令写到生成了可执行文件之后。

```cmake
target_link_libraries(app pthread)
  • app: 对应的是最终生成的可执行程序的名字
  • pthread:这是可执行程序要加载的动态库,这个库是系统提供的线程库,全名为 libpthread.so,在指定的时候一般会掐头(lib)去尾(.so)。
日志
message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...)
  • (无) :重要消息

  • STATUS :非重要消息

  • WARNING:CMake 警告,会继续执行

  • AUTHOR_WARNING:CMake 警告 (dev), 会继续执行

  • SEND_ERROR:CMake 错误,继续执行,但是会跳过生成的步骤

  • FATAL_ERROR:CMake 错误,终止所有处理过程

CMake 的命令行工具会在 stdout 上显示 STATUS 消息,在 stderr 上显示其他所有消息。CMake 的 GUI 会在它的 log 区域显示所有消息。

CMake 警告和错误消息的文本显示使用的是一种简单的标记语言。文本没有缩进,超过长度的行会回卷,段落之间以新行做为分隔符。

# 输出一般日志信息
message(STATUS "source path: ${PROJECT_SOURCE_DIR}")
# 输出警告信息
message(WARNING "source path: ${PROJECT_SOURCE_DIR}")
# 输出错误信息
message(FATAL_ERROR "source path: ${PROJECT_SOURCE_DIR}")
宏定义
add_definitions(-D宏名称)
预定义宏
功能
PROJECT_SOURCE_DIR使用 cmake 命令后紧跟的目录,一般是工程的根目录
PROJECT_BINARY_DIR执行 cmake 命令的目录
CMAKE_CURRENT_SOURCE_DIR当前处理的 CMakeLists.txt 所在的路径
CMAKE_CURRENT_BINARY_DIRtarget 编译目录
EXECUTABLE_OUTPUT_PATH重新定义目标二进制可执行文件的存放位置
LIBRARY_OUTPUT_PATH重新定义目标链接库文件的存放位置
PROJECT_NAME返回通过 PROJECT 指令定义的项目名称
CMAKE_BINARY_DIR项目实际构建路径,假设在 build 目录进行的构建,那么得到的就是这个目录的路径
节点关系
  • 根节点 CMakeLists.txt 中的变量全局有效
  • 父节点 CMakeLists.txt 中的变量可以在子节点中使用
  • 子节点 CMakeLists.txt 中的变量只能在当前节点中使用
添加子目录
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

source_dir:指定了 CMakeLists.txt 源文件和代码文件的位置,其实就是指定子目录

条件判断
if(<condition>)
  <commands>
elseif(<condition>) # 可选快, 可以重复
  <commands>
else()              # 可选快
  <commands>
endif()
逻辑判断
if(NOT <condition>)
if(<cond1> AND <cond2>)
if(<cond1> OR <cond2>)
数值比较
if(<variable|string> LESS <variable|string>)
if(<variable|string> GREATER <variable|string>)
if(<variable|string> EQUAL <variable|string>)
if(<variable|string> LESS_EQUAL <variable|string>)
if(<variable|string> GREATER_EQUAL <variable|string>)
字符串比较
if(<variable|string> STRLESS <variable|string>)
if(<variable|string> STRGREATER <variable|string>)
if(<variable|string> STREQUAL <variable|string>)
if(<variable|string> STRLESS_EQUAL <variable|string>)
if(<variable|string> STRGREATER_EQUAL <variable|string>)
文件操作
#判断文件或者目录是否存在
if(EXISTS path-to-file-or-directory)
#判断是不是目录
if(IS_DIRECTORY path)
#判断是不是软连接
if(IS_SYMLINK file-name)
#判断是不是绝对路径
if(IS_ABSOLUTE path)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值